嵌入式軟件中利用內(nèi)部flash存儲(chǔ)參數(shù)的方法
01
前言
嵌入式軟件中經(jīng)常要存儲(chǔ)一些非易失參數(shù),例如用戶設(shè)置、校準(zhǔn)參數(shù)、設(shè)備運(yùn)行參數(shù)等,通常情況下我們都會(huì)選擇存儲(chǔ)在EEPROM或者SPI-FLASH中。在削減成本考量的情況下,我們可以把存儲(chǔ)器省下來(lái),參數(shù)存儲(chǔ)在內(nèi)部flash中,畢竟就算每片減少一塊錢(qián),量大后還是非常可觀的。
02
選擇參數(shù)存儲(chǔ)位置
stm32的flash地址起始于0x08000000,結(jié)束地址是0x08000000加上芯片實(shí)際的flash大小,不同的芯片flash大小不同。我們可以在KEIL項(xiàng)目工程的Target也看到ROM的起始地址和大小,前提是Device頁(yè)要選對(duì)正在使用的芯片規(guī)型號(hào)。
因?yàn)閟tm32擦除flash的時(shí)候是以扇區(qū)(sector)為單位的,我們存儲(chǔ)參數(shù)也是選擇以扇區(qū)為單位,從扇區(qū)頭開(kāi)始擦、讀、寫(xiě),這樣邏輯簡(jiǎn)單。LD、MD型產(chǎn)品的扇區(qū)大小是1K,HD、CL型產(chǎn)品的扇區(qū)大小是2K。一般將參數(shù)存儲(chǔ)在flash的尾部最后幾個(gè)扇區(qū)比較穩(wěn)妥,我們只要確保程序固件(編譯出的燒錄bin文件)的大小不進(jìn)入尾部的這幾個(gè)扇區(qū)就可以。
以stm32f103cbt6為例,flash起始地址為0x8000000,大小是0x20000。一個(gè)Sector的大小是1K。那么定義參數(shù)位置如下:
03
參數(shù)形式
將參數(shù)封裝成一個(gè)結(jié)構(gòu)體,方便讀存。注意flash存儲(chǔ)時(shí)會(huì)自動(dòng)做4字節(jié)對(duì)齊,所有盡量保證PARASAVED_T的大小是4的整數(shù)倍,避免存入讀取后數(shù)據(jù)錯(cuò)位的麻煩。
typedef struct{ u8 para[64]; u32 flag;}PARASAVED_T;PARASAVED_T para_t;
04
參數(shù)存取
讀參數(shù),將flash內(nèi)的數(shù)據(jù),讀入到para_t結(jié)構(gòu)體中
void ReadData(void){ u32 address; u32 *pd; u16 i; address = PARA_START_ADDR; pd = (u32 *)(?_t); 0; i{ *((u32 *) address); = address += 4; pd ++; }} =
寫(xiě)參數(shù),將para_t的數(shù)據(jù)寫(xiě)入到flash中
void SaveData(void){ u16 i; u8 writeTimes; u32 address; u8 isRight; u32 * pd; FLASH_Unlock(); | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); writeTimes = MAX_FLASH_WRITE_TIMES; while(writeTimes--) { FLASH_ErasePage(PARA_START_ADDR); address = PARA_START_ADDR; pd = (u32 *)(?_t); 0; i{ *pd); address += 4; pd ++; } isRight = 1; address = PARA_START_ADDR; pd = (u32 *)(?_t); 0; i { u32*) address) != *pd) { isRight = 0; } address += 4; pd ++; } if (isRight) { break; } }} = =
05
讀寫(xiě)調(diào)用邏輯
開(kāi)機(jī)調(diào)用read函數(shù),將參數(shù)讀取到全局變量para_t中,后面在整個(gè)生命周期中都操作para_t。當(dāng)para_t的內(nèi)容被改動(dòng)后,調(diào)用save函數(shù),將改動(dòng)值保存。
結(jié)構(gòu)體中的flag的作用,是做為一個(gè)全部參數(shù)的存儲(chǔ)標(biāo)記,當(dāng)開(kāi)機(jī)讀到它是全ff時(shí),就是參數(shù)全空的初始狀態(tài),此時(shí)可以做初始化參數(shù)的操作,將一些默認(rèn)值寫(xiě)入到flash中。當(dāng)開(kāi)機(jī)讀到flag非全ff,但是與define PARA_FLAG不同時(shí),就初始化參數(shù)或者參數(shù)中的一部分。這個(gè)作用是當(dāng)我們需要改變某些默認(rèn)參數(shù)值,并希望他在升級(jí)后生效時(shí),可以修改define值,來(lái)觸發(fā)參數(shù)初始化。
06
優(yōu)勢(shì)與缺點(diǎn)
把參數(shù)存儲(chǔ)在內(nèi)部flash,好處是可以cost down,但是也要壞處,就是一旦全刷芯片的固件,所有的參數(shù)就會(huì)消失。但是一般的應(yīng)用場(chǎng)合,這參數(shù)消失后觸發(fā)參數(shù)初始化,也沒(méi)有什么大問(wèn)題。但是如果參數(shù)中存儲(chǔ)了一些非常困難才得到的校準(zhǔn)參數(shù)、運(yùn)行數(shù)據(jù)等,要慎用。
猜你喜歡:
C語(yǔ)言、嵌入式重點(diǎn)知識(shí):回調(diào)函數(shù)
【Linux筆記】設(shè)備樹(shù)實(shí)例分析
【Linux筆記】通俗易懂的Linux驅(qū)動(dòng)基礎(chǔ)
【Linux筆記】pc機(jī)_開(kāi)發(fā)板_ubuntu互ping實(shí)驗(yàn)
學(xué)習(xí)STM32的一些經(jīng)驗(yàn)分享
基于LiteOS的智慧農(nóng)業(yè)案例實(shí)驗(yàn)分享
后臺(tái)回復(fù):加群。添加ZhengN微信,加入交流群
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!