2017-05-06 32 views
-1

我正在为一个侧面项目制作引导程序。内部引导程序ARM cortex M4 NRF52芯片

我已经读取了一个十六进制文件,验证了校验和,并将所有内容都存储在闪存中,其偏移量为0x4000。我有问题跳到我的应用程序。我已经阅读,搜索并尝试了很多不同的东西,比如这里的代码。

http://www.keil.com/support/docs/3913.htm

我当前的代码是这样的;

int binary_exec(void * Address){ 
    int i; 
    __disable_irq(); 
// Disable IRQs 
for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF; 
// Clear pending IRQs 
for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF; 

// -- Modify vector table location 
// Barriars 
__DSB(); 
__ISB(); 
// Change the vector table 
SCB->VTOR = ((uint32_t)0x4000 & 0x1ffff80); 
// Barriars 
__DSB(); 
__ISB(); 

__enable_irq(); 

// -- Load Stack & PC 
binExec(Address); 
return 0; 
} 

__asm void binexec(uint32_t *address) 
{ 
    mov r1, r0  
    ldr r0, [r1, #4] 
    ldr sp, [r1]  
    blx r0" 

}

这只是跳转到一个随机位置,并没有做任何事情。我使用keil的注册窗口手动将地址添加到PC,并直接跳到我的应用程序,但我还没有找到使用代码的方法。有任何想法吗?先谢谢你。

而且第二至十六进制文件有起始线性地址记录的最后一行: http://www.keil.com/support/docs/1584.htm

没有人知道这一行做什么?

谢谢

埃里克MICALLEF

+0

你已经设置了lsbit,这是一个cortex-m4是的,所以当你想使用blx或bx或mov pc或任何你需要的将lsbit设置为表示您正在分支到拇指代码(这是设置cortex-m知道的唯一指示)。也许这就是发生了什么? –

+0

在十六进制文件中的最后一行的情况下,lsbit已经被设置,把它放在一个寄存器中,比如r0,然后是bx r0。 –

+0

我该如何设置lsbit? –

回答

0

这是我在说什么,你能告诉我们一些片段是这样的,这是一个完整的应用程序只是不去做太多......

20004000 <_start>: 
20004000: 20008000 
20004004: 20004049 
20004008: 2000404f 
2000400c: 2000404f 
20004010: 2000404f 
20004014: 2000404f 
20004018: 2000404f 
2000401c: 2000404f 
20004020: 2000404f 
20004024: 2000404f 
20004028: 2000404f 
2000402c: 2000404f 
20004030: 2000404f 
20004034: 2000404f 
20004038: 2000404f 
2000403c: 20004055 
20004040: 2000404f 
20004044: 2000404f 

20004048 <reset>: 
20004048: f000 f806 bl 20004058 <notmain> 
2000404c: e7ff  b.n 2000404e <hang> 

2000404e <hang>: 
2000404e: e7fe  b.n 2000404e <hang> 

20004050 <dummy>: 
20004050: 4770  bx lr 
    ... 

20004054 <systick_handler>: 
20004054: 4770  bx lr 
20004056: bf00  nop 

20004058 <notmain>: 
20004058: b510  push {r4, lr} 
2000405a: 2400  movs r4, #0 
2000405c: 4620  mov r0, r4 
2000405e: 3401  adds r4, #1 
20004060: f7ff fff6 bl 20004050 <dummy> 
20004064: 2c64  cmp r4, #100 ; 0x64 
20004066: d1f9  bne.n 2000405c <notmain+0x4> 
20004068: 2000  movs r0, #0 
2000406a: bd10  pop {r4, pc} 

偏移0x00为堆栈指针

20004000: 20008000 

偏移值0x04我S中的复位向量或入口点此程序

20004004: 20004049 

我填补了未使用的,使他们在一个无限循环

20004008: 2000404f 

土地,并在不同的一个扔只是为了显示

2000403c: 20004055 

在这种情况下,VTOR将被设置为0x2004000我会从0x20004004读取0x20004049,然后从BX读取该地址。

所以我binexec将被送入地址0x20004000,我会做这样的事情

ldr r1,[r0] 
mov sp,r1 
ldr r2,[r0,#4] 
bx r2 

如果我想假复位到该代码。 thumb2的拇指方法我假设你可以ldr sp,[r0],我不用手代码thumb2所以没有记住这些,并且有不同的thumb2扩展集,以及不同的气体语法选项。

现在,如果您不打算支持中断或其他原因(可能会在您的闪存中携带一些二进制代码,希望您的执行效果更好,并将其从闪存复制到内存然后在内存中使用),则可以下载猛撞,仅仅有其第一个指令在入口点,没有矢量表的应用程序:

20004000 <_start>: 
20004000: f000 f804 bl 2000400c <notmain> 
20004004: e7ff  b.n 20004006 <hang> 

20004006 <hang>: 
20004006: e7fe  b.n 20004006 <hang> 

20004008 <dummy>: 
20004008: 4770  bx lr 
    ... 

2000400c <notmain>: 
2000400c: b510  push {r4, lr} 
2000400e: 2400  movs r4, #0 
20004010: 4620  mov r0, r4 
20004012: 3401  adds r4, #1 
20004014: f7ff fff8 bl 20004008 <dummy> 
20004018: 2c64  cmp r4, #100 ; 0x64 
2000401a: d1f9  bne.n 20004010 <notmain+0x4> 
2000401c: 2000  movs r0, #0 
2000401e: bd10  pop {r4, pc} 

在这种情况下,将需要同意下载的程序是为0x20004000建,你将下载数据那个地址,但是当你想运行它时,你会这样做

.globl binexec 
binexec: 
    bx r0 

用C

binexec(0x20004000|1); 

.globl binexec 
binexec: 
    orr r0,#1 
    bx r0 

只是为了安全起见(R)。

在这两种情况下,如果你想让它们运行,你需要建立你的二进制文件,两者都必须链接到目标地址,特别是向量表方法,因此问题是否可以向我们展示一个示例向量表从你下载的程序之一,即使前几个字也可以...

+0

hi @old_timer。我并不完全确定如何向你提供你所要求的buuuuuuuuut,我确实得到了它的工作。在keil中有一个设置规定了IROM1和IROM2的空间,我没有意识到必须设置这些空间。对不起,我造成的沮丧感谢您的帮助,虽然! –

+0

没有挫折,只是想帮助。 –