电子产业一站式赋能平台

PCB联盟网

搜索
查看: 36|回复: 0
收起左侧

鲜为人知的__attribute__((__section__(section_name))),你知道怎么用吗?

[复制链接]

210

主题

210

帖子

1680

积分

三级会员

Rank: 3Rank: 3

积分
1680
发表于 2023-4-15 17:01:00 | 显示全部楼层 |阅读模式
简介__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;
    }
}
来看一下运行的结果:
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表