熱度 10
上一篇主要說(shuō)明NVM區操作注意事項,本文針對上篇提到的NVM區數據備份方法進(jìn)行補充講解。
NVM區主要特性是寫(xiě)入數據掉電不丟失,可以永久的保存數據,一般用作存放不經(jīng)常修改的數據,此功能類(lèi)似FLASH。向NVM區寫(xiě)入數據可分為3步:第一步,將目標扇區內原有數據讀出到RAM中;第二步,擦除NVM目標扇區內數據;第三步,將新數據和RAM中的舊數據寫(xiě)入到該扇區中;谝陨蠈(xiě)操作的特點(diǎn)可以看出,若執行寫(xiě)NVM區操作的第二步或第三步時(shí)芯片斷電了,就會(huì )造成NVM區內原有數據丟失,而新數據寫(xiě)入失敗,表現出NVM區內數據錯亂的現象。雖然這只是小概率事件,但出于穩定性和產(chǎn)品健壯性考慮也要加入數據備份機制。
數據備份有兩套基本方案,分別適用于小數據量和大數據量的應用場(chǎng)景。本期介紹小數據量備份方案,即要求每次更新數據量小于一個(gè)扇區大小減1,本例扇區大小256字節,因此更新數據量最大255字節。(注意:不同型號芯片NVM扇區大小會(huì )有差異,可以聯(lián)系凌科技術(shù)確認)。實(shí)現思路是:從NVM區選取兩塊區域,每個(gè)區域的最后一字節記錄該區域的操作次數。以該標志決定更新數據應選用哪個(gè)區域。依次循環(huán)操作兩個(gè)區域,操作區域1的時(shí)候,區域2就充當了備份作用,反之同理。
第一次寫(xiě)入數據
第一步:將NVM區地址0x0000~0x00FF定義為Block1,將0x0200~0x02FF定義為Block2。
#define Block1 0x0000
#define Block2 0x0200
第二步:定義一個(gè)256字節的數組databuf和一個(gè)標志位變量cnt,并將cnt賦值0。
unsigned char databuf[256];
Unsigned char cnt = 0;
第三步:將目標數據(待寫(xiě)入數據)拷貝到databuf數組中,并將cnt+1拷貝到databuf+255的位置。
databuf[255] = cnt+1;
第四步:調用WriteNVM函數向Block1寫(xiě)入數據databuf,寫(xiě)入長(cháng)度256字節。調用WriteNVM函數向Block2+255位置寫(xiě)入cnt,寫(xiě)入長(cháng)度1字節
WriteNVM(Block1,databuf,256);
WriteNVM(Block2+255,&cnt,1);
更新數據
第一步:調用ReadNVM函數分別讀取Block1和Block2的標志位(最后一字節)。
unsigned char flag1,flag2;
ReadNVM(Block1+255,&flag1,1);
ReadNVM(Block2+255,&flag2,1);
第二步:判斷兩個(gè)Block的標志位大小,選取標志位數值小的Block進(jìn)行更新。將目標數據(待寫(xiě)入數據)拷貝到databuf數組中,并將標志位加2后拷貝到databuf+255的位置。
if(flag1 > flag2)
{
cnt = flag2 + 2;
databuf[255] = cnt;
WriteNVM(Block2,databuf,256);
}else{
cnt = flag1 +2;
databuf[255] = cnt;
WriteNVM(Block1,databuf,256);
}
讀取數據
第一步:讀取Block1和Block2的標志位數據。
ReadNVM(Block1+255,&flag1,1);
ReadNVM(Block2+255,&flag2,1);
第二步:判斷標志位大小,數值大的Block內為新數據,數值小的Block內為舊數據。
if(flag1 > flag2)
{
ReadNVM(Block1,databuf,255);
}else{
ReadNVM(Block2,databuf,255);
}