在嵌入式設(shè)備開發(fā)中,往往需要保存一些掉電不易失性的數(shù)據(jù),如果系統(tǒng)配置、用戶定制信息等等,如果增加額外的ROM IC,比如(基于I2C的24C02等等)往往會(huì)造成額外的PCB空間增大,硬件成本增加,降低產(chǎn)品的性價(jià)比。如果單從實(shí)用性來(lái)講,在stm32的系統(tǒng)中,諸如此類的應(yīng)用,筆者推薦如下2個(gè)方法可以去嘗試和借鑒。
基于備份寄存器
原理:對(duì)于大容量的MCU系列來(lái)說(shuō),它有著42個(gè)16bit的備份寄存器,而中小容量的微處理器卻只有10個(gè)16bit的備份寄存器。以STM32F103C8T6為例,42個(gè)備份寄存器的地址偏移為:0x04~0x28,0x40~0xBC,共可以存儲(chǔ)84個(gè)byte數(shù)據(jù)。備份寄存器是依賴者備份電源的,當(dāng)外界的VDD掉電,只要系統(tǒng)的VBAT能正常存在,那么Bakeup Domaain Registers的內(nèi)容可以被正常保存起來(lái)。
軟件編程要點(diǎn),以一個(gè)項(xiàng)目中常用的case為例:
功能初始化:
備份寄存器讀出:void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data)
備份寄存器讀出:uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR)
該方法使用簡(jiǎn)單,清晰,但是由于總共的可以利用的空間少,故該方法只是適合于保存小批量的數(shù)據(jù),如穿戴設(shè)備中用戶的常用配置數(shù)據(jù)。
基于內(nèi)部閃存
原理:FLASH 存儲(chǔ)器又稱為閃存,它也是可重復(fù)擦寫的儲(chǔ)器。它分為 NOR FLASH 和 NAND FLASH,NOR FLASH一般應(yīng)用在代碼存儲(chǔ)的場(chǎng)合,如嵌入式控制器內(nèi)部的程序存儲(chǔ)空間;而 NAND FLASH 一般應(yīng)用在大數(shù)據(jù)量存儲(chǔ)的場(chǎng)合,如U 盤以及固態(tài)硬盤等,一般都是 NAND FLASH 類型的。
在stm32芯片中,F(xiàn)lash的讀寫單位都是以“頁(yè)”為單位的,以STM32F103C8T6為例,它的每頁(yè)大小為2K bytes;
軟件編程要點(diǎn)
讀寫保護(hù)解除:使用這種方法前提是,當(dāng)前讀和寫Flash的允許的,假設(shè)當(dāng)前flash已經(jīng)是允許寫的。所以暫時(shí)一些關(guān)于OptionBytes的操作和Flash的讀寫保護(hù)操作等API暫時(shí)不做討論。
FlashWrite:?jiǎn)蝹€(gè)uint32_t數(shù)據(jù)的寫入簡(jiǎn)易流程如圖:
FlashRead:對(duì)于單個(gè)int數(shù)據(jù)的讀出,比較簡(jiǎn)單,通過(guò)下列語(yǔ)句完成:rdData= (*(__IOuint32_t *)dataAddr);
由于SW介入的API較多,并且有很多的額外的背景知識(shí)需要碼農(nóng)去了解,使用該方法,相對(duì)比較復(fù)雜。但是由于保存數(shù)據(jù)以頁(yè)為單位,頁(yè)的大小可以多達(dá)2048bytes,所以該方法可以實(shí)用于保存掉電不易失的大數(shù)據(jù)。考慮到flash讀寫保護(hù)的邏輯機(jī)制,該方法最好在不考慮數(shù)據(jù)的安全性問(wèn)題前提下,才使用這種方法。
對(duì)于諸如此類的掉電保護(hù)數(shù)據(jù)方法,這里僅僅是拋磚引玉,歡迎大家多多提出更好的方案。