Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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/ より

Slide 4

Slide 4 text

これまでのあらすじ • 昨年の技術書典オンラインに出した 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 • 現在レビュー中。

Slide 5

Slide 5 text

おたより紹介 武漢にお住まいの 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

Slide 6

Slide 6 text

おたより紹介 ソース見ていただいた、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.

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

起動処理 • おおむね、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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

ありがとうございます