FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Arm DesignStart Cortex-M3を試す(5. オリジナルプログラムをビルドしてシミュレーションする試行)

f:id:msyksphinz:20181026004305p:plain

Arm DesignStart ProgramではCortex-M3も開放されており、こちらもRTLシミュレーション環境が用意されていた。

前回はDhrystoneやhelloを動かしてみたが、オリジナルプログラムをコンパイルして動作させることはできるだろうか。試行する。

例えばhelloのプログラムは、ディレクトリ内のAT421-MN-80001-r0p0-02rel0/m3designstart/logical/testbench/testcodes/helloに存在している。 Ubuntu-18.04ならばapt-getでArmのコンパイルツールをダウンロードできるので、ダウンロードしてみる。

$ sudo apt install binutils-arm-none-eabi gcc-arm-none-eabi

これでリコンパイルした。当該ディレクトリに移って、makeをたたいてみる。

$ cd AT421-MN-80001-r0p0-02rel0/m3designstart/logical/testbench/testcodes/hello
$ make
$ make
arm-none-eabi-gcc -g -O3 -mthumb -mcpu=cortex-m3 --specs=nosys.specs --specs=nano.specs -Wl,--gc-sections -D__STARTUP_CLEAR_BSS ../../../../software/cmsis/Device/ARM/CM3DS/Source/GCC/startup_CM3DS.s \
        hello.c \
        ../../../../software/common/retarget/retarget.c \
        ../../../../software/common/retarget/uart_stdout.c \
        ../../../../software/cmsis/Device/ARM/CM3DS/Source/system_CM3DS.c \
        -I ../../../../software/cmsis/Device/ARM/CM3DS/Include -I ../../../../software/cmsis/CMSIS/Include \
                -I ../../../../software/common/retarget  \
        -L ../../../../software/common/scripts \
        -D__STACK_SIZE=0x200 \
        -D__HEAP_SIZE=0x1000 \
        -DCORTEX_M3 -T ../../../../software/common/scripts/cm3ds.ld -o hello.o
# Generate disassembly code
arm-none-eabi-objdump -S hello.o > hello.lst
# Generate binary file
arm-none-eabi-objcopy -S hello.o -O binary hello.bin
# Generate hex file
arm-none-eabi-objcopy -S hello.o -O verilog hello.hex

コンパイルしてみたコードをさっそくシミュレーションしてみたのだが、最後まで完走しない。 というか、まったくprintf()が表示されない。

よくよく調べてみると、どうも生成されているtest.binが大きすぎる。 最終的にodコマンドなどを使用してflash_main.iniに変換されてシミュレータに流されるのだが、どうも生成されているバイナリがそもそもおかしいようだ。

Armの公式Webサイトからツールチェインをダウンロードして、使ってみよう。 まずはaptで入手したツールを削除する。

$ sudo apt remove gcc-arm-none-eabi binutils-arm-none-eabi

下記から最新版のArmのツールチェインをダウンロードして、PATHを通した。これで再度バイナリを作成した。

developer.arm.com

同様にコンパイルしてみたが、やはりコンパイル結果は同じだ。どのように変えれば良いのだろうか? 引き続き解析する。

参考:ツールチェインを使ってコンパイルした結果をobjdumpすると、以下のように0x00がコードになっていない気がするぞ?

hello.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <__isr_vector>:
   0:   2000fc00        .word   0x2000fc00
   4:   00000125        .word   0x00000125
   8:   0000016d        .word   0x0000016d
   c:   0000016f        .word   0x0000016f
  10:   00000171        .word   0x00000171
  14:   00000173        .word   0x00000173
  18:   00000175        .word   0x00000175
        ...
  2c:   00000177        .word   0x00000177
  30:   00000179        .word   0x00000179
  34:   00000000        .word   0x00000000
  38:   0000017b        .word   0x0000017b
  3c:   0000017d        .word   0x0000017d
  40:   0000017f        .word   0x0000017f
...

2018/10/28追記。先ほどリトライしたら上手くいった。 どうもisr_vectorを最初にフェッチした後に割り込み(か単なる分岐?)を使って本当のブート位置にジャンプするらしい。 例えば、m3designstart/logical/testbench/testcodes/hello/hello.cを以下のように変更すると、ちゃんと変更したプログラムが動いた。

--- a/arm_designstart/AT421-MN-80001-r0p0-02rel0/m3designstart/logical/testbench/testcodes/hello/hello.c
+++ b/arm_designstart/AT421-MN-80001-r0p0-02rel0/m3designstart/logical/testbench/testcodes/hello/hello.c
@@ -31,7 +31,7 @@ int main (void)
   // UART init
   UartStdOutInit();

-  printf("Hello world\n");
+  printf("Hello world MSYKSPHINZ\n");

   printf("** TEST PASSED **\n");

@@ -40,4 +40,3 @@ int main (void)

   return 0;
 }
f:id:msyksphinz:20181028200126p:plain