繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM