DSP内部FLASH不能用于存放用户代码,所以为了使DSP在掉电后能够正常运行,必须将程序存储在外部非易失存储器中。一般的FLASH读取比较慢,为了使得DSP充分发挥其高速执行指令的功能,需要将程序和数据都存储在高速内存中,一般为静态RAM或者动态RAM。所以上电之后需要通过自引导的方式将FLASH中的代码搬移到内部存储器(IRAM)或者外部高速RAM(ddr等高速RAM)中运行。下面首先介绍DSP的启动过程。
本文只介绍DSP C6000系列的相关知识,所以启动模式仅限于C6000系列。DSP C6000内部的FLASH固化了厂商的初始BOOT代码,无法修改,在DSP上电后,系统首先进入复位状态,并且保持,程序进入内部bootloader执行,首先bootloader读取BOOTCFG寄存器,bootloader决定从哪个外设启动,本历程为从NANDFLASH启动,根据TI提供的手册,需要将BOOTCFG中的字段BOOTMODE设置成0111,相应的引脚需要在硬件上连接才能设置BOOTMODE,在硬件上还需注意的是NANDFLASH必须连接到EMIFA的CS2地址空间上,在执行完bootloader后程序跳转到用户代码空间,复位结束,开始执行用户代码。
网上很多资料都是讲解bootloader只能搬移1KB或者64KB的程序,一般需要进行二级bootloader引导。本文不进行这一方面的介绍,而是直接使用TI固化的bootloader执行脚本命令来启动程序,这个脚本被称为AIS(Application Image Script),用户代码可以全部转化成AIS脚本,直接烧写在NANDFALSH上,不需要二次引导即可启动。
为了能顺利的进行NANDFLASH的固化操作,有必要对NANDFLASH进行非常详细的了解,下面就进行一些简单的介绍。
提到NAND FLASH不得不也提到NOR FLASH,这两种是主要的非易失闪存技术。NOR FLASH最大的优点就是读取速度非常快(与NAND FLASH相比),程序可以直接在NOR FLASH中执行,不必搬移到内存中。但是其缺点也很大,它的写入和擦除速度非常慢,存储单元密度较低,成本较高,相比之下NANDFLASH的优势就比较大,下面列出他们的性能比较。
NOR FLASH与NAND FLASH的比较
比较项 | NOR FLASH | NAND FLASH |
读速度 | 相对快 | 相对慢 |
写速度 | 慢很多 | 快很多 |
擦除速度 | 慢很多 | 块很多 |
擦除单元 | 擦除单元大,擦除电路大一些 | 擦除单元小,擦擦电路小一些 |
容量 | 相对小,主要存放代码 | 大,适用于存放大量数据 |
成本 | 相对高 | 相对低 |
寿命 | 擦写10万次 | 擦除100万次 |
接着介绍NANDFLASH的操作,首先需要了解NANDFLASH的内部结构。一个NAND FLASH有很多块(Block)组成,块的大小一般是128KB, 256KB, 512KB,笔者用到的是ST公司的NAND512-A,查相应的数据手册可知快大小在8位数据总线下为16KB,每一块又由很多页组成,一页由512B组成,除了可以用来存储的空间外,NANDFLASH每一块预留512B或256B,每一页预留16B或8B来记录对应块与页的状态。FLASH操作的最小单位为:读取写入为页,擦除操作为块;而且要写入数据必须先擦除一整块。一般而言,DSP程序都比较大,选择NANDFALSH是不错的选择。
下面具体编程操作:
#include "stdio.h" #include "evm6424.h" #include "evm6424_nandflash.h" void main( void ) { int FlashPages = 0; unsigned char data[512]; int i = 0; EVM6424_init( ); FlashPages = EVM6424_NANDFLASH_getTotalPages(); printf("NANDFLASH pages:%d\n",FlashPages); //向第一页写入0~255~0 for(i=0;i<512;i++) { data[i] = i; } EVM6424_NANDFLASH_erase(0); EVM6424_NANDFLASH_writePage(0,0,(Uint32)data); //EVM6424_NANDFLASH_readPage(0,0,(Uint32)data); while(1) { ; } }
程序首先进行初始化,然后读取总共的页数,首先初始化为0~127~-128,为了检验写入是否成功,先向第一页写入数据,运行,然后在读取,读取的数据是否为前次写入的数据。在这个过程中,为了避免程序执行的奇异,读取之前先将数组清空为0。
#include "stdio.h" #include "evm6424.h" #include "evm6424_nandflash.h" void main( void ) { int FlashPages = 0; unsigned char data[512]; int i = 0; EVM6424_init( ); FlashPages = EVM6424_NANDFLASH_getTotalPages(); printf("NANDFLASH pages:%d\n",FlashPages); //向第一页写入0~255~0 for(i=0;i<512;i++) { data[i] = 0; } //EVM6424_NANDFLASH_erase(0); //EVM6424_NANDFLASH_writePage(0,0,(Uint32)data); EVM6424_NANDFLASH_readPage(0,0,(Uint32)data); while(1) { ; } }
当在CCS上调试时运行到最后,data变量不在全为0而是0~127~-128则说明程序NANDFLASH擦除写入读取成功,可以接着进行下一节的学习了。
本节重点:
- FLASH的操作单位:读取写入为页,擦除为块;
- FLASH在写之前必须先擦除,在电路上存储器只能有1变为0;
- NANDFLASH启动的前提:BOOTMODE为0111,存储器挂接在EMIFA的CS2空间。