金牌会员
 
- 积分
- 2107
- 金钱
- 2107
- 注册时间
- 2017-2-11
- 在线时间
- 307 小时
|
5金钱
本帖最后由 jiangyy 于 2020-9-25 10:19 编辑
最近一直在使用STMCUBEIDE软件编程,在移植正点原子的内存池管理这章节(基于HAL库),发现有几处地方报错,如下:
//内存池(32字节对齐)
__align(32) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
__align(32) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000))); //外部SRAM内存池
__align(32) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X10000000))); //内部CCM内存池
//内存管理表
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
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
注意报错的地方是 软件无法识别 __attribute__((at(addr))),在网上找了相关文件(比较少),说可以使用 __attribute__((section(“.name”)))来替代,但是问题来了,这个肯定会涉及到启动文件.ld的修改。于是我就更改了STM32F407ZGTX_FLASH.ld文件,只罗列修改地方,如下所示:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
SRAM (rx) : ORIGIN = 0x68000000, LENGTH = 1024K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section into "RAM" Ram type memory */
.ccmram :
{
. = ALIGN(4);
_sccmram = .; /* create a global symbol at ccmram start */
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_eccmram = .; /* create a global symbol at ccmram end */
} >CCMRAM AT> FLASH/*新增,第一处修改*/
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
.sram :
{
. = ALIGN(4);
_SRAM_SYMBOLS = .; /* create a global symbol at data start */
*(.sram) /* .data sections */
*(.sram*) /* .data* sections */
. = ALIGN(4);
_ESRAM_SYMBOLS = .; /* define a global symbol at data end */
} >SRAM/*新增,第二处修改*/
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
上面有两个地方是新增的,修改好.ld文件后,再次去修改malloc.c文件的地方,如下:
//内存池(32字节对齐)
__attribute__ ((aligned (32))) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
__attribute__ ((aligned (32))) u8 mem2base[MEM2_MAX_SIZE] __attribute__((section(".sram.__at_0x68000000"))); //外部SRAM内存池
__attribute__ ((aligned (32))) u8 mem3base[MEM3_MAX_SIZE] __attribute__((section(".ccmram.__at_0x10000000"))); //内部CCM内存池
//内存管理表
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((section(".sram.__at_0x680F0000"))); //外部SRAM内存池MAP
u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((section(".ccmram.__at_0x1000F000"))); //内部CCM内存池MAP
最后,我做了一个测试函数,内容如下:
void Malloc_Test(void)
{
u8 *p=0;
u8 *tp=0;
u8 paddr[18]; //存放P Addr:+p地址的ASCII值
u8 sramx=0; //默认为内部sram
p=mymalloc(sramx,2048);//内部内存池申请2K字节
if(p!=NULL)
{
tp=p;
sprintf((char*)paddr,"0X%08X",(u32)tp);
sprintf((char*)p,"Memory SRAMIN ADDR:");//向p写入一些内容
printf("%s",p);
printf("%s\r\n",paddr);
}
myfree(sramx,p);//释放内部内存池内存
p=0; //指向空地址
sramx++;
p=mymalloc(sramx,2048);//外部内存池申请2K字节
if(p!=NULL)
{
tp=p;
sprintf((char*)paddr,"0X%08X",(u32)tp);
sprintf((char*)p,"Memory SRAMEX ADDR:");//向p写入一些内容
printf("%s",p);
printf("%s\r\n",paddr);
}
myfree(sramx,p);//释放外部内存池内存
p=0; //指向空地址
sramx++;
p=mymalloc(sramx,2048);//CCM内存池申请2K字节
if(p!=NULL)
{
tp=p;
sprintf((char*)paddr,"0X%08X",(u32)tp);
sprintf((char*)p,"Memory SRAMCCM ADDR:");//向p写入一些内容
printf("%s",p);
printf("%s\r\n",paddr);
}
myfree(sramx,p);//释放CCM内存池内存
p=0; //指向空地址
}
编译通过,能烧录成功,串口打印数据如下:
Memory SRAMIN ADDR:0X2001AE40
Memory SRAMEX ADDR:0X680EF800
Memory SRAMCCM ADDR:0X1000E800
通过串口,可以看出确实内存申请成功了,但是问题来了,注意!!!!
我发现我生成的.bin文件超级大,1.5G!!!! .hex文件也超级大,有3.12M。我的天啊!!!看到有个文章,说是修改.ld文件的第二处地方,那就是最后结束的地方>SRAM要加上AT> FLASH,如果不加上的话,bin文件将连续生成,由于我们外部sram的地址在0x68000000,因此,gcc将会把这部分当做flash的地址一部分,也就是说将会生成一个超大的bin文件!!如下:
.sram :
{
. = ALIGN(4);
_SRAM_SYMBOLS = .; /* create a global symbol at data start */
*(.sram) /* .data sections */
*(.sram*) /* .data* sections */
. = ALIGN(4);
_ESRAM_SYMBOLS = .; /* define a global symbol at data end */
} >SRAM AT> FLASH/*新增,第二处修改*/
我的妈耶,编译器编译不通过,提示如下:
\STM32CubuIDE\jaymie\STM32F407ZGTX_FLASH.ld:191: warning: memory region `FLASH/' not declared
\jaymie\STM32F407ZGTX_FLASH.ld:191: syntax error
请问有没有贴友们,用过STM32CUBEIDE软件编程,关于这个问题,怎么解决的?折磨了一天,很头疼。
|
最佳答案
查看完整内容[请看2#楼]
目标文件比较大,是因为目标文件里包含了所添加的段里的变量的初始化值(值为0)(并位于data段),而这些全局变量比较多,所以目标文件里有很多0值。
解决方法有两种:
1 在ld链接脚本内使用 NOLOAD 修饰声明的段,来告诉编译器不要初始化这个段,如:
2 使用自定义命令来生成目标文件,在命令内用-R选项排除指定的段的初始化值添加到data段内,如通过工程配置里的“Build Steps”添加自定义命令:
arm-none-eabi-objcopy ...
|