关于STM32 ISP升级程序遇到地址冲突的一系列问题及解决办法

2019-12-14 12:34发布

平台:STM32F429VIT6  2M FLASH  (192K+64K) RAM  没有外挂SRAM
实现功能:百兆网络、与FPGA进行图像数据交换以及处理、以及各种外围接口(IIC、SPI、CAN、485等等)、ISP升级程序

//内存池大小宏定义
#define MEM1_BLOCK_SIZE        32                          //ÄÚ´æ¿é´óСΪ32×Ö½Ú
#define MEM1_MAX_SIZE                80*1024         //×î´ó¹ÜÀíÄÚ´æ 110k      //´Ë´¦·ÖÅäµÄÄÚ´æ²»ÄÜ̫С£¬²»È»ÍøÂç³õʼ»¯·ÖÅäÄÚ´æ²»¹»£¬Í¨²»¹ý
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE  //ÄÚ´æ±í´óС

//mem2ÄÚ´æ²ÎÊýÉ趨,mem2´¦ÓÚÍⲿSRAMÀïÃæ
#define MEM2_BLOCK_SIZE        32                          //ÄÚ´æ¿é´óСΪ32×Ö½Ú
#define MEM2_MAX_SIZE                32//200*1024           //×î´ó¹ÜÀíÄÚ´æ 200k    ûÓÐÍâÀ©SRAMËùÒÔ·ÖÅä32×Ö½Ú´óС£¨Ìﶬ£©
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE  //ÄÚ´æ±í´óС

//mem3ÄÚ´æ²ÎÊýÉ趨,mem3´¦ÓÚCCM,ÓÃÓÚ¹ÜÀíCCM(Ìرð×¢Òâ,Õⲿ·ÖSRAM,½üCPU¿ÉÒÔ·ÃÎÊ)
#define MEM3_BLOCK_SIZE        32                          //ÄÚ´æ¿é´óСΪ32×Ö½Ú
#define MEM3_MAX_SIZE                60*1024         //×î´ó¹ÜÀíÄÚ´æ 60k
#define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE  //ÄÚ´æ±í´óС


一、此段代码分配的地址出现冲突

配置3.jpg (753.53 KB, 下载次数: 0) 下载附件 2018-12-18 15:20 上传
//内存池分配
__align(4) u8 mem1base[MEM1_MAX_SIZE];
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0x68000000))); //ÍⲿSRAMÄÚ´æ³Ø
__align(4) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0x10000000))); //ÄÚ²¿CMMÄÚ´æ³Ø
//ÄÚ´æ¹ÜÀí±í
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE)));        //ÍⲿSRAMÄÚ´æ³ØMAP
u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000+MEM3_MAX_SIZE)));        //ÄÚ²¿CCMÄÚ´æ³ØMAP
//ÄÚ´æ¹ÜÀí²ÎÊý          
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE};        //ÄÚ´æ±í´óС
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE};                                        //ÄÚ´æ·Ö¿é´óС
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE};                                                        //ÄÚ´æ×Ü´óС


编译结果:kei报错如下,.Objectsxxx.axf: Error: L6971E: uservar.o(.data) type RW incompatible with malloc.o(.ARM.__AT_0x1000F000) type ZI in er RW_IRAM2.
问题分析:编译器报IRAM2地址冲突,首先uservar.o(.data)分配49Kbyte大数组,在勾选IRAM2(CCM)的情况下编译器会把变量占用的RAM放入IRAM2(CCM),而我在mallo.c里已经分配了63Kbyte多(60+60*1024/32),最终造成其他文件的.data或.bss地址与malloc.c形成的数据地址冲突。
疑点:实际上IRAM1还有很多没用到,在IRAM1没用完的情况下,编译器会把变量数据分配到IRAM2(CCM)这怎么解释???(有知道的大神麻烦解释下)

二、此段代码分配的地址没有出现冲突,但是代码功能不正常运行(从BOOTLOAD无法跳转到APP)

//内存池分配
__align(4) u8 mem1base[MEM1_MAX_SIZE];
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0x68000000))); //ÍⲿSRAMÄÚ´æ³Ø
__align(4) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0x10000000))); //ÄÚ²¿CMMÄÚ´æ³Ø
//ÄÚ´æ¹ÜÀí±í
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE)));        //ÍⲿSRAMÄÚ´æ³ØMAP
u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000+MEM3_MAX_SIZE)));        //ÄÚ²¿CCMÄÚ´æ³ØMAP
//ÄÚ´æ¹ÜÀí²ÎÊý          
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE};        //ÄÚ´æ±í´óС
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE};                                        //ÄÚ´æ·Ö¿é´óС
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE};                                                        //ÄÚ´æ×Ü´óС

编译结果:Program Size: Code=93084 RO-data=721984 RW-data=540 ZI-data=209112  
问题:针对一出现的现象,我把勾选上IRAM2取消,编译没有出现地址冲突,编译完全通过。
问题分析:将正常的ISP程序和本功能代码烧录进单片机,发现程序功能不正常,调试发现程序根本没有运行到0X08000000以后的地址。也就是说一直卡在bootload代码处。

三、此段代码分配的地址没有出现冲突,代码功能正常运行(从BOOTLOAD无法跳转到APP)

//内存池分配
__align(4) u8 mem1base[MEM1_MAX_SIZE] __attribute__((at(0x2001ABC4)));//为什么定义此处地址,是根据MAP文件查看到此后面的RAM没有用过
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0x68000000))); //ÍⲿSRAMÄÚ´æ³Ø
__align(4) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0x10000000))); //ÄÚ²¿CMMÄÚ´æ³Ø
//ÄÚ´æ¹ÜÀí±í
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE] __attribute__((at(0x2001ABC4+MEM1_MAX_SIZE)));
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE)));        //ÍⲿSRAMÄÚ´æ³ØMAP
u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000+MEM3_MAX_SIZE)));        //ÄÚ²¿CCMÄÚ´æ³ØMAP
//ÄÚ´æ¹ÜÀí²ÎÊý          
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE};        //ÄÚ´æ±í´óС
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE};                                        //ÄÚ´æ·Ö¿é´óС
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE};                                                        //ÄÚ´æ×Ü´óС

编译结果:Program Size: Code=93084 RO-data=721984 RW-data=540 ZI-data=261324  
结果:针对二出现的现象,仅仅将地址指定分配到IRAM1的某个固定位置(具体地址是根据MAP文件发现此后的IRAM1都没用到,而且很大,所以就将地址指定于此),编译成功,下载后程序功能正常。ISP跳转APP或是APP跳转ISP正常,以及程序功能也正常。
疑点:从编译结果看出RW-data + ZI-data完全超过了IRAM1(RAM) +IRAM2(CCM)和256Kbyte,为什么内存突然变大50Kbyte左右????,然后查看MAP文件,ZI-data加起来没有261324byte,发现inc1.Padding有52220byte,将ZI-data +inc1.Padding刚好216324byte。
         请问inc.Padding是什么,在指定地址分配内存后为什么占用那么大(在第二种情况下为0byte)??????

上述二、三两情况的MAP文件随附件一起发送,一编译不过MAP文件没意义没有附送,keil里的地址配置随附件图片发送。
哪位大神看到此贴给个解释,先谢了!!!!!

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。