5

ARM Cortex-M3 (SiLabs) SOC のプロジェクトに取り組んでいます。「ブートローダー」用のスペースを作るために、割り込みベクトル [編集] とコードをフラッシュの下部から離す必要があります。ブートローダはアドレス 0 から開始し、コアがリセットから復帰したときに起動します。その機能は、より高いアドレスにロードされたメイン イメージを検証し、場合によってはそのメイン イメージを新しいイメージに置き換えることです。

したがって、ブート ローダーのベクター テーブルは 0 で、その後にコードが続きます。上位の固定アドレス (たとえば 8KB) は、ベクター テーブルから始まるメイン イメージになります。

ブートローダーがハードウェアを新しいベクターテーブルに向けるために (明らかに割り込みをマスクして) 使用できるベクターテーブルオフセットレジスターについて説明しているこのページを見つけました。

私の質問は、ゼロからではなく、フラッシュに書き込まれたときに機能するようにリンクされた「メイン」イメージを取得する方法です。私はARMアセンブリに精通していませんが、コードは位置に依存していないと思います。

ツールチェーンに gcc を使用する SiLabs の Precision32 IDE を使用しています。リンカーフラグを追加する方法を見つけました。私の質問は、どの gcc フラグがベクター テーブルとコードのベースに変更をもたらすかということです。

ありがとうございました。

4

1 に答える 1

6

ベクトル.s

.cpu cortex-m3
.thumb

.word   0x20008000  /* stack top address */
.word   _start      /* Reset */
.word   hang
.word   hang
/* ... */

.thumb_func
hang:   b .

.thumb_func
.globl _start
_start:
    bl notmain
    b hang

notmain.c

extern void fun ( unsigned int );
void notmain ( void )
{
    fun(7);
}

fun.c

void fun ( unsigned int x )
{
}

Makefile

hello.elf : vectors.s fun.c notmain.c memmap
    arm-none-eabi-as vectors.s -o vectors.o
    arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c notmain.c -o notmain.o
    arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c fun.c -o fun.o
    arm-none-eabi-ld -o hello.elf -T memmap vectors.o notmain.o fun.o
    arm-none-eabi-objdump -D hello.elf > hello.list
    arm-none-eabi-objcopy hello.elf -O binary hello.bin

したがって、リンカースクリプト(memmapは私が使用した名前です)が次のようになっている場合

MEMORY
{
   rom : ORIGIN = 0x00000000, LENGTH = 0x40000
   ram : ORIGIN = 0x20000000, LENGTH = 0x8000
}

SECTIONS
{
   .text : { *(.text*) } > rom
   .bss  : { *(.bss*) } > ram
}

上記はすべて .text であり、.bss も .data も含まれていないため、リンカは ld コマンドラインにリストされているオブジェクトを取得し、そのアドレスから配置します...

セクション .text の mbly:

00000000 <hang-0x10>:
   0:   20008000    andcs   r8, r0, r0
   4:   00000013    andeq   r0, r0, r3, lsl r0
   8:   00000011    andeq   r0, r0, r1, lsl r0
   c:   00000011    andeq   r0, r0, r1, lsl r0

00000010 <hang>:
  10:   e7fe        b.n 10 <hang>

00000012 <_start>:
  12:   f000 f801   bl  18 <notmain>
  16:   e7fb        b.n 10 <hang>

00000018 <notmain>:
  18:   2007        movs    r0, #7
  1a:   f000 b801   b.w 20 <fun>
  1e:   bf00        nop

00000020 <fun>:
  20:   4770        bx  lr
  22:   bf00        nop

したがって、これを機能させるには、ブートストラップ コードをコマンド ラインの最初に配置するように注意する必要があります。しかし、リンカー スクリプトを使用してこのようなことを行うこともできます。

特定のオブジェクトファイルを最初にリストし、次に一般的な .text をリストして、順序が重要であるように見えます

MEMORY
{
   romx : ORIGIN = 0x00000000, LENGTH = 0x1000
   romy : ORIGIN = 0x00010000, LENGTH = 0x1000
   ram  : ORIGIN = 0x00030000, LENGTH = 0x1000
   bob  : ORIGIN = 0x00040000, LENGTH = 0x1000
   ted  : ORIGIN = 0x00050000, LENGTH = 0x1000
}

SECTIONS
{
   abc : { vectors.o } > romx
   def : { fun.o } > ted
   .text : { *(.text*) } > romy
   .bss  : { *(.bss*) } > ram
}

そして、これを取得します

00000000 <hang-0x10>:
   0:   20008000    andcs   r8, r0, r0
   4:   00000013    andeq   r0, r0, r3, lsl r0
   8:   00000011    andeq   r0, r0, r1, lsl r0
   c:   00000011    andeq   r0, r0, r1, lsl r0

00000010 <hang>:
  10:   e7fe        b.n 10 <hang>

00000012 <_start>:
  12:   f00f fff5   bl  10000 <notmain>
  16:   e7fb        b.n 10 <hang>

Disassembly of section def:

00050000 <fun>:
   50000:   4770        bx  lr
   50002:   bf00        nop

Disassembly of section .text:

00010000 <notmain>:
   10000:   2007        movs    r0, #7
   10002:   f03f bffd   b.w 50000 <fun>
   10006:   bf00        nop

簡単な答えは、リンカー スクリプトを使用して最終的な場所を操作する gnu ツールを使用することです。これらの関数を ROM の特定の場所に配置する必要があると思います。あなたが何をしているのか正確にはわかりません。しかし、たとえば、最初に main() への分岐のような単純なものをフラッシュに入れようとしていて、 main() がフラッシュのより深いところにある場合、どういうわけか、フラッシュのより深いところにあるコードを介して、または他の方法を介して、後で、ゼロに近いものだけを消去して再プログラムします。最初は main() への簡単な分岐が必要です。私が vector.o と呼んでいるものを強制的にアドレス 0 にすると、.text をフラッシュの奥深くに配置して、コードのすべてのリセットを基本的にそこに置き、それをフラッシュに残して、ゼロのものだけを置き換えることができます。

このような

MEMORY
{
   romx : ORIGIN = 0x00000000, LENGTH = 0x1000
   romy : ORIGIN = 0x00010000, LENGTH = 0x1000
   ram  : ORIGIN = 0x00030000, LENGTH = 0x1000
   bob  : ORIGIN = 0x00040000, LENGTH = 0x1000
   ted  : ORIGIN = 0x00050000, LENGTH = 0x1000
}

SECTIONS
{
   abc : { vectors.o } > romx
   .text : { *(.text*) } > romy
   .bss  : { *(.bss*) } > ram
}

与える

00000000 <hang-0x10>:
   0:   20008000    andcs   r8, r0, r0
   4:   00000013    andeq   r0, r0, r3, lsl r0
   8:   00000011    andeq   r0, r0, r1, lsl r0
   c:   00000011    andeq   r0, r0, r1, lsl r0

00000010 <hang>:
  10:   e7fe        b.n 10 <hang>

00000012 <_start>:
  12:   f00f fff7   bl  10004 <notmain>
  16:   e7fb        b.n 10 <hang>

Disassembly of section .text:

00010000 <fun>:
   10000:   4770        bx  lr
   10002:   bf00        nop

00010004 <notmain>:
   10004:   2007        movs    r0, #7
   10006:   f7ff bffb   b.w 10000 <fun>
   1000a:   bf00        nop

次に、0x10000 のものを残し、後で 0x00000 のものを置き換えます。

とにかく、短い答えはリンカースクリプトです。リンカースクリプトを作成して、必要な場所に配置する必要があります。gnu リンカ スクリプトは非常に複雑になる可能性があるため、私は単純なものに傾倒しています。

ベクターテーブルを含む他のアドレスにすべてを配置したい場合は、おそらく次のようになります。

ホップス

.cpu cortex-m3
.thumb

.word   0x20008000  /* stack top address */
.word   _start      /* Reset */
.word   hang
.word   hang
/* ... */

.thumb_func
hang:   b .

.thumb_func
    ldr r0,=_start
    bx r0

この

MEMORY
{
   romx : ORIGIN = 0x00000000, LENGTH = 0x1000
   romy : ORIGIN = 0x00010000, LENGTH = 0x1000
   ram  : ORIGIN = 0x00030000, LENGTH = 0x1000
   bob  : ORIGIN = 0x00040000, LENGTH = 0x1000
   ted  : ORIGIN = 0x00050000, LENGTH = 0x1000
}

SECTIONS
{
   abc : { hop.o } > romx
   .text : { *(.text*) } > romy
   .bss  : { *(.bss*) } > ram
}

これを与える

Disassembly of section abc:
00000000 <hang-0x10>:
   0:   20008000    andcs   r8, r0, r0
   4:   00010013    andeq   r0, r1, r3, lsl r0
   8:   00000011    andeq   r0, r0, r1, lsl r0
   c:   00000011    andeq   r0, r0, r1, lsl r0

00000010 <hang>:
  10:   e7fe        b.n 10 <hang>
  12:   4801        ldr r0, [pc, #4]    ; (18 <hang+0x8>)
  14:   4700        bx  r0
  16:   00130000
  1a:   20410001

Disassembly of section .text:

00010000 <hang-0x10>:
   10000:   20008000    andcs   r8, r0, r0
   10004:   00010013    andeq   r0, r1, r3, lsl r0
   10008:   00010011    andeq   r0, r1, r1, lsl r0
   1000c:   00010011    andeq   r0, r1, r1, lsl r0

00010010 <hang>:
   10010:   e7fe        b.n 10010 <hang>

00010012 <_start>:
   10012:   f000 f803   bl  1001c <notmain>
   10016:   e7fb        b.n 10010 <hang>

00010018 <fun>:
   10018:   4770        bx  lr
   1001a:   bf00        nop

0001001c <notmain>:
   1001c:   2007        movs    r0, #7
   1001e:   f7ff bffb   b.w 10018 <fun>
   10022:   bf00        nop

たとえば、ベクター テーブルを 0x10000 に変更できます。

ブートローダーを 0x00000 に設定するなどの別の質問をしている場合、ブートローダーはフラッシュを変更してアプリケーションを 0x20000 に追加します。そのアプリケーションを実行したい場合は、必ずしも場所を変更する必要のない簡単な解決策があります。ベクターテーブル。

于 2013-08-10T02:53:46.647 に答える