在使用SN Write寫Ethernet MAC過程中出現了以下的錯誤:
ERROR!! Ethernet Mac:MetaResult = SPMETA_DLL::META_LID_INVALID。
複製程式碼
後來確認是AP_DB裡面沒找到AP_CFG_RDEB_FILE_ETHERNET_LID這個引數導致報錯的,需在NVRAM中新增乙太網的LID的引數。
本文就以AP_CFG_RDEB_FILE_ETHERNET_LID這隻LID新增過程為例,簡單說明客製化NVRAM的過程。
NVRAM介紹
Nvram: Non-volatile random access memory,是MTK平臺的一種機制。
主要的目的是:用來描述RAM中的資料型別,關機也不會丟失;手機重要的引數在恢復出廠設定或者升級被刪除後還能恢復。這些重要的資料包括兩部分:AP端和Modem端,這裡只介紹AP端部分。
AP端的主要有Wifi,Bt,Gps,sensor資料等。
Modem端的資料主要是打電話相關的引數,比如IMEI,RF等引數。
AP NVRAM Features:Backup
工廠Meta mode下做校準測試/寫號等操作,工具結束disconnect 前觸發backup動作, backup是從nvdata 分割槽(檔案系統)備份到nvram 分割槽(raw data)。
AP NVRAM Features:Restore
使用下載工具做韌體升級(firmware upgrade) 或者恢復出廠設定,會觸發restore動作。 Restore是從nvram分割槽還原到nvdata分割槽,如果nvram 分割槽內容為空,則用nvram default值還原。
不同專案的需求,NVRAM模組需要提供客製化配置,包括預設值和LID的資料結構NVRAM的資料分兩部分
1. Common 公共部分
MTK 平臺使用,可以看到相關LID的資料結構,但是不要修改它。
2. 為不同的專案客製化部分
給客製化用的,可以看到相關LID的資料結構,並且可以修改它。
客製化相關的資料夾在以下的幾個目錄
mediatek\custom\ [project] \cgen裡面有三個資料夾。
- cfgdefault 用來設定預設值的
- cfgfileinc 用來定義LID的資料結構的
- inc 用來支援NVRAM 模組功能的
NVRAM item的資訊
每一項的格式是:
- 檔案路徑
- 檔案版本
- 記錄的大小
- 記錄的總數
- 預設值的型別
- 預設值
- 資料轉換函式
舉例:
{
"/data/nvram/APCFG/APRDEB/ETHERNET", //1.檔案路徑
VER(AP_CFG_RDEB_FILE_ETHERNET_LID), //2.檔案版本
CFG_FILE_ETHERNET_REC_SIZE, //3.記錄的大小
CFG_FILE_ETHERNET_REC_TOTAL, //4.記錄的總數
SIGNLE_DEFUALT_REC, //5.預設值的型別
(char *)&stEthernetDefault, //6.預設值
DataReset , //7.資料轉換函式
NULL
}
/*注意,LID的順序,必須和某順序保持對應*/
複製程式碼
新增AP_CFG_RDEB_FILE_ETHERNET_LID
1、新增一個標頭檔案CFG_Ethernet_File.h,指定資料結構、記錄大小、記錄數目
路徑: mediatek/proprietary/custom/[Project]/cgen/cfgfileinc/CFG_Ethernet_File.h
#ifndef _CFG_ETHERNET_FILE_H
#define _CFG_ETHERNET_FILE_H
typedef struct
{
unsigned char addr[6];
} File_ETHERNET_Struct;
#define CFG_FILE_ETHERNET_REC_SIZE sizeof(File_ETHERNET_Struct)
#define CFG_FILE_ETHERNET_REC_TOTAL 1
#endif
複製程式碼
2、新增一個標頭檔案CFG_Ethernet_Default.h,描述LID的預設值
路徑:mediatek/proprietary/custom/[Project]/cgen/cfgdefault/CFG_Ethernet_Default.h
#ifndef _CFG_ETHERNET_D_H
#define _CFG_ETHERNET_D_H
File_ETHERNET_Struct stEthernetDefault =
{
/*{*/ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12 /*}*/ /* MAC ADDRESS */
};
#endif
複製程式碼
3、新增Item項的檔案版本
路徑:mediatek/proprietary/custom/[Project]/cgen/inc/Custom_NvRam_LID.h
在typedef enum新增新的LID:
AP_CFG_RDEB_FILE_ETHERNET_LID,
複製程式碼
新增版本資訊:
#define AP_CFG_CUSTOM_FILE_CUSTOM1_LID_VERNO “000”
複製程式碼
4、在g_akCFG_File_Custom新加item項
路徑:mediatek/proprietary/custom/[Project]/cgen/inc/CFG_file_info_custom.h
在TCFG_FILE g_akCFG_File_Custom[]中新增:
{
"/data/nvram/APCFG/APRDEB/ETHERNET", VER(AP_CFG_RDEB_FILE_ETHERNET_LID), CFG_FILE_ETHERNET_REC_SIZE,
CFG_FILE_ETHERNET_REC_TOTAL, SIGNLE_DEFUALT_REC, (char *)&stEthernetDefault, DataReset , NULL
},
複製程式碼
5、在Custom_NvRam_data_item.h中新增相應的資訊
路徑:mediatek/proprietary/custom/[Project]/cgen/inc/Custom_NvRam_data_item.h
LID_BIT VER_LID(AP_CFG_RDEB_FILE_ETHERNET_LID)
File_ETHERNET_Struct *CFG_FILE_ETHERNET_REC_TOTAL
{
};
複製程式碼
6、如果LID需要備份,將它新增到aBackupToBinRegion[]
路徑: mediatek/proprietary/external/nvram/libcustom_nvram/CFG_file_info.c
在aBackupToBinRegion[]中新增:
{"ETHERNET",AP_CFG_RDEB_FILE_ETHERNET_LID},
複製程式碼
通過以上六個步驟,我們已經成功的新增了AP_CFG_RDEB_FILE_ETHERNET_LID這隻NVRAM LID,此時我們可以使用SN工具將乙太網的MAC地址寫入NVRAM並且通過AP Editor讀取和設定NVRAM中的乙太網地址。
設定乙太網地址
我們想要實現的效果是:通過SN工具將乙太網地址寫入NVRAM中,並且在開機後可以檢視到乙太網地址為我們寫入的資料。
從nvram的角度來看,只能提供儲存ethernet mac地址的檔案路徑,以及檔案結構,想要實現最終的效果需要請ethernet driver的owner去開啟儲存資料的檔案,並讀取mac地址。
1、從NVRAM中讀取乙太網的地址
char dp[15] = {0}; //大小設定為15個位元組,如果太小,會出現錯誤
int result;
F_ID ethernet_nvram_id;
int file_lid = AP_CFG_RDEB_FILE_ETHERNET_LID; //乙太網的LID
int rec_size=0 , rec_num = 0;
File_ETHERNET_Struct ethernet_struct;
bool IsRead = true;
ethernet_nvram_id = NVM_GetFileDesc(file_lid, &rec_size, &rec_num, IsRead);
if(ethernet_nvram_id.iFileDesc < 0){
printf("NVM_GetFileDesc failed\n");
}
result = read(ethernet_nvram_id.iFileDesc, ðernet_struct , rec_size * rec_num);
if(result != rec_num*rec_size){
printf("Get file failed\n");
}
sprintf(dp, "%02x%02x%02x%02x%02x%02x", ethernet_struct.addr[0],ethernet_struct.addr[1],ethernet_struct.addr[2],ethernet_struct.addr[3],ethernet_struct.addr[4],ethernet_struct.addr[5]);
if(!NVM_CloseFileDesc(ethernet_nvram_id))
{
printf("NVM_CloseFileDesc failed\n");
}
複製程式碼
2、通過shell命令將mac地址寫入節點
char cmd[1024];
snprintf(cmd, 1024, "rtunicpg /efuse /nodeid %s", dp);
ALOGE("%s", cmd);
system(cmd);
複製程式碼