|
首頁┆日志┆博客┆推薦┆熱評┆熱門┆管理┆登錄浮躁的人 - zhuang0393的BLOG http://zhuang0393./ - 復制 - 收藏 正 文MTK之NVRAM研究(轉,寫的很好) (2011-2-25 18:49)原文地址:http://blog.csdn.net/MONKEY126/archive/2011/01/06/6119760.aspx MTK之NVRAM研究[一]
由NVRAM文件管理器管理的數據單元都是邏輯數據項,一個數據項可以被看作為一個固定大小的記錄,所以我們根據他們的記錄的大小將所有的邏輯數據項分為兩種類型; 1,透明數據元(Transparent EF):這個類型的數據項的記錄的大小為一個byte;因此,這種數據項可以認為是一系列的bytes; 2,線性固定數據元(linear fixed EF):這個類型的數據項的記錄的大小遠大于一個byte;所有的數據按線性存儲;
如下圖所示: 一,先來看“線性固定數據元” 首先我們來新建一項NV;分析每個步驟的原理; 總的步驟必須遵循如下幾步: 1,在文件:“nvram_user_defs.h”的枚舉結構體“nvram_LID_cust_enum”中定義一個新的LID:“NVRAM_EF_[new logical data item name]_LID”; 注意:請將新LID項加在NVRAM_EF_LAST_LID_CORE.之前; ex: NVRAM_EF_PORT_SETTING_LID; lzq:這個LID項的主要作用是什么呢?為什么一定要添加一個LID?因為NVRAM中的數據是在fs文件系統(tǒng)的管理中操作的,而文 件操作需要識別數據項和管理數據項,都是通過這個LID來操作的; 2,在文件:“nvram_user_defs.h”中定義兩個常量:SIZE和TOTAL;
ex: #define NVRAM_EF_PORT_SETTING_SIZE 16 #define NVRAM_EF_PORT_SETTING_TOTAL 1 lzq:既然是一塊內存,很明顯就必須要設置這塊內存的大??;這樣將結構體的數據保存和讀取時都很容易的操作到了特定的內存中; 并且有效的控制的內存不足和溢出的問題;就像是初始話一個數組的大小; (lzq_091216_補充:如果size是個結構體,則注意這個結構體的定義就和上面的定義寫在一起;) 如: #ifdef __HL_WEB_PHONE__ typedef struct { kal_uint8 status; //open or close; kal_uint32 phone_number[11]; //本機號碼; kal_uint8 number_exten[10];//號碼前綴; kal_uint8 number_zone[8]; //本地區(qū)號; }MY_WEB_PHONE; #define NVRAM_EF_MY_WEB_PHONE_DATA_SIZE sizeof(MY_WEB_PHONE) //MY_WEB_PHONE #define NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL 1 //1 #endif 3,在文件:“custom_nvram_editor_data_item.h”中定義版本號:“NVRAM_[new data item name]_LID_VERNO”。
ex: #define NVRAM_EF_PORT_SETTING_LID_VERNO "000" lzq:由于文件系統(tǒng)管理了這些NV數據;這些數據難免要進行各式的操作,比如修改,添加,刪除的操作,那么文件系統(tǒng)是怎么知道 它所管理的這些NV數據已經改變了呢?就是通過這個版本號來識別的,比如你修改了某個NV數據但沒有更該它的版本號,文件 系統(tǒng)是不會對原始數據更改的;只有在更改了NV值并且修改了版本號,這時文件系統(tǒng)才識別到已經更改,并進行相應的數據更新 例如 short類型NV的版本號是:NVRAM_EF_CACHE_SHORT_LID_VERNO ; 4,在文件:“nvram_user_config.c”中設置這個新nv項的默認值;
ex: static kal_uint8 const NVRAM_EF_PORT_SETTING_DEFAULT[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00 }; lzq:在申請了一塊內存后,需要進行初始化默認值;這樣在手機的異常時,比如恢復出廠設置時,NV將只載入默認值; 5,在文件:“nvram_user_config.c”中的結構體數組logical_data_item_table_cust[]中新添加一個條目(Add a new entry);
注意:這個新的條目是設置這個LID項的屬性的;以提供文件系統(tǒng)來對它操作; ex: { NVRAM_EF_PORT_SETTING_LID, NVRAM_EF_PORT_SETTING_SIZE, NVRAM_EF_PORT_SETTING_TOTAL, NVRAM_EF_PORT_SETTING_DEFAULT, NVRAM_ATTR_AVERAGE, NVRAM_CATEGORY_USER, "MP1y", //注意:在這里如果上個是MP1y,那么這里應該為加一為:MP2y,表明有新的條目添加了; VER(NVRAM_EF_PORT_SETTING_LID), "Port Settings\0", NVRAM_RESERVED_VALUE }, 6,在文件custom_nvram_editor_data_item.h 中添加結構體定義;這個結構體定義只為了在使用mata工具時,能看到的新添加的NV項的結構體數組中的各個值;如果不添加將在 mata工具中看不到這個新添加的nv項 ;
ex:這個是透明數據元byte在META工具中將要顯示的byte的NV項中所有記錄的字符串描述數組的結構體; typedef struct { kal_uint8 CacheByte[NVRAM_CACHE_SIZE]; } nvram_cache_byte_struct ; 7,在文件:custom_nvram_editor_data_item.h中.添加 bit-level 說明;這個也是只為了在mata工具中的操作而實現的;在程序中并用不到 ; ex:這個是byte項的NV 的META工具中的字符串初始化默認值; LID_BIT VER_LID(NVRAM_EF_CACHE_BYTE_LID) nvram_cache_byte_struct *NVRAM_CACHE_TOTAL { CacheByte:"One-byte parameter setting "; CacheByte[14] { default_lang:8 "Default Language " { }; }; CacheByte[24] { time_zone:8 "Time Zone (Current City )" { }; }; CacheByte[25] { date_format:8 "Time Format " { }; }; CacheByte[26] { date_format:8 "Date Format " { }; }; }; 整個過程如下圖: lzq總結:NV數據實現了數據的讀寫保護,保證了數據在手機上正常而安全的使用;我們知道對于手機上的一些屬性值,比如開機聲音,待機畫面等是由一些數據來控制的 ,這些數據是全局的,可以在隨時隨地的對它調用;如果是在一個游戲應用中,我們只要將它設置為一個全局的變量,在游戲開始時進行初始化就可以了;但在手機上我們必須保
證這些數據不能丟失,并且在整個系統(tǒng)運行中當系統(tǒng)出現數據損壞并崩潰時,這些數據也是不會被丟失和更改;保證了手機系統(tǒng)的安全運行;也許我們可以說為什么不用一個文件
來保存這些數據呢?我們知道如果用文件的話,雖然實現了數據的異地保存,但一旦這個文件丟失,將導致系統(tǒng)致命錯誤;另外,這些數據接受用戶的個性修改,如果用文件保存
的話,數據修改并不方便;而且在讀寫速度上明顯不及直接NVRAM存儲器的操作;因此,我們可以這樣認為,NV讓我們將一些數據從全局中取了出來,并放入了一個不能擦除的存
儲器中保護起來;
接下來讓我們看看NVRAM的結構:
從上圖中我們發(fā)現,在文件系統(tǒng)中Data Item Management System 管理著NVRAM;而這個管理系統(tǒng)(Data Item Management System)通過內部的一個查詢表(lookup table)來獲
得每個數據項的具體細節(jié);
而這個查詢表(lookup table )包含以下4個部分: 1. MT reign, for project independent data items; 2. MP reign, for MTK /PMT common applications; 3. CT reign, for the customer usage. 4. CV reign, for the vendor of customer usage. 下圖顯示了NVRAM定制文件布局。我們經常操作的文件一般在CT部分;
NVRAM LID 的定義部分都在以下幾個文件中進行:
- nvram_data_items.h : for MT use - nvram_data_items.c : for MT use - nvram_common_defs.h : for MP use - nvram_common_config.c : for MP use - nvram_user_defs.h : for CT use - nvram_user_config.c : for CT use - nvram_cust_pack.c: for CustPack use - nvram_vendor_config.c: for CV use - nvram_vendor_defs.h: for CV use META tool 的說明介紹內容都在以下幾個文件中實現;: - nvram_editor_data_item.h: for MT use - common_nvram_editor_data_item.h : for MP use - custom_ nvram_editor_data_item.h : for CT use - vendor_nvram_editor_data_item.h: for CV use 現在我們回頭去看步驟5,添加新的條目的操作中,我們會問,為什么要添加新的條目,而且在這些變量中,各個項的涵義是什么呢? 如下: ex: { NVRAM_EF_PORT_SETTING_LID, NVRAM_EF_PORT_SETTING_SIZE, NVRAM_EF_PORT_SETTING_TOTAL, NVRAM_EF_PORT_SETTING_DEFAULT, NVRAM_ATTR_AVERAGE, NVRAM_CATEGORY_USER, "MP1y", VER(NVRAM_EF_PORT_SETTING_LID), "Port Settings\0", NVRAM_RESERVED_VALUE }, 我們剛才知道了,管理系統(tǒng)(Data Item Management System)通過內部的一個查詢表(lookup table)來獲得每個數據項的具體細節(jié)的,我們在這里實現的這個新的條目就是為 了讓管理系統(tǒng)通過查詢表來找到它并對它進行操作;所以每個新的LID都要來這里添加新的條目;
那么每個新的條目的具體的數據結構是什么樣的呢?如下是它的定義: typedef struct { nvram_lid_enum LID; kal_uint16 size; kal_uint16 total_records; kal_uint8 const *default_value; nvram_attr_enum attr; nvram_category_enum category; kal_char fileprefix[FILE_PREFIX_LEN + 1]; kal_char fileverno[FILE_VERNO_LEN + 1]; kal_char *description; kal_uint8 record_ID; } ltable_entry_struct; 具體涵義如下:
接下來分別分析一些具體數據項的涵義:
1,屬性attr ; 屬性選項是個可選的,它由枚舉:nvram_attr_enum定義: NVRAM_ATTR_AVERAGE: 0x0000 //這是個默認的屬性選項; NVRAM_ATTR_IMPORTANT: 0x0001 //當一個IMPORTANT的數據項被更改時,會先將相關程序停止,并被要求進行備份和保存, //只有在成功備份和保存后,才會將程序重新安全開啟; NVRAM_ATTR_WRITEPROTECT: 0x0002 //寫保護,只讀; NVRAM_ATTR_MULTIPLE: 0x0004 //如果一個數據項的屬性是multiple,那么NVRAM會自動將它做一個備份,并當在其中有一個數據 //被損壞時,NVRAM會從另個數據中將它還原; NVRAM_ATTR_CONFIDENTIAL: 0x0008 //對數據采用對稱算法進行加密或解密;所以:mulitiple+confidential能實現最好的數據保護; NVRAM_ATTR_MULTIREC_READ: 0x0010 //適用于那些需要一次性對一數據進行多次讀取操作的數據項; NVRAM_ATTR_OTP: 0x0020 //This attribute is supported only if One Time Programming (OTP) function exists on the flash storage. NVRAM will //maintain a small table to OTP region; the table consists of all OTP data items, by order in the lookup table.
NVRAM_ATTR_DIFFERENCE: 0x0080 //NVRAM保留。 2,模板category; 這個選項和attr非常相似,可以說是attr的分支;一個數據項可以屬于很多category的或者是很多數據項屬于一個category;所以NVRAM需要找到那些需要被category重 新設置的數據項;它的枚舉包含如下:
NVRAM_CATEGORY_USER: 0x0000 //默認屬性; NVRAM_CATEGORY_SYSTEM: 0x0001 //一旦版本號更改,這個數據項將被初始化為默認值; NVRAM_CATEGORY_COMPOSED: 0x0002 //NVRAM 保留; NVRAM_CATEGORY_FACTORY: 0x0004 //當MSG_ID_NVRAM_RESET_REQ隨著 reset_category = NVRAM_RESET_FACTORY,NVRAM 將重新設置NVRAM_CATEGORY_FACTORY的值,并且清除預定義的文件和設置; NVRAM_CATEGORY_MULTI_DEFAULT: 0x0008 //這樣的數據項的每個記錄可能有不能的值,但是所有的默認值必須在一個連續(xù)的數組里。 NVRAM_CATEGORY_CUSTPACK: 0x0010 //NVRAM will auto assign default values in CustPack BIN to this category. Once the version of CustPack BIN changes, NVRAM_CATEGORY_CUSTPACK will be reset to default.
NVRAM_CATEGORY_BRANCH: 0x0020 //This category of data item will be kept even the branch number of software version changes. Every time the branch number is different from previous one, NVRAM will clear all data items except NVRAM_CATEGORY_BRANCH. NVRAM_CATEGORY_SHADOW: 0x0040 //This category is only used for single bank NOR-flash. With single bank NOR-flash, only this category could be modified in normal mode. NVRAM uses Shadow mechanism to
make device type transparent to applications. Please see chapter 7. to get more details.
IMPORTANT: Shadow needs additional memory. NVRAM_CATEGORY_SHADOW_MS: 0x0080 //When USB boot mode, all data item can’t be accessed because of storage exporting. Thus NVRAM uses Shadow mechanism to make a few applications still can access their data.
IMPORTANT: Shadow needs additional memory. 我們再來看看LID文件的命名和LID的版本號規(guī)則: File Name Format: (0~3) File Name ( 4) M. (5~7) Version 1. File Name: The first 4 bytes of the File Name Format are used for the file name, which needs to be distinguishable from all other file names. The File naming rule: - Data items in the core: MT[x][y], where x and y in the range (0~9, a~z) - Data items in custom/common folder: MP[x][y] , where x and y in the range (0~9, a~z) - Data items in custom/app folder: CT[x][y] , where x and y in the range (0~9, a~z) - Data items in vendor folder: CV[x][y] , where x and y in the range (0~9, a~z) - 4-byte filenames. The file naming MT[x][y], MP[x][y] ,CT[x][y] and CV[]x[y] allow maximum sequence number up to 36*36 = 1296 each. IMPORTANT: Any file name MUST be unique. 2. M byte: The byte is used to indicate the ‘multiple’ attribute of the data item. - If a data item is defined to be ‘multiple’, M can be ‘a’ or ‘b’ to represent two copies of the file. - If a data item is defined w/o the ‘multiple’ attribute, M will be ‘_’. 3. Version: Three human-readable digits, for example, ‘000’ the version number is incremented when a data item is added / deleted or its data structure is changed, or its attribute is changed. For ease of reading, the 3-byte version number can be used from 000 ~ 999. That means a single LID can be versioned 1000 times. If the limit is hit, a work-around is to delete the LID and make it a new one with version 000. MTK之NVRAM研究[二] 二,再來看“透明邏輯數據元” 這樣的數據項已經實現了的三個數據項: 1,byte 數據項; 2,short數據項; 3,double數據項; 這些數據項都已經實現了數據項LID的定義,數據項的定義和值的定義;如: LID: 在文件Nvram_user_defs.h中: NVRAM_EF_CACHE_BYTE _LID = NVRAM_LID_CUST_BEGIN,
NVRAM_EF_CACHE_SHORT _LID, NVRAM_EF_CACHE_DOUBLE _LID, size:custom_mmi_default_value.h中: #define NVRAM_CACHE_SIZE 512 //很明顯byte,short ,double的數據項都有512個記錄,一個記錄只有一個byte值 ; #define NVRAM_CACHE_TOTAL 1 新增數據項在文件:Nvram_user_config.h中 ltable_entry_struct logical_data_item_table_cust[] = { { NVRAM_EF_CACHE_BYTE_LID, NVRAM_CACHE_SIZE, // 512 NVRAM_CACHE_TOTAL, //1 NVRAM_EF_ZERO_DEFAULT, NVRAM_ATTR_AVERAGE, NVRAM_CATEGORY_USER | NVRAM_CATEGORY_CUSTPACK | NVRAM_CATEGORY_SHADOW_MS, "CT00", VER(NVRAM_EF_CACHE_BYTE_LID), "1-byte Setting\0", NVRAM_RESERVED_VALUE } ,{ NVRAM_EF_CACHE_SHORT_LID, NVRAM_CACHE_SIZE, // 512 NVRAM_CACHE_TOTAL, // 1 NVRAM_EF_ZERO_DEFAULT, NVRAM_ATTR_AVERAGE, NVRAM_CATEGORY_USER | NVRAM_CATEGORY_CUSTPACK | NVRAM_CATEGORY_SHADOW_MS, "CT01", VER(NVRAM_EF_CACHE_SHORT_LID), "2-byte Setting\0", NVRAM_RESERVED_VALUE } ,{ NVRAM_EF_CACHE_DOUBLE_LID, NVRAM_CACHE_SIZE, //512 NVRAM_CACHE_TOTAL, //1 NVRAM_EF_ZERO_DEFAULT, NVRAM_ATTR_AVERAGE, NVRAM_CATEGORY_USER | NVRAM_CATEGORY_CUSTPACK | NVRAM_CATEGORY_SHADOW_MS, "CT02", VER(NVRAM_EF_CACHE_DOUBLE_LID), "8-byte Setting\0", NVRAM_RESERVED_VALUE } ... 默認值: kal_uint8 const NVRAM_EF_ZERO_DEFAULT[] = { 0x00 }; 我們先來看一個條目的數據結構: 上圖中顯示,當total_records == 1時,說明這個LID為透明數據元,size就表示這個邏輯數據項的大??;比如byte,那么就是size=1*512; 如果 total_records != 1 時,說明這個LID為線性固定數據元,total_records 就是記錄的個數,size就是每個記錄的大??; ( lzq注 :我們從這兩種數據元的特征中可以得出這樣的結論: 透明數據元相當于一維數組;已經實現了的數據項LID就相當于一個數組byte record[ Record_ID ]; 其中數組個數512; Recodr_ID為枚舉ID; short record2[ Record_ID ]; //Record_ID由用戶自己定義并初始化;
double record3[ Recodr_ID ];
線性固定數據元相當于二維數組 :已經實現了的數據項LID就相當于My_type_struct records[ total_records ][ size ]; )
由此分析,我們可以直接當做一個byte數據項的一個記錄來直接添加到里面;即在數組record[]中的某個位置從新添加一個值;而不需要另外去實現一個新的byte的LID;大大的 簡化了操作;而且在byte,short,double的數據項里新添加一個數據很方便,具體只有兩步驟:
1,定義menu_ID typedef enum { ...... #ifdef __HQ_CLAMSHELL_TONE__CONTROL__ //參考yj的一個滑蓋聲音模塊的LID; NVRAM_CLAMSHELL_TONE_CONTROL_SETTING, //定義一個Record_ID; #endif ...... NVRAM_LAST_BYTE_ELEMENT } BYTEDATA; 2,將這個數組值設置一個默認值; #ifdef __HQ_CLAMSHELL_TONE__CONTROL__ BYTE_ENTRY( NVRAM_CLAMSHELL_TONE_CONTROL_SETTING , 0x01 ), //默認值為0x01; #endif Appendix: 一,當數據都已經定義完后剩下的就是怎么使用這個數據了; 對透明數據(一維數組)的讀寫操作有: WriteValue (NVRAM_CLAMSHELL_TONE_CONTROL_SETTING, &data, DS_BYTE, &error); ReadValue (NVRAM_CLAMSHELL_TONE_CONTROL_SETTING, &data, DS_BYTE, &error); 對線性固定數據元(二維數組)的讀寫操作有: ReadRecord ( NVRAM_EF_TIMING_SMS_LIST_LID, //參考宏:__HQ_TIMING_SMS__ (U16) (i + 1), (void*)&(g_timingsms_cntx.TaskList[i]), NVRAM_TIMING_SMS_LIST_RECORD_SIZE, &error); WriteRecord ( NVRAM_EF_TIMING_SMS_LIST_LID, (U16) (index + 1), (void*)&(g_timingsms_cntx.TaskList[index]), NVRAM_TIMING_SMS_LIST_RECORD_SIZE, &error); 二,現在來看下NVRAM的META工具中用到的‘位級別的注釋’(bit_level description); 也就是在上面的步驟6和步驟7中的操作; 先讓我們來看個資料:NVRAM LID腳本 這個特殊的腳本能夠用來描述NVRAM LID;在編譯的過程中,這個腳本會解析并且將信息保存到有cgen.exe生成的數據庫中;PC工具(如META工具)可以利用這個數據庫去 解析這個LID的原始數據;這個腳本可以被保存在一個頭文件中并將在由cgen.exe解析之前進行預處理;程序員可以利用標準c語言(,//注釋)去編程,并且可以用宏 “#define
” 去控制;
例如: typedef struct { kal_uint8 context_id;
kal_uint8 nsapi; kal_uint8 pdp_addr_type; kal_uint8 pdp_addr_len; kal_uint8 addr_val[4]; qos_struct req_qos; qos_struct min_qos; kal_uint8 apn_len; kal_uint8 apn[100]; kal_uint8 pcomp_algo; kal_uint8 dcomp_algo; kal_uint8 context_type; kal_uint8 primary_context_id; kal_uint8 is_sib_defined; } nvram_ef_tcm_PDP_profile_record_struct; //lzq:第六步:定義META工具使用的數據結構 ;
typedef struct {
kal_uint8 qos_length;
kal_uint8 unused1; kal_uint8 delay_class; kal_uint8 reliability_class; kal_uint8 peak_throughput; kal_uint8 unused2; kal_uint8 precedence_class; kal_uint8 unused3; kal_uint8 mean_throughput; kal_uint8 traffic_class; kal_uint8 delivery_order; kal_uint8 delivery_of_err_sdu; kal_uint8 max_sdu_size; kal_uint8 max_bitrate_up_lnk; kal_uint8 max_bitrate_down_lnk; kal_uint8 residual_bit_err_rate; kal_uint8 sdu_err_ratio; kal_uint8 transfer_delay; kal_uint8 traffic_hndl_priority; kal_uint8 guarntd_bit_rate_up_lnk; kal_uint8 guarntd_bit_rate_down_lnk; } qos_struct; //lzq:在這個例子中,有嵌入式結構體定義;實現原理一樣,不過要用到'" 、"來獲得子成員變量
;
BEGIN_NVRAM_DATA
LID_BIT VER_LID(NVRAM_EF_TCM_PDP_PROFILE_LID) nvram_ef_tcm_PDP_profile_record_struct*1 { context_id: "" {}; //lzq:這個是上面定義的數據結構(第6步中實現的)nvram_ef_tcm_PDP_profile_record_struct中的成員變量 ;
addr_val: "Statistic PDP address value, in MSB" {};//lzq:語法: 結構體成員變量名?。?描述語" {更多子項,可以為空 }; addr_val[0] { addr_v1:4 " Address Value 1" {}; addr_v2:4 " Address Value 2" {}; }; req_qos: "Requested QoS" {}; req_qos.qos_length: "Length of QoS" {}; req_qos.unused1: "Delay Class" { req_qos_identifier:3 " Request QoS Identifier" { 0x0:"Req QoS Invaild"; 0x2:"Req QoS Vaild"; 0x4:"Req QoS Under Verifing"; }; req_qos_list:2 { 0x0:"Req QoS List 1"; 0x1:"Req QoS List 2"; 0x2:"Req QoS List 3"; }; }; req_qos.delay_class: "Delay Class" {}; req_qos.reliability_class: "Reliability Class" { reliablity_class:8 { 0x00: "Realiablity Class Zero"; 0x01: "Realiablity Class Low"; 0x02: "Realiablity Class Medium"; } } req_qos.peak_throughput: "Peak Throughput" {}; apn: "APN string" {} ; };
END_NVRAM_DATA 再來看第二個例子,透明數據員bity的描述實現: typedef struct { kal_uint8 CacheByte[NVRAM_CACHE_SIZE]; } nvram_cache_byte_struct; LID_BIT VER_LID(NVRAM_EF_CACHE_BYTE_LID) nvram_cache_byte_struct *NVRAM_CACHE_TOTAL { CacheByte :"One-byte parameter setting"; CacheByte [14] //lzq:這里表示在結構體成員變量CacheByte[]數組的第14個數據項的描敘 ; { default_lang:8 "Default Language" //default_lang: 8 ---表示直接顯示這個串; "Default Language"---表示對這個數據項的補充說明; { }; }; CacheByte[24] //lzq:這里表示在結構體成員變量CacheByte[]數組的第24個數據項的描敘 ; { time_zone:8 "Time Zone (Current City)" { }; }; CacheByte[25] //lzq:這里表示在結構體成員變量CacheByte[]數組的第25個數據項的描敘 ; { date_format:8 "Time Format" { }; }; CacheByte[26] //lzq:這里表示在結構體成員變量CacheByte[]數組的第26個數據項的描敘 ; { date_format:8 "Date Format" { }; }; 更多的實現功能可以參考原程序中的定義實現,再結合META工具去查看該數據項的顯示效果; lzq自己添加的LID項,如下圖; 在實現的過程中,遇到一個問題: 當我們完成所有的步驟(7步)后,當用META工具察看時卻發(fā)現不了自己新添加的那個LID:NVRAM_EF_MY_NEW_DATA_LID; 分析原因: 沒有看到LID說明兩個問題:1,在實現的過程中有的地方出錯; 2,在用META工具查看時,選擇了不對的datebase(數據庫),導致手機database和META工具的database 版本不對;
操作: 在檢查了所有的原代碼后,確認沒有出錯,再從新new了一遍后,重新用META工具查看時,出現如下圖的錯誤: 說明在選擇database時選擇了錯誤的版本,因此用META工具看到的還是原來的老的版本的數據,因此看不到我們新添加的LID; end 2009-7-17 下午 05:36:39 MTK之NVRAM研究[三] 一,下面來具體看看兩個不同的NV項的實現過程,具體的步驟還是和上面的一樣的; 這里面實現兩中NV項: NV項一:_LZQ_TEST_ :他的數據結構比較簡單,只是一個數組; NV項二:__HL_WEB_PHONE__ :他的數據結構是個結構體,和NV項一相比有些地方實現不一樣; 具體實現如下: //--------------------在文件中定義NV項的LID:nvram_user_defs.h----------
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
NVRAM_EF_MY_NEW_DATA_LID, #endif #ifdef __HL_WEB_PHONE__
NVRAM_EF_MY_WEB_PHONE_DATA_LID, #endif //--------------------在文件中定義NV項的大小和個數:nvram_user_defs.h---------- #ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
#define NVRAM_EF_MY_NEW_DATA_SIZE 10 // 10 byte each record #define NVRAM_EF_MY_NEW_DATA_TOTAL 9 //9 records #endif #ifdef __HL_WEB_PHONE__
typedef struct { kal_uint8 status; //open or close; kal_uint32 phone_number[11]; //本機號碼; kal_uint8 number_exten[10];//號碼前綴; kal_uint8 number_zone[8]; //本地區(qū)號; }MY_WEB_PHONE; #define NVRAM_EF_MY_WEB_PHONE_DATA_SIZE sizeof(MY_WEB_PHONE) //MY_WEB_PHONE #define NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL 1 //1 #endif //lzq說明:注意這里,新添加的NV項如果用到了數據結構,則一定要和它聲明結構體大小的地方一起聲明,不然編譯時找不到結構體; //---------------------------在文件中設置NV的默認值:nvram_user_config.c---------
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
static kal_uint8 const NVRAM_EF_MY_NEW_DATA_DEFAULT[90] ={ 0x12,0x34,0x56,0x78,0x90, 0x12,0x34,0x56,0x78,0x90 }; #endif //在這里由于NV項二不用默認值,他只要使用平臺的默認0值就可以了,所以在這里他不用聲明和定義默認值; //---------------------------在文件中設置NV的屬性:nvram_user_config.c---------
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__ ,{ NVRAM_EF_MY_NEW_DATA_LID, NVRAM_EF_MY_NEW_DATA_SIZE, NVRAM_EF_MY_NEW_DATA_TOTAL, NVRAM_EF_MY_NEW_DATA_DEFAULT,//lzq:當不好設置默認值時就用默認的0代替; NVRAM_ATTR_MULTIPLE, NVRAM_CATEGORY_USER, "CT52", //lzq:這是做什么的? VER(NVRAM_EF_MY_NEW_DATA_LID), //lzq:這是做什么的? "My new data\0", //lzq:這是做什么的? NVRAM_INVALID_VALUE } #endif #ifdef __HL_WEB_PHONE__ //__HQ_ADD_BOOKMARK_DEFAULT__ ,{ NVRAM_EF_MY_WEB_PHONE_DATA_LID, NVRAM_EF_MY_WEB_PHONE_DATA_SIZE, NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL, NVRAM_EF_ZERO_DEFAULT,//NVRAM_EF_MY_NEW_DATA_DEFAULT,//lzq:當不好設置默認值時就用默認的0代替; NVRAM_ATTR_MULTIPLE, NVRAM_CATEGORY_USER, "CT53", //lzq:這是做什么的? VER(NVRAM_EF_MY_WEB_PHONE_DATA_LID), //lzq:這是做什么的? "My new data2\0", //lzq:這是做什么的? NVRAM_INVALID_VALUE } #endif //-----------在文件中設置NV的版本號:custom_nvram_editor_data_item.h---------------
//lzq: 為新添加的NV項添加版本號;
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
#define NVRAM_EF_MY_NEW_DATA_LID_VERNO "002" #endif //lzq: 為新添加的NV項添加版本號;
#ifdef __HL_WEB_PHONE__ //__HQ_ADD_BOOKMARK_DEFAULT__
#define NVRAM_EF_MY_WEB_PHONE_DATA_LID_VERNO "000" #endif //-----------在文件中設置meta屬性值:custom_nvram_editor_data_item.h---------------
--------------先添加meta說明的結構體------------------------------- //lzq: 為新添加的NV項添加NV META工具中的說明結構體;
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
typedef struct { kal_uint8 nvram_ef_my_new_data_field[NVRAM_EF_MY_NEW_DATA_SIZE]; }nvram_ef_my_new_data_struct; #endif //lzq: 為新添加的NV項添加NV META工具中的說明結構體;
#ifdef __HL_WEB_PHONE__ //__HQ_ADD_BOOKMARK_DEFAULT__
typedef struct { MY_WEB_PHONE nvram_ef_my_new_data2_field; }nvram_ef_my_new_data2_struct; #endif //lzq說明:在這里聲明nvram_ef_my_new_data2_field時一定要用自己的數據結構來聲明,不然在meta工具中看不到自己的數據; ----------------然后設置meta說明結構體:--------------------------- //lzq: 為新添加的NV項添加NV META工具中的說明字符串;
#ifdef _LZQ_TEST_ //__HQ_ADD_BOOKMARK_DEFAULT__
LID_BIT VER_LID(NVRAM_EF_MY_NEW_DATA_LID) nvram_ef_my_new_data_struct* NVRAM_EF_MY_NEW_DATA_TOTAL { nvram_ef_my_new_data_field:"my_new_data setting"; nvram_ef_my_new_data_field[2] { MynewData:6 "lzq" { }; }; };
#endif //lzq: 為新添加的NV項添加NV META工具中的說明字符串;
#ifdef __HL_WEB_PHONE__ //__HQ_ADD_BOOKMARK_DEFAULT__
LID_BIT VER_LID(NVRAM_EF_MY_WEB_PHONE_DATA_LID) nvram_ef_my_new_data2_struct* NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL { };
#endif 具體的結果看下圖: 注意:在步驟六中出現了這樣的問題:
Reading custom_data succeeded. Start to parse the custom NVRAM DATA! make: *** [.\tst\database_classb\BPLGUInfoCustomAppSrc] Error 1 因為在結構體中使用了說明字符串: LID_BIT VER_LID(NVRAM_EF_MY_WEB_PHONE_DATA_LID) nvram_ef_my_new_data2_struct* NVRAM_EF_MY_WEB_PHONE_DATA_TOTAL { //-------------------web phone----------- nvram_ef_my_new_data2_field:"my_web_phone setting"{}; status:"open or close switch"{}; phone_number:"the phone number"{}; number_exten:"the phone number pre extern"{}; number_zone:"the zone number"{}; }; 此時只要將上面的這段紅色的代碼注釋掉就可以了,本來按照文檔的解釋這樣寫是沒問題的,但不知道為什么會出現問題;高手路過多指教; 另外附上平臺的一個NV的流程,僅作參考: //------1---------在文件中定義LID: nvram_common_defs.h --------------------------------- NVRAM_EF_WAP_PROFILE_CONTENT_LID, //-------2----------在文件中 定義結構體common_nvram_editor_data_item.h--------------------------------------- typedef struct { kal_uint8 editable; kal_uint8 empty; kal_uint16 proxy_port; kal_uint8 homepage_url[NVRAM_WAP_PROFILE_HOMEPAGE_URL_LEN]; kal_uint8 data_account; kal_uint8 conn_type; kal_uint8 proxy_ip[4]; kal_uint8 username[NVRAM_WAP_PROFILE_USERNAME_LEN]; kal_uint8 password[NVRAM_WAP_PROFILE_PASSWORD_LEN]; } nvram_wap_profile_content_struct; //-------3--------------在文件中定義內存大小:Nvram_common_defs.h------------------------------------------ #define NVRAM_EF_WAP_PROFILE_CONTENT_SIZE sizeof(nvram_wap_profile_content_struct)
#define NVRAM_EF_WAP_PROFILE_CONTENT_TOTAL 10 //--------4-------------在文件中定義默認值:Nvram_common_config.c--------------------------------------------
nvram_wap_profile_content_struct const NVRAM_EF_WAP_PROFILE_CONTENT_DEFAULT[NVRAM_WAP_PROFILE_MAX]= { #ifdef CUSTOM_WAP_PROFILE_CONTENT_DEFAULT CUSTOM_WAP_PROFILE_CONTENT_DEFAULT #else { 1,0,80,"http://mobile.",10,1,210,241,199,199,"","" }, { 1,0,8080,"http://wap.",11,1,10,1,1,1,"","" }, } //-----------5----------------在文件中設置屬性nvram_common_config.c-------------------------------------------- ,{ NVRAM_EF_WAP_PROFILE_CONTENT_LID, NVRAM_EF_WAP_PROFILE_CONTENT_SIZE, NVRAM_EF_WAP_PROFILE_CONTENT_TOTAL, (kal_uint8*)NVRAM_EF_WAP_PROFILE_CONTENT_DEFAULT, NVRAM_ATTR_AVERAGE | NVRAM_ATTR_MULTIREC_READ, NVRAM_CATEGORY_MULTI_DEFAULT, "MP2U", VER(NVRAM_EF_WAP_PROFILE_CONTENT_LID), "wap profile\0", NVRAM_RESERVED_VALUE } //該nv項的lid為:NVRAM_EF_WAP_PROFILE_CONTENT_LID, //------------6-----------在文件中:common_nvram_editor_data_item.h中設置mata屬性-----------------------;
typedef struct { nvram_wap_profile_content_struct wapProfile1; nvram_wap_profile_content_struct wapProfile2; nvram_wap_profile_content_struct wapProfile3; nvram_wap_profile_content_struct wapProfile4; nvram_wap_profile_content_struct wapProfile5; nvram_wap_profile_content_struct wapProfile6; nvram_wap_profile_content_struct wapProfile7; nvram_wap_profile_content_struct wapProfile8; nvram_wap_profile_content_struct wapProfile9; nvram_wap_profile_content_struct wapProfile10; } nvram_meta_wap_profile_content_struct; LID_BIT VER_LID(NVRAM_EF_WAP_PROFILE_CONTENT_LID) nvram_meta_wap_profile_content_struct *NVRAM_EF_WAP_PROFILE_CONTENT_TOTAL { }; 【lzq2010-4-7 下午 04:28:22 補充】 1,在手機中隱藏了一個盤符:C盤;在modis上我們能看到這個盤符里的文件,都是臨時文件和NV文件;這個盤符很重要因為在down軟件時半擦不會將這個盤里的文件刪除;而如 果是全擦的話就會刪除這里的全部文件;所以半擦時沒有升級版本號的NV不會生效;
另外,升級了版本號的NV是如何生效的需要另外深入研究; 閱讀全文(2300) | 評論(4) | 推薦(10) 10頂一下 分享到:復制網址郵件收藏夾QQ空間新浪微博騰訊微博開心網更多0評 論4樓 52RD網友 發(fā)表于 2011-3-25 17:27 回復 無線開鋒科技有限公司真垃圾 3樓 gddzxh 發(fā)表于 2011-3-24 10:22 回復 非常非常的好啊 2樓 wujie_1120 發(fā)表于 2011-3-11 09:20 回復 不錯,寫的好 啊 1樓 tongfei1108 發(fā)表于 2011-3-2 19:40 回復 牛逼,寫的相當不錯,受益匪淺啊! 匿名 博 主 博客名稱:浮躁的人
日志總數:8 評論數量:14 訪問次數:8704 建立時間:2010-9-23 15:31:00 導 航 首頁(8)c和c(0)公 告評 論52RD網友: 無線開鋒科技有限公司真垃圾 (3-25) -------------------------------------------------------------------------------- gddzxh:非常非常的好啊(3-24) -------------------------------------------------------------------------------- joyanis:閱過,謝謝分享(3-21) -------------------------------------------------------------------------------- joyanis:總結的很好,贊一個(3-20) -------------------------------------------------------------------------------- gavin1121:總結得很好(3-12) -------------------------------------------------------------------------------- wujie_1120:不錯,寫的好 啊(3-11) -------------------------------------------------------------------------------- tongfei1108:不錯,要看看。(3-4) -------------------------------------------------------------------------------- tongfei1108:牛逼,寫的相當不錯,受益匪淺?。?3-2) -------------------------------------------------------------------------------- gddzxh:支持一下,雖然只看了書單里面很小一部分書,但是感覺是很不錯的(3-2) -------------------------------------------------------------------------------- phphph:hao ,感謝!(2-25) -------------------------------------------------------------------------------- 鏈 接http://zhuang0393.blog.163.com日志搜索: 52RD.com 研鼎信息技術有限公司 個人博客內容只代表個人觀點 本文來自:我愛研發(fā)網(52RD.com) - R&D大本營
詳細出處:http://www./Blog/Detail_RD.Blog_zhuang0393_26029.html |
|
|