attribute
在阅读程序源码时,有时看到类似于下面的写法:
static uint8_t prucarray[256] __attribute__((aligned(8)));
即,在某个标识符完成定义后,使用__attribute__(xxx)可以用来设置函数属性、变量属性和类型属性。
__attribute__的用法是在attribute前后都有两个下划线且后面紧跟一对括号,括号中包含对应的参数:
__attribute__(parameter-list);
关键字__attribute__可以对函数、变量、类型(包括结构体struct和共用体union)进行属性设置,在使用__attribute__参数时,可以在参数前后也加上双下划线__,效果是在相应头文件里使用它而不用担心是否存在重名宏定义。
常见的attribute参数介绍
aligned
aligned指定对象的对齐格式(字节单位),如下面的例子:
struct s {
short usarray[3];
int ulparameter;
}__attribute__(aligned(8));
typedef int int32_t __attribute__((aligned(8)));
该声明将强制编译器确保变量类型struct s或int32_t 的变量在分配空间时采用8字节对齐方式。
接下来继续通过举例子来讲解__attribute__的作用:
struct str_p{
int ula; //4字节
char cb; //1字节
short usc; //2字节
}__attribute__((aligned(4))); //按4字节对齐,4+1+1+2 = 6;6除以4不能整除,故按4字节对齐方式结果为8;
struct x
{
int ula; // 4字节
char cb; // 1字节
struct p prx; // 8字节
short usc; // 2字节
}__attribute__((aligned(8))) xx; // 按8对齐,4+(1+3)+8+2 = 18; 18除以8不能整除,按8字节对齐方式,故分配24字节内存大小。
关于字节对齐参考字节对齐
packed
使用该属性对struct 和union类型进行定义,设定其类型的每一个变量的内存约束。要求编译器取消**结构在编译过程中的优化对齐(按1字节对齐)**是GCC特有的语法,只跟编译器有关。
struct unpacked_str{
char ca;
int ula;
};
struct packed_str{
char ca;
int uli;
};__attribute__((__packed__));
在上面的例子中,packed_str类型的变量中的成员会紧紧挨在一起,但需要注意器内部unpacked_str类型变量成员会按照默认的对齐方式进行分配内存。
at
at表示绝对定位,可以把变量或函数绝对定位到flash中,或定位到RAM。
定位flash
当定位到flash中,一般用于固化信息,如出厂参数,上位机配置参数,ID卡卡号、flash标记等。
const uint16_t usflash_def_value_g[512] __attribute__((at(0x0800F000))) = {0x1111,0x1111,0x1111,0x0111,0x0111,0x0111};//定位在flash中,其他flash补充为00
const uint16_t usflash_data_g __attribute__((at(0x0800F000))) = 0xffff;
定位RAM
定位到RAM中,一般用于数据量比较大的缓存,如串口缓存,在就是某个位置的特定变量。
uint8_t ucusart_rx_buffer[usart_rev_len] __attribute__((at(0X20001000)));
绝对定位不能在函数中定义,局部变量定义在栈区,有MDK自动分配释放,不能定义为绝对地址,只能定义在函数外;定义长度不能造成堆栈或flash溢出。
section
section的作用是将函数放入指定段中。
void vfunciton_attribute_section __attribute__((section("new_section")));
void vfunciton_attribute_section(void)
{
static int aStatic =0;
aStatic++;
}
将函数vfunciton_attribute_section放入指定的new_section段中。