|
简介__attribute__ 是gcc编译器支持的一个编译特性(arm编译器也支持此特性,比如我们常用的keil就是用的ARMGCC编译器),也就是通过给函数或者变量声明属性值,以便让编译器能够对要编译的程序进行优化处理。
更多详细内容,请看这篇官网文档:《Unixwiz.net - Software Consulting Central -- Using GNU C __attribute__》:http://www.unixwiz.net/techtips/gnu-c-attributes.html而对于 section 这个关键字,我们可以通过它将指定的变量定义到指定的输入段中。keil中对于此用法的描述是:ARM Compiler v5.06 for uVision armcc User Guide
section 属性指定变量必须放置在特定数据部分中,通常,ARM 编译器将其生成的对象放在 .data 和 .bss 等部分中。但是,您可能需要其他数据部分,或者您可能希望变量出现在特殊部分中,例如,映射到特殊硬件。
如果使用 section 属性,则只读变量将放置在 RO 数据部分中,读写变量将放置在 RW 数据部分中,除非您使用 zero_init 属性。在这种情况下,变量放置在 ZI 部分中。
/* in RO section */
const int descriptor[3] __attribute__((section ("descr"))) = { 1,2,3 };
/* in RW section */
long long rw_initialized[10] __attribute__((section ("INITIALIZED_RW"))) = {5};
/* in RW section */
long long rw[10] __attribute__((section ("RW")));
/* in ZI section */
long long altstack[10] __attribute__((section ("STACK"), zero_init));
用法详解先来看一段代码(摘自CSDN,如有侵权,联系删除):
#include
#define SEC __attribute__((__section__("ss"), aligned(sizeof(void *))))
void func_1(int a, int b)
{
printf("%s %d %d
", __func__, __LINE__, a + b);
}
void func_2(int a, int b)
{
printf("%s %d %d
", __func__, __LINE__, a * b);
}
// 编译器会自动提供__start_ss,__stop_ss标志段ss的起止地址
extern size_t __start_ss;
extern size_t __stop_ss;
typedef struct
{
void (*p)(int, int);
} node_t;
// 结构体变量a位于自定义段ss
SEC node_t a = {
.p = func_1,
};
SEC node_t b = {
.p = func_2,
};
int main(int argc, char **argv)
{
int a = 3, b = 4;
node_t *p;
// 遍历段ss,执行node_t结构中的p指向的函数
for (p = (node_t *)&__start_ss; p p(a, b);
a += 1;
b += 2;
}
}
来看一下运行的结果: |
|