如何为Rust中的ARM芯片的堆栈指针赋值?

时间:2018-02-23 22:16:18

标签: rust embedded

我正在尝试为Rust中的STM32编写一个bootloader,我无法弄清楚如何正确填充堆栈指针。我可以告诉代码应该是:

asm!("MOV SP, $0" :: "0"(stack_pointer));  // set the stack pointer

但是编译器不同意:

error: invalid operand in inline asm: 'MOV SP, $0'
  --> src/main.rs:38:5
   |
38 |     asm!("MOV SP, $0" :: "0"(stack_pointer));  // set the stack pointer
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: <inline asm>:1:11: error: unexpected token in operand
        MOV SP, 
                ^

  --> src/main.rs:38:5
   |
38 |     asm!("MOV SP, $0" :: "0"(stack_pointer));  // set the stack pointer
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我做错了什么?它似乎在抱怨美元符号,但我是直接从the documentation得到的。

根据评论中的对话,我尝试了两件事,两者都编译(!),但两者似乎都没有用(但这可能是十亿个理由中的任何一个,仍然在努力): / p>

版本A:

asm!("MOV R0, #0x0800");
asm!("LSL R0, R0, #16");
asm!("MOV R1, #0x8000");
asm!("ORR R2, R1, R0");
asm!("LDRT R0, [R2]");
asm!("MOV SP, R0");
entry_point()

版本B:

#[inline(never)]
unsafe fn go(_addr: u32, entry_point: fn()->()) {
    asm!("MOV SP, R0");
    entry_point()
}

1 个答案:

答案 0 :(得分:0)

我最终选择了@ stefan实现@clifford的方法以及以下代码来调用它:

let firmware_address = 0x08008000u32;
unsafe {
    let scb = &*stm32f40x::SCB::ptr();
    scb.vtor.write(firmware_address);
    asm::isb();
    go(&*(firmware_address as *const VectorTable));
}