link もっと前
   2020年 2月 14日 -
      2020年 2月 5日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

link 編集する

Zephyr OS で遊ぼう その 9 - Zephyr 2.2.0 に対応する

Zephyr は開発中なので、ときおり内部構造が変わり、過去と互換性がなくなってしまうことがあります。ボードや SoC の定義も例外ではありません。

前回までの説明では Zephyr 2.1.0 を使用していましたが、2.1.0 から 2.2.0 の間で、ボードの defconfig の書き方が変更されました。具体的に言うと、

  • ボード側: アーキテクチャ CONFIG_RISCV を書かなくて良くなった
  • SoC 側: CONFIG_RISCV を depends on → select に変える必要が生じた

下記のパッチにあるような変更をすると、2.2.0 でも Hoge ボードと Spike SoC の対応が適用できます。

それぞれ 1行ずつしか変更していませんので、すぐわかると思います。

Zephyr の不思議なコンフィグ

Zephyr は Linux と同じ Kconfig を採用していますが、コンフィグの起点に対する考え方がだいぶ違います。Zephyr は最初に cmake で「ボード名(-DBOARD オプション)」を指定します。すなわちコンフィグの起点はボードです。一方の Linux は export ARCH=x86 のようにアーキテクチャを設定の起点にします。

Zephyr 2.1.0 では、アーキテクチャ(CONFIG_RISCV など)、SoC(CONFIG_SOC_RISCV_SIFIVE_FREEDOM など)、ボードの依存関係は下記のようになっていました。

2.1.0 の依存関係
アーキテクチャ(ボードの defconfig が y にする)← アーキテクチャが依存の起点
↑depends on
SoC(ボードの defconfig が y にする)
↑depends on
ボード(ボードの defconfig が y にする)← Zephyr はなぜかボードがコンフィグの起点

依存関係とコンフィグの起点が矛盾しているため menuconfig が異常な動きをします。おそらく ninja menuconfig を弄れば矛盾に気づくと思いますが、Zephyr はなぜかボードが未対応のアーキテクチャや SoC(例えば qemu_riscv32 で CONFIG_ARM を選択できる)を有効にできます。Zephyr 2.1.0 だと 2つ、おかしな設定ができます。

  • qemu_riscv32 ボードで未対応のアーキテクチャ(例えば CONFIG_X86)を選択すると、SoC の選択肢がおかしくなる(X86 だと言っているのに、RISC-V 用の SoC が出てくる)
  • qemu_riscv32 ボードで未対応の SoC(例えば CONFIG_SOC_LITEX_VEXRISCV)を選択すると、ボードの一覧が空になって選べなくなる(これは 2.2.0 でもできる)

実際に ninja menuconfig で、qemu_riscv32 が未対応のアーキテクチャを選ぶと下記のようになります。

Zephyr 2.1.0 の変なコンフィグ
# qemu_riscv32 のデフォルト

    Modules  --->
    Board Selection (QEMU RISCV32 target)  --->
    Board Options  ----
    SoC/CPU/Configuration Selection (SiFive Freedom SOC implementation)  --->
    Hardware Configuration  --->
    RISCV Options  --->
    Architecture (RISCV architecture)  --->
    General Architecture Options  --->
    General Kernel Options  --->
    ...


# ボードが対応していないアーキテクチャを選択すると、SoC が勝手に変わる、ボードは何も選べなくなる

    Modules  --->
    Board Selection  ----
    Board Options  ----
    SoC/CPU/Configuration Selection (LiteX VexRiscv system implementation)  --->    ★なぜか RISC-V 用の SoC が出てくる
    Hardware Configuration  ----
    Architecture (x86 architecture)  --->    ★x86 に変えた
    General Architecture Options  --->
    General Kernel Options  --->
    ...

そもそも x86 が選択可能な時点でおかしいですが、x86 を選択したのに x86 じゃない SoC が選択肢に出てくるなど、かなりおかしな動きです。

中途半端に直った Zephyr 2.2.0

Zephyr 2.2.0 では依存関係は下記のように、少しだけ整理されました。

2.2.0 の依存関係
アーキテクチャ(SoC が強制的に y にする、menuconfig では触れない)
↑select
SoC(ボードの defconfig が y にする)
↑depends on
ボード(ボードの defconfig が y にする)← ここが起点

アーキテクチャを変えることが出来なくなりました。前よりマシですが、やはり変なところは残っていて、未対応の SoC を選択するとボードの選択肢が消えてしまいます。

Zephyr 2.2.0 の変なコンフィグ設定
# qemu_riscv32 のデフォルト

    Modules  --->
    Board Selection (QEMU RISCV32 target)  --->
    Board Options  ----
    SoC/CPU/Configuration Selection (SiFive Freedom SOC implementation)  --->
    Hardware Configuration  --->
    RISCV Options  --->
    ...


# SoC を無理やり未対応のものに変えると、ボードが選べなくなる

    Modules  --->
    Board Selection  ----
    Board Options  ----
    SoC/CPU/Configuration Selection (LiteX VexRiscv system implementation)  --->
    Hardware Configuration  ----
    RISCV Options  --->
    ...

個人的には Zephyr の Kconfig の使い方は変だな、と思います。依存関係があることはわかっているのだから、依存の根本の方から設定(要は、アーキテクチャ → SoC → ボード、の順)したら良いのに、Zephyr はなぜかボードの設定から固定していて、変な動きになっています。

Linux はどうしているかというと、最初に export ARCH=x86 とします。すなわち、アーキテクチャを設定の起点にしています。自然です。特に変な動きもしません。

Zephyr の方が Linux より後発ですが、ビルド周りは退化したように感じます。不思議。

[編集者: すずき]
[更新: 2020年 2月 16日 18:21]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Zephyr OS で遊ぼう その 8 - 独自のシリアルドライバの実装

前回はシリアルドライバの枠組み、というか、何も実装されていないドライバを追加しました。今回はシリアルドライバを実装します。

Zephyr のドライバについてはドキュメント(Device Driver Model - Zephyr Project Documentation)があります。ドライバの定義や初期化を司る API が Driver API の節に書いてあります。

今回作成する UART ドライバでは初期化は要りませんが、ドライバの API をいくつか実装したいので DEVICE_AND_API_INIT() を使います。

UART のドライバで実装できる API の一覧はドキュメント(UART - Zephyr Project Documentation)に書いてあります。API はたくさんありますが、poll_in, poll_out があれば動作するようなので、この 2つを作ります。

コードは下記のようにしました。

QEMU Spike モード用のシリアルドライバ実装

/*
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief UART driver for the Spike Simulator
 */

#include <kernel.h>
#include <arch/cpu.h>
#include <drivers/uart.h>

volatile u64_t tohost;
volatile u64_t fromhost;

void uart_spike_poll_out(struct device *dev, unsigned char c)
{
        u64_t cmd;

        // QEMU spike mode
        u8_t dev_no = 1;
        u8_t cmd_no = 1;
        u64_t payload = c;

        cmd = ((u64_t)dev_no << 56) |
                ((u64_t)cmd_no << 48) |
                (payload & 0xffffffffffffULL);

        tohost = cmd;

        while (fromhost == 0)
                ;
        fromhost = 0;
}

static int uart_spike_poll_in(struct device *dev, unsigned char *c)
{
        return -1;
}

static int uart_spike_init(struct device *dev)
{
        return 0;
}

static const struct uart_driver_api uart_spike_driver_api = {
        .poll_in          = uart_spike_poll_in,
        .poll_out         = uart_spike_poll_out,
};

DEVICE_AND_API_INIT(uart_spike_0, DT_INST_0_SPIKE_UART_SPIKE_LABEL,
                    uart_spike_init, NULL, NULL,
                    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
                    (void *)&uart_spike_driver_api);

このままビルドすると DEVICE_AND_API_INIT() に渡しているラベル DT_INST_0_SPIKE_UART_SPIKE_LABEL が未定義だと怒られます。これについては後ほど作り方を説明します。

ラベルが未定義のエラー
zephyr/drivers/serial/uart_spike.c:73:35: error: 'DT_INST_0_SPIKE_UART_SPIKE_LABEL' undeclared here (not in a function); did you mean 'DT_COMPAT_SPIKE_UART_SPIKE'?
 DEVICE_AND_API_INIT(uart_spike_0, DT_INST_0_SPIKE_UART_SPIKE_LABEL,
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/device.h:106:11: note: in definition of macro 'DEVICE_AND_API_INIT'
   .name = drv_name, .init = (init_fn),     \
           ^~~~~~~~
[89/97] Linking C static library zephyr/libzephyr.a
ninja: build stopped: subcommand failed.

初期化は DEVICE_AND_API_INIT() で指定します。引数の意味は DEVICE_AND_API_INIT() のドキュメントを見たほうが良いでしょう。

引っかかりそうなところは dev_name にダブルクォートを「付けない」こと、一番に初期化されるように PRE_KERNEL_1 にすることくらいでしょうか。

QEMU Spike モードの文字出力

文字出力 poll_out の実装は、グローバル変数に謎の数字を書くだけの不思議実装になっていますが、これは QEMU Spike モードの Host, Guest 間インタフェースの仕様に従っているためです。

ちなみに QEMU 側はこんなコードになっています。

QEMU Spike モードの文字出力

// https://github.com/qemu/qemu/blob/master/hw/riscv/riscv_htif.c

...

static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
{
    uint8_t device = val_written >> 56;
    uint8_t cmd = val_written >> 48;
    uint64_t payload = val_written & 0xFFFFFFFFFFFFULL;
    int resp = 0;

...

    } else if (likely(device == 0x1)) {
        /* HTIF Console */
        if (cmd == 0x0) {
            /* this should be a queue, but not yet implemented as such */
            htifstate->pending_read = val_written;
            htifstate->env->mtohost = 0; /* clear to indicate we read */
            return;
        } else if (cmd == 0x1) {
            qemu_chr_fe_write(&htifstate->chr, (uint8_t *)&payload, 1);
            resp = 0x100 | (uint8_t)payload;
        } else {
            qemu_log("HTIF device %d: unknown command\n", device);
        }
    } else {

...

    htifstate->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
    htifstate->env->mtohost = 0; /* clear to indicate we read */
}

途中の if 文を見るとわかるように、device=1, cmd=1 にすると文字が出力できます。また QEMU が文字出力を終えたときに fromhost が 0 以外の値に書き換わります(なので、Zephyr のシリアルドライバ側では fromhost をポーリングで監視する実装にしています)。

シリアルドライバのラベル定義と bindings

DT_INST_0_SPIKE_UART_SPIKE_LABEL のようなラベルはユーザが定義するのではなく、zephyr/dts/bindings 以下のファイルに存在する compatible と、デバイスツリーを突き合わせて自動生成するみたいです。命名規則については、以前 Zephyr OS で遊ぼう その 3(2020年 2月 4日の日記参照)で紹介したとおりです。

zephyr/dts/bindings/serial/spike,uart-spike.yaml

# SPDX-License-Identifier: Apache-2.0

description: UART for Spike Simulator

compatible: "spike,uart-spike"

include: uart-controller.yaml

デバイスツリーの compatible の突き合わせとラベルの自動生成は、zephyr/scripts/dts/gen_defines.py と edtlib.py 辺りでやっていることは間違いなさそうなのですが、詳細な仕組みはまだ追えていません。

若干もやっとしますが YAML ファイルを作成して、compatible をデバイスツリーで使用したものと合わせると、目的のラベル DT_INST_0_SPIKE_UART_SPIKE_LABEL が定義され、ビルドが通ります。

Hello world

ビルドが通ったら実行します。

QEMU Spike モードで Hello world
$ /usr/bin/qemu-system-riscv32 -nographic -machine spike -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel zephyr/build/zephyr/zephyr.elf

qemu-system-riscv32: clint: time_hi write not implemented
qemu-system-riscv32: clint: time_lo write not implemented
qemu-system-riscv32: clint: time_hi write not implemented
*** Booting Zephyr OS build zephyr-v2.1.0-1699-gbb40304f2531  ***
Hello World! hoge

やっと Hello world が拝めました。長かった。 (2/19 追記: qemu-system-riscv32: clint: time_hi write not implemented のエラーメッセージは mtime と mtimecmp のアドレスが逆だったために発生していたエラーです。アドレス修正後は表示されません)

パッチ

今まで説明してきた変更をパッチとしてまとめておきます。

[編集者: すずき]
[更新: 2020年 2月 19日 23:52]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Zephyr OS で遊ぼう その 7 - 独自のシリアルドライバの枠組み

Zephyr のビルドに成功し、gdb で追跡したところ Hello world の main 関数まで到達していることもわかりました。ここまでくればあとは文字出力だけです。

まず Hoge ボードの defconfig に CONFIG_UART_SPIKE=y を加えます。cmake に「そんなコンフィグはない」と怒られるようになりますが、これから作るので OK です。

シリアルドライバの Kconfig, CMake

シリアルドライバのディレクトリは zephyr/drivers/serial にあります。ディレクトリの構造を見ると、CMakeLists.txt, Kconfig.*, ソースコード uart_*.c が並んでいます。この 3つの組を追加もしくは変更すれば良さそうです。

zephyr/drivers/serial/Kconfig.spike

# SPDX-License-Identifier: Apache-2.0

menuconfig UART_SPIKE
        bool "Spike Simulator serial driver"
        depends on SOC_RISCV_SPIKE
        select SERIAL_HAS_DRIVER
        help
          This option enables the Spike Simulator serial driver.

名前は何でも良いですが、Kconfig.spike という名前にしました。Kconfig.soc とは違って、ファイルを足すだけではダメで、シリアルドライバの Kconfig から読んでもらう必要があります。

zephyr/drivers/serial/Kconfig に追加する行

...

source "drivers/serial/Kconfig.litex"

source "drivers/serial/Kconfig.rtt"

source "drivers/serial/Kconfig.xlnx"

source "drivers/serial/Kconfig.spike"    # ★この行を足す★

endif # SERIAL

Kconfig を追加して cmake をするとまだ怒られます。CMakeList.txt も変更する必要があるとのことです。

Kconfig 追加後の cmake
-- Configuring done
CMake Error at ../../cmake/extensions.cmake:372 (add_library):
  No SOURCES given to target: drivers__serial
Call Stack (most recent call first):
  ../../cmake/extensions.cmake:349 (zephyr_library_named)
  ../../drivers/serial/CMakeLists.txt:3 (zephyr_library)


CMake Generate step failed.  Build files cannot be regenerated correctly.
FAILED: build.ninja

CMakeLists.txt は他の行に習って追加します。CMakeLists.txt を変更しただけだと uart_spike.c が無いと言われるので、touch uart_spike.c で空のファイルを作成します。

zephyr/drivers/serial/CMakeLists.txt に追加する行

...

zephyr_library_sources_if_kconfig(uart_liteuart.c)
zephyr_library_sources_ifdef(CONFIG_UART_RTT_DRIVER uart_rtt.c)
zephyr_library_sources_if_kconfig(uart_xlnx_ps.c)
zephyr_library_sources_if_kconfig(uart_spike.c)    # ★この行を足す★

...

他の行に習って追加するだけではつまらないので、CMake のスクリプトも眺めます。今回使用した zephyr_library_sources_if_kconfig() と zephyr_library_sources_ifdef() との違いは、ソースコードのコメントにある説明がわかりやすいです。

ファイル名を大文字にして、CONFIG_ と連結させた名前(今回のケースだと CONFIG_UART_SPIKE)を生成して、コンフィグが有効ならソースコードをビルド対象に加えるという意味です。Kconfig のコンフィグは y, n, m の 3値を取りますが、Zephyr のスクリプトでは、コンフィグが有効だと y という値が入り、無効だと未定義になるようです。

zephyr_library_sources_if_kconfig の実装

# zephyr/cmake/extensions.cmake

...

# zephyr_library_sources_if_kconfig(fft.c)
# is the same as
# zephyr_library_sources_ifdef(CONFIG_FFT fft.c)

...

function(zephyr_library_sources_if_kconfig item)
  get_filename_component(item_basename ${item} NAME_WE)
  string(TOUPPER CONFIG_${item_basename} UPPER_CASE_CONFIG)
  zephyr_library_sources_ifdef(${UPPER_CASE_CONFIG} ${item})
endfunction()

...

function(zephyr_library_sources_ifdef feature_toggle source)
  if(${${feature_toggle}})
    zephyr_library_sources(${source} ${ARGN})
  endif()
endfunction()


# zephyr/cmake/extensions.cmake

...

function(zephyr_library_sources source)
  target_sources(${ZEPHYR_CURRENT_LIBRARY} PRIVATE ${source} ${ARGN})
endfunction()

...

以上の変更でビルドが通り、シリアルドライバを実装する枠が完成しました。続きは次回。

[編集者: すずき]
[更新: 2020年 2月 16日 18:23]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Zephyr OS で遊ぼう その 6 - 独自の SoC 定義でビルド

やっと cmake を通過したので、いよいよビルドに挑みます。

最初の ninja 実行結果
In file included from ../include/arch/cpu.h:25,
                 from ../include/kernel_includes.h:34,
                 from ../include/kernel.h:17,
                 from zephyr/arch/riscv/core/offsets/offsets.c:16:
../include/arch/riscv/arch.h:25:10: fatal error: soc.h: No such file or directory
 #include <soc.h>
          ^~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.

他の soc.h を見ると、soc_common.h, devicetree.h というヘッダをインクルードしているようです。それに習っておきます。

zephyr/soc/riscv/riscv-privilege/spike/soc.h

/*
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file SoC configuration macros for the Spike series processor
 */

#ifndef __RISCV_SPIKE_SOC_H_
#define __RISCV_SPIKE_SOC_H_

#include <soc_common.h>
#include <devicetree.h>

#endif /* __RISCV_SPIKE_SOC_H_ */

再びビルドすると、今度は PLIC_* がないと怒られます。

soc.h 追加後の ninja 実行結果
zephyr/drivers/interrupt_controller/intc_plic.c: In function 'riscv_plic_irq_enable':
zephyr/drivers/interrupt_controller/intc_plic.c:45:41: error: 'DT_PLIC_IRQ_EN' undeclared (first use in this function); did you mean 'PLIC_IRQS'?
  volatile u32_t *en = (volatile u32_t *)DT_PLIC_IRQ_EN;
                                         ^~~~~~~~~~~~~~
                                         PLIC_IRQS

RISC-V Privileged 系の SoC では PLIC という割り込みコントローラのドライバが自動的に有効になります。今回、動作させるに当たって PLIC のサポートは不要なので、zephyr/boards/riscv/hoge/hoge_defconfig で無効にします。具体的には CONFIG_PLIC=n を足します。

この後 cmake からやり直してみると、

soc.h 追加後の ninja 実行結果
zephyr/drivers/timer/riscv_machine_timer.c: In function 'set_mtimecmp':
zephyr/drivers/timer/riscv_machine_timer.c:28:31: error: 'RISCV_MTIMECMP_BASE' undeclared (first use in this function)
  volatile u32_t *r = (u32_t *)RISCV_MTIMECMP_BASE;
                               ^~~~~~~~~~~~~~~~~~~
zephyr/drivers/timer/riscv_machine_timer.c:28:31: note: each undeclared identifier is reported only once for each function it appears in
zephyr/drivers/timer/riscv_machine_timer.c: In function 'mtime':
zephyr/drivers/timer/riscv_machine_timer.c:47:31: error: 'RISCV_MTIME_BASE' undeclared (first use in this function)
  volatile u32_t *r = (u32_t *)RISCV_MTIME_BASE;
                               ^~~~~~~~~~~~~~~~
[87/94] Linking C static library zephyr/kernel/libkernel.a
ninja: build stopped: subcommand failed.

CLINT のレジスタ mtime, mtimecmp のアドレスを必要としているようです。

CLINT のレジスタはどこに?

他の SoC を眺めてみると、CLINT のレジスタアドレスを定義する場所は soc.h のようです。しかし肝心のアドレスがわかりません。QEMU のドキュメントに載っていれば簡単でしたが、見当たらなかったので QEMU のソースコードを見ます。

QEMU の Spike, CLINT 関連のソースコード

// https://github.com/qemu/qemu/blob/master/hw/riscv/spike.c

static const struct MemmapEntry {
    hwaddr base;
    hwaddr size;
} spike_memmap[] = {
    [SPIKE_MROM] =     {     0x1000,    0x11000 },
    [SPIKE_CLINT] =    {  0x2000000,    0x10000 },
    [SPIKE_DRAM] =     { 0x80000000,        0x0 },
};


// https://github.com/qemu/qemu/blob/master/include/hw/riscv/sifive_clint.h

enum {
    SIFIVE_SIP_BASE     = 0x0,
    SIFIVE_TIMECMP_BASE = 0x4000,
    SIFIVE_TIME_BASE    = 0xBFF8
};

ベースアドレスが 0x02000000 で、レジスタのオフセットアドレスもわかりました。soc.h に追記します。
(2/19 訂正: MTIMECMP_BASE と MTIME_BASE のアドレスが逆だったので、修正しました)

zephyr/soc/riscv/riscv-privilege/spike/soc.h に追記する内容

/* Timer configuration */
#define RISCV_MTIMECMP_BASE          0x02004000
#define RISCV_MTIME_BASE             0x0200bff8

再びビルドします。やっとビルドをパスしました。

ビルド成功
$ ninja

[0/1] Re-running CMake...
-- Zephyr version: 2.1.99
-- Selected BOARD hoge
-- Loading zephyr/boards/riscv/hoge/hoge.dts as base
hoge.dts.pre.tmp:22.17-25.5: Warning (simple_bus_reg): /soc/serial: missing or empty reg/ranges property
  also defined at hoge.dts.pre.tmp:37.8-39.3
Devicetree header saved to 'zephyr/build/zephyr/include/generated/devicetree_unfixed.h'
Parsing zephyr/Kconfig
Loaded configuration 'zephyr/build/zephyr/.config'
No change to configuration in 'zephyr/build/zephyr/.config'
No change to Kconfig header in 'zephyr/build/zephyr/include/generated/autoconf.h'
-- Cache files will be written to: /home/katsuhiro/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: zephyr/build
[89/94] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
             RAM:       12752 B        16 KB     77.83%
        IDT_LIST:          25 B         2 KB      1.22%
[94/94] Linking C executable zephyr/zephyr.elf

まだめでたしめでたし、ではありません。

実行、デバッグ

生成されたバイナリを実行すると何かエラーが表示されるものの、Hello world は表示されません。残念です。

実行しても何も表示されない
$ /usr/bin/qemu-system-riscv32 -nographic -machine spike -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel zephyr/build/zephyr/zephyr.elf

qemu-system-riscv32: clint: time_hi write not implemented
qemu-system-riscv32: clint: time_lo write not implemented
qemu-system-riscv32: clint: time_hi write not implemented

このままでは全く何も実行されていないのか、惜しいところまで実行されたのか判別が付きません。以前ご紹介した(2020年 1月 31日の日記参照)デバッグオプション -s と -S を使い、gdb で追跡します。

復習ですが、オプション -s は GDB の接続を localhost:1234 で受け付け、-S はエミュレータを Halted 状態で起動し gdb から再開要求をするまで動かないで待っている、という意味です。

main 関数まで到達しているようだ
$ riscv64-zephyr-elf-gdb zephyr/build/zephyr/zephyr.elf

GNU gdb (crosstool-NG 1.24.0.60-a152d61) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.

...

(gdb) target remote localhost:1234

Remote debugging using localhost:1234
0x00001000 in ?? ()


(gdb) b main

Breakpoint 1 at 0x800006d4: file zephyr/samples/hello_world/src/main.c, line 12.


(gdb) c

Continuing.

Breakpoint 1, main ()
    at zephyr/samples/hello_world/src/main.c:12
12              printk("Hello World! %s
", CONFIG_BOARD);

ターゲット(QEMU)に接続し、main にブレークを設定して、実行を継続しています。Hello world の main 関数に到達していることがわかります。素晴らしいですね。printk は呼ばれているものの、文字が出ないことが問題だとわかりました。

Hello world を拝むには、シリアルのドライバを追加する必要があります。続きはまた次回。

[編集者: すずき]
[更新: 2020年 2月 19日 03:37]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Zephyr OS で遊ぼう その 5 - 独自の SoC 定義(続き)

今回は cmake をパスするまで頑張ります。

エラー内容の調査

今後の方針のため cmake のエラーを見ます。どうやら SOC_FAMILY_RISCV_PRIVILEGE がないとか、SOC_SERIES_RISCV_SPIKE とは何だ?とか、Kconfig 周りの設定で怒っているようです。何も定義していないので当然ですね。

hoge.dts を変更して cmake したときのエラー
warning: UART_CONSOLE (defined at drivers/console/Kconfig:47) was assigned the value 'y' but got the
value 'n'. Check these unsatisfied dependencies: SERIAL_HAS_DRIVER (=n). See
http://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_UART_CONSOLE.html and/or look up
UART_CONSOLE in the menuconfig/guiconfig interface. The Application Development Primer, Setting
Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful
too.


warning: RISCV_MACHINE_TIMER (defined at drivers/timer/Kconfig:153) was assigned the value 'y' but
got the value 'n'. Check these unsatisfied dependencies: SOC_FAMILY_RISCV_PRIVILEGE (=n). See
http://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_RISCV_MACHINE_TIMER.html and/or look
up RISCV_MACHINE_TIMER in the menuconfig/guiconfig interface. The Application Development Primer,
Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
helpful too.


warning: The choice symbol BOARD_HOGE (defined at boards/riscv/hoge/Kconfig.board:3) was selected
(set =y), but no symbol ended up as the choice selection. See
http://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_BOARD_HOGE.html and/or look up
BOARD_HOGE in the menuconfig/guiconfig interface. The Application Development Primer, Setting
Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful
too.


zephyr/boards/riscv/hoge/hoge_defconfig:4: warning: attempt to assign the value 'y' to the undefined symbol SOC_SERIES_RISCV_SPIKE

zephyr/boards/riscv/hoge/hoge_defconfig:5: warning: attempt to assign the value 'y' to the undefined symbol SOC_RISCV_SPIKE

error: Aborting due to Kconfig warnings

CMake Error at zephyr/cmake/kconfig.cmake:216 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  zephyr/cmake/app/boilerplate.cmake:461 (include)
  CMakeLists.txt:5 (include)

すぐに Kconfig を追加と行きたいところですが、その前に少しやることがあります。

ボードの defconfig を見直す

Hoge ボードの defconfig で余計なもの(SiFive FE310 SoC 用の設定)を定義しているので、削りましょう。SiFive 由来のドライバの設定、前回のデバイスツリーで定義していない PINMUX や GPIO の設定を削ります。

hoge_defconfig から SiFive 用の設定を削る

diff --git a/boards/riscv/hoge/hoge_defconfig b/boards/riscv/hoge/hoge_defconfig
index 3f9626815f..32c4e9e90d 100644
--- a/boards/riscv/hoge/hoge_defconfig
+++ b/boards/riscv/hoge/hoge_defconfig
@@ -1,19 +1,12 @@
 # SPDX-License-Identifier: Apache-2.0
 
 CONFIG_RISCV=y
-CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y
-CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y
+CONFIG_SOC_SERIES_RISCV_SPIKE=y
+CONFIG_SOC_RISCV_SPIKE=y
 CONFIG_BOARD_HOGE=y
 CONFIG_CONSOLE=y
 CONFIG_PRINTK=y
 CONFIG_SERIAL=y
-CONFIG_UART_SIFIVE=y
-CONFIG_UART_SIFIVE_PORT_0=y
 CONFIG_UART_CONSOLE=y
-CONFIG_PLIC=y
-CONFIG_PINMUX=y
-CONFIG_PINMUX_SIFIVE=y
 CONFIG_RISCV_MACHINE_TIMER=y
-CONFIG_GPIO=y
-CONFIG_GPIO_SIFIVE=y
 CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000

これで余計なコンフィグが原因で怒られることはないはずです。

SoC 用の Kconfig の追加

基本的に SoC の Kconfig を追加する場合、zephyr/soc/アーキテクチャ名/SoC 名/Kconfig.soc を足せば良いですが、RISC-V Privileged 系の SoC は少し様子が違い、Kconfig が 2段構成になります。

Kconfig の依存関係
# zephyr/soc/Kconfig

  source "$(SOC_DIR)/$(ARCH)/*/Kconfig.soc"


# zephyr/soc/riscv/riscv-privilege/Kconfig.soc

  source "soc/riscv/riscv-privilege/*/Kconfig.series"

ファイルを足すべき場所がわかりました。早速 Kconfig.series を足します。内容は隣にある SiFive のディレクトリ(sifive-freedom)などを参考にします。

zephyr/soc/riscv/riscv-privilege/spike/Kconfig.series

# RISCV_SPIKE SOC implementation

# SPDX-License-Identifier: Apache-2.0

config SOC_SERIES_RISCV_SPIKE
        bool "SPIKE series SOC implementation"
        depends on RISCV
        select SOC_FAMILY_RISCV_PRIVILEGE
        help
          Enable support for Spike series SOC

再度 cmake を実行すると SOC_SERIES_RISCV_SPIKE のエラーが消えるはずです。残りの SOC_RISCV_SPIKE はどこで定義すべきでしょうか?

RISC-V Privileged の Kconfig は 2つある

RISC-V Privileged や他のディレクトリを見ると気づくと思いますが、SoC の Kconfig には 2つ系列があります。

riscv-privilege/Kconfig.soc -> riscv-privilege/spike/Kconfig.series のラインと、
riscv-privilege/Kconfig -> riscv-privilege/spike/Kconfig.soc のラインです。先程、追加したのは前者です。名前が紛らわしいのは RISC-V Privileged 系列の実装の良くないところですね……。

RISC-V Privileged の Kconfig 依存関係(再整理)

# zephyr/Kconfig

  source "Kconfig.zephyr"


# zephyr/Kconfig.zephyr

  source "$(SOC_DIR)/Kconfig"    # SOC_DIR = soc


# zephyr/soc/Kconfig

  choice
  	prompt "SoC/CPU/Configuration Selection"

  source "$(SOC_DIR)/$(ARCH)/*/Kconfig.soc"    # soc/riscv/riscv-privilege/Kconfig.soc

  endchoice

  menu "Hardware Configuration"
  osource "$(SOC_DIR)/$(ARCH)/Kconfig"
  osource "$(SOC_DIR)/$(ARCH)/*/Kconfig"    # soc/riscv/riscv-privilege/Kconfig


# zephyr/soc/riscv/riscv-privilege/Kconfig.soc

  source "soc/riscv/riscv-privilege/*/Kconfig.series"


# zephyr/soc/riscv/riscv-privilege/Kconfig

  config SOC_FAMILY_RISCV_PRIVILEGE    # riscv-privilege/spike/Kconfig.series の select で有効にする
  config SOC_FAMILY
  config RISCV_HAS_PLIC

  ...

  source "soc/riscv/riscv-privilege/*/Kconfig.soc"

仕組みがわかったところで、後者の Kconfig.soc も追加しましょう。内容はやはり SiFive の Kconfig を参考にします。ありがとう SiFive さん。

zephyr/soc/riscv/riscv-privilege/spike/Kconfig.soc

# RISCV_SPIKE SOC configuration options

# SPDX-License-Identifier: Apache-2.0

choice
        prompt "Spike series SOC implementation"
        depends on SOC_SERIES_RISCV_SPIKE

config SOC_RISCV_SPIKE
        bool "Spike SOC implementation"
        select ATOMIC_OPERATIONS_C

endchoice

SOC_SERIES_RISCV_SPIKE は、先程 Kconfig.series にて定義しました。ATOMIC_OPERATIONS_C はアトミック演算を行う関数を定義するためのコンフィグです。これを指定しないと、後ほどリンクする際に atomic_cas() がないと言われます。

アトミック演算の定義箇所

//zephyr/include/sys/atomic.h

#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline bool atomic_cas(atomic_t *target, atomic_val_t old_value,
                          atomic_val_t new_value)
{
        return __atomic_compare_exchange_n(target, &old_value, new_value,
                                           0, __ATOMIC_SEQ_CST,
                                           __ATOMIC_SEQ_CST);
}
#elif defined(CONFIG_ATOMIC_OPERATIONS_C)
__syscall int atomic_cas(atomic_t *target, atomic_val_t old_value,
                         atomic_val_t new_value);

#else
extern int atomic_cas(atomic_t *target, atomic_val_t old_value,
                      atomic_val_t new_value);
#endif

これでもまだ cmake に怒られます。linker.ld がどうのこうのと言っています。パスもなにやらおかしいです。

Kconfig 追加後の cmake のエラー
CMake Error at ../../CMakeLists.txt:372 (message):
  Could not find linker script:
  'zephyr/soc/riscv//linker.ld'.
  Corrupted configuration?

この linker.ld を探しているのは cmake です。下記の部分で探しています。

cmake が linker.ld を探している箇所

# zephyr/CMakeLists.txt

...

if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT)
  set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT})
  if(NOT EXISTS ${LINKER_SCRIPT})
    set(LINKER_SCRIPT ${CONFIG_CUSTOM_LINKER_SCRIPT})
    assert_exists(CONFIG_CUSTOM_LINKER_SCRIPT)
  endif()
else()
  # Try a board specific linker file
  set(LINKER_SCRIPT ${BOARD_DIR}/linker.ld)    # ★★★これ、もしくは★★★
  if(NOT EXISTS ${LINKER_SCRIPT})
    # If not available, try an SoC specific linker file
    set(LINKER_SCRIPT ${SOC_DIR}/${ARCH}/${SOC_PATH}/linker.ld)    # ★★★これ★★★
  endif()
endif()

if(NOT EXISTS ${LINKER_SCRIPT})
  message(FATAL_ERROR "Could not find linker script: '${LINKER_SCRIPT}'. Corrupted configuration?")
endif()

デバッグメッセージ(message(SOC_PATH ${SOC_PATH}) を書き足すなど)を出して確認すると、SOC_PATH が空になっています。まだ何か足りないようですので、調べます。SOC_PATH を定義しているのは下記の部分です。

cmake が SOC_PATH を決める箇所

# zephyr/cmake/app/boilerplate.cmake

...

set(SOC_NAME   ${CONFIG_SOC})
set(SOC_SERIES ${CONFIG_SOC_SERIES})
set(SOC_FAMILY ${CONFIG_SOC_FAMILY})

if("${SOC_SERIES}" STREQUAL "")
  set(SOC_PATH ${SOC_NAME})
else()
  set(SOC_PATH ${SOC_FAMILY}/${SOC_SERIES})
endif()

CONFIG_SOC もしくは CONFIG_SOC_FAMILY と CONFIG_SOC_SERIES を定義する必要があるようです。探してみると CONFIG_SOC_FAMILY は zephyr/soc/riscv/riscv-privilege/Kconfig で定義されています。

もう一方の CONFIG_SOC_SERIES は Kconfig.defconfig.series というとても変な名前の Kconfig ファイルで定義するようです。

CONFIG_SOC_SERIES の定義箇所
$ cd zephyr/soc/riscv/riscv-privilege
$ grep -r 'config SOC_SERIES'

miv/Kconfig.defconfig.series:config SOC_SERIES
miv/Kconfig.series:config SOC_SERIES_RISCV32_MIV
sifive-freedom/Kconfig.defconfig.series:config SOC_SERIES
sifive-freedom/Kconfig.series:config SOC_SERIES_RISCV_SIFIVE_FREEDOM

この Kconfig はどこから参照されているのでしょうか?これも一応、調べておきましょう。

Kconfig.defconfig.series の依存関係

# zephyr/Kconfig

  source "Kconfig.zephyr"

# zephyr/Kconfig.zephyr

  source "$(SOC_DIR)/$(ARCH)/*/Kconfig.defconfig"    # SOC_DIR = soc, ARCH = riscv


# zephyr/soc/riscv/riscv-privilege/Kconfig.defconfig

  source "soc/riscv/riscv-privilege/*/Kconfig.defconfig.series"

Kconfig.defconfig.series も他の SoC に習って追加しましょう。Spike に PLIC は実装されていないので、RISCV_HAS_PLIC は n にしています。また Flash ROM もないので、XIP(Execution In Place)を無効にしています。

zephyr/soc/riscv/riscv-privilege/spike/Kconfig.defconfig.series

# SPDX-License-Identifier: Apache-2.0

if SOC_SERIES_RISCV_SPIKE

config SOC_SERIES
        default "spike"

config RISCV_HAS_PLIC
        default n

config NUM_IRQS
        default 16

config XIP
        default n

endif #SOC_SERIES_RISCV_SPIKE

肝心の linker.ld を追加することも忘れないようにします。これも他の SoC を見ればわかるはず。

zephyr/soc/riscv/riscv-privilege/spike/linker.ld

/*
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Linker script for the Spike series processor
 */

#include <arch/riscv/common/linker.ld>

これで Kconfig 周りが整ったはずです。

最後の一手は CMakeList.txt

これでクリアかと思いきや、まだ cmake に怒られます。もう一手だけ必要です。

cmake 最後のエラー
CMake Error at ../../soc/riscv/riscv-privilege/CMakeLists.txt:4 (add_subdirectory):
  The source directory

    /home/katsuhiro/share/projects/oss/zephyr/soc/riscv/riscv-privilege/spike

  does not contain a CMakeLists.txt file.


-- Configuring incomplete, errors occurred!

CMakeLists.txt がないと言っています。このファイルには何を書くのが正解なのか、私もイマイチ理解できないですが、他の SoC を見ると、下記の一行を書いておけば良さそうです。

zephyr/soc/riscv/riscv-privilege/spike/CMakeLists.txt

# SPDX-License-Identifier: Apache-2.0

zephyr_sources()

ここまで変更すると cmake のエラーが解消します。良く見ると何やら UART_CONSOLE がどうのこうのと文句を言っていますが、後ほど対応します。

Hoge ボード + Spike SoC で cmake 成功

$ cmake -G Ninja -DBOARD=hoge ../samples/hello_world/
-- Zephyr version: 2.1.99
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.7.6", minimum required is "3.6")
-- Selected BOARD hoge
-- Loading zephyr/boards/riscv/hoge/hoge.dts as base
hoge.dts.pre.tmp:22.17-25.5: Warning (simple_bus_reg): /soc/serial: missing or empty reg/ranges property
  also defined at hoge.dts.pre.tmp:37.8-39.3
Devicetree header saved to 'zephyr/build/zephyr/include/generated/devicetree_unfixed.h'
Parsing zephyr/Kconfig
Loaded configuration 'zephyr/boards/riscv/hoge/hoge_defconfig'
Merged configuration 'zephyr/samples/hello_world/prj.conf'
Configuration saved to 'zephyr/build/zephyr/.config'
Kconfig header saved to 'zephyr/build/zephyr/include/generated/autoconf.h'

warning: UART_CONSOLE (defined at drivers/console/Kconfig:47) was assigned the value 'y' but got the
value 'n'. Check these unsatisfied dependencies: SERIAL_HAS_DRIVER (=n). See
http://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_UART_CONSOLE.html and/or look up
UART_CONSOLE in the menuconfig/guiconfig interface. The Application Development Primer, Setting
Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful
too.

-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- The ASM compiler identification is GNU
-- Found assembler: /home/katsuhiro/x-tools/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-gcc
-- Cache files will be written to: /home/katsuhiro/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: zephyr/build

この後は ninja のビルドエラーがたくさん出るので、1つずつ解消していくことになります。続きはまた次回です。

[編集者: すずき]
[更新: 2020年 2月 16日 18:22]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

Zephyr OS で遊ぼう その 4 - 独自の SoC 定義

Hoge ボードの定義を一通り実装しました。Hoge ボードの SoC は qemu_riscv32 と同じ SiFive FE310 にしたことを覚えているでしょうか?Zephyr の移植に興味のある方からすると「ボード名を変えただけで、qemu_riscv32 のコピーでは?」と感じるはずです。そんな悲しみの声にお答えすべく、次は SoC の変更を行います。

今回、ターゲットとする SoC は QEMU の Spike モードです。このモードは、特別なハードウェアが必要なく手軽、偶然にも現状の Zephyr が対応していない、簡単なドライバの実装が 1つだけ必要、など学習にピッタリです。

Spike はシミュレータのみで、物理的に存在する SoC ではありません。ですが名前がないと説明しづらいので、以降の説明では Spike SoC と呼びます。

RISC-V SoC ディレクトリの構造と Spike SoC の定義場所

将来複雑になるかもしれませんが、今は簡単な構造です。zephyr/soc/riscv の下に SoC が定義されており、litex-vexriscv(LiteX VexRiscv), openisa_rv32m1(OpenISA RV32M1), riscv-privilege(RISC-V Priviledged Architecture 対応 SoC)の 3つのディレクトリが存在しています。このうち riscv-privilege は、さらに内部にいくつかの SoC の定義を抱えています。

Spike は RISC-V Priviledged に対応しているので、今回は riscv-privilege シリーズの 1つとして、新たな SoC を定義すると良さそうです。

ボードの定義を改造

Hoge ボードの定義を見直してみると、Kconfig.board に "depends on SOC_RISCV_SIFIVE_FREEDOM" の記述があり、hoge.dts に #include <riscv32-fe310.dtsi> の記述があります。とりあえずこれを下記のように変更します。

Kconfig.board と hoge.dts の変更点

diff --git a/boards/riscv/hoge/Kconfig.board b/boards/riscv/hoge/Kconfig.board
index 7ece0d6dee..c90614a391 100644
--- a/boards/riscv/hoge/Kconfig.board
+++ b/boards/riscv/hoge/Kconfig.board
@@ -2,4 +2,4 @@

 config BOARD_HOGE
        bool "Hoge target"
-       depends on SOC_RISCV_SIFIVE_FREEDOM
+       depends on SOC_RISCV_SPIKE


diff --git a/boards/riscv/hoge/hoge.dts b/boards/riscv/hoge/hoge.dts
index 21678f49ea..ee0c6589c4 100644
--- a/boards/riscv/hoge/hoge.dts
+++ b/boards/riscv/hoge/hoge.dts
@@ -2,7 +2,7 @@

 /dts-v1/;

-#include <riscv32-fe310.dtsi>
+#include <riscv32-spike.dtsi>

 / {
        model = "Hoge";

この状態で cmake をやり直します。念のため build ディレクトリのファイルを全て削除してから、実行したほうが良いでしょう。

Kconfig.board と hoge.dts を変更して cmake
$ cmake -G Ninja -DBOARD=hoge ../samples/hello_world/

-- Zephyr version: 2.1.99
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.7.6", minimum required is "3.6")
-- Selected BOARD hoge
-- Loading zephyr/boards/riscv/hoge/hoge.dts as base
In file included from <command-line>:
zephyr/boards/riscv/hoge/hoge.dts:5:10: fatal error: riscv32-spike.dtsi: No such file or directory
 #include <riscv32-spike.dtsi>
          ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
CMake Error at zephyr/cmake/dts.cmake:140 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  zephyr/cmake/app/boilerplate.cmake:460 (include)
  CMakeLists.txt:5 (include)


-- Configuring incomplete, errors occurred!

エラーをみるに riscv32-spike.dtsi がないと言って怒られているようですから、追加しましょう。

SoC のデバイスツリー

Zephyr のデバイスツリーは zephyr/dts 以下にあります。今回は RISC-V 一派の SoC を追加しますから、zephyr/dts/riscv の下に riscv32-spike.dtsi を作りましょう。

riscv32-spike.dtsi

/* SPDX-License-Identifier: Apache-2.0 */

/ {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "spike-dev";
        model = "spike";
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "spike-soc", "simple-bus";
                ranges;

                clint: clint@2000000 {
                        compatible = "riscv,clint0";
                        reg = <0x02000000 0x10000>;
                        reg-names = "control";
                };

                mem: mem@80000000 {
                        compatible = "spike,mem";
                        reg = <0x80000000 0x4000>;
                        reg-names = "mem";
                };

                uart0: serial {
                        compatible = "spike,uart-spike";
                        label = "uart_0";
                };
        };
};

最低限のデバイスだけ定義しています。

clint
割り込みコントローラ(Core Local Interruptor)です。タイマーのレジスタ(mtime, mtimecmp)を持っているコアです。
mem
SRAM 領域です。QEMU は数百 MB くらいメモリ領域があった気がしますが、そんなに要らないので 16KB にしています。
uart0
シリアルデバイスです。実はこの名前は適切ではありません。Spike は特殊なゲスト、ホスト間の通信により文字出力を実現していて、UART ハードウェアを模している訳ではないからです。レジスタ領域の定義が不要なのも、ハードウェアアクセスではないからです。

このファイルを加えてもまだ cmake に怒られます。Spike SoC 用のデバイスツリーに出てこないノード(gpio, spi など)を参照している箇所があるためです。ボード側の定義からばっさり削除します。

hoge.dts のさらなる変更

diff --git a/boards/riscv/hoge/hoge.dts b/boards/riscv/hoge/hoge.dts
index 21678f49ea..e572d5a769 100644
--- a/boards/riscv/hoge/hoge.dts
+++ b/boards/riscv/hoge/hoge.dts
@@ -11,34 +11,10 @@
        chosen {
                zephyr,console = &uart0;
                zephyr,shell-uart = &uart0;
-               zephyr,sram = &dtim;
-               zephyr,flash = &flash0;
+               zephyr,sram = &mem;
        };
 };
 
-&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>;
-       };
 };

これでもまだ cmake は通過できません。長くなってきましたので、続きはまた今度。

[編集者: すずき]
[更新: 2020年 2月 16日 18:22]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2020年 2月 14日 -
      2020年 2月 5日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 2/22 03:01

カレンダー

<2020>
<<<02>>>
------1
2345678
9101112131415
16171819202122
23242526272829

最近のコメント 5件

  • link 19年09月01日
    すずき 「私も正直びっくりです。間違って違う製品を...」
    (更新:09/04 23:39)
  • link 19年09月01日
    hdk 「車向けの製品の中でも、車載コンピューター...」
    (更新:09/02 23:20)
  • link 19年07月18日
    hdk 「あっ、AAMはマニュアルのオペレーション...」
    (更新:07/25 00:02)
  • link 19年07月18日
    すずき 「AAM(ASCII Adjust AX ...」
    (更新:07/24 22:22)
  • link 19年07月18日
    hdk 「加算減算は符号のありなしどちらも命令が同...」
    (更新:07/24 07:25)

最近の記事 20件

link もっとみる
  • link 20年02月21日
    すずき 「[Zephyr と RISC-V とマルチプロセッサ] 昨日(20...」
    (更新:02/22 03:01)
  • link 20年02月20日
    すずき 「[Zephyr の 16550 シリアルドライバ] 先日は Zep...」
    (更新:02/22 02:55)
  • link 19年03月28日
    すずき 「[マンガ紹介] お気に入りのマンガ紹介シリーズ。[マンガ紹介 その ] ...」
    (更新:02/21 20:37)
  • link 18年11月13日
    すずき 「[お気に入りのマンガ] お気に入りのマンガ紹介シリーズ。Kindl...」
    (更新:02/21 20:36)
  • link 19年02月03日
    すずき 「[続編が楽しみなマンガ 10作品] お気に入りのマンガ紹介シリーズ...」
    (更新:02/21 20:36)
  • link 20年02月09日
    すずき 「[Zephyr OS で遊ぼう その 8 - 独自のシリアルド] ...」
    (更新:02/19 23:52)
  • link 20年02月04日
    すずき 「[Zephyr OS で遊ぼう その 3 - ボードのデフォル] ...」
    (更新:02/19 23:38)
  • link 20年02月19日
    すずき 「[Zephyr のブート処理 - ドライバの初期化情報とリンカ] ...」
    (更新:02/19 22:11)
  • link 20年02月18日
    すずき 「[Zephyr のブート処理 - ドライバの初期化情報の謎] Ze...」
    (更新:02/19 22:10)
  • link 20年02月17日
    すずき 「[Zephyr のブート処理 - ドライバの初期化まで] Zeph...」
    (更新:02/19 22:10)
  • link 20年02月16日
    すずき 「[Zephyr のブート処理 - C 言語と出会うまで] Zeph...」
    (更新:02/19 22:10)
  • link 20年02月07日
    すずき 「[Zephyr OS で遊ぼう その 6 - 独自の SoC ] ...」
    (更新:02/19 03:37)
  • link 20年02月08日
    すずき 「[Zephyr OS で遊ぼう その 7 - 独自のシリアルド] ...」
    (更新:02/16 18:23)
  • link 20年02月06日
    すずき 「[Zephyr OS で遊ぼう その 5 - 独自の SoC ] ...」
    (更新:02/16 18:22)
  • link 20年02月05日
    すずき 「[Zephyr OS で遊ぼう その 4 - 独自の SoC ] ...」
    (更新:02/16 18:22)
  • link 20年02月03日
    すずき 「[Zephyr OS で遊ぼう その 2 - ボードを追加して] ...」
    (更新:02/16 18:22)
  • link 20年02月02日
    すずき 「[Zephyr OS で遊ぼう その 1 - ボードを追加して] ...」
    (更新:02/16 18:21)
  • link 20年02月01日
    すずき 「[Zephyr のエントリアドレス] Hello! Zephyr ...」
    (更新:02/16 18:21)
  • link 20年01月31日
    すずき 「[Hello! Zephyr OS!! (RISC-V 32b] ...」
    (更新:02/16 18:21)
  • link 20年02月10日
    すずき 「[Zephyr OS で遊ぼう その 9 - Zephyr 2] ...」
    (更新:02/16 18:21)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報