zoukankan      html  css  js  c++  java
  • 【.Net Micro Framework PortingKit – 11】NandFlash驱动开发

    .Net Micro Framework系统来说,正常情况下Flash(包括NandFlashNORFlash)分为六个区,分别为:

    1、        BLOCKTYPE_BOOTSTRAP(存放启动代码,一般为TinyBooter

    2、        BLOCKTYPE_CONFIG(配置区,存放配置信息)

    3、        BLOCKTYPE_CODE(本地代码区,指TinyCLR代码)

    4、        BLOCKTYPE_DEPLOYMENT(托管代码区,存放用户的C#程序)

    5、        BLOCKTYPE_STORAGE_A(用户数据存储区)

    6、        BLOCKTYPE_FILESYSTEM(文件系统)

    其中234项为.Net Micro Framework系统所必须。

    如果FlashNandFlash,则存放在BLOCKTYPE_BOOTSTRAP区的启动代码是无法直接执行的,系统必须在ROMNORFlash或其它线性执行存储区存放一个Bootload,由该Bootload加载TinyBooter,然后由TinyBooter引导TinyCLR启动(当然如果空间允许,TinyBooter也可以放在NORFlash,直接运行来引导TinyCLR,Bootload直接引导TinyCLR也是可以的)。

    TinyCLR一般常见大小为700k左右,其实也可以放在NORFlash中,不需要TinyBooter而直接运行,不过这样就不方便用MFDeployTinyCLR进行升级了。

    常见的MF系统,TinyBooter启动后一般把TinyCLRNandFlash拷贝到RAM中,TinyCLR实际是在RAM中执行的。这就需要RAM的大小至少要大于TinyCLR的大小,加上堆和栈的大小,理想的RAM大小至少要大于2M

    EM-STM3210E开发板上的Flash含四部分,片内Flash 512k(系统Flash2k,存放系统Bootload,不能更改,ISP功能就是由该Bootload来支持的),2M NOR Flash8M SPI Flash128Mb16M字节) NandFlash

    Flash相对比较丰富,但是RAM资源却有些不足,片内含64K RAM,片外扩展了128KB SRAM。由于RAM相对偏小,所以TinyCLR的代码是不可能拷贝到RAM中执行的,如果TinyCLR达到常见大小,则片内用户FLASH也是放不下的,也只有放到2M NOR Flash中去了。不过我们这次Porting.Net Micro Framework仅是最小集,TinyCLR大概250K左右,此外TinyBooter对我们也不是必须的,我们通过ISP方式下载TinyCLR

    NORFlashSPI 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目录,下有两个子目录addDevicesNandFlashNandFlash目录放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 (NandFlashSD卡等)都是要通过FSMC实现,所以这里要编写NandFlash之前,一定要先配置好FSMC寄存器,配置好之后,其Flash 驱动代码和普通的ARM7ARM9NandFlash驱动类似。

    具体的代码这里不列举了,可以参考EM-STM3210E开发板的示例代码,不过这里需要说明的是,地址部分四个字节,其中一个字节表示扇区偏移,三个字节表示扇区地址。但是我们的扇区(页)大小为512+16个字节,一个字节无法表示0~511的偏移,这个问题在示例代码中找不到答案,只能看相关手册了。

    其实一个扇区(页)分三部分,ABCA为扇区前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驱动的实现。
  • 相关阅读:
    chapter2——习题
    chapter2 算法——程序的灵魂
    物理数据库设计 读书笔记
    从visio数据库脚本生成添加 MS_Description 的sql脚本
    SSIS包中CASE与NVARCHAR的恩怨
    又到年末
    delicious备份文件转入firefox书签,delicious2firefox 原创、开源
    软件架构设计 温昱著 读书笔记
    重构 读书笔记
    再遇SSIS包与MSSQL问题
  • 原文地址:https://www.cnblogs.com/yefanqiu/p/1668622.html
Copyright © 2011-2022 走看看