zl程序教程

您现在的位置是:首页 >  其他

当前栏目

rt-thread中MSH_CMD_EXPORT()函数的实现原理-const char __fsym_##cmd##_name[] RT_SECTION(“.rodata.name“) = #cmd

2023-03-20 14:54:24 时间

const char _fsym##cmd##_name[] RT_SECTION(".rodata.name") = #cmd
学习一下这行代码
对这行代码里面的 __fsym 双#,RT_SECTION这些都不理解

#define RT_SECTION(x) attribute((section(x)))
这行代码的__attribute__((section(x)))又是什么意思???

学习结论:
把__fsym_##cmd##_name[]这个变量放置到名为".rodata.name"的段中

attribute((section(x))) 使用详解----精品

那么问题来了,使用section将变量放到我们自定义的输入段中有什么意义呢?

言归正传,现在继续来讲如何使用section将不同的函数放到我们想要的输入段中,并且获得他们的起始地址和结束地址。

我们可以在每个XXX_Init函数后面都调用宏CMD_EXPORT,在调用这个宏时编译器会将XXX_init这个函数加入到输入段中,由于变量在输入段中的地址是连续的,并且顺序先按 section 名 01234排一遍,section 内再按函数名称排。所以可以按照输入段中顺序来逐个调用这些初始化函数来完成系统的初始化。

大佬出品,必属精品

单井号和双井号(##)的意义

二、#运算符的用法
(1)#运算符用在预编译时期,用于将宏参数转换为字符串,即是加上双引号。
三、##运算符的使用
(1)##运算符用于在预编译期粘连两个符号,增大了宏的使用灵活性!

看这里
看上面的代码,啥也不想说了。已经很明显了,我们已经看到了 ## 运算符的强大之处。如果我们的 # 和 ## 运算符运用的好的话,那么代码质量就会非常高。通过对 # 和 ## 运算符的学习,总结如下:1、# 运算符用于在预处理期将宏参数转换为字符串;2、## 运算符用于在预处理期粘连两个标识符;3、编译器不知道 # 和 ## 运算符的存在,# 和 ## 运算符只在宏定义中有效。

attribute((section(”name“)))是gcc编译器支持的一个编译特性(arm编译器也支持此特性),实现在编译时把某个函数/数据放到name的数据段中。
__attribute__主要用于改变所声明或定义的函数或 数据的特性,它有很多子项,用于改变作用对象的特性。比如对函数,noline将禁止进行内联扩展、noreturn表示没有返回值、pure表明函数除 返回值外,不会通过其它(如全局变量、指针)对函数外部产生任何影响。当然,__attribute__肯定有很多的用法,今天就用到了section部分,所以就只针对这个做一些记录。

提到section,就得说RO RI ZI了,在ARM编译器编译之后,代码被划分为不同的段,RO Section(ReadOnly) RW Section(ReadWrite)ZI Section。

于是本文的大体意思就清晰了,attribute((section(“section_name”))),其作用是将作用的函数或数据放入指定名为"section_name"对应的段中。

https://blog.csdn.net/liming0931/article/details/99706615?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164465205416780274161156%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164465205416780274161156&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-9-99706615.pc_search_result_cache&utm_term=%23%23&spm=1018.2226.3001.4187

https://blog.csdn.net/weixin_33967071/article/details/92715657?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164465205416780274161156%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164465205416780274161156&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-5-92715657.pc_search_result_cache&utm_term=%23%23&spm=1018.2226.3001.4187

gcc attribute((section(“section_name”))) 使用方法

gcc的__attribute__编译属性有很多子项,用于改变作用对象的特性。这里讨论section子项的作用。

__attribute__的section子项使用方式为:

__attribute__((section("section_name")))

其作用是将作用的函数或数据放入指定名为"section_name"的段。

原文链接:https://blog.csdn.net/nyist327/article/details/59481809

https://blog.csdn.net/swj9099/article/details/96713277?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164465336416780271938417%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164465336416780271938417&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-96713277.pc_search_result_cache&utm_term=attribute&spm=1018.2226.3001.4187