对齐方式定义头文件:bsp_compiler_support.h
#define BSP_SECTION_STACK ".stack" #define BSP_SECTION_HEAP ".heap" #define BSP_SECTION_VECTOR ".vectors" #define BSP_SECTION_ROM_REGISTERS ".rom_registers" #define BSP_PLACE_IN_SECTION(x) __attribute__ ((section(x))) __attribute__ ((__used__)) #define BSP_DONT_REMOVE #define BSP_ALIGN_VARIABLE(x) __attribute__ ((aligned (x))) #define BSP_PACKED __attribute__ ((aligned(1)))
系统默认为4字节自然地址对齐方式。
“符号”对齐配置:
typedef struct _SystemActive_ { TempStatus sTemp; LedStatus sLed; Cup sCup; bool bSetWaterCircle; BuzzerType eBuzzer; bool bPumpMotor; }SystemActive; typedef struct _SystemStatus_ { PoolStat ePool; uint32_t u32PoolTemp; uint32_t u32CompressTemp; CupSet aCup[CUP_MAX]; bool bIsCool; bool bIsCoolHeatChange; bool bIsAutoCup; bool bIsCleanMode; CupStatus eCup; bool bIsTestSelf; uint32_t u32Magic; }SystemStatus BSP_ALIGN_VARIABLE(16); SystemStatus g_sysSta; SystemActive g_sysAct;
地址空间如下:
g_netif_init_done/g_sysSta 地址空间相邻,g_netif_init_done 地址空间为“0x2003b994”,大小为“4”个字节,以此推,下一个符号g_sysSta 的地址应为 0x2003b994 + 4 = 0x2003b998
但g_sysSta 设置的对16字节齐方式“BSP_ALIGN_VARIABLE(16)”,如下g_sysSta地址为“0x2003b9a0” 16字节对齐
[kk@Debug]$readelf -s iotBaidu.elf | sort -k 2 > ss.c 11110: 2003b982 1 OBJECT GLOBAL DEFAULT 7 dev_stat 10319: 2003b984 16 OBJECT GLOBAL DEFAULT 7 g_active_interface 11121: 2003b994 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003b9a0 56 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003b9d8 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick
如果设置为“256”字节对齐,地址空间如下:
11110: 2003ba12 1 OBJECT GLOBAL DEFAULT 7 dev_stat 10319: 2003ba14 16 OBJECT GLOBAL DEFAULT 7 g_active_interface 11121: 2003ba24 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003bb00 56 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003bb38 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick
那么在两个符号之间,0x2003ba24->0x2003bb00造成了比较大的空间浪费(0x2003bb00 - 0x2003ba24 - 4 = 216字节浪费)。
__attribute__ ((aligned (x))) 位置比较关键:
书写在不同的位置,符号占用空间是不一样的。
[kk@Debug]$ readelf -s iotBaidu.elf | sort -k 2 typedef struct _SystemStatus_ { PoolStat ePool; uint32_t u32PoolTemp; uint32_t u32CompressTemp; CupSet aCup[CUP_MAX]; bool bIsCool; bool bIsCoolHeatChange; bool bIsAutoCup; bool bIsCleanMode; CupStatus eCup; bool bIsTestSelf; uint32_t u32Magic; }SystemStatus BSP_ALIGN_VARIABLE(256); //符号只是地址空间256字节对齐,符号的大小是没有变化的,即56字节 11121: 2003ba24 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003bb00 56 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003bb38 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick typedef struct _SystemStatus_ { PoolStat ePool; uint32_t u32PoolTemp; uint32_t u32CompressTemp; CupSet aCup[CUP_MAX]; bool bIsCool; bool bIsCoolHeatChange; bool bIsAutoCup; bool bIsCleanMode; CupStatus eCup; bool bIsTestSelf; uint32_t u32Magic; }BSP_ALIGN_VARIABLE(256) SystemStatus; //符号的地址空间对齐方式和占用大小均为256字节 11121: 2003ba24 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003bb00 256 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003bc00 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick
结构体内部的对齐方式:
1、使用#pragma pack(x) / #pragma pack()
2、使用 “__attribute__((packed))”对齐,相当于#pragma pack(1)
typedef struct _SystemStatus_ { PoolStat ePool; uint32_t u32PoolTemp; uint32_t u32CompressTemp; CupSet aCup[CUP_MAX]; bool bIsCool; bool bIsCoolHeatChange; bool bIsAutoCup; bool bIsCleanMode; CupStatus eCup; bool bIsTestSelf; uint32_t u32Magic; }__attribute__((packed)) SystemStatus; //注意位置,地址空间及占用大小 //注意:这种方式黄色区域还是自然4字节对齐,其它1字节对齐,所以最后占用51字节 11121: 2003b994 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003b998 51 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003b9cc 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick
#pragma pack(x)方式:
#pragma pack(1) ... ... ... typedef struct _SystemStatus_ { PoolStat ePool; uint32_t u32PoolTemp; uint32_t u32CompressTemp; CupSet aCup[CUP_MAX]; bool bIsCool; bool bIsCoolHeatChange; bool bIsAutoCup; bool bIsCleanMode; CupStatus eCup; bool bIsTestSelf; uint32_t u32Magic; }SystemStatus; ... ... ... #pragma pack() //这种方式,在#pragma pack(1) 到 #pragma pack()定义的类型都是1字节对齐,如下占用39字节 为最小占用 11121: 2003b994 4 OBJECT GLOBAL DEFAULT 7 g_netif_init_done 8584: 2003b998 39 OBJECT GLOBAL DEFAULT 7 g_sysSta 8729: 2003b9c0 4 OBJECT GLOBAL DEFAULT 7 g_pumpWaterStartTick