Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Longan NanoでZephyrRTOSを動かしてみる

Longan NanoでZephyrRTOSを動かしてみる

Longan NanoでZephyrRTOSを動かしてみる

soburi

May 26, 2021
Tweet

More Decks by soburi

Other Decks in Technology

Transcript

  1. Longan Nanoで
    ZephyrRTOSを
    動かしてみる
    常田 裕士
    あすもの研ONLINEミートアップ 2021年5月度

    View Slide

  2. ZephyrRTOS
    • LinuxFoundationがやっている組み込みOS
    • もともとはWindRiverが作った。割と素性は良い。
    • LinuxからKconfigとDeviceTreeの仕組みを借りてきている。
    これで、多種多様なデバイスをサポートしてもシステムとして破綻なく管理できている。
    • POSIX互換レイヤーもある。
    • 「組み込み用のLinux」と言っても当たらずとも遠からじ、みたいな雰囲気。
    • 最近はNordicSemiが自社の開発環境に組み込んで、
    がっつり使い倒している。
    画像は
    https://ja.wikipedia.org/wiki/Zephy
    r_(オペレーティングシステム) より

    View Slide

  3. Longan Nano
    • 去年ぐらいに秋葉原の電子工作界隈でちょっと流行ったマイコン
    • 小さなカラーLCDが付いて800円。爆安。
    • 中華RISC-V GigaDevice GD32V搭載
    • もともとGigaDeviceにGD32というARMのマイコンのラインがあった。
    GD32はS〇M32とピンコンパチのマイコン
    (世界で一番売れているARMチップらしい、STM32F103のコンパチ)
    ピンだけでなくて、レジスタもほぼコンパチ。
    ということは〇TM32のファームがほぼそのまま動く?!
    → それはパクリというのでは?!
    • コアがRISCVになって、パチモノというよりは、ST〇32とピンコンパチ、
    ほぼペリフェラルも互換のマイコンぐらいのおとなしい感じになったw
    画像はhttps://www.switch-
    science.com/catalog/5946/ より

    View Slide

  4. これまでのあらすじ
    • 昨年の技術書典オンラインに出した
    https://soburi.github.io/zephyr_porting_gd32v/
    が今月頭、フランス語に訳されていた。リンガフランカ感ある。
    • 内容はLongan NanoでZephyrRTOSを動かすというテーマ。
    つまり、大枠では去年完成していた。
    • ところが、メーカー含めてLongan NanoのZephyrRTOS対応はいまだに実施されず。
    (誰かやるだろう、と思ってると誰もやらない、といういつもの話)
    • さすがに読者いるのでほっとけない、ということで、upstreamにPRを投げた。
    https://github.com/zephyrproject-rtos/zephyr/pull/34970#issuecomment-
    843705198
    • 現在レビュー中。

    View Slide

  5. おたより紹介
    武漢にお住まいの HUAQI FANG さん
    GD32VのCPUコア設計のNuclei社の人
    Hi @soburi , very happy about you are PR to Zephyr with Nuclei SDK project, our team
    in Nuclei are also planning to provide zephyr integeration in future, using the Nuclei SDK
    project is a good choice.
    I also see you have made some changes to Nuclei SDK, any extra requrements to be
    maded to support Zephyr, maybe I can provide some help to see whether the changes
    can be placed in Nuclei SDK project directly.
    Thanks
    Huaqi

    View Slide

  6. おたより紹介
    ソース見ていただいた、GERSON FERNANDO BUDKE さん
    GD32のzephyr対応をやろうとしていたみたい。
    Hello soburi,
    I look at your implementation. It is very nice all the work that you made.
    I added part of your work to my branch, just to share with you my structure.
    https://github.com/nandojve/zephyr/tree/gigadevice
    I noted that there is a project dedicated to NMSIS at https://github.com/Nuclei-
    Software/NMSIS I think it will be better if we can use that directly, somehow. Zephyr
    folks can suggest best way.
    The #34970 is too dense. People will ask to you split. In the past, I already try add
    some work like you.
    https://github.com/zephyrproject-rtos/zephyr/pull/34970
    The first thing is, reorganize the #34970 on a minimal implementation, like on my
    branch.
    You only need a hello world working. No interrupt driver, gpio, pinctrl etc. Only the
    minimal serial driver.
    I made (on my branch) a directory soc/riscv/gigadevice. Probably, the correct one is
    soc/riscv/nuclei/gigadevice.
    People from Zephyr will orientate the best place to put the gigadevice directory.
    On your PR, you are mixing some code. Try clean around soc.
    The ECLIB driver is not, in fact, necessary to introduce the nuclei. You can simple add
    that few lines at soc.c.
    Later a unique PR can be created.
    Drop clock, gpio and interrupt_controller drivers at first. each one need a separated PR.
    Use a minimal serial driver like the one on my branch.
    At logan board, add only the minimal necessary features to run a hello world.
    Above are some tips. I hope you understand I only want contribute a little of my
    experience with Zephyr and I rely want to see this boards soon on Zephyr.
    BTW, until next design cycle, people from Zephyr probably want
    comment anything. They are so busy preparing the 2.6 release.

    View Slide

  7. ZephyrへのCPUアーキ追加
    • Zephyrのソースの構成は→のような感じ。
    • ソースの共通化のグループで
    arch→soc→boards
    の構造がある。矢印の順でバリエーションが多い。
    • archはx86, arm, riscvなどの区分け。
    • socはarmのstm32, nrf5x など。要はチップのレイヤー。
    • boardsはsocを積んだボードに生えているIOのピンなどを定義する。通常はだ
    いたいここをいじるぐらい。
    • socに追加するのはかなりのレアケースになる。
    (新規にCPUの製造するときになる。今回はここ。しかも非関係者がやるw)
    • archはもっとレア。命令セットを作らないと追加できない。
    Zephyr
    arch
    boards
    soc
    driver
    kernel
    dts
    subsys

    View Slide

  8. ARCHでやってること
    • 主に基本的な割り込みの定義と処理
    • 割り込みに関連して、コンテクストスイッチの処理もここで実装
    • 起動の処理、CPU例外の処理、アイドル処理
    • 実はそんなにコード量は多くない。
    • アセンブラソースが多い箇所。
    .cのファイルでもC言語と思うな、あれはただのアセンブラマクロだw

    View Slide

  9. SOCでやってること
    • 初期化処理
    • ここで起動処理をやる場合も。
    • archよりはかなり少なくなるが、まだ、アセンブラソースは残る。
    • リンカの設定
    • CPU archごとに多少文化は違う。
    ものによってはほとんど中身はない。

    View Slide

  10. BOARDSでやること
    • dtsを作成して、ボードに存在するピンを見せる
    • ピンの見えないような共通の挙動は

    View Slide

  11. LONGAN NANO(GD32V, NUCLEI CORE)対応
    でやったこと
    • 初期化コードの移植
    • MCAUSEの例外を正しくハンドリングする
    • Zephyr共通の割り込みハンドラを割り込みベクタに設定する
    • タイマーの実装の修正
    (突き詰めると、起動して、タイマー割り込みが動いて、コンテクストスイッチができればOSになる。)
    • ドライバの作成

    View Slide

  12. 起動処理
    • おおむね、SDKのサンプルの定義を持ってくることになる。
    (メーカー提供のサンプルが多くの場合で最も信頼できるコードになる。
    本物のローレベルはデバッグするにも覚悟が必要である。)
    • サンプルのブートコードをほぼそのまま踏襲して、既存のRISC-Vの共通処理の__initializeに接続。
    BSSとかスタックとかはこちらでやってくれる。
    • このコア独自の割り込みコントローラのレジスタに共通の割り込みハンドラの__irq_wrapperを設定する
    • https://github.com/soburi/zephyr/blob/add_basic_support_gd32v/soc/riscv/riscv-
    privilege/gigadevice-gd32v/entry.S

    View Slide

  13. 初期設定しているレジスタ
    • MSTATUS 割り込みの有効化
    • MTVT 割り込みベクタ
    • MTVT2 割り込みベクタ(ベンダ拡張)
    • MTVEC 割り込みハンドラのアドレス

    View Slide

  14. MCAUSEの処理
    • RISC-Vの標準的な定義だと割り込み定義では
    NMIの発生理由を示すMCAUSEは
    全ビット使われるのだが、
    Nucleiのコアだと11ビット目までしか
    MCAUSE本来の役割として使用して、
    上位ビットは別の用途で使われている。
    • MCAUSEのマスク値を変更できるようにソース修正
    Field Bit Description
    INTERRUPT 31
    Current trap type:
    •0: Exception or
    NMI
    •1: Interrupt
    MINHV 30
    Indicate processer
    is reading
    interrupt vector
    table
    MPP 29:28
    privilege mode
    before interrupt
    MPIE 27
    Interrupt enable
    before interrupt
    Reserved 26:24 Reserved 0
    MPIL 23:16
    Previous interrupt
    level
    Reserved 15:12 Reserved 0
    EXCCODE 11:0
    Exception/Interrup
    t Encoding

    View Slide

  15. MACHINE TIMERの設定
    • RISC-VではCPUの入力クロックを使ったタイマー(Machine Timer, mtimer)を持っている。
    • ところが、GD32Vでは、CPUクロックの1/4のクロックがこのタイマーに入力されている。
    • 動くには動くが、実時間動作が4倍速になってしまうので、帳尻を合わせる。
    • 色々なものがCPUクロックを基準に処理を記述しているので、タイマーの入口で1/4して出口で4倍にして、
    CPUクロックとの換算値を作る
    • タイマが動くとだいたいOSは動作する
    • https://github.com/soburi/zephyr/commit/b670c1712d338fadea534c226f097bc09ccc
    8fab

    View Slide

  16. CLOCK DIAGRAM
    • どうやら、クロックの系統が分かれているらしい。

    View Slide

  17. ドライバの作成
    • GD32Vは、ST〇32と非常によく似た構成のペリフェラルを持っている。
    • あくまで互換。独自実装のもの。
    • ベンダー提供のドライバもシンボル名は違うが、よく似た構造のAPIになっている。
    • つまり、Zephyr側の実装も、S〇M32のソースをちょろっと書き換えてあげればOK!
    • 例えば、フラグ名 RXNE (RX Not Empty) が RBNE (Receive Buffer Not Empty)とか…

    View Slide

  18. ありがとうございます

    View Slide