目次: Zephyr
前回ninjaを実行したときに嫌というほどエラーが出ました。エラーを追う前に、コンフィグがあっているかチェックしたいと思います。
ZephyrはLinux Kernelと似たコンフィグのシステム(Kconfig)を持っています。使い方もLinuxと似ており、ninja menuconfigとすると、ケバケバしい色(私の環境だと真っ白+黄色になる……)の画面が表示されます。
なぜかArchitectureがx86となっていたり、SoCがLiteXになっていたり、色々おかしいです。なぜこうなってしまったかは後にして、手当たり次第でそれらしい値に直すと、Board Selectionに今回追加したHoge targetが出現します。
$ ninja menuconfig Architecture (x86 architecture) ---> ( ) RISCV architectureを選択 SoC/CPU/Configuration Selection (LiteX VexRiscv system implementation) ---> ( ) SiFive Freedom SOC implementationを選択
コンフィグがそれらしくなったらninjaでビルドします。
$ ninja zephyr/samples/hello_world/src/main.c:12:30: error: 'CONFIG_BOARD' undeclared (first use in this function); did you mean 'CONFIG_ARCH'? printk("Hello World! %s\n", CONFIG_BOARD); ^~~~~~~~~~~~ CONFIG_ARCH ... In file included from ../include/devicetree.h:12, from ../soc/riscv/riscv-privilege/sifive-freedom/soc.h:15, from ../include/arch/riscv/arch.h:25, from ../include/arch/cpu.h:23, from ../include/kernel_includes.h:34, from ../include/kernel.h:17, from zephyr/drivers/interrupt_controller/intc_plic.c:13: zephyr/drivers/interrupt_controller/intc_plic.c: In function 'riscv_plic_irq_enable': zephyr/include/generated/devicetree_fixups.h:8:25: error: 'DT_INST_0_SIFIVE_PLIC_1_0_0_IRQ_EN_BASE_ADDRESS' undeclared (first use in this function) #define DT_PLIC_IRQ_EN DT_INST_0_SIFIVE_PLIC_1_0_0_IRQ_EN_BASE_ADDRESS ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
先程よりはマシになりましたが、まだエラーが山のように出ます。エラーの種類を大別するとCONFIG_BOARDの定義がない、DT_INST_ なんちゃらの定義がない、に分けられます。
最初のCONFIG_BOARDについては、いかにもボード側で定義しなければならなさそうな名前です。おなじみ他のボードを参照(boards/riscv/qemu_riscv32/Kconfig.defconfigなど)すると、Kconfig.boardで定義したconfig BOARD_HOGEが定義されているときに限り、CONFIG_BOARDにボード名のデフォルト値を設定していました。
つまり、このように書けば良いみたいです。
# SPDX-License-Identifier: Apache-2.0
if BOARD_HOGE
config BOARD
default "hoge"
endif
それ以外のDT_INST_ なんちゃらの定義については、少し複雑です。
Linuxではデバイスツリーファイル(*.dts)をデバイスツリーコンパイラdtcでコンパイルして、Flattened Device Tree(fdt)という形式のバイナリにします。fdtはカーネル内部に組み込んだり、ブートローダが起動時にカーネルに渡すなどして利用されます。
しかしZephyrはそもそもdtcを使わず、Pythonで処理します。デバイスツリーを書き間違えるとPythonスクリプトが怒ってくるのですが、これが理由みたいです。なんだと?と思う方はZephyrのドキュメント(Devicetree - Zephyr Project Documentation)をご参照ください。下記に引用します。
Note: In addition to the Python code above, the standard dtc DTS compiler is also run on the devicetree. This is just to catch any errors or warnings it generates. The output is unused.
ドキュメントのGenerated macrosの章を見ると、デバイスツリーからDT_INST_ なんちゃら、というマクロを生成する、という説明があり、ビルドエラーの原因となったマクロの仲間のようです。
推測するにデバイスツリーを何も定義していないことが、DT_INST_ なんちゃらマクロが存在しないことの原因ではないでしょうか?他のボード(boards/riscv/qemu_riscv32/qemu_riscv32.dtsなど)がデバイスツリーをどうしているか、見ながら真似してみます。
/* SPDX-License-Identifier: Apache-2.0 */
/dts-v1/;
#include <riscv32-fe310.dtsi>
/ {
model = "Hoge Board";
compatible = "hoge,hoge";
chosen {
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,sram = &dtim;
zephyr,flash = &flash0;
};
};
&gpio0 {
status = "okay";
};
&uart0 {
status = "okay";
current-speed = <115200>;
clock-frequency = <16000000>;
};
&spi0 {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x10014000 0x1000 0x20400000 0xc00000>;
flash0: flash@0 {
compatible = "issi,is25lp128", "jedec,spi-nor";
size = <134217728>;
label = "FLASH0";
jedec-id = [96 60 18];
reg = <0>;
// Dummy entry
spi-max-frequency = <0>;
};
};
ほぼ全てコピーしただけです。ビルドしてみると、最後の方まで行きますが、いくつかシンボルがないと言われます。ログはフルパスが出ていて鬱陶しいので意味が残る程度に削っています。
$ ninja ... riscv64-zephyr-elf/bin/ld: zephyr/arch/arch/riscv/core/libarch__riscv__core.a(isr.S.obj): in function `.L0 ': zephyr/arch/riscv/core/isr.S:244: undefined reference to `_sw_isr_table' riscv64-zephyr-elf/bin/ld: zephyr/kernel/libkernel.a(sched.c.obj): in function `z_reset_time_slice': zephyr/kernel/sched.c:276: undefined reference to `z_clock_elapsed' riscv64-zephyr-elf/bin/ld: zephyr/kernel/libkernel.a(timeout.c.obj): in function `elapsed': zephyr/kernel/timeout.c:69: undefined reference to `z_clock_elapsed' collect2: error: ld returned 1 exit status % ninja: build stopped: subcommand failed.
これらのシンボルはドライバが提供するもののようですので、コンフィグでそれらしきものをONにしていきます。
General Architecture Options ---> Interrupt Configuration ---> [ ] Use generated IRQ tablesを選択 General Kernel Options ---> [ ] Execute in place Device Drivers ---> [ ] Serial Drivers ---- [ ] Enable UART Interrupt supportを選択 [ ] SiFive Freedom serial driver (NEW) ---- [ ] Enable SIFIVE Port 0 (NEW) ---- を選択 [ ] Console drivers --- [ ] Use UART for console (NEW) を選択 Timer Drivers ---> [ ] RISCV Machine Timerを選択 [ ] GPIO Drivers ---- [ ] SiFive Freedom Processor GPIO driver (NEW) ---- を選択 [ ] Enable board pinmux driver ---- [ ] SiFive Freedom SOC pinmux driver (NEW) ----
このように全て手動で設定する必要はない(後々不要となる)ので、あまり詳しくなる必要はないですが、
コンフィグがそれらしくなったらninjaでビルドして、実行します。
$ ninja ... Memory region Used Size Region Size %age Used ROM: 13165 B 12 MB 0.10% RAM: 3808 B 16 KB 23.24% IDT_LIST: 569 B 2 KB 27.78% [98/98] Linking C executable zephyr/zephyr.elf $ /usr/bin/qemu-system-riscv32 -nographic -machine sifive_e -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel /home/katsuhiro/share/projects/oss/zephyr/build/zephyr/zephyr.elf *** Booting Zephyr OS build zephyr-v2.1.0-1471-g7e7a4426d835 *** Hello World! hoge
実行できました。Hello Worldの後ろがボード名(CONFIG_BOARD)です。無事、アプリがhogeボード上で動いたということですね。次回は面倒くさかった手動コンフィグの撲滅に挑みます。
< | 2020 | > | ||||
<< | < | 02 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | - | 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)