.c文件如何转换成.bin文件
链接:C代码编译过程 - yangrourou - 博客园 (cnblogs.com)
链接:C语言__attribute__的使用 - 雪球球 - 博客园 (cnblogs.com)
.c 预处理 .i 编译 .s 汇编 .o(可重定位目标程序) 链接 .bin
__attribute__可以设置函数属性(function attribute)、变量属性(variable attribute)和类型属性(type attribute)。
__attribute__语法格式为:__attribute__((attribute-list))
关键字__attribute__也可以对结构体(struct)或共用体(union)进行属性设置。大致有六个参数可以被设定,即:aligned,packed,transparent_union,unused,deprecated和may_alias。
参数介绍
aligned指定对象的对齐格式(以字节为单位)
注意:attribute属性的效力与连接器有关,如果连接器最大只支持16字节对齐,那么此时定义32字节对齐也无济于事。
packed使用该属性对struct或者union类型进行定义。设定其类型的每一个变量的内存约束。就是告诉编译器取消结构在编译过程中的优化对齐(使用1字节对齐),按照实际占用字节数对齐。
at绝对定位,可以把变量或函数绝对定位到Flash中,或者定位到RAM。
定位到flash中,一般用于固化的信息,如出厂设置的参数,上位机配置的参数,ID卡的ID号,flash标记等。
定位到RAM中,一般用于数据量比较大的缓存,如串口的接收缓存,再就是某个位置的特定变量。
const u16 gflashdata __attribute__((at(0x0800F00)))=0XFFFF;//在Flash地址的0x0800F00处定义变量gflashdata,变量的值为0XFFFF;
u8 USART2_RX_BUF[USART2_REC_LEN] __attribute__ ((at(0x20001000)));//接收缓存,最大USART2_REC_LEN字节,起始地址0x20001000;
注:绝对定位不能在函数中定义,局部变量是定义在栈区的,栈区由MDK自动分配、释放,不能定义为绝对地址,只能放在函数外定义。
定义的长度不能超过栈或者Flash的大小,否则,造成栈、Flash溢出。
section
在ARM编译器编译之后,代码被划分为不同的段:RO section(read only)中存放代码段和常量,RW section(read and write)中存放可读可写的静态变量和全局变量,ZI section(zero init)中存放在RW段中值为0的变量
Image文件包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间
链接:Keil编译产生的RO,RW和ZI是什么_【ql君】qlexcel的博客-CSDN博客
__attribute__(section("section_name"))的作用是将函数或者数据放在指定名为section_name对应的段中
const int VER_and_PRODUCT __attribute__((section(".ARM.__at_0x08014000"))) = ((BIGVER<<24) | (MIDVER<<16) | (TEMPVER<<8) | PRODUCT_INDEX);
组合使用 u8 FileAddr[100] __attribute__((section("FILE_RAM"), zero_init,aligned(4));