为什么要武装
我得到了一些带有uC STM32F405RG
,这款微型ARM Cortext M4 core
具有ARM Cortext M4 core
。 请参考uC:
http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144#
我也从下面的站点使用arm-none-eabi
工具链for linux:
https://launchpad.net/gcc-arm-embedded
编译和链接一些项目后,我注意到链接器在存储在.bss部分的全局变量之间放置了额外的填充字节。 请从地图文件中找到简短的片段:
.bss.variable1
0x20002d14 0x15 /path/to/application.o
.bss.variable2
0x20002d29 0x1 /path/to/application.o
.bss.variable3
0x20002d2a 0x1 /path/to/application.o
.bss.variable4
0x20002d2b 0x1 /path/to/application.o
.bss.variable5
0x20002d2c 0x1c /path/to/application.o
.bss.variable6
0x20002d48 0x1 /path/to/application.o
*fill* 0x20002d49 0x3
.bss.variable7
0x20002d4c 0x4 /path/to/application.o
.bss.variable8
0x20002d50 0x8 /path/to/application.o
.bss.variable9
0x20002d58 0x1c /path/to/application.o
.bss.variable10
0x20002d74 0x1 /path/to/application.o
另外这里是我的链接器脚本:
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000 + 256K, LENGTH = 1M - 256K -(3*128K)
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
_stack_size = 16K;
_estack = ORIGIN(RAM) + LENGTH(RAM);
_sstack = _estack - _stack_size;
SECTIONS
{
.text :
{
_stext = .;
KEEP(*(.isr_vector))
. += 8;
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
.ARM.extab :
{
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
} >FLASH
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
_sidata = .;
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
. = ALIGN(4);
.bss :
{
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
.stack :
{
. += _stack_size;
} >RAM
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
这里是类型声明,它们分布在几个头文件中,但是我立刻把它们放在这里:
typedef enum
{
False=0,
True=1
} bool;
typedef enum
{
Unknown,
Data,
Crc
} type3_t;
typedef struct
{
unsigned char data[20];
unsigned char size;
} __attribute__((packed)) type1_t;
typedef enum
{
msg1,
msg2,
msg3
} msg_type_t
typedef struct
{
uint8_t msg;
uint32_t src;
uint32_t dest;
} header_t;
typedef struct
{
header_t header;
uint8_t len;
uint8_t id;
uint8_t idx;
uint8_t type;
} header2_t;
typedef struct
{
header2_t header;
uint8_t* data;
} ex_header_t;
typedef struct
{
msg_type_t type;
union
{
uint8_t * rawData;
header_t header;
ex_header_t ex_header;
} u;
uint8_t val;
} type5_t;
typedef struct
{
uint32_t id;
uint8_t idx;
uint8_t crc[2];
} type8_t;
和application.c文件,我留下了* .c文件中的命令:
static type5_t variable5;
static type5_t variable9;
static type8_t variable8;
static type3_t variable3 = Unknown;
static type1_t variable1;
static bool variable10 = False;
static unsigned char variable6 = 0;
static bool variable4;
static unsigned char variable2 = 0;
/* few function definitions here */
static void * variable7;
问题是为什么arm-none-eabi-ld连接器是这样做的? 为什么链接器不能填充填充字节,一个字节大的变量(如字符)? 一切都发生在同一个翻译单元中,所以我认为链接器应该能够对它们进行排序并利用更多的RAM内存。 即使在同一翻译单元中不存在一个字节(char)或两个字节的变量(短),为什么连接器不应该将它们从其他* .o文件中取出?
链接地址: http://www.djcxy.com/p/70399.html上一篇: Why arm