Bas*_*ijk 25 c variables gcc arm keil
RealView ARM C编译器支持使用变量属性将变量放在给定的内存地址at(address):
int var __attribute__((at(0x40001000)));
var = 4; // changes the memory located at 0x40001000
Run Code Online (Sandbox Code Playgroud)
GCC是否具有类似的变量属性?
Pro*_*ica 22
我不知道,但你可以轻松地创建一个这样的解决方法:
int *var = (int*)0x40001000;
*var = 4;
Run Code Online (Sandbox Code Playgroud)
它不是完全相同的东西,但在大多数情况下是一个完美的替代品.它适用于任何编译器,而不仅仅是GCC.
如果您使用GCC,我假设您也使用GNU ld(当然,这不是确定的)并且ld支持将变量放在任何您想要的位置.
我想让联系人做这项工作很常见.
受@rib的回答启发,我将补充一点,如果绝对地址是针对某些控制寄存器的,我会添加volatile到指针定义中.如果它只是RAM,那没关系.
小智 9
这是一种实际上在内存中的固定地址保留空间而无需编辑链接器文件的解决方案:
extern const uint8_t dev_serial[12];
asm(".equ dev_serial, 0x1FFFF7E8");
/* or asm("dev_serial = 0x1FFFF7E8"); */
...
for (i = 0 ; i < sizeof(dev_serial); i++)
printf((char *)"%02x ", dev_serial[i]);
Run Code Online (Sandbox Code Playgroud)
小智 7
您已回答了问题,在上面的链接中指出:
使用GNU GCC编译器,您可以仅使用指针定义来访问绝对内存位置.例如:
#define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
IOPIN0 = 0x4;
Run Code Online (Sandbox Code Playgroud)
顺便说一句http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Variable-Attributes.html#Variable%20Attributes
最小的可运行链接描述文件示例
在以下网址中提到了该技术:https://stackoverflow.com/a/4081574/895245,但现在我将提供一个具体示例。
main.c
#include <stdio.h>
int myvar __attribute__((section(".mySection"))) = 0x9ABCDEF0;
int main(void) {
printf("adr %p\n", (void*)&myvar);
printf("val 0x%x\n", myvar);
myvar = 0;
printf("val 0x%x\n", myvar);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
链接
SECTIONS
{
.mySegment 0x12345678 : {KEEP(*(.mySection))}
}
Run Code Online (Sandbox Code Playgroud)
编译并运行:
SECTIONS
{
.mySegment 0x12345678 : {KEEP(*(.mySection))}
}
Run Code Online (Sandbox Code Playgroud)
输出:
adr 0x12345678
val 0x9abcdef0
val 0x0
Run Code Online (Sandbox Code Playgroud)
因此,我们看到它已放置在所需的地址。
我在GCC手册中找不到该文档的记录位置,但语法如下:
gcc link.ld main.c
Run Code Online (Sandbox Code Playgroud)
似乎将给定的链接脚本附加到将要使用的默认脚本中。
-fno-pie -no-pie是必需的,因为Ubuntu工具链现在已配置为默认情况下生成PIE可执行文件,这导致Linux内核每次都将可执行文件放在不同的地址上,这与我们的实验相混淆。另请参见:gcc和ld中与位置无关的可执行文件的-fPIE选项是什么?
TODO:编译产生警告:
/usr/bin/x86_64-linux-gnu-ld: warning: link.ld contains output sections; did you forget -T?
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?如何摆脱它?另请参见:如何消除警告:link.res包含输出部分;你忘了-T吗?
在Ubuntu 18.10,GCC 8.2.0上进行了测试。
| 归档时间: |
|
| 查看次数: |
50005 次 |
| 最近记录: |