版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、z-stack的flash驅(qū)動。在分析flash驅(qū)動之前,需要熟讀cc2530的datasheet關(guān)于flash controller那一章節(jié)!我們先從hal_flash.c文件中的HalFlashRead函數(shù)開始: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
2、 + HAL_FLASH_PAGE_MAP) + (pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE); uint8 memctr = MEMCTR; / Save to restore.#if !defined HAL_OAD_BOOT_CODE halIntState_t is;#endif pg /= HAL_FLASH_
3、PAGE_PER_BANK; / Calculate the flash bank from the flash page.#if !defined HAL_OAD_BOOT_CODE HAL_ENTER_CRITICAL_SECTION(is);#endif / Calculate and map the containing flash bank into XDATA. MEMCTR = (MEMCTR & 0xF8) | pg; while (cnt-) *buf+ =
4、*ptr+; MEMCTR = memctr;#if !defined HAL_OAD_BOOT_CODE HAL_EXIT_CRITICAL_SECTION(is);#endif 在講解這個函數(shù)之前,先說一下z-stack中對flash的布局。z-stack將256KBflash的最末八個字節(jié)作為zigbee中的IEEE地址,當(dāng)然在這八個字節(jié)之后還有16個字節(jié)lock bits,這些flash的lock所需要用的,每2kb(1page)的flash有1bit的lock位,那么256kb的flash有128個2kb,當(dāng)然也就有128(16X8)位
5、的lock bits了。從F8w2530.xcl文件中可以看出:-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
6、,_FIRST_BANK_ADDR值為0x8000,這些值是在options.里面設(shè)置的。所以_IEEE_ADDRESS_SPACE_START的值為0x40000 - 0x18 = 0x3FFE8,_IEEE_ADDRESS_SPACE_END值就為0x3FFE8+7 = 0x3FFEF。 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
7、_ADDRESS_SPACE_START+0x2FFF)-Z(CODE)ZIGNV_ADDRESS_SPACE=_ZIGNV_ADDRESS_SPACE_START-_ZIGNV_ADDRESS_SPACE_END我們知道0x3800為7個page即14KB,0x2FFF為6個page,則Z-STACK將最末的7個page的前6個page用來作為Nv存儲,最后一個page用來存儲其他信息,如IEEE地址。 好!我們接下來看這個函數(shù)。uint8 *ptr = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) +
8、 (pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE);首先計算了這個地址映射到XDATA中之后的值,HAL_FLASH_PAGE_MAP為0X8000,HAL_FLASH_PAGE_PER_BANK值為16,HAL_FLASH_PAGE_SIZE值為2024即2KB,這個計算很顯然了。z-stack中的page是從0開始的,一直到127,總共128page,假如我們要讀某一page中的數(shù)據(jù),那么我們必須先把這個page所
9、在的bank映射到XDATA的0x80000xFFFF中,我們讀取page值為100,偏移量為20的數(shù)據(jù)時,這個地址通過上面的表達式就很容易計算出來為20+0x8000+(100%16)*2024 = 0x9FB4,注意這個地址轉(zhuǎn)換成了(uint8 *),即為XDATA空間的地址。 pg /= HAL_FLASH_PAGE_PER_BANK;計算page所在的bank,如果pg為100,則其所在bank值為100/16= 6; MEMCTR = (MEMCTR & 0xF8) | pg;這句是將剛才計算所得的bank映射到XDATA的0x80000xFFFF中去,M
10、EMCTR的低三位為XDATA的bank選擇位 while (cnt-) *buf+ = *ptr+; 很明顯,將ptr指針指向的數(shù)據(jù)復(fù)制到buf指針?biāo)赶虻牡刂啡?,這個buf和ptr變量是在運行時堆棧上的,只不過是將數(shù)據(jù)從XDATA的一個地放復(fù)制到sram中某個地方! 那么這個函數(shù)的最用就很明顯了:它是將flash內(nèi)部的某個page,相對其偏移量為offet地址處的數(shù)據(jù),讀取cnt個字節(jié)到buf中去。 接下來看看HalFlashInit這個函數(shù):void HalFlashInit(void
11、) / Load the code to run from RAM into its reserved area of RAM once at startup. HalFlashRead(PAGE_OF_RAM_CODE, OSET_OF_RAM_CODE, ramCode, SIZE_OF_RAM_CODE);這個flash初始化函數(shù)直接調(diào)用了HalFlashRead函數(shù),我們看看這幾個實參數(shù)據(jù),PAGE_OF_RAM_CODE值為51,OSET_OF_RAM_CODE值為0x6DD,SIZE_OF_RAM_CODE為0x23,ramCode為:#pragma loc
12、ation="RAM_CODE_XDATA"static _no_init uint8 ramCodeSIZE_OF_RAM_CODE;這個ramCode是不能初始化的靜態(tài)數(shù)組這個ramCode是在RAM_CODE_XDATAsegment,打開F8w2530.xcl文件:-D_RAM_CODE_XDATA_START=0x01EDD-D_RAM_CODE_XDATA_END=(_RAM_CODE_XDATA_START+0x22)-Z(XDATA)RAM_CODE_XDATA=_RAM_CODE_XDATA_START-_RAM_CODE_XDATA_END很明顯RAM_
13、CODE_XDATA這段范圍是8kb的sram中最末的23個字節(jié),那么這個初始化函數(shù)的作用就是將flash中23個字節(jié)的代碼加載到ram去運行。那么這個有什么用途呢?而且為什么是23字節(jié)呢?看到這個注釋,Any code that will be run from RAM by setting XMAP of MEMCTL must have the same bank-relative address as the address in RAM to which the CODE will be copied to run. Thus, any part of the f
14、irst 8k of any bank can be dedicated to code that will run from RAM aslong as the corresponding relative address range is reserved in RAM by RAM_CODE_XDATA. 這時候我們看到這幾句:#pragma location="RAM_CODE_FLASH"#if defined HAL_OAD_BOOT_CODEstatic void HalFlashWriteTrigger(void);#elsestatic _mon
15、itor void HalFlashWriteTrigger(void);#endif_monitor表示此函數(shù)不能被中斷!這個函數(shù)的位置就是在RAM_CODE_FLASH處,-Z(CODE)RAM_CODE_FLASH=_RAM_CODE_FLASH_START-_RAM_CODE_FLASH_END-D_RAM_CODE_FLASH_START=0x39EDD-D_RAM_CODE_FLASH_END=(_RAM_CODE_FLASH_START+0x22)這個表示的code段RAM_CODE_FLASH范圍,為0x39EDD0x39EFF,這個跟之前的那個51page,0x6DD是什么關(guān)
16、系呢?我們先看這個地址值出在什么位置,51page出在第三個bank里(注意bank是從0開始起的),那么將其映射到code memory(64KB)中就是在32KB+3page+0x6DD處,記住code空間的第一個為root bank,接著我們將39EDD映射到code空間中,其bank為7,其值為115page+0x6DD(注意page也是從0開始的),16page為1個bank,映射之后再code中的值為32KB+3page+0x6DD,看到了嗎? 這兩個值在映射之后竟然為同一地址,而且這一地址都是在switch bank的開始8kb末端23字節(jié)處!這說明什么呢?
17、而且,從上面代碼看出,這23個字節(jié)存儲的就是HalFlashWriteTrigger這個函數(shù)的實現(xiàn)代碼,不信反匯編代碼去看看,這個函數(shù)代碼就是23個字節(jié)。 那么在系統(tǒng)初始化flash的時候,0x39DEE映射到code空間,flash控制器將這23個字節(jié)的函數(shù)代碼復(fù)制到sram(8KB)的末端23字節(jié)的地址處,這樣當(dāng)系統(tǒng)執(zhí)行這個函數(shù)時,將這8KBsram映射到code空間的0x80000x8000+sram_size-1,cpu就在sram中執(zhí)行這個函數(shù),很顯然,速度是超快的!那么正好這個函數(shù)要求不能被中斷,那么它最好是越快越好!當(dāng)然就把它放在sram中執(zhí)行啦 flash驅(qū)
18、動先分析到這!下章介紹flash write函數(shù)! 今天來分析一下flash的write函數(shù):void HalFlashWrite(uint16 addr, uint8 *buf, uint16 cnt) halDMADesc_t *ch = HAL_NV_DMA_GET_DESC(); HAL_DMA_SET_SOURCE(ch, buf); HAL_DMA_SET_DEST(ch, &FWDATA); HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_USE_LEN); HAL_DMA_SET_
19、LEN(ch, (cnt * HAL_FLASH_WORD_SIZE); HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE); HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE); HAL_DMA_SET_TRIG_SRC(ch, HAL_DMA_TRIG_FLASH); HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1); HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0);
20、60; / The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_DISABLE); HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS); HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH); HAL_DMA_CLEAR_IRQ(HAL_NV_DMA_CH); HAL_DMA_ARM_CH(HAL_NV_DMA_CH
21、); FADDRL = (uint8)addr; FADDRH = (uint8)(addr >> 8); HalFlashWriteTrigger();這個函數(shù)的功能就是向flash內(nèi)部的addr地址處寫cnt個字節(jié)的buf內(nèi)容。我們知道flash-write operation 有兩種方法:Using DMA transfer (preferred method)Using CPU, running code from SRAM肯定DMA是首選!DMA驅(qū)動在注意一點 DMA控制器傳輸?shù)臄?shù)據(jù)都是在XDATA地址空間范圍內(nèi)的,當(dāng)然它可以存儲在ra
22、m中也可以存儲在flash中!只不過他們都必須映射到XDATA空間中!The DMA controller controls data transfers over the entire address range in XDATA memory space看到datasheet有這樣幾句:The CPU cannot access the flash, e.g., to read program code, while a flash write operation is in progress.Therefore, the program code executing the flash
23、write must be executed from RAM.CPU不能直接訪問flash來讀取程序代碼,但是可以進行寫flash操作!執(zhí)行flash write的程序代碼必須在RAM中執(zhí)行!當(dāng)然這是針對flash-write operation的第二種方法!如果我們用第一種方法,即DMA傳輸,我們先看一下流程圖:
24、60;
25、60; DMA描述符的配置過程具體就不說了!看代碼 FADDRL = (uint8)addr; FADDRH = (uint8)(addr >> 8); HalFlashWriteTrigger();將地址賦值給FADDRL:FADDRH,這個addr是16位的,但是如果我們想往地址0x3FFEE地址寫數(shù)據(jù),那豈不是寫不了?這
26、里為什么是16位的地址呢?其實,我們在寫flash之前都已經(jīng)將要寫的地址映射到了XDATA空間的XBANK區(qū)了! 我們先來看一下這個HalFlashWrite函數(shù)用在哪些地方!找到OSAL_Nv.c文件中有一兩個函數(shù)調(diào)用了HalFlashWrite,分別是static void writeWord( uint8 pg, uint16 offset, uint8 *buf )static void writeWordM( uint8 pg, uint16 offset, uint8 *buf, uint16 cnt )這兩個函數(shù)其實對HalFlashWrite的封裝。我們可以對照一下H
27、alFlashRead函數(shù)的聲明:void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt)他們的返回值和參數(shù)都是一樣的! 我們看下函數(shù)writeWord的代碼 offset = (offset >> 2) + (uint16)pg << 9); if ( OSAL_NV_CHECK_BUS_VOLTAGE ) HalFlashWrite(offset, buf, 1); else
28、0; failF = TRUE; 這里為我們計算offset即為映射之后的地址值!這是咋計算出來的呢?假如我們要在121page的 offset為0的地址處寫值,注意有這么一句:When accessed by the flash controller, the flash memory is word-addressable, where a word consists of 32 bits. 所以我們write flash時必須指定offset為4的整數(shù)倍,要不然會寫不進去的!所以有了 offset>>2,即除以4,
29、我們通過flash controller訪問flash時,看到的地址都是0x0000 0x0004 0x0008.即末位都是4的倍數(shù)的值,(uint16)pg << 9)即將pg乘以2KB再除以4,這個表達式相當(dāng)于 offset = (offset + pg×2KB)/4,分子為pg,offset的真正地址,然后將其除以4,然后調(diào)用HalFlashWrite(offset, buf, 1);對應(yīng)參數(shù)為,addr = offset,buf = buf, cnt = 1;所以執(zhí)行HalFlashWrite,向offset地址處寫4個字節(jié)我們看到有這么一句注
30、釋:param addr - Valid HAL flash write address: actual addr / 4 and quad-aligned.param cnt - Number of 4-byte blocks to write.實際地址是addr/4,所以要將offset除以4!但是我們知道這個addr的值是XDATA地址空間的地址,我們是往flash中寫數(shù)據(jù),也就是說在write flash之前,必須將pg所在的bank映射到XBANK中,然后再將buf中數(shù)據(jù)寫到XBANK的flash中!但是找了半天,沒有發(fā)現(xiàn)執(zhí)行映射的語句!這一點還沒想通!在程序初始化的時候:_low_level_init函數(shù)中執(zhí)行了 MEMCTR = (MEMCTR & 0xF
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度淋浴房行業(yè)綠色環(huán)保認(rèn)證服務(wù)合同4篇
- 2025年度茶葉產(chǎn)業(yè)扶貧合作項目合同4篇
- 2024年綠色建筑運營管理合同
- 智能家居系統(tǒng)安裝維護合同書
- 2024年度廣告投放代理合同
- 高端婚紗攝影服務(wù)合同
- 2025版城市綠化項目綠植租擺合作合同2篇
- 2025年度木制托盤環(huán)保認(rèn)證檢測報告審核專家采購合同3篇
- 2025年度貨物運輸印花稅合同稅率標(biāo)準(zhǔn)與細(xì)則3篇
- 2025年個人住宅抵押擔(dān)保合同范文(2篇)
- 2025年度土地經(jīng)營權(quán)流轉(zhuǎn)合同補充條款范本
- 南通市2025屆高三第一次調(diào)研測試(一模)地理試卷(含答案 )
- Python試題庫(附參考答案)
- 聚酯合成副反應(yīng)介紹
- DB37-T 1342-2021平原水庫工程設(shè)計規(guī)范
- 電除顫教學(xué)課件
- 廣東省藥品電子交易平臺結(jié)算門戶系統(tǒng)會員操作手冊
- DB32T 3960-2020 抗水性自修復(fù)穩(wěn)定土基層施工技術(shù)規(guī)范
- 大斷面隧道設(shè)計技術(shù)基本原理
- 41某31層框架結(jié)構(gòu)住宅預(yù)算書工程概算表
- 成都市國土資源局關(guān)于加強國有建設(shè)用地土地用途變更和
評論
0/150
提交評論