并行FLASH引导的一点经验-阿哲
最近BBS上关于FLASH和BOOT的讨论很活跃,我也多次来此请教。前几天自制的DSP板引导成功,早就打算写写这方面的东西。我用的DSP是5416,以其为核心,做了一个相对独立的子系统(硬件、软件、算法),目前都已基本做好。 下面把在FLASH引导方面做的工作向大家汇报一下,希望能对大家有所帮助。本人经验和文笔都有限,写的不好请大家谅解。 硬件环境: DSP:TMS320VC5416PGE160 FLASH:SST39VF400A-70-4C-EK 都是贴片的,FLASH映射在DSP数据空间的0x8000-0xFFFF 软件环境: CCS v2.12.01 主程序(要烧入FLASH的程序): DEBUG版,程序占用空间0x28000-0x2FFFF(片内SARAM),中断向量表在0x0080-0x00FF(片内DARAM),数据空间使用0x0100-0x7FFF(片内DARAM)。 因为FLASH是贴片的,所以需要自己编一个数据搬移程序,把要主程序搬移到FLASH中。在写入FLASH数据时,还应写入引导表的格式数据。最后在数据空间的0xFFFF处写入引导表的起始地址(这里为0x8000)。 搬移程序: DEBUG版,程序空间0x38000-0x3FFFF(片内SARAM),中断向量表在0x7800-0x78FF(片内DARAM),数据空间使用0x5000-0x77FF(片内DARAM)。 搬移程序不能使用与主程序的程序空间和中断向量表重合的物理空间,以免覆盖。 烧写时,同时打开主程序和搬移程序的PROJECT,先LOAD主程序,再LOAD搬移程序,然后执行搬移程序,烧写OK! 附:搬移程序(仅供参考) volatile unsigned int *pTemp=(unsigned int *)0x7e00; unsigned int iFlashAddr; int iLoop; /* 在引导表头存放并行引导关键字 */ iFlashAddr=0x8000; WriteFlash(iFlashAddr,0x10aa); iFlashAddr++; /* 初始化SWWSR值 */ WriteFlash(iFlashAddr,0x7e00); iFlashAddr++; /* 初始化BSCR值 */ WriteFlash(iFlashAddr,0x8006); iFlashAddr++; /* 程序执行的入口地址 */ WriteFlash(iFlashAddr,0x0002); iFlashAddr++; WriteFlash(iFlashAddr,0x8085); iFlashAddr++; /* 程序长度 */ WriteFlash(iFlashAddr,0x7f00); iFlashAddr++; /* 程序要装载到的地址 */ WriteFlash(iFlashAddr,0x0002); iFlashAddr++; WriteFlash(iFlashAddr,0x8000); iFlashAddr++; for (iLoop=0;iLoop<0x7f00;iLoop++) { /* 从程序空间读数据,放到暂存单元 */ asm(" pshm al"); asm(" pshm ah"); asm(" rsbx cpl"); asm(" ld #00fch,dp"); asm(" stm #0000h, ah"); asm(" MVDM _iLoop, al"); asm(" add #2800h,4,a"); asm(" reada 0h"); asm(" popm ah"); asm(" popm al"); asm(" ssbx cpl"); /* 把暂存单元内容写入FLASH */ WriteFlash(iFlashAddr,*pTemp); iFlashAddr++; } /* 中断向量表长度 */ WriteFlash(iFlashAddr,0x0080); iFlashAddr++; /* 中断向量表装载地址 */ WriteFlash(iFlashAddr,0x0000); iFlashAddr++; WriteFlash(iFlashAddr,0x0080); iFlashAddr++; for (iLoop=0;iLoop<0x0080;iLoop++) { /* 从程序空间读数据,放到暂存单元 */ asm(" pshm al"); asm(" pshm ah"); asm(" rsbx cpl"); asm(" ld #00fch,dp"); asm(" stm #0000h, ah"); asm(" MVDM _iLoop, al"); asm(" add #0080h,0,a"); asm(" reada 0h"); asm(" popm ah"); asm(" popm al"); asm(" ssbx cpl"); /* 把暂存单元内容写入FLASH */ WriteFlash(iFlashAddr,*pTemp); iFlashAddr++; } /* 写入引导表结束标志 */ WriteFlash(iFlashAddr,0x0000); iFlashAddr++; WriteFlash(iFlashAddr,0x0000); /* 在数据空间的0xFFFF写入引导表起始地址 */ iFlashAddr=0xffff; WriteFlash(iFlashAddr,0x8000);
|