Ecc option开启后报错解决(植入实际程序后)
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 = 0x001000FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000ECC0_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 = 0xFFFLASH_BANK1_SEC1 : origin = 0x091000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC2 : origin = 0x092000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC3 : origin = 0x093000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC4 : origin = 0x094000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC5 : origin = 0x095000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC6 : origin = 0x096000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC7 : origin = 0x097000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC8 : origin = 0x098000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC9 : origin = 0x099000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000, vfill = 0xFFFLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0, vfill = 0xFFECC1_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 = 0ECC0_1 : > ECC0_1, PAGE = 0ECC0_2 : > ECC0_2, PAGE = 0ECC0_3 : > ECC0_3, PAGE = 0ECC0_4 : > ECC0_4, PAGE = 0ECC0_5 : > ECC0_5, PAGE = 0ECC0_6 : > ECC0_6, PAGE = 0ECC0_7 : > ECC0_7, PAGE = 0ECC0_8 : > ECC0_8, PAGE = 0ECC0_9 : > ECC0_9, PAGE = 0ECC0_10 : > ECC0_10, PAGE = 0ECC0_11 : > ECC0_11, PAGE = 0ECC0_12 : > ECC0_12, PAGE = 0ECC0_13 : > ECC0_13, PAGE = 0ECC0_14 : > ECC0_14, PAGE = 0ECC0_15 : > ECC0_15, PAGE = 0// 如果你使用 Bank1,也加入 ECC1 的映射ECC1_0 : > ECC1_0, PAGE = 0ECC1_1 : > ECC1_1, PAGE = 0ECC1_2 : > ECC1_2, PAGE = 0ECC1_3 : > ECC1_3, PAGE = 0ECC1_4 : > ECC1_4, PAGE = 0ECC1_5 : > ECC1_5, PAGE = 0ECC1_6 : > ECC1_6, PAGE = 0ECC1_7 : > ECC1_7, PAGE = 0ECC1_8 : > ECC1_8, PAGE = 0ECC1_9 : > ECC1_9, PAGE = 0ECC1_10 : > ECC1_10, PAGE = 0ECC1_11 : > ECC1_11, PAGE = 0ECC1_12 : > ECC1_12, PAGE = 0ECC1_13 : > ECC1_13, PAGE = 0ECC1_14 : > ECC1_14, PAGE = 0ECC1_15 : > ECC1_15, PAGE = 0ramgs0 : > RAMGS0, PAGE = 1ramgs1 : > RAMGS1, PAGE = 1RAMGS0 : > RAMGS0, PAGE = 1GROUP{.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 = 1DataBufferSection : > RAMLS4, PAGE = 0, ALIGN(4)
}ECC {C2000_Algo: address_mask = 0x1FFFFCparity_mask = 0xFCmirroring = 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区域理解为‘只读区域’。
通过上述修改,整个代码终于可以正常运行了!!!!