gpt4 book ai didi

c - 是否可以通过内联汇编访问硬件寄存器

转载 作者:太空宇宙 更新时间:2023-11-04 01:22:54 25 4
gpt4 key购买 nike

我正在尝试通过内联汇编访问 Broadcom ARM 处理器上的硬件寄存器。我已经通过裸机编程访问了硬件寄存器,但现在我正在尝试使用 asm 将这些裸机编程代码合并到 C 文件中。这是我在 Raspberry Pi 2 上切换 GPIO 17 的代码:

void main() {

__asm__(

".section .init\n\t"

".globl _start\n\t"
"_start:"
"ldr r0,=0x3F200000\n\t"
"mov r1, #1\n\t"
"lsl r1, #21\n\t"
"str r1, [r0, #4]\n\t"
"loop$:\n\t"

"mov r1, #1\n\t"
"lsl r1, #17\n\t"
"str r1, [r0, #28]\n\t"



"mov r1, #1\n\t"
"lsl r1, #17\n\t"
"str r1, [r0, #40]\n\t"

"b loop$\n\t"

);
}

但是当我用gcc file.c编译的时候

它抛出以下错误

/tmp/ccrfp9mv.s: Assembler messages:
/tmp/ccrfp9mv.s: Error: .size expression for main does not evaluate to a constant

最佳答案

您得到 Error: .size expression for main does not evaluate to a constant 因为您更改了函数内部的部分。正如您在 godbolt compiler explorer 上看到的那样,编译器将发出 asm 指令来计算 ELF 元数据,其中的行如下:

.size   main,   .-main       # size_of_main  =  current_pos - start_of_main

由于您在 main 主体内切换部分,mainmain 结尾之间的距离直到链接时才知道,并且不可能让链接器这么晚填写这条元数据。 (.size 必须是汇编时常量,而不仅仅是链接时常量)。


就像人们评论的那样,你应该用 C 来完成整个事情,例如与全局喜欢

#include <stdint.h>
volatile uint32_t *const GPIO17 = (uint32_t*)0x3F200000; // address is const, contents aren't.

大概您需要请求操作系统访问该 MMIO 寄存器。操作系统的部分工作是阻止程序直接与硬件对话并扰乱同时做同样事情的其他程序。


即使您的代码已组装,它也不会链接,因为您对 _start 的定义将与 libc 运行时代码提供的定义发生冲突。

不要试图在另一个函数中定义内联汇编中的函数。如果您想这样做,请编写一个独立的函数。

关于c - 是否可以通过内联汇编访问硬件寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37254761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com