1. Error #10413: 指定地址不在已初始化的 section 中
#10413: error specified at 0x86000 does not lie within an initialized section
这个错误表示没有对改地址进行初始化操作,原始cmd文件中是这样定义的:
FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000 /* on-chip Flash */
再没有开启ecc功能之前,没有报错,因此这是ECC配置没有成功告诉链接器SEC6是有效的。因此需要再ECC配置中指明FLASH_BANK0_SEC6时ECC要涵盖的区域。对于auto模式,flash数据和ecc地址是自动完成映射的,但是由于我们需要引入错误位,因此改用手动模式,这时就需要再cmd文件中添加ecc的地址,并且在cmd中添加ECC模块的支持算法,修改后的cmd文件如下:
/* BANK 0 */
FLASH_BANK0_SEC0 : origin = 0x080002, length = 0x000FF0 /* on-chip Flash */
FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000
FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000
FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000
FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000
FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000
FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000
FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000
FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000
FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000
FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000
FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000
FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000
FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000
FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000
FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000
ECC0_0 : origin = 0x1080000, length = 0x1FE, ECC = {input_range=FLASH_BANK0_SEC0 algorithm = C2000_Algo}
ECC0_1 : origin = 0x1080200, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC1 algorithm = C2000_Algo}
ECC0_2 : origin = 0x1080400, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC2 algorithm = C2000_Algo}
ECC0_3 : origin = 0x1080600, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC3 algorithm = C2000_Algo}
ECC0_4 : origin = 0x1080800, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC4 algorithm = C2000_Algo}
ECC0_5 : origin = 0x1080A00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC5 algorithm = C2000_Algo}
ECC0_6 : origin = 0x1080C00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC6 algorithm = C2000_Algo}
ECC0_7 : origin = 0x1080E00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC7 algorithm = C2000_Algo}
ECC0_8 : origin = 0x1081000, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC8 algorithm = C2000_Algo}
ECC0_9 : origin = 0x1081200, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC9 algorithm = C2000_Algo}
ECC0_10 : origin = 0x1081400, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC10 algorithm = C2000_Algo}
ECC0_11 : origin = 0x1081600, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC11 algorithm = C2000_Algo}
ECC0_12 : origin = 0x1081800, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC12 algorithm = C2000_Algo}
ECC0_13 : origin = 0x1081A00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC13 algorithm = C2000_Algo}
ECC0_14 : origin = 0x1081C00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC14 algorithm = C2000_Algo}
ECC0_15 : origin = 0x1081E00, length = 0x200, ECC = {input_range=FLASH_BANK0_SEC15 algorithm = C2000_Algo}
//FLASH_BANK0 : origin= 0x080002, length = 0xFEFF
/* BANK 1 */
FLASH_BANK1_SEC0 : origin = 0x090000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC1 : origin = 0x091000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC2 : origin = 0x092000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC3 : origin = 0x093000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC4 : origin = 0x094000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC5 : origin = 0x095000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC6 : origin = 0x096000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC7 : origin = 0x097000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC8 : origin = 0x098000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC9 : origin = 0x099000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000, vfill = 0xFF
FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0, vfill = 0xFF
ECC1_0 : origin = 0x1082000, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC0 algorithm = C2000_Algo}
ECC1_1 : origin = 0x1082200, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC1 algorithm = C2000_Algo}
ECC1_2 : origin = 0x1082400, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC2 algorithm = C2000_Algo}
ECC1_3 : origin = 0x1082600, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC3 algorithm = C2000_Algo}
ECC1_4 : origin = 0x1082800, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC4 algorithm = C2000_Algo}
ECC1_5 : origin = 0x1082A00, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC5 algorithm = C2000_Algo}
ECC1_6 : origin = 0x1082C00, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC6 algorithm = C2000_Algo}
ECC1_7 : origin = 0x1082E00, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC7 algorithm = C2000_Algo}
ECC1_8 : origin = 0x1083000, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC8 algorithm = C2000_Algo}
ECC1_9 : origin = 0x1083200, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC9 algorithm = C2000_Algo}
ECC1_10 : origin = 0x1083400, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC10 algorithm = C2000_Algo}
ECC1_11 : origin = 0x1083600, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC11 algorithm = C2000_Algo}
ECC1_12 : origin = 0x1083800, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC12 algorithm = C2000_Algo}
ECC1_13 : origin = 0x1083A00, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC13 algorithm = C2000_Algo}
ECC1_14 : origin = 0x1083C00, length = 0x200, ECC = {input_range=FLASH_BANK1_SEC14 algorithm = C2000_Algo}
ECC1_15 : origin = 0x1083E00, length = 0x1FE, ECC = {input_range=FLASH_BANK1_SEC15 algorithm = C2000_Algo}
修改之后,如果还是出现这个错误,说明sector6里面没有存入数据,他会认为这个区域没有被使用,所以必须要保证sector6里面被存入了数据。 我将test中的内容存储了一部分在sector6里面
.text : >>FLASH_BANK0_SEC0 | FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4 | FLASH_BANK0_SEC6, PAGE = 0, ALIGN(4)
修改完以后,这个问题解决了。
2. 出现错误:C28xx_CPU1: File Loader: Verification failed: Attempted to write past the end of memory at 0x1080000@Program
这个问题说明启用了 ECC,但 .cmd
文件中 ECC 的地址段并没有被程序识别为“有效可写内存区域”。这是因为没有告诉linker,这些段是可以写入的。因此需要在SECTION中添加对ECC区域的映射,告诉它ECC区域可以被使用。并且在cmd文件的最后,添加ECC的算法。
SECTIONS
{
codestart : > BEGIN, PAGE = 0, ALIGN(4)
.text : >>FLASH_BANK0_SEC0 | FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4 | FLASH_BANK0_SEC5, PAGE = 0, ALIGN(4)
.cinit : > FLASH_BANK0_SEC5, PAGE = 0, ALIGN(4)
.pinit : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4)
.switch : > FLASH_BANK0_SEC1, PAGE = 0, ALIGN(4)
.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
.bss : > RAMLS5, PAGE = 1
.data : > RAMLS5, PAGE = 1
.const : > FLASH_BANK0_SEC5, PAGE = 0
.init_array : > FLASH_BANK0_SEC1, PAGE = 0
.sysmem : > RAMLS6, PAGE = 1
.cio : > RAMLS03, PAGE = 0
.stack : > RAMM1, PAGE = 1
.ebss : > RAMLS5, PAGE = 1
.esysmem : > RAMLS6, PAGE = 1
.econst : > FLASH_BANK0_SEC5, PAGE = 0, ALIGN(4)
.boot : > FLASH_BANK0_SEC6, PAGE = 0, ALIGN(4)
// 添加 ECC0 的映射
ECC0_0 : > ECC0_0, PAGE = 0
ECC0_1 : > ECC0_1, PAGE = 0
ECC0_2 : > ECC0_2, PAGE = 0
ECC0_3 : > ECC0_3, PAGE = 0
ECC0_4 : > ECC0_4, PAGE = 0
ECC0_5 : > ECC0_5, PAGE = 0
ECC0_6 : > ECC0_6, PAGE = 0
ECC0_7 : > ECC0_7, PAGE = 0
ECC0_8 : > ECC0_8, PAGE = 0
ECC0_9 : > ECC0_9, PAGE = 0
ECC0_10 : > ECC0_10, PAGE = 0
ECC0_11 : > ECC0_11, PAGE = 0
ECC0_12 : > ECC0_12, PAGE = 0
ECC0_13 : > ECC0_13, PAGE = 0
ECC0_14 : > ECC0_14, PAGE = 0
ECC0_15 : > ECC0_15, PAGE = 0
// 如果你使用 Bank1,也加入 ECC1 的映射
ECC1_0 : > ECC1_0, PAGE = 0
ECC1_1 : > ECC1_1, PAGE = 0
ECC1_2 : > ECC1_2, PAGE = 0
ECC1_3 : > ECC1_3, PAGE = 0
ECC1_4 : > ECC1_4, PAGE = 0
ECC1_5 : > ECC1_5, PAGE = 0
ECC1_6 : > ECC1_6, PAGE = 0
ECC1_7 : > ECC1_7, PAGE = 0
ECC1_8 : > ECC1_8, PAGE = 0
ECC1_9 : > ECC1_9, PAGE = 0
ECC1_10 : > ECC1_10, PAGE = 0
ECC1_11 : > ECC1_11, PAGE = 0
ECC1_12 : > ECC1_12, PAGE = 0
ECC1_13 : > ECC1_13, PAGE = 0
ECC1_14 : > ECC1_14, PAGE = 0
ECC1_15 : > ECC1_15, PAGE = 0
ramgs0 : > RAMGS0, PAGE = 1
ramgs1 : > RAMGS1, PAGE = 1
RAMGS0 : > RAMGS0, PAGE = 1
GROUP
{
.TI.ramfunc
{ -l F021_API_F28004x_FPU32_EABI.lib}
} LOAD = FLASH_BANK0_SEC10,
RUN = RAMLS03,
LOAD_START(RamfuncsLoadStart),
LOAD_SIZE(RamfuncsLoadSize),
LOAD_END(RamfuncsLoadEnd),
RUN_START(RamfuncsRunStart),
RUN_SIZE(RamfuncsRunSize),
RUN_END(RamfuncsRunEnd),
PAGE = 0, ALIGN(4)
.data : LOAD = FLASH_BANK0_SEC10,
RUN = RAMLS5,
LOAD_START(DataLoadStart),
RUN_START(DataRunStart),
LOAD_SIZE(DataLoadSize),
PAGE = 1
DataBufferSection : > RAMLS4, PAGE = 0, ALIGN(4)
}
ECC {C2000_Algo: address_mask = 0x1FFFFC
parity_mask = 0xFC
mirroring = F021
}
如果还不能解决这个问题,这个时候需要检查自己是否关闭了自动生成ecc的模式。如果没有关闭,两者会产生冲突,也会出现报错。 点击debug位置的黑色倒三角,选择Debug Configurations
在这里一定要注意,选择C28xx_CPU1:
然后选择界面上的Target——Flash settings,关闭这里的Auto ECC Generation功能:
重新设定以后,上述报错有效解决。
3. 程序运行过程中出现意外中断。由于我在程序中对flash操作的每个阶段设置了提示,我发现程序没有办法正常的运行。这个时候才意识到,我把text段落的一部分存到了sector6里面,但是flash需要再写入数据前进行擦除操作,也就是说在程序运行的过程中,一些有用的数据被删掉了!那程序自然不能正常运行。针对这个问题,我希望通过在sector6中写入一些无用数据,来填充它好让程序认为它被使用了。具体的操作如下:
在cmd文件的section部分指定一个sector6区域的位置:
my_app_data : > FLASH_BANK0_SEC6, PAGE = 0, ALIGN(4)
这个操作意味着,my_app_data中的内容只能被放入到SEC6中。然后在主函数中告诉编译器把 myData
的数据放到指定的段 my_app_data
中:
#pragma DATA_SECTION(myData, "my_app_data")
再定义需要写入的数据,这些数据随便写入就行:
const uint16_t myData[10] = {
0x1234, 0x5678, 0x9ABC, 0xDEF0,
0x1357, 0x2468, 0xAAAA, 0x5555,
0x0F0F, 0xF0F0
};
这里特别要注意需要使用const对数据进行定义。
我最开始写的是 uint16_t myData[10],然后又出现报错1,说sector6没有被使用。我查了一下,应该是因为编译器 优化掉了这个数组(我后续没用到它)。然后建议我改成volatile,但是会出现:error #10392-D: cannot generate ECC for "my_app_data" in memory range FLASH_BANK0_SEC6; objects may only have load data in this range.
我查了一下他们的定义,volatile是变量,告诉编译器这些数值会被修改,在烧写是放入data段,在运行的时候装载。编译器不会允许这样的变量存放在ecc区域中。因为flash的数据写入必须进行擦除,每次写入都要进行擦除后才能修改数据,因此把一个可变变量直接写入会出现报错。但是const代表常量,是不会被修改的,就是一个只读变量,所以flash允许它写入。可以把ECC区域理解为‘只读区域’。
通过上述修改,整个代码终于可以正常运行了!!!!