[英]Is it possible to access hardware register through inline assembly
我正在尝试通过内联汇编访问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编译器资源管理器上看到的那样 ,编译器将发出asm指令来计算ELF元数据,其行如下:
.size main, .-main # size_of_main = current_pos - start_of_main
既然你切换的体内部分main
之间的距离, main
与年底main
是不知道,直到链接时,这是不可能得到的链接在这片元数据,以填补这一晚。 ( .size
必须是一个汇编时间常数,而不仅仅是一个链接时间常数)。
就像人们评论过的那样,您应该使用C做整个事情,例如使用全局
#include <stdint.h>
volatile uint32_t *const GPIO17 = (uint32_t*)0x3F200000; // address is const, contents aren't.
大概您需要请求操作系统访问该MMIO寄存器。 操作系统的一部分工作是阻止程序直接与硬件通讯,并弄乱同时执行相同操作的其他程序。
即使您的代码已汇编,它也不会链接,因为您对_start
的定义将与libc运行时代码提供的定义冲突。
不要试图在另一个函数内的内联汇编中定义一个函数。 如果要编写一个独立的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.