はじめに
PlatformIOでHiFive1 Rev.Bを動かすで下記のように書いたので ベアメタルで動かしてみる。
標準のライブラリやヘッダは使っていないので、リンカスクリプトとスタートアップを書けば、 ベアメタルでもこのまま動くはず。
リンカスクリプト
リンカスクリプトをlinker.ld
として次の内容で作成する。
MEMORY { rom : ORIGIN = 0x20010000, LENGTH = 0x6a120 ram : ORIGIN = 0x80000000, LENGTH = 0x4000 } ENTRY(start) SECTIONS { .text : {*(.text*)} > rom .rodata : {*(.rodata*)} > rom .bss : {*(.bss*)} > ram }
スタートアップ
utils.S
にスタートアップのコードを追加する。
.global start start: lui sp, 0x80004 jal main j . .global dummy dummy: ret .global put32 put32: sw x11,(x10) ret
Makefile
Makefileを次の内容で作成する。
RISCVGNU = riscv32-unknown-elf AOPS = -march=rv32imac COPS = -march=rv32imac -Wall -O0 -g -nostdlib -nostartfiles -ffreestanding #COPS = -march=rv32imac -Wall -O2 -nostdlib -nostartfiles -ffreestanding all : blinker.hex clean : rm -f *.o rm -f *.elf rm -f *.hex rm -f *.list rm -f *~ utils.o : utils.S $(RISCVGNU)-as $(AOPS) utils.S -o utils.o led.o : led.c $(RISCVGNU)-gcc $(COPS) -c led.c -o led.o blinker.hex : linker.ld utils.o led.o $(RISCVGNU)-ld utils.o led.o -T linker.ld -o blinker.elf $(RISCVGNU)-objdump -D blinker.elf > blinker.list $(RISCVGNU)-objcopy blinker.elf -O ihex blinker.hex flash : blinker.hex JLinkExe -device FE310 -speed 1000 -if JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript "upload.jlink"
Cプログラム
led.c
の内容はそのままなので省略。
JLinkコマンドファイル
ターゲットへの書き込みにupload.jlink
として次の内容でファイルを作成する。
h loadfile ./blinker.hex r q
ツールチェイン
ツールチェインはRISC-Vのベアメタル入門(自分用)を参照。
J-Linkのツール
SEGGERのサイトからパッケージをダウンロードする。
PlatformIOのものを使う場合には.bashrc
に次のように追加してPATHを通す。
export PATH="${HOME}/.platformio/packages/tool-jlink:${PATH}"
書き込み
Makefileに次の部分を仕込んだのでmakeコマンドで書き込むことができる。
flash : blinker.hex JLinkExe -device FE310 -speed 1000 -if JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript "upload.jlink"
書き込みにはJLinkExe
を使用するのでJ-Linkのツールが必要となる。
次のようにしてプログラムを書き込む。
$ make flash
まとめ
ベアメタルでもLチカができた。