CC2530之Flash筆記
最近在看CC2530的Flash部分,翻閱一些文章,將記錄下來,做為筆記以免遺忘,如有錯誤之處請指出。
參考文章:
https://www.cfanz.cn/?c=article&a=read&id=173767
https://www.xuebuyuan.com/1035130.html
https://blog.csdn.net/crystal736/article/details/8727111
https://wenku.baidu.com/view/b640309043323968001c925d.html
https://www.xuexila.com/diannao/rumen/607222.html
https://www.cnblogs.com/felixfang/p/3420462.html
一、基礎知識
我使用的TI的芯片型號為CC2530-F256,擁有256K的 Flash,8K SRAM,內核為8051,隻支持64K訪問空間,以下為一些基本概念。
1.CODE. A read-only memory space for program memory. This memory
space addresses 64 KB.
2.DATA. A read/write data memory space that can be directly or indirectly accessed by a single-cycle CPU instruction. This memory space addresses 256 bytes. The lower 128 bytes of the DATA memory space can be addressed either directly or indirectly, the upper 128 bytes only indirectly.
3.XDATA. A read/write data memory space, access to which usually requires 4–5 CPU instruction cycles.This memory space addresses 64 KB. Access to XDATA memory is also slower than DATA access, as the CODE and XDATA memory spaces share a common bus on the CPU core, and instruction
prefetch from CODE can thus not be performed in parallel with XDATA
accesses.
4.SFR. A read/write register memory space which can be directly accessed by a single CPU instruction.This memory space consists of 128 bytes. For SFR registers whose address is divisible by eight, each bit is also individually addressable.
在此處我們隻需要記住 DATA和 XDATA 存在 SRAM 上,而 CODE存在 Flash上即可。
二、CC2530中的 Flash 結構
由於CC2530隻支持64K尋址,因此,采用 Bank映射的方式尋址,其中,32K作為 ROOT,用於存放啟動代碼等,地址空間為 0x0000~0x7FFF;剩餘32K用於映射不同的 Bank(0~7),地址為0x8000~0xFFFF.在查詢某個 Bank 的數據或代碼時,將該 Bank映射到地址空間 0x8000 ~ 0xFFFF即可。
通過ZigBee協議棧中的定義
#define HAL_FLASH_PAGE_SIZE 2048
我們可以知道每頁page的大小為2K,定義每16個page為1個Bank,下圖為Bank與page的關係
Bank地址:
Bank0: 0x00000 ~ 0x07FFFF
Bank1: 0x18000 ~ 0x1FFFFF
Bank2: 0x28000 ~ 0x2FFFFF
Bank3: 0x38000 ~ 0x3FFFFF
Bank4: 0x48000 ~ 0x4FFFFF
Bank5: 0x58000 ~ 0x5FFFFF
Bank6: 0x68000 ~ 0x6FFFFF
Bank7: 0x78000 ~ 0x7FFFFF
三、計算Bank的數據或代碼的地址
在計算地址前,首先了解物理地址與邏輯地址的概念,及兩者之間的轉換公式。
1、物理地址與邏輯地址
物理地址:加載到內存地址寄存器中的地址,內存單元的真正地址。在前端總線上傳輸的內存地址都是物理內存地址,編號從0開始一直到可用物理內存的最高端。這些數字被北橋(Nortbridge chip)映射到實際的內存條上。物理地址是明確的、最終用在總線上的編號,不必轉換,不必分頁,也沒有特權級檢查(no translation, no paging, no privilege checks)。
邏輯地址:CPU所生成的地址。邏輯地址是內部和編程使用的、並不唯一。例如,你在進行C語言指針編程中,可以讀取指針變量本身值(&操作),實際上這個值就是邏輯地址,它是相對於你當前進程數據段的地址(偏移地址),不和絕對物理地址相幹。
2、物理地址與邏輯地址的轉換
(1)確定虛擬地址(物理地址)的有效位
例如:假設頁麵大小1KB,共32頁。(頁麵:邏輯地址 頁框:物理地址)
由32(KB)=32×1024(B) 即等於32×1024 字節
二進製用多少位能有效表示這麼多字節呢?
答案是:15位 因為32×102 4=2^5×2^10=2^15
(2)再次確定邏輯地址頁麵位數 你應該知道:邏輯地址=頁號+頁麵
還是以上假設,那麼頁麵大小為1KB=1024字節 同樣的方法計算出表示位數:10位
如果給你邏輯地址:0000 1111 1000 0000
那麼由:011+11100000000(相當於 頁號+頁麵(10位))推得出頁號011=3
(3)根據頁號找出對應的頁框號
由 物理地址=頁框號×頁塊大小(頁塊大小是等於頁麵大小的)+頁內位移(即頁麵邏輯地址)//物理地址=塊的大小(即頁的大小L)*塊號f+頁內地址d
根據上麵 物理地址=頁框號×1024B + 1110000000 ( 這裏的相加是指位置上而言)
例如:110+110=110110(即高地址+低地址)
有了以上的知識,我們來看一看CC2530的Flash的讀寫是怎樣通過邏輯地址找到物理地址的
void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt)
{
..............
// Calculate the offset into the containing flash bank as it gets
mapped into XDATA.
uint8 *ptr = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) +
((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE);
.............
}
ptr為物理地址,offset為偏移量, pg為頁數
#define HAL_FLASH_PAGE_MAP 0x8000
#define HAL_FLASH_PAGE_PER_BANK 16
#define HAL_FLASH_PAGE_SIZE 2048
假如我們要讀某一page中的數據,那麼我們必須先把這個page所在的
bank映射到XDATA的0x8000~0xFFFF中,我們讀取page值為100,偏移量為20的數據時,這個地址通過上麵的表達式就很容易計算出來為20+0x8000+(100%16)*2024 = 0x9FB4,注意這個地址轉換成了(uint8 *),即為XDATA空間的地址。
pg /= HAL_FLASH_PAGE_PER_BANK;
計算page所在的bank,如果pg為100,則其所在bank值為100/16= 6
MEMCTR = (MEMCTR & 0xF8) | pg;
這句是將剛才計算所得的bank映射到XDATA的0x8000~0xFFFF中去,
MEMCTR的低三位為XDATA的bank選擇位
四、其他地址
1、IEEE
-D_IEEE_ADDRESS_SPACE_START=(((_NR_OF_BANKS+1)*_FIRST_BANK_ADDR)-0x18)
-D_IEEE_ADDRESS_SPACE_END=(_IEEE_ADDRESS_SPACE_START+7)
-Z(CODE)IEEE_ADDRESS_SPACE=_IEEE_ADDRESS_SPACE_START-_IEEE_ADDRESS_SPACE_END
注:0x18 = 24 = 16 +8;
_IEEE_ADDRESS_SPACE_START容易算出來,_NR_OF_BANKS值為0x07,_FIRST_BANK_ADDR值為0x8000,這些值是在options...裏麵設置的。所以_IEEE_ADDRESS_SPACE_START的值為0x40000 - 0x18 = 0x3FFE8,_IEEE_ADDRESS_SPACE_END值就為0x3FFE8+7 = 0x3FFEF。
(備注:每2kb(1page)的flash有1bit的lock位)
2、NV
Z-STACK將flash的最末處的12KB(6page)用來作為Nv存儲的,具體看:
-D_ZIGNV_ADDRESS_SPACE_START=(((_NR_OF_BANKS+1)*_FIRST_BANK_ADDR)-0x3800)
-D_ZIGNV_ADDRESS_SPACE_END=(_ZIGNV_ADDRESS_SPACE_START+0x2FFF)
-Z(CODE)ZIGNV_ADDRESS_SPACE=_ZIGNV_ADDRESS_SPACE_START-_ZIGNV_ADDRESS_SPACE_END
最後更新:2017-05-03 09:30:37