德馨轩

斯是陋室,惟吾德馨。QQ:275000205

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
MTK提供的NVRAM存取方式有两种,一种读取单条数据,一种是读取结构数据.
读取单条数据的比较常见,在mtk代码中随处可以找到例子,主要的接口函数是ReadValue和WriteValue,函数中nDataType参数对应的是
1 typedef enum    /* Pixtel Defined enum */
2 {
3     DS_BYTE = 1,
4     DS_SHORT = 2,
5     DS_DOUBLE = 8
6 } DATASIZE; /* Enum for caching purposes */

 

一般我的应用中,DS_BYTE 类型我们对应U8来使用,DS_SHORT对应U16,DS_DOUBLE 对应U64,(double的操作可以参考THEME_MANAGER_MAX_THEME_ID)
可根据数据的需求来用不同的类型,参数nDataItemId定义在custom_mmi_default_value.h中,对应不同类型分别放于BYTEDATA,SHORTDATA,DOUBLEDATA中.
  实际工作中我们最常用这种方法存储程序的开关,一般我们会使用DS_BYTE 类型来存储,实则用U8来存储一个0/1的数据太浪费了,所以我们一般要充分利用U8中的每个位,程序上在读出数据后进行位操作即可得到自己想要得数据,存储前的时候也要进行相应位操作后才能进行存储.比如我前面设计的呼吸灯的功能,对于不同情况下的呼吸需要存储开关,速度和效果,我根据数据特征将U8分成三个部分来分别存储,即AABBCCCC,AA开关,BB速度,CCCC效果,将开关设置两位是为了避免nvram存储值为0,不便于对nvram初始值进行判断.
 1 //开关
 2 typedef enum
 3 {
 4     SWITCH_NULL,//增加该项使nvram存储值不为0
 5     SWITCH_ON,    
 6     SWITCH_OFF,
 7     
 8     //add item befor this
 9     RF_UTPLUS_SWITCH_END
10 }utplus_rf_breath_switch;
11 //从nvram中获取初始化值
12 void utplus_rf_breath_init_nvram_value(void)
13 {
14     U8 data = 0;
15     U8 i;
16     S16 error;
17     for(i=0;i<RF_UTPLUS_FEATRUE_END;i++)
18     {
19         ReadValue(NVRAM_RF_UTPLUS_SETTING_START + i + 1,&data, DS_BYTE , &error);
20         dbg_print("\r\n UtPlus BreathLED init nvram read  data = %d , \r\n ",data);
21         if(data==0xff|| data < 0x40 ||error !=NVRAM_READ_SUCCESS)
22         {
23             dbg_print("UtPlus BreathLED init nvram read err i = %d ,err = %d \r\n ",i,error);
24             data = ((U8)(ut_g_rfb[i].switch_id)<<6)|( (U8)(ut_g_rfb[i].speed_level) <<4)|( (U8)(ut_g_rfb[i].breath_type_id));
25             dbg_print("UtPlus BreathLED init nvram write  data = %d , \r\n ",data);
26             WriteValue(NVRAM_RF_UTPLUS_SETTING_START + i + 1 ,&data, DS_BYTE , &error);
27         }
28         else
29         {
30             dbg_print("UtPlus BreathLED init nvram read success i = %d \r\n ",i);
31             ut_g_rfb[i].switch_id = (data&0xC0)>>6;
32             ut_g_rfb[i].speed_level = (data&0x30)>>4;
33             ut_g_rfb[i].breath_type_id = (data&0x0f);
34         }
35     }
36 }
37 //在nvram存储对应修改值
38 void utplus_rf_breath_set_nvram_value(U8 index,utplus_rf_breath* utrb)
39 {
40     U8 data = 0;
41     S16 error;
42 
43     ASSERT(index<RF_UTPLUS_FEATRUE_END);
44     
45     data = ((U8)(utrb->switch_id)<<6)|( (U8)(utrb->speed_level) <<4)|( (U8)(utrb->breath_type_id));
46     dbg_print("\r\n UtPlus BreathLED set nvram read index = %d  data = %d , \r\n ",index,data);
47     WriteValue(NVRAM_RF_UTPLUS_SETTING_START + index  + 1,&data, DS_BYTE , &error);
48     ut_g_rfb[index].switch_id = utrb->switch_id;
49     ut_g_rfb[index].speed_level = utrb->speed_level;
50     ut_g_rfb[index].breath_type_id = utrb->breath_type_id;
51 }
52 

 

读取结构数据也是比较常用的方式,可能初级的程序员还是比较少的接触这个的,常用的接口函数是WriteRecord和ReadRecord
这两个函数逻辑处理的核心数据是
ltable_entry_struct logical_data_item_table_comm_app[] 

 

在这个结构定义前MTK有如下说明:
 1 
 2 /**
 3  * Steps of defining logical data item:
 4  * 1> Define LID of new logical data item into `nvram_LID_cust_enum' in 
 5  *    nvram_user_defs.h
 6  * 2> Define two constants: SIZE and TOTAL, in nvram_user_defs.h
 7  * 3> Define default value of that new logical data item in nvram_user_config.c
 8  * 4> Define attributes of that new logical data item into 
 9  *    `logical_data_item_table_cust'
10  * 5> Bypass.
11  * 6> Change version number CODED_DATA_VERSION in nvram_user_config.c
12  */
13 /**
14  * The logical data item table.
15  * Note:
16  * Each logical data item must be:
17  * 1> Size must be EVEN
18  * 2> Size of default value must be equal to the logical data item's size.
19  */
20  /**
21  * The rule for data item changes:
22  * 1. To add a new data item, its name must be the next of the current last LID, for example, 
23  *     the last LID in the CT reign now is CT20, the new one must be CT21. 
24  * 2. Version must be increased if 
25  *    (a) Size is changed, or 
26  *    (b) Number of sections is changed, or 
27  *    (c) Attribute is changed, or 
28  *    (d) data structure is changed.
29  */

 

上面已经将部分配置说明的比较清楚了,下面拿出mtk的一项举例说明:
 1 #ifdef __MMI_FILE_MANAGER__
 2     ,{
 3         NVRAM_EF_WPSS_FILENAME_LID,
 4         NVRAM_EF_WPSS_FILENAME_SIZE,
 5         NVRAM_EF_WPSS_FILENAME_TOTAL,
 6         NVRAM_NORMAL(NVRAM_EF_ZERO_DEFAULT),
 7         NVRAM_ATTR_AVERAGE,
 8         NVRAM_CATEGORY_USER | NVRAM_CATEGORY_FACTORY,
 9         "MP1S",
10         VER(NVRAM_EF_WPSS_FILENAME_LID),
11         "Dispchar path",
12         NVRAM_APP_RESERVED
13     }
14 #endif /* __MMI_FILE_MANAGER__ */

 


NVRAM_EF_WPSS_FILENAME_SIZE,定义为 sizeof(PHNSET_WPSS_FILENAME_STRUCT),单个结构体的大小
NVRAM_EF_WPSS_FILENAME_TOTAL 表示存储几个这样的结构体
NVRAM_NORMAL(NVRAM_EF_ZERO_DEFAULT)每个结构体的初始值,此处表示初始化值全为0, 如果想初始化需要的默认值可以参考NVRAM_EF_PROFILES_LID情景模式的初始值.
下面两个参数是

 

      nvram_attr_enum attr;           /* U16 */

     nvram_category_enum category;   /* U32 */

 

 

这两个属性在系统进行nvram的read/write中用到,具体意义我也不太清楚,比如IMEI的NVRAM_EF_IMEI_IMEISV_LID就有NVRAM_ATTR_WRITEPROTECT属性.
下面的VER(NVRAM_EF_WPSS_FILENAME_LID)是将NVRAM_EF_WPSS_FILENAME_LID变为NVRAM_EF_WPSS_FILENAME_LID_VERNO,这个定义Record版本号,定义在common_nvram_editor_data_item.h,据说是系统升级后系统会自动对比这个版本号,如果这个版本号不同的话就会自动覆盖原先的值.有研究手段的朋友请告知我,谢谢啊.
  上面的byte,short,double的存储也是组合成record来进行的,其size都是NVRAM_CACHE_SIZE=512,也就是说存储byte的个数 上限是512个,short的个数上限是256个,double的个数的上限是64个(如果你的应用需要存储的数据量比较大最好新建record).他们分别对应NVRAM_EF_CACHE_BYTE_LID,NVRAM_EF_CACHE_SHORT_LID,NVRAM_EF_CACHE_DOUBLE_LID.所以对于一些常规的nvram修改如果不像格式化重新校准软件就可以升级对应的nvram版本号即可.  
  下面阐述关于NVRAM的编译生成和读取流程.
 NVRAM的编译生成主要依靠tools\NVRAMStatistic下的相关文件,src是相关源代码文件,通过NVRAMAutogen.bat每次生成新的nvram_auto_gen.exe,nvram数据的生成也是通过logical_data_item_table_comm_app为接口的.
  NVRAM系统读取得模块代码位于工程nvram目录下,系统的实现接口是
kal_bool nvram_create(comptask_handler_struct **handle)
比较核心的处理函数是;void nvram_main(ilm_struct *ilm_ptr)
 1 /*****************************************************************************
 2  * FUNCTION
 3  *  nvram_main
 4  * DESCRIPTION
 5  *  This is main() function of NVRAM module.
 6  * PARAMETERS
 7  *  ilm_ptr     [IN]        The primitives
 8  * RETURNS
 9  *  void
10  *****************************************************************************/
11 void nvram_main(ilm_struct *ilm_ptr)
12 {
13     /*----------------------------------------------------------------*/
14     /* Local Variables                                                */
15     /*----------------------------------------------------------------*/
16 
17     /*----------------------------------------------------------------*/
18     /* Code Body                                                      */
19     /*----------------------------------------------------------------*/
20     ASSERT(ilm_ptr != NULL);
21 
22     if (ilm_ptr != NULL)
23     {
24         if ((ilm_ptr->msg_id >= MSG_ID_NVRAM_CODE_BEGIN) && (ilm_ptr->msg_id <= MSG_ID_NVRAM_CODE_END))
25         {
26 
27             if (ilm_ptr->msg_id == MSG_ID_NVRAM_STARTUP_REQ)
28             {
29                 nvram_startup_handler(ilm_ptr);
30             }
31             else if (ilm_ptr->msg_id == MSG_ID_NVRAM_RESET_REQ)
32             {
33                 nvram_reset_handler(ilm_ptr);
34             }
35             else if (ilm_ptr->msg_id == MSG_ID_NVRAM_READ_REQ)
36             {
37                 nvram_read_handler(ilm_ptr);
38             }
39             else if (ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_REQ)
40             {
41                 nvram_write_handler(ilm_ptr);
42             }
43             else if (ilm_ptr->msg_id == MSG_ID_NVRAM_WRITE_IMEI_REQ)
44             {
45                 nvram_write_imei_handler(ilm_ptr);
46             }
47             else if (ilm_ptr->msg_id == MSG_ID_NVRAM_SET_LOCK_REQ)
48             {
49                 nvram_set_lock_handler(ilm_ptr);
50             }
51         }
52     #ifdef TST_HANDLER
53         else
54         {
55             /* not nvram defined message */
56             if (ilm_ptr->msg_id == MSG_ID_TST_INJECT_STRING)
57             {
58                 nvram_tst_handler(ilm_ptr);
59             }
60         }
61     #endif /* TST_HANDLER */ 
62 
63     }
64 }   /* end of module main function */

 


主要处理的是 : startup,reset,read,write,write_imei,set_lock
在这里对imei的单独处理可能跟他的NVRAM_ATTR_WRITEPROTECT属性有关吧.

作者:张素丰,转载请注明出处:http://www.cnblogs.com/zhangsufeng/archive/2010/09/11/1824100.html

  这只是表面的分析,深入的研究需要更多的能力,我现在还比较欠缺,渴望和大家多交流,我QQ号是275000205。

20100912 0:22补充:

今日研究了下电话本的nvram存储,不惑,得一高人点拨,发现在记录里还有一个重要的特性:

     LID_BIT VER_LID(NVRAM_EF_WPSS_FILENAME_LID)
     nvram_wpss_filename_struct *NVRAM_EF_WPSS_FILENAME_TOTAL
     {
     };
用来将LID和结构体关联,而且我们找LID所用的结构可以快速的通过这个找到。

关于这方面的详细介绍请见:http://blog.ednchina.com/Jerome_home/1801884/message.aspx

posted on 2010-09-11 19:44  Anpher Zhang  阅读(5459)  评论(0编辑  收藏  举报