一般来说,把一个在RAM里正常运行的程序移植到FLASH里(运行时将FLASH中的程序拷贝到RAM中运行)的步骤如下:

1.需要将适合RAM运行环境的CMD文件移出工程,替换成FLASH专用的的F28335.cmd

 

2.将另一个文件DSP2833x_CodeStartBranch.asm添加到工程中,如果工程内本来就有这个文件,就不用再添加了

 

3.在DSP28_SysCtrl.c文件中添加如下代码,如果工程里已有InitFlash函数,则不用再添加,检查下函数内容即可

 1 #pragma CODE_SECTION(InitFlash, "RamFuncs");
 2 
 3 void InitFlash(void)
 4 
 5 {
 6 
 7    EALLOW;
 8 
 9    //Enable Flash Pipeline mode to improve performance
10 
11    //of code executed from Flash.
12 
13    FlashRegs.FOPT.bit.ENPIPE = 1;
14 
15    //                CAUTION
16 
17    //Minimum waitstates required for the flash operating
18 
19    //at a given CPU rate must be characterized by TI.
20 
21    //Refer to the datasheet for the latest information.
22 
23  
24 
25    //Set the Paged Waitstate for the Flash
26 
27    FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;
28 
29  
30 
31    //Set the Random Waitstate for the Flash
32 
33    FlashRegs.FBANKWAIT.bit.RANDWAIT = 5;
34 
35  
36 
37    //Set the Waitstate for the OTP
38 
39    FlashRegs.FOTPWAIT.bit.OTPWAIT = 8;
40 
41  
42 
43    //                CAUTION
44 
45    //ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
46 
47    FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
48 
49    FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
50 
51    EDIS;
52 
53  
54 
55    //Force a pipeline flush to ensure that the write to
56 
57    //the last register configured occurs before returning.
58 
59  
60 
61    asm(" RPT #7 || NOP");
62 
63 }

 

4.在main函数所在的源文件中,添加下面所示的代码,位置可以放在main函数之前

1 extern Uint16 RamFuncs_loadstart;
2 
3 extern Uint16 RamFuncs_loadend;
4 
5 extern Uint16 RamFuncs_runstart; 

 

5.在main函数中添加如下以红色字体显示的代码

 1 /*初始化系统*/
 2 
 3 InitSysCtrl();
 4 
 5 memcpy(&RamFuncs_runstart,&RamFuncs_loadstart,&RamFuncs_loadend - &RamFuncs_loadstart);
 6 
 7    asm(" RPT #8 || NOP");
 8 
 9  
10 
11   /*FLASH 初始化 */
12 
13  InitFlash();
14 
15  
16 
17 /*关中断*/
18 
19 DINT;
20 
21 IER = 0x0000;
22 
23 IFR = 0x0000;

 

 6.在头文件DSP2833x_GlobalPrototypes.h中添加FLASH初始化函数的声明,如果已经声明,就不用再添加

 1 extern void InitFlash(void); 

 

//7.验证Boot mode      //通常已经正确选择

//DSP开发板上的拨码开关都拨到ON,本质含义是:将F28335的GPIO84、GPIO85、GPIO86、GPIO87这四个引脚用1k到10k之间电阻上拉到3.3V,这样就把Boot mode选为从DSP内部FLASH处boot程序的模式;

 

通常,上述步骤完成之后,在编译没有报错的情况下直接Debug即可将程序烧写进FLASH,之后断电,拔掉仿真器,再重新上电,程序即可自动运行。

但是我在实际调试的过程中却遇到了在将程序Debug之后,直接在线仿真调试程序可以正常运行,但是一旦断电,拔掉仿真器,再重新上电之后,程序无法自动运行的现象。

经过一步步把程序向例程迁移→调试→迁移的尝试,最后发现问题出在DSP2833x_usDelay.asm 文件的内容和新的CMD文件配置不符。

原版的DSP2833x_usDelay.asm 文件是这样写的:

1 .def _DSP28x_usDelay
2 .sect "ramfuncs"
3 
4 .global __DSP28x_usDelay
5 _DSP28x_usDelay:
6 SUB ACC,#1
7 BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0
8 LRETR

 

可以看到分配到了”ramfuncs”段,而新的CMD文件中并无对应的Section

 1 SECTIONS
 2 {
 3 
 4 /* Allocate program areas: */
 5 .cinit : > FLASHB PAGE = 0
 6 .pinit : > FLASHB PAGE = 0
 7 .text : > FLASHB PAGE = 0
 8 codestart : > BEGIN PAGE = 0
 9 //RamFuncs : > FLASHC    PAGE = 0 
10 RamFuncs : LOAD = FLASHC, PAGE = 0 /* Should be Flash */ 
11 RUN = RAML1, PAGE = 0 /* Must be CSM secured RAM */
12 LOAD_START(_RamFuncs_loadstart),
13 LOAD_END(_RamFuncs_loadend),
14 RUN_START(_RamFuncs_runstart)
15 
16 
17 csmpasswds : > CSM_PWL PAGE = 0
18 csm_rsvd : > CSM_RSVD PAGE = 0
19 
20 /* Allocate uninitalized data sectins: */
21 .stack : > RAMM1 PAGE = 1
22 .ebss : > RAML5 PAGE = 1
23 .esysmem : > RAMM1 PAGE = 1
24 
25 /* Initalized sections go in Flash */
26 /* For SDFlash to program these, they must be allocated to page 0 */
27 .econst : > FLASHB PAGE = 0
28 .switch : > FLASHB PAGE = 0
29 
30 /* Allocate IQ math areas: */
31 IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD 
32 IQmathTables2 : > IQTABLES2, PAGE = 0, TYPE = NOLOAD 
33 FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD 
34 
35 .reset : > RESET, PAGE = 0, TYPE = DSECT
36 vectors : > VECTORS PAGE = 0, TYPE = DSECT
37 
38 /* Allocate ADC_cal function (pre-programmed by factory into TI reserved memory) */
39 .adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD
40 
41 }

 

 那么既然找到了问题的所在,解决方法也就很简单了,只要把DSP2833x_usDelay.asm 文件中的“ramfuncs”段修改为新CMD文件中存在的Section中即可

1 .def _DSP28x_usDelay
2 .sect "RamFuncs"
3
4 .global __DSP28x_usDelay
5 _DSP28x_usDelay:
6 SUB ACC,#1
7 BF _DSP28x_usDelay,GEQ ;; Loop if ACC >= 0
8 LRETR

 

重新编译,Debug之后,程序已经可以在脱离仿真器的状态下正常运行。

 

备注:问题的关键主要在于新CMD文件和DSP2833x_usDelay.asm 文件编写的不配套。

应该说不是所有人都会遇到这种错误现象,但是当我遇到这种错误时,在互联网上查阅多时,都没有找到相关讨论。

记录下来,一来是给自己提个醒,二来也希望给遇到同一种错误现象的同学提供一种可能的解决问题的思路。

欢迎指正。

 

版权声明:本文为Fangjq2020原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Fangjq2020/p/13205708.html