字节对齐:
//KEIL编译器
__align(num) 这个用于修改最高级别对象的字节边界
eg: __align(64) u8 mem1base[MEM1_MAX_SIZE];
//IAR GCC 编译器
#pragma pack(num) 指定下面变量按num字节对齐 作用域为下面所有变量,如果要恢复需要使用#pragma pack()
#pragma pack() 能够取消自定义的对齐方式,恢复默认对齐
//eg push pop声明作用域
#pragma pack(push)
#pragma pack(4)struct。。。//需要字节对齐的变量或结构体
#pragma pack(pop)
#pragma pack(4)
u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0X68000000)));
#pragma pack()
#pragma pack(push)
#pragma pack(32)
//#pragma location=0x20230000
u8 mem1base[MEM1_MAX_SIZE] ; //内部SRAM内存池
#pragma location=0x80800000
u8 mem2base[MEM2_MAX_SIZE] ;//__attribute__((at(0x80800000))); //外部SDRAM内存池,前面8M给LTDC用了(1280*800*2)
#pragma pack(pop)
MDK与IAR的绝对定位
1.直接通过链接文件地址,需要定义section段和修改链接文件//如rt1052工程
#if defined(__CC_ARM) || defined(__GNUC__) //GCC 与 MDK
__attribute__((section(".boot_hdr.conf")))
#elif defined(__ICCARM__) //IAR
#pragma location=".boot_hdr.conf"
#endif
2.通过关键字定义
IAR编译器:#pragma location= //@应该也可以
#pragma pack(push)
#pragma pack(32)
//#pragma location=0x20230000
u8 mem1base[MEM1_MAX_SIZE] ; //内部SRAM内存池
#pragma location=0x80800000
u8 mem2base[MEM2_MAX_SIZE] ;//__attribute__((at(0x80800000))); //外部SDRAM内存池,前面8M给LTDC用了(1280*800*2)
#pragma pack(pop)
MDK编译器:attribute((at(0X20000000)))
__align(64) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0X20000000))); //原子 malloc函数
总结示例如下:
#if defined ( __CC_ARM ) // MDK
const uint8_t Test_flash[] __attribute__((at(0x08030000))) = "Test Flash";
const uint32_t Test_Addr __attribute__((at(0x08030010))) = 0x12345678;
#elif defined ( __ICCARM__ ) // IAR
const uint8_t Test_flash[] @ 0x08030000 = "Test Flash";
const uint32_t Test_Addr @ 0x08030010 = 0x12345678;
#else
const uint8_t Test_flash[] = "Test Flash";
const uint32_t Test_Addr = 0x12345678;
#endif
MDK常量定位到rom会有以下为题:
我用的STM32F107VC,有256K的flash,而现在的测试程序10K左右。
IAR会很干脆的将我要定位的数据放到指定的位置,中间空白的地方保持0xFF;
而MDK则不干脆,在0x08030000附近,还有程序的其它const数据放进去了。
这还不是最重要的,最重要的是主程序和0x08030000之间的数据都清成ix00了。
这会导致两个问题,第一个问题是:我编译完毕后看到的信息,flash是很大很大的(本质是包括了那些0x00);
第二个问题是,我下载程序需要的时间长很多。