打印
[开发工具]

有人在Keil(MDK)中用过 __attribute__功能么?

[复制链接]
7729|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
thy_1994|  楼主 | 2017-6-7 22:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GUN C中可以使用 __attribute__() 给变量、函数、类型设置各种属性。
其中__attribute__((section("name")))可以将被修饰的东西定义到名为name的内存段内。
网上搜到过相关的博文,他们确实用keil实现了,但我按照他们的来却不行,想在这里问问有没有哪位在keil中成功地使用过这一功能,一起交流交流。
沙发
yklstudent| | 2017-6-7 22:38 | 只看该作者
const INT16U FlashOKData __attribute__ ((at(cOKAddress))) = 0x4F4B;                //将ok信息放入app flash的起始位置
像这样用就可以

使用特权

评论回复
板凳
z00| | 2017-6-8 08:58 | 只看该作者
可以看看KEIL的帮助文件 里面介绍的比较详细

使用特权

评论回复
地板
sonicll| | 2017-6-8 09:35 | 只看该作者
你找个外扩SRAM的例子代码,会有把变量定位到外部SRAM的用法,比如:
u32 testsram[250000] __attribute__((at(0X68000000)));//测试用数组

使用特权

评论回复
5
thy_1994|  楼主 | 2017-6-8 14:58 | 只看该作者
yklstudent 发表于 2017-6-7 22:38
const INT16U FlashOKData __attribute__ ((at(cOKAddress))) = 0x4F4B;                //将ok信息放入app flash的起始位 ...

理解的没错的话,你这是把变量存在具体地址吧,其实我需要的只是存到一个区域。

使用特权

评论回复
6
thy_1994|  楼主 | 2017-6-8 15:03 | 只看该作者
z00 发表于 2017-6-8 08:58
可以看看KEIL的帮助文件 里面介绍的比较详细

已经这个干过了,确实找到了可行方案。
现在我想知道“name”这个内存段的起始地址、结束地址或长度,在map文件中有,但我想赋给程序里的变量,不知道怎么操作,也没找到相关信息,你有什么建议吗?

使用特权

评论回复
7
thy_1994|  楼主 | 2017-6-8 15:04 | 只看该作者
sonicll 发表于 2017-6-8 09:35
你找个外扩SRAM的例子代码,会有把变量定位到外部SRAM的用法,比如:
u32 testsram[250000] __attribute__( ...

还没到扩展内存的地步,只是想将一些特定变量放在一起,单片机本身存储空间是够的。

使用特权

评论回复
8
guojin0273| | 2017-6-8 17:00 | 只看该作者
thy_1994 发表于 2017-6-8 15:03
已经这个干过了,确实找到了可行方案。
现在我想知道“name”这个内存段的起始地址、结束地址或长度,在m ...

这样理解可行?

u8 name[10] __attribute__((at(0x20000000)));

u32         RamLen = sizeof(name);

u32         BassAddr = (u32)&name;

u32        EndAddr = BassAddr + RamLen ;


使用特权

评论回复
9
jack821119| | 2017-6-8 17:52 | 只看该作者
|Image$$RO$$Limit|
RO用本身定义的section的名称来替代.

LDR R0,=|Image$$RO$$Limit|
R0里面就是section的大小.

如果你想C语言调用的话,那要通过汇编函数返回了。

使用特权

评论回复
10
thy_1994|  楼主 | 2017-6-8 23:26 | 只看该作者
jack821119 发表于 2017-6-8 17:52
|Image$$RO$$Limit|
RO用本身定义的section的名称来替代.

对!我需要的就是这样!我看到的就是这样的语句:**$$**$$**,也在搜相关资料,无奈收获不大,能否提供点链接、资料我学习学习,给个方向也行。

使用特权

评论回复
11
thy_1994|  楼主 | 2017-6-8 23:31 | 只看该作者
guojin0273 发表于 2017-6-8 17:00
这样理解可行?

u8 name[10] __attribute__((at(0x20000000)));

这么干确实可行,简单实用,但略微有点繁琐,对于自定义的内存块是可以直接得到起始地址和长度的,我不会,但这个论坛里有人会

使用特权

评论回复
12
LyCrystal| | 2017-6-9 09:00 | 只看该作者
__attribute__((section("name")))这个使用正常,而且数据有交叉的时候编译器还会提出警告

使用特权

评论回复
13
jack821119| | 2017-6-9 09:46 | 只看该作者
Image$$region_name$$Length  表示自定义区域的大小
Image$$region_name$$Base 表示自定义区域的起始地址
Image$$region_name$$Limit表示自定义区域的结束地址

使用特权

评论回复
14
jack821119| | 2017-6-9 09:54 | 只看该作者
extern unsigned int Image$$RW_IRAM1$$Length;
extern char Image$$RW_IRAM1$$Base[];
memset(Image$$RW_IRAM1$$Base,0,(unsigned int)Image$$RW_IRAM1$$Length);
这个是C语言的用法,在keil 上编译通过的

使用特权

评论回复
15
thy_1994|  楼主 | 2017-6-9 14:00 | 只看该作者
jack821119 发表于 2017-6-9 09:54
extern unsigned int Image$$RW_IRAM1$$Length;
extern char Image$$RW_IRAM1$$Base[];
memset(Image$$RW_I ...

多谢多谢!的确可行!
还有个问题,前两天就发现了:定义了段名称并向其中存全局变量,如果这些变量名我在其它地方用到,那map文件中就能看到这个内存段。问题来了,定义了变量后,是直接用地址对内存进行操作的,代码中并没有用到变量名,所以编译提示:Warning: L6329W:Pattern *(SECTION) only matches removed unused sections.在map中可以看到这个内存段大小是0。定义变量的时候我已经用__attribute__((unused,section("SECTION")))修饰了,优化等级也是最低,变量还是被忽略了,请问这怎么解决?

使用特权

评论回复
16
jack821119| | 2017-6-9 14:42 | 只看该作者
只要你分配了段的区域大小,那么在map文件中应该是可以看到,不管你有没有将变量存到此区域里面.
你将变量分配到此区域的话,IDE 是不会把你变量忽略的,除非你分配的方式有问题.

使用特权

评论回复
17
jack821119| | 2017-6-9 17:14 | 只看该作者
补充一下:
extern unsigned int Image$$RW_IRAM1$$Length;
extern char Image$$RW_IRAM1$$Base[];
memset(Image$$RW_IRAM1$$Base,0,(unsigned int)Image$$RW_IRAM1$$Length);
这个有点问题,应该是下面的才对
extern unsigned int Image$$RW_IRAM1$$Length;
extern char Image$$RW_IRAM1$$Base[];
memset(Image$$RW_IRAM1$$Base,0,(unsigned int)&Image$$RW_IRAM1$$Length);

使用特权

评论回复
18
thy_1994|  楼主 | 2017-6-9 21:08 | 只看该作者
jack821119 发表于 2017-6-9 17:14
补充一下:
extern unsigned int Image$$RW_IRAM1$$Length;
extern char Image$$RW_IRAM1$$Base[];

确实是定义的时候出了问题,修饰里不应该用unused,而应该是used,还是功课做的不够,换成__attribute__((used, section("SECTION"))),整个世界都美好了。

多谢多谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

31

帖子

1

粉丝