对.Net Micro Framework系统来说,正常情况下Flash(包括NandFlash和NORFlash)分为六个区,分别为:
1、 BLOCKTYPE_BOOTSTRAP(存放启动代码,一般为TinyBooter)
2、 BLOCKTYPE_CONFIG(配置区,存放配置信息)
3、 BLOCKTYPE_CODE(本地代码区,指TinyCLR代码)
4、 BLOCKTYPE_DEPLOYMENT(托管代码区,存放用户的C#程序)
5、 BLOCKTYPE_STORAGE_A(用户数据存储区)
6、 BLOCKTYPE_FILESYSTEM(文件系统)
其中2、3、4项为.Net Micro Framework系统所必须。
如果Flash为NandFlash,则存放在BLOCKTYPE_BOOTSTRAP区的启动代码是无法直接执行的,系统必须在ROM、NORFlash或其它线性执行存储区存放一个Bootload,由该Bootload加载TinyBooter,然后由TinyBooter引导TinyCLR启动(当然如果空间允许,TinyBooter也可以放在NORFlash,直接运行来引导TinyCLR,或Bootload直接引导TinyCLR也是可以的)。
TinyCLR一般常见大小为700k左右,其实也可以放在NORFlash中,不需要TinyBooter而直接运行,不过这样就不方便用MFDeploy对TinyCLR进行升级了。
常见的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驱动的实现。
分享到:
相关推荐
本资源为三星系列Nand Flash芯片K9F5608的驱动代码,用C语言开发,具有良好的编程风格,已经过实际调试验证,可用于实际工程开发。
nandflash驱动开发和移植,在linux操作台系统下完成nandflash驱动的开发和移植
stm32 通过FSMC驱动nandflash 驱动代码,nansflash为K9F1G08
nand flash 驱动分析nand flash 驱动分析nand flash 驱动分析nand flash 驱动分析nand flash 驱动分析
以及如果要去实现Linux下面的Nand Flash驱动之前,所要了解到的 Nand FLash的硬件知识,Linux下面Nand Flash的框架, 以及如何去在Linux的框架下,实现对应的Nand Flash的驱动。 在1.7的版本上: 1. 添加了Nand ...
再从Flash硬件机制开始,介绍到Nand Flash的常见的物理特性,且深入介绍了Nand Flash的一些高级功能,然后开始介绍Linux下面和Nand Flash相关的软件架构MTD的相关知识,最后介绍了在Linux的MTD驱动框架下,...
2.2.4 Nand Flash数据存储单元的整体架构 11 2.2.5 Nand Flash的物理存储单元的阵列组织结构 12 2.2.6 Flash名称的由来 13 2.2.7 Flash相对于普通设备的特殊性 13 2.2.8 Nand Flash引脚(Pin)的说明 14 2.2.9 Nand ...
s5pv210开发板的nandflash驱动代码,含测试案例
嵌入式Linux中的Nand Flash驱动详解.pdf
NAND Flash的驱动程序设计NAND Flash的驱动程序设计
nandflash的驱动程序 GPIO方式编写
本文主要介绍了Nand Flash的各种硬件背景知识,以及Linux框架下的MTD等软件背景知识,最后介绍了在Linux的MTD驱动框架下,如何实现Nand Flash的驱动。
本文档详细描述了nandflash硬件特性及在linux下nandflash驱动实现的代码详细注释,可作为编写nandflash驱动的参考
spi接口的nand flash。程序是基于GD5F1GQ4xExIG的协议编写的,完成了读寄存器,写寄存器,擦除,读PAGE,写PAGE,读cache,写cahche等接口。不包括坏块管理和空间管理。
华邦NAND FLASH 128M容量驱动 STM32407单片机驱动 参考三星128M NAND FLASH
非常详细的代码,代码注释完全,从底层到高层各个函数都有设计,非常详细,niosii开发nandflash驱动,有参考价值
由于NAND闪存的特性,相应的驱动需要按特定的方式操作
首先,这个文档是分享的,个人学习了一下,感觉非常实用,对于初始学者很有帮助,特别是对于最初接触nandflash的学习者,里面对于nandflash的介绍很详细