【问题标题】:Embedded Rust- How to prevent generation of 'extra' code for ISREmbedded Rust-如何防止为 ISR 生成“额外”代码
【发布时间】:2021-10-29 12:54:42
【问题描述】:

我正在尝试编写简单的 RTOS,但我正在为编译器生成的额外 asm 代码而苦苦挣扎。代码针对我使用 cortex-m 和 cortex-m-rt crates 的 cortex-m4 cpu。 我可以使用 #[no_mangle] 属性删除蹦床,但我不知道如何删除/防止生成 push {r7, lr}pop {r7, pc} 指令。

这是我的 PendSV 代码:

#[allow(non_snake_case)]
#[no_mangle]
pub fn PendSV() {
    unsafe{
        asm!("nop")
    }
}

这里是生成的代码:

push    {r7, lr}
mov     r7, sp
nop                                                                                                                                      
pop     {r7, pc}

我正在寻找某种属性或编译器选项,这样我就可以将 nop 作为 PendSV 函数的一部分生成。有可能吗?

【问题讨论】:

标签: rust embedded


【解决方案1】:

您需要将PendSV 设为naked function。 “裸”表示该函数不生成前奏,不生成返回码。

所以,天真地,像这样:

#![feature(asm)]
#![feature(naked_functions)]

#[allow(non_snake_case)]
#[no_mangle]
#[naked]
pub fn PendSV() {
    unsafe {
        asm!("nop")
    }
}

使用以下代码,您会收到两个警告:

警告:Rust ABI 在裸函数中不受支持

警告:裸函数中的 asm 必须使用 noreturn 选项

要进行补救,请使用 C ABI 和 noreturn 选项:

#[allow(non_snake_case)]
#[no_mangle]
#[naked]
pub extern "C" fn PendSV() {
    unsafe {
        asm!(
            "nop",
            options(noreturn)
        )
    }
}

在 x86 下,编译为(通过Compiler Explorer):

PendSV:
        nop
        ud2

ud2 可能仍然不是您想要的。之所以生成它是因为到目前为止,您已经指示该函数不会返回,但是,在执行单个 nop 之后,执行流程将到达函数的末尾(它返回的地方,如果不是因为您使用的是裸函数...)

因此,您有责任决定在PendSV 之后执行什么。您可能想要无限循环、跳转或“从中断返回”指令(iret 用 x86 术语说,我对 ARM 不太熟悉)。

【讨论】:

  • 我是无返回的,因为作为一个裸函数,编译器不知道如何返回。因此,您将负责使用正确的调用约定和 arm 上的 bl 指令返回自己
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
相关资源
最近更新 更多