對.Net Micro Framework系統來講,正常狀況下Flash(包括NandFlash和NORFlash)分爲六個區,分別爲:ide
一、 BLOCKTYPE_BOOTSTRAP(存放啓動代碼,通常爲TinyBooter)測試
二、 BLOCKTYPE_CONFIG(配置區,存放配置信息)ui
三、 BLOCKTYPE_CODE(本地代碼區,指TinyCLR代碼)spa
四、 BLOCKTYPE_DEPLOYMENT(託管代碼區,存放用戶的C#程序)debug
五、 BLOCKTYPE_STORAGE_A(用戶數據存儲區)xml
六、 BLOCKTYPE_FILESYSTEM(文件系統)資源
其中二、三、4項爲.Net Micro Framework系統所必須。開發
若是Flash爲NandFlash,則存放在BLOCKTYPE_BOOTSTRAP區的啓動代碼是沒法直接執行的,系統必須在ROM、NORFlash或其它線性執行存儲區存放一個Bootload,由該Bootload加載TinyBooter,而後由TinyBooter引導TinyCLR啓動(固然若是空間容許,TinyBooter也能夠放在NORFlash,直接運行來引導TinyCLR,或Bootload直接引導TinyCLR也是能夠的)。get
TinyCLR通常常見大小爲700k左右,其實也能夠放在NORFlash中,不須要TinyBooter而直接運行,不過這樣就不方便用MFDeploy對TinyCLR進行升級了。it
常見的MF系統,TinyBooter啓動後通常把TinyCLR從NandFlash拷貝到RAM中,TinyCLR實際是在RAM中執行的。這就須要RAM的大小至少要大於TinyCLR的大小,加上堆和棧的大小,理想的RAM大小至少要大於2M。
EM-STM3210E開發板上的Flash含四部分,片內Flash 512k(系統Flash2k,存放系統Bootload,不能更改,ISP功能就是由該Bootload來支持的),2M NOR Flash,8M SPI Flash,128Mb(16M字節) NandFlash。
Flash相對比較豐富,可是RAM資源卻有些不足,片內含64K RAM,片外擴展了128KB SRAM。因爲RAM相對偏小,因此TinyCLR的代碼是不可能拷貝到RAM中執行的,若是TinyCLR達到常見大小,則片內用戶FLASH也是放不下的,也只有放到2M的 NOR Flash中去了。不過咱們此次Porting的.Net Micro Framework僅是最小集,TinyCLR大概250K左右,此外TinyBooter對咱們也不是必須的,咱們經過ISP方式下載TinyCLR。
NORFlash和SPI Flash對咱們來講沒必要要,僅需實現NandFlash便可,Flash的型號爲ST NAND128W3A2BNb,最終的NandFlash分區以下:
- const BlockRange g_NandFlash_BlockStatus[] =
- {
- { BlockRange::BLOCKTYPE_CONFIG , 0, 7 }, //128K
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 8, 47 }, //640K
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 48, 87 },
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 128, 167 },
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 208, 247 },
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 288, 327 },
- { BlockRange::BLOCKTYPE_DEPLOYMENT, 328, 1007 },
- { BlockRange::BLOCKTYPE_STORAGE_A , 1008,1015 },
- { BlockRange::BLOCKTYPE_STORAGE_B , 1016,1023 },
- };
咱們的NandFlash驅動不要放在\DeviceCode\Targets\Native\CortexM3\DeviceCode目錄,由於不一樣的開發板雖然採用STM32系列的CPU,可是外圍的Flash有可能型號不一樣,該NandFlash驅動要放在\Solutions\STM3210E\DeviceCode的目錄,這樣安排比較合理。
咱們在該目錄下建立Blockstorage目錄,下有兩個子目錄addDevices和NandFlash,NandFlash目錄放NandFlash驅動代碼和配置信息,addDevices目錄下的代碼比較簡單,就是把實現的NandFlash驅動加載到BlockStorageList中去,相關代碼以下:
- void BlockStorage_AddDevices()
- {
- BlockStorageList::AddDevice( &g_NandFlash_BS, &g_NandFlash_BS_DeviceTable, &g_NandFlash_BS_Config, FALSE );
- }
NandFlash的配置文件中主要的內容就是咱們上面提到的const BlockRange g_NandFlash_BlockStatus[],此外還要根據NandFlash的實際參數,填寫一些宏。
- #define FLASH_MANUFACTURER_CODE 0x20
- #define FLASH_DEVICE_CODE 0x73
- #define FLASH_BASE_ADDRESS 0x00000000
- #define FLASH_SIZE 0x01000000 //16M 128Mbit
- #define FLASH_BLOCK_COUNT 1024
- #define FLASH_SECTOR_PER_BLOCK 32
- #define FLASH_SECTOR_SIZE 512
- #define FLASH_BLOCK_SIZE FLASH_SECTOR_PER_BLOCK*FLASH_SECTOR_SIZE
- … …
NandFlash驅動是核心內容,咱們知道Cortex-M3平臺下不管是訪問SRAM仍是NandFlash (或NandFlash、SD卡等)都是要經過FSMC實現,因此這裏要編寫NandFlash以前,必定要先配置好FSMC寄存器,配置好以後,其Flash 驅動代碼和普通的ARM7或ARM9下NandFlash驅動相似。
具體的代碼這裏不列舉了,能夠參考EM-STM3210E開發板的示例代碼,不過這裏須要說明的是,地址部分四個字節,其中一個字節表示扇區偏移,三個字節表示扇區地址。可是咱們的扇區(頁)大小爲512+16個字節,一個字節沒法表示0~511的偏移,這個問題在示例代碼中找不到答案,只能看相關手冊了。
其實一個扇區(頁)分三部分,A、B、C,A爲扇區前256字節,B爲扇區下個256字節,C區爲16字節。因此下面的代碼就能實現0~511的扇區偏移。
- WriteCommand(offset<256 ? COMMAND_AREA_A : COMMAND_AREA_B);
- WriteCommand(COMMAND_READ_1);
- WriteAddress(offset & 0xFF);
- WriteAddress((StartSector >> 0) & 0xFF);
- WriteAddress((StartSector >> 8) & 0xFF);
- WriteAddress((StartSector >> 16) & 0xFF);
此外還要說明的是,該Flash的擦寫是以Block爲邊界的,這和通常的NandFlash以扇區爲邊界不一樣,可是擦寫單位都爲一個Block,這是相同的。因此這部分代碼在Porting時要和之前平臺的驅動要有些區別。
在NativeSample.proj文件中添加以下條目,就能夠測試咱們的NandFlash代碼了。
- <ItemGroup>
- <RequiredProjects Include="$(SPOCLIENT)\Solutions\Stm3210e\DeviceCode\Blockstorage\addDevices\dotNetMF.proj" />
- <DriverLibs Include="BlockStorage_AddDevices_NandFlash.$(LIB_EXT)" />
- </ItemGroup>
- <ItemGroup>
- <RequiredProjects Include="$(SPOCLIENT)\Solutions\Stm3210e\DeviceCode\Blockstorage\NandFlash\Driver\dotNetMF.proj" />
- <DriverLibs Include="NandFlash_BL.$(LIB_EXT)" />
- </ItemGroup>
- <ItemGroup>
- <RequiredProjects Include="$(SPOCLIENT)\Solutions\Stm3210e\DeviceCode\Blockstorage\NandFlash\Config\dotNetMF.proj" />
- <DriverLibs Include="NandFlash_BL_Config.$(LIB_EXT)" />
- </ItemGroup>
- NativeSample.cpp中的測試代碼以下:
- BlockStorageDevice *device= BlockStorageList::GetFirstDevice();
- if(device!=NULL)
- {
- UINT8 bytRet= device->EraseBlock(0x0); //0x20000
- debug_printf("EraseBlock:%s\r\n",bytRet? "OK":"ERROR");
- BYTE bytWriteData[10];
- for(int i=0;i<10;i++) bytWriteData[i]=(BYTE)(i % 256);
- bytRet=device->Write(10,10,bytWriteData,FALSE);
- debug_printf("Write:%s\r\n",bytRet? "OK":"ERROR");
- bytRet=device->Write(30,10,bytWriteData,FALSE);
- debug_printf("Write:%s\r\n",bytRet? "OK":"ERROR");
- bytRet=device->Write(513,10,bytWriteData,FALSE);
- debug_printf("Write:%s\r\n",bytRet? "OK":"ERROR");
- BYTE bytReadData[1024];
- bytRet=device->Read(5,1024,bytReadData);
- debug_printf("Read:%s\r\n",bytRet? "OK":"ERROR"); }
好了,NandFlash驅動咱們編寫完畢,下一篇將介紹SysTick驅動的實現。