我在Ada中编写嵌入式代码。我想跳转到位于地址0x0E00的引导加载程序代码。我正在尝试使用以下代码:
with Interfaces; use Interfaces;
with System;
package AVR.bootloader is
procedure Call;
pragma No_Return(Call);
pragma Import (Assembler,Call);
for Call'Address use System'To_Address (16#0E00#);
end AVR.bootloader;
问题是这不起作用。
编辑:我想做一个以下C等价物:
void (*boot)(void)=0x0E00;
答案 0 :(得分:2)
由于启动加载器通常在复位时运行,因此最简单的方法是强制重置处理器。引导加载程序可以合理地假设它在处于复位状态的未初始化系统上运行,并且可能执行在已初始化的系统上无效的初始化,因此强制重置是最安全的方法。
您的处理器可能有重置指令或可以直接执行此操作的重置控制器。如果没有它可能有一个可以产生复位的看门狗定时器。以适当的短暂超时启动看门狗定时器,让它在没有维修的情况下运行。
答案 1 :(得分:2)
我在这款Macbook Pro上做了一个小实验,你的代码似乎按照你的意思去做;我将代码修改为
with System;
procedure Bootloader is
procedure Call;
pragma No_Return (Call);
pragma Import (Assembler, Call);
for Call'Address use System'To_Address (16#0E00#);
begin
Call;
end Bootloader;
当我用gnatmake -c -u -f -S bootloader.adb
编译时,保存的汇编程序是
.text
.globl __ada_bootloader
__ada_bootloader:
LFB1:
pushq %rbp
LCFI0:
movq %rsp, %rbp
LCFI1:
subq $16, %rsp
LCFI2:
movq $3584, -8(%rbp)
movq -8(%rbp), %rax
call *%rax
leave
LCFI3:
ret
[...]
看起来很有希望,虽然我不熟悉asm知道。
在gdb下运行我得到(经过大量的讨论)
(gdb) run
Starting program: /Users/simon/tmp/bootloader
Reading symbols for shared libraries ++........................ done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000e00
0x0000000000000e00 in ?? ()
(gdb) bt
#0 0x0000000000000e00 in ?? ()
Cannot access memory at address 0xe00
#1 0x0000000100000d93 in main (argc=1, argv=140734799805048, envp=140734799805064) at /Users/simon/tmp/b~bootloader.adb:121
#2 0x0000000100000bf4 in start ()
看起来更有希望。
也许您的AVR编译器没有正确生成代码?