嵌入式中利用內(nèi)部flash存儲(chǔ)參數(shù)
嵌入式軟件中經(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ù)位置如下:
#define PARA_START_ADDR ((u32)0x0801fc00)
#define PARA_PAGE_SIZE ((u16)0x400)
03參數(shù)形式將參數(shù)封裝成一個(gè)結(jié)構(gòu)體,方便讀存。注意flash存儲(chǔ)時(shí)會(huì)自動(dòng)做4字節(jié)對(duì)齊,所有盡量保證PARASAVED_T的大小是4的整數(shù)倍,避免存入讀取后數(shù)據(jù)錯(cuò)位的麻煩。
#define PARA_FLAG 0x1000 //參數(shù)標(biāo)記
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 *)(