2026年2月5日木曜日

μiTRONプログラマーがZephyrに挑戦! その7

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


μITRONとZephyrの比較

TOPPERS/ASPのサンプルプロジェクトをZephyrに移植し、動かして見てみることで両者を比較し、Zephyrを学ぼう!という今回の趣旨、ここまでお付き合いくださいまして誠にありがとうございました。

また、この数ヶ月、本業で初めてZephyrを使用した製品の開発を完了させることができました。

今回は、その過程において私のようなμITRONを使用しているプログラマーの視点から、Zephyrを使う上で感じた個人的な違和感をメモに残しておきたいと思います。

例えば、μITRONのプログラムをZephyrに移植する際に障害となった問題(ていうかハマった部分)の回避策も一部紹介させていただきます。

理由は後述しますが、今後自分が関わるプロジェクトにおいて、もう二度とZephyrを使うことはないでしょう。

しかし、万が一、μiTRONからZephyrに戻る様な状況(考えたくはないけど、不具合修正とか?)になった時のための備忘録です。

Zephyr vs μITRON


スリープのシステムコールの違い

TOPPERS/ASPのサンプルプロジェクトを移植する中で、一番最初に違和感を感じたのは、スリープのシステムコールです。

要するに、一定期間タスク/スレッドを待ち状態(スリープ)にし、自分よりも優先度の低いものも含め、他のタスク/スレッドへ処理を一時的に明け渡すという最もシンプルな仕組みです。

μITRONでは「tslp_tsk(<待ち時間>)」、一方、Zephyrで同じような働きをするシステムコールは「k_sleep(<待ち時間>)」です。

Zephyrの「k_sleep()」には、μITRONの「tslp_tsk()」では備わっていた以下3つの重要な機能がありません。


1.Zephyrの「k_sleep()」は、その起床原因がタイムアウトなのか、ウェイクアップ要求によるものかの区別がない

μITRONの「tslp_tsk()」は、以下の3つの起床原因を返します。


◯他のタスクや割り込みハンドラからの起床命令による起床(「E_OK」)

◯タイムアウトによる起床(「E_TMOUT」)

◯他のタスクや割り込みハンドラからの待ち状態(スリープ)強制解除による起床(「E_RLWAI」)


一度スリープに入ったタスクは、指定した時間が経過(タイムアウト)するか、または他のタスクや割り込みハンドラから叩き起こされる(ウェイクアップ)かによって起床します。

上記の通り、前者の場合は「E_TMOUT」、後者の場合は「E_OK」が関数の戻り値として返るため、起床原因が判別できます。

E_RLWAI」については、後述します。

一方、Zephyrの「k_wakeup()」の場合は、タイムアウトだろうが、他者からのウェイクアップだろうが、戻り値としては「0」しか返らず、起床原因が判りません。

これが困るのは、以下のような処理のケースです。

デバイスからの割り込みをタスクで処理するためのμITRONのデバイスドライバか何かの一部だと思ってください。

  1. /*
  2.  * メインタスク(MAIN_TASK)
  3.  */
  4. void main_task(intptr_t exinf)
  5. {
  6.     ER ercd;
  7.     
  8.     while (1) {
  9.         /*
  10.          * 5秒間割り込み待ち
  11.          */
  12.         ercd = tslp_tsk(5000);
  13.         if (ercd == E_TMOUT) {
  14.             /*
  15.              * 以降タイムアウトの場合のエラー処理
  16.              */
  17.             ...
  18.             continue;
  19.         }
  20.         /*
  21.          * 時間以内に割り込みが発生!
  22.          * 以降割り込みに応じた処理
  23.          */
  24.         ...
  25.     }
  26. }
  27. /*
  28.  * 割り込みハンドラ
  29.  */
  30. void int_handler(void)
  31. {
  32.     /*
  33.      * 割り込み発生!
  34.      * 割り込みハンドラからタスクへ処理を渡す
  35.      */
  36.     iwup_tsk(MAIN_TASK);
  37. }


タスクは開始されて間もなく「tslp_tsk()」で5秒間割り込みハンドラからの起床命令を待っています。

一方、割り込みハンドラには、タスクをウェイクアップさせるための「iwup_tsk(<タスクID>)」が配置されています。

割り込みハンドラに長々と処理を記述するのは、リアルタイム性を損なうのでご法度です。

ですので、これは何らか割り込みが発生した場合、割り込みハンドラからタスクへ処理が渡されるという非常にありがちな処理です。

前述の通り、Zephyrの場合は、ウェイクアップの原因が正常な割り込み処理の結果なのか?それとも、タイムアウト…すなわち、異常なのか?の区別が付かないことが問題です。

この問題の回避策は、後ほど提示します。


2.Zephyrの「k_sleep()」は、待ち状態期間中の「k_wakeup()」のキューイングを行わない

あるタスク(スレッド)に対し、それがスリープ状態ではない時に起床命令を実行した場合の違いです。

たとえは、以下は普通のμITRONの場合です。

STM32 Nucleo-144( NUCLEO-F207ZG)という評価ボードで動いています。

こもターゲットをパソコンに接続しTeraTermで見ている状態です。

TeraTerm - 1


ここで、以下の操作を行います。

すでに今起床している(スリープ状態ではない)「task1」に対して起床命令を発行します。

これには、ターミナルに対し「1」、「w」と順に入力します。

TeraTerm - 2


この後、スリープ命令を「s」で発行すると、以下のように「task1」はスリープになりません。

もし「task1」がスリープに入ったのなら「task2」に処理が切り替わるはずです。

でも、引き続き「task1」が続行していることが判ります。

TeraTerm - 3


もう一度、スリープ命令を「s」で1回発行すると、ようやく「task1」はスリープし、代わりに「task2」に処理が移ります。

TeraTerm - 4


このように、μITRONにおいては、そのタスクがスリープ状態ではない時でも自分に対して発行された起床命令を覚えていて(キューイング)、その後のスリープ命令を無視します。

これを「タスク起動要求キューイング」と呼んだりします。

キューイングの数はμITRONの実装によって異なりますが、TOPPERS/ASPの場合は通常1回です。


一方のZephyrのスリープ/起床命令には、この仕組みがありません。

以下は今回の「zephyr-sample」の場合です。

ターゲットをパソコンに接続しTeraTermで見てみましょう。

TeraTerm - 5


今起床している(スリープ状態ではない)「thread1」に対して起床命令を発行します。

これには、ターミナルに対し「1」、「w」と入力します。

TeraTerm - 6


この後、スリープ命令を「s」で1回発行すると…

TeraTerm - 7


…このように、即座に「thread2」に処理が移ります。

つまり、スリープ状態でなかった時に発行された起床命令はガン無視です。

このことは、μITRONからZephyrへソフトウェアを移植する際に非常に発見しづらいバグを生む可能性があります。

タスク起動要求キューイングの目的は、起床命令を取りこぼさないことです。

前述したようなデバイスドライバの処理などにおいて、割り込み割り込みハンドラからの起床命令を取りこぼすことは致命的です。

割り込みハンドラからの起床命令が発行された時点で、それを待つスレッドが必ずしもスリープ状態であるとは限りません。

割り込み頻度が高いデバイスであれば尚更です。

特に、そのデバイスドライバのソースコードが十分に検証されたμITRON用のものであり、それをZephyrに移植しようとした場合、これを知らないと「来るはずの割り込みが来ない!!」と言って、大いに焦ることになります。

…はい、私はその罠に見事にかかりました!

かなり長時間にわたり悩み続けましたよ…。

この問題も、どうやって回避したのかを後ほど提示します。


3.Zephyrの「k_sleep()」は、起床原因として「待ち状態の強制解除」がない

これは、前の2つに比べて重要性はあまり高くないものの、μITRONでは使っている人が多い機能だと思います。

おさらいですが、μITRONの「tslp_tsk()」は、以下の3つの起床原因を返します。


◯他のタスクや割り込みハンドラからの起床命令による起床(「E_OK」)

◯タイムアウトによる起床(「E_TMOUT」)

◯他のタスクや割り込みハンドラからの待ち状態(スリープ)強制解除による起床(「E_RLWAI」)


3つ目の「待ち状態(スリープ)強制解除」の説明です。

待ち状態(スリープ)強制解除は、μITRONでは「(i)wup_tsk(<タスクID>)」の代わりに「(i)rel_wai(<タスクID>)」をコールすることにより発行できます。

共にスリープしているタスクを起床させる機能を持つシステムコールですが、「(i)wup_tsk()」と「(i)rel_wai()」では何が違うのでしょう?

トロンフォーラムの配布する「µITRON4.0仕様」には、これについては以下のような違いが説明されています。

  • rel_waiとwup_tskには次のような違いがある。

  • 1. wup_tskは起床待ち状態からのみ待ち解除するが、rel_waiは任意要因による待ち状態から待ち解除する。

  • 2. 起床待ち状態になっていたタスクから見ると、wup_tskによる待ち解除は正常終了(E_OK)であるのに対して、rel_waiによる強制的な待ち解除はエラー(E_RLWAI)である。

  • 3. wup_tskの場合は、対象タスクが起床待ち状態でない場合には、要求がキューイングされる。それに対してrel_waiの場合は、対象タスクが待ち状態でない場合にはE_OBJエラーとなる。

μITRON4.0仕様 - WG024-S001-04.03.03 - P.124「rel_wai/irel_wai 待ち状態の強制解除」より抜粋


1番目の「任意要因による待ち状態」とは、スリープ=起床待ち以外の待ち状態のことです。

起床待ちは「slp_tsk()」や「tslp_tsk()」でタスクが「待ち」に入った状態です。

それ以外の「待ち」とは、セマフォの資源待ちシステムコールである「wai_sem(<セマフォID>)」やイベント待ちシステムコール「wai_flg(フラグID)」などにより、それぞれの=任意の要因でタスクが「待ち」に入った状態です。

つまり「wup_tsk()」は起床待ち=スリープだけを解除するけれども、一方「rel_wai()」は、それ以外の全ての待ち状態を強制的に解除します…と言っています。

2番目は「slp_tsk()」や「tslp_tsk()」で入った起床待ち=スリープ状態が待ち状態解除された後、これらのシステムコールが返り値を返しますが、その要因が「wup_tsk()」と「rel_wai()」の場合で異なりますよ…と言っています。

「wup_tsk()」の場合は「E_OK」で正常終了、一方「rel_wai()」の場合は「E_RLWAI」がエラーとして返ることを説明しています。

3番目のキューイングに関しては、既に前述の通りです。

「rel_wai()」は、タスク起動要求キューイングをされません。

つまり、該当のタスクが「待ち」状態でない時点でコールしてもキューイングはされず、「E_OBJ」エラーが返ることを説明しています。


一方のZephyrでは、この「待ち状態(スリープ)強制解除」に類するシステムコールが見当たりません。

μITRONの待ち状態(スリープ)強制解除は、意図しない待ち解除が発生するため、強力ですが危険です。

上手く使えばデッドロック防止やエラー処理などにおいて便利な場合がありますが、そもそも、そのような設計をするべきではない…というZephyrの設計思想なのでしょう。

確かにその通りですが、キューイングの有り無しは別として、起床原因の切り分けをするために便利なので(「E_OK」なのか?「E_RLWAI」なのか?)、よく使っているμITRONプログラマーもいるかもしれません。

私は、結構気軽に使っちゃってます。

μITRONのプログラムをZephyrに移植する際に、もし元ソースで「rel_wai()」が使われていたり、スリープが「E_RLWAI」で待っているような処理を見かけた場合、残念ながらこの問題に対するスマートな解決策はありません。

今回の「zephyr-sample」では、起床命令発行時にグローバル変数を使用して起床原因を設定し、起床した直後のスレッドでそれを判断するという、スマートじゃない方法で回避してます…。

すんません。


さて、μITRONの「tslp_tsk()」が持っているのに、Zephyrの「k_sleep()」にはない3つの機能を紹介させていただきました。

3つ目の待ち状態(スリープ)強制解除に関しては、今のところ良い回避策は思い付きませんが、1つ目の起床原因の区別と、2つ目のキューイングに関しては回避策があります。

どうすれば良いか?ですが…。

結論を言ってしまえば、その回避策とはスリープをセマフォに置き換えることです。

今回の「zephyr-sample」では「k_sleep()」で起床待ち状態に入ったタスクを「k_wakeup()」で起床させています。

それを「k_sem_take()」でセマフォ資源待ち状態に入ったタスクを「k_sem_give()」で起床(正しくはセマフォ資源を返す)させるようにします。

具体的に「zephyr-sample」を改造してみましょう。


…というところで一旦切りましょう。

このスリープの問題、開発していた時に最後までハマった部分なので、詳細に書いておきたいと思いました。

よくよく調べれば簡単な話だったんですけどね。


<続く>

2025年12月30日火曜日

TOPPERS/ASP - PIC24F版 その3

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


開発環境の構築(Cygwin編)

続きまして「Cygwin」のインストールを行います。

今回は開発環境にナウい「Visual Studio Code」を使うと言いましたが、TOPPERS/ASPを使用するにあたってはどうしてもこの「Cygwin」が必要になります。

「Cygwin」の中の「make」や「perl」といったツールを使いたいからです。

実作業は、このページ(TOPPERS/ASPのビルドからデバッグまで~Cygwinの導入)を参考にしてください。


「Cygwin」がインストールできたら、ここまでの作業が上手くいっているかどうか確認しておきましょう。

次のページ(TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトのビルド)を参照してください。

ただし、今回使用するソースコードはこのページの冒頭の「NUCLEO-F401RE STM32 Nucleo-64」開発ボード用のTOPPERS/ASPカーネル簡易パッケージではなく、「Explorer 16/32 Deveopment Kit」用のものを使います。

ソースコードのダウンロードはこちらからどうぞ。

また、「Github」を使いたい方は以下のコマンドでソースコードのクローンを行います。


$ git clone https://github.com/RyutaroMorita/asp_pic24f_gcc.git

Cygwinターミナル - 1


ダウンロードとGithub、いずれの場合も「asp_pic24f_gcc」というディレクトリの名前を「asp_1.9.2」などと改名すると、上記のページと同じ状況になります。

また、今回は「OBJ」ディレクトリを作成する必要はありません。

これは既に用意されていますので、そのまま「OBJ」ディレクトリに移動し「make~」コマンドを実行してください。


<補足>

「make depend」の実行時に以下のようなエラーが出ることがあります。

Cygwinターミナル - 2


これは、「extract24.exe」というユーティリティの実行権限がないためプログラムが実行できないという意味です。

このユーティリティは「make depend」を実行する過程で呼ばれます。

これを解決するには、以下のコマンドでこのユーティリティに実行権限を与えます。

以下のコマンドを実行します。


$ chmod 755 ../arch/pic24f_gcc/utils/extract24.exe


じゃあ、この「extract24.exe」って何なの?…ということですが、これは私の自作のユーティリティです。

PIC24FマイコンのバイナリをTOPPERS/ASPのコンフィギュレーターに通すときに絶対に必要だったもので、これはPIC24のアーキテクチャに起因し…と、説明が長くなりそうなので、機会があれば「まとめ」の記事にでも説明したいと思います。


開発環境の構築(Visual Studio Code編)

お次は「Visual Studio Code」のインストールを行います。

すでに統合開発環境(IDE)として、前回「MPLAB X IDE」をインストールしました。

もちろん、これを使って開発を進めても問題ありません。

しかしながら、実際にコードを書いてみると判りますが「Visual Studio Code」は軽量で非常に優秀なエディターです。

強力な検索機能や、ハイライト表示、コード補完機能(構造体変数に「.」と打つと候補のリストビューが出てきたりするヤツね!)など、生産性は大きく向上すると思います。

こういったものは個人の好み(ていうか信仰)がありますので、お好みのエディターをご使用ください。

とりま、この記事ではエディターとして「Visual Studio Code」、デバッガモニタとして「MPLAB X IDE」を使用するものとして説明します。

さて、その「Visual Studio Code」のインストール方法ですが、このページ(μiTRONプログラマーがZephyrに挑戦! その3)を参考にしてください。

今回のPIC24マイコンとは全く違う記事ですが、インストーラーのダウンロードから日本語設定まで説明してます。


Visual Studio Codeの使い方

さて、インストールして日本語化まで行った「Visual Studio Code」、開いている方は、一旦閉じちゃってください。

そして、ダウンロードして一度ビルドまで通した「Explorer 16/32 Development Kit」用のTOPPERS/ASPのソースディレクトリを見てみましょう。

名前は「asp_pic24f_gcc」(改名した場合は「asp_1.9.2」ですね)というディレクトリでしたね。

記事通りであれば以下のパスです。


C:\cygwin64\home\<ユーザー名>\asp_pic24f_gcc

TOPPERS/ASPソースツリーのディレクトリ - 1


エクスプローラをちょっとだけ下にスクロールしてやりますと「asp_pic24f_gcc.code-workspace」というファイルがあると思います。

こいつをダブルクリックしてください。

TOPPERS/ASPソースツリーのディレクトリ - 2


以下のように「Visual Studio Code」が起動し「Explorer 16/32 Deveopment Kit」用のTOPPERS/ASPワークスペースが開かれます。

「Visual Studio Code」 - 1


この過程で以下のようなポップアップが出るかもしれません。

その場合は「はい、作成者を信頼します」をクリックしてください。

信頼して!

「Visual Studio Code」 - 2


次に、このソースツリーに対し、ビルドやクリーンなど色々と操作するためのターミナルを表示させましょう。

それには「Visual Studio Code」上方に配置されている「表示」メニューから「ターミナル」をクリックします。

「Visual Studio Code」 - 3


すると「Visual Studio Code」下方にターミナルが表示されました。

「Visual Studio Code」 - 4


このターミナルは、すでにインストールした「Cygwinターミナル」そのものです。

ここでは「Cygwinターミナル」と全く同じ操作を行うことができます。


例えば、ソースツリーの「asp_pic24f_gcc」(改名した場合は「asp_1.9.2」)ディレクトリの中の「OBJ」へ移動するために、以下のコマンドを入力します。

ルートは「C:\cygwin64\home\<ユーザー名>」です。


$ cd ./asp_pic24f_gcc/OBJ


サンプルプロジェクト「OBJ」は「Cygwinターミナル」で先程、確認のためにビルドしていますよね?

それを一旦キレイにクリアしましょう。

以下のコマンドを入力します。


$ make realclean


実行結果は以下の通り。

「OBJ」ディレクトリの中にあった「~.d」とか「~.o」などのビルド生成物がクリアされ、ソースコードのみが残った状態になります。

「Visual Studio Code」 - 5


これで作業中に「Visual Studio Code」と「Cygwinターミナル」の二窓をしなくて良くなります。

※「二窓」とは、Windowsで複数のアプリを同時に起動させるという意味のオジサン言葉である。昔は複数のアプリ(特にブラウザ)を立ち上げるとWindowsが頻繁にフリーズしたため、オジサンたちにとってはリスキーな行為であるというトラウマが根強く残る。


ソースコードの編集は、一般的な統合開発環境(IDE)と同様に、リストビューからファイルを選び、メインビューでソースコードを表示して、それを編集するスタイルとなります。

例えば、今回のビルド対象であるサンプルプロジェクト「OBJ」のメインファイルを編集したい場合は「Visual Studio Code」左側のエクスプローラーから「OBJ」ディレクトリ以下の「sample1.c」をダブルクリックします。

中央のメインビューにソースコードが表示されたでしょうか?

「Visual Studio Code」 - 6


編集が終わったらソースコードを保存して「Visual Studio Code」下方のターミナルで以下のコマンドでビルドを行います。


$ make depend

$ make


全く「Cygwinターミナル」と一緒ですね!


以上で、開発環境の構築は終わりました。

次回からは、このPIC24版TOPPERS/ASPのサンプルプロジェクトを実際に実機(Explorer 16/32 Development Kit)で動かしていく準備をしていきましょう。


本業が地獄みたいな状態で、3ヶ月以上もブログの更新を止めてしまいました。

年末のご挨拶をしたいので何とか年内に更新を!と…。


皆様、どうか良いお年を!

来年も皆様にとって素晴らしい年になりますように!


<続く>

2025年9月15日月曜日

μiTRONプログラマーがZephyrに挑戦! その6

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


「zephyr-sample」プロジェクトを動かそう!

さて、今回の本題「zephyr-sample」プロジェクトを「Visual Studio Code」で開き、ビルドをしてターゲット「nRF7002 Development Kit」上で動かしてみましょう。

まずは「zephyr-sample」のソースコードをダウンロードします。

これには2つの方法があります。

まず一つ目、以下のGitHubからZIPでダウンロードする方法です。

以下のリポジトリにアクセスしてもらって、緑色の「<>Code」というボタンをクリックします。


https://github.com/RyutaroMorita/zephyr-sample

「Zephyr-sample」リポジトリ - 1


次に「<>Code」ボタンの下に展開された「Download ZIP」という表示をクリックして「zephyr-sample-master.zip」をダウンロードします。

「Zephyr-sample」リポジトリ - 2


あとは「zephyr-sample-master.zip」を展開すればOKです。


2つ目の方法は「git clone」コマンドを使用することです。

Cygwinなどを使用して、ターミナルから以下のコマンドを入力すると「zephyr-sample」の

ソースツリーがダウンロードできます。

Cygwinのセットアップ方法は、こちらの記事を参考にしてください。


$ git clone git@github.com:RyutaroMorita/zephyr-sample.git

Cygwinターミナル


では、ゲットした「zephyr-sample」を「Visual Studio Code」で開いてみましょう。

まずは「nRF7002 Development Kit」をパソコンに接続した状態で「Visua
l Studio Code」を起動し、以下の操作を行います。

次に画面左端のアイコンが並んでいるところ、その中の四角いアイコン(「nRF Connect」)をクリックします。

「Visual Studio Code」 - 1


画面左端の各項目が以下のように変化したはずです。

その中で、一番上にある「WELCOME」という表示の直下「+ Open an existing application」の表示をクリックします。

「Visual Studio Code」 - 2


以下のようにディレクトリ選択ダイアログが表示されます。

ここで、ゲットしたソースコードのディレクトリを選択します。

ZIPファイルでダウンロードした場合は、ディレクトリ名が「zephyr-sample-master」、「git clone」コマンドでクローンした場合は、ディレクトリ名が「zephyr-sample」です。

いずれも「src」というディレクトリの一個上の階層のディレクトリを指定し、ダイアログ右下の「OK」ボタンをクリックです。

「Open an existing application」ダイアログ


すると、以下の警告が表示されます。

ここは「はい、作成者を信頼します」をクリックしてください。

警告表示


画面上方のリストビューには「zephyr-sample-master」、もしくは「zephyr-sample」という表示はされていますね?

画面左端の「フォルダー」アイコンをクリックしてソースディレクトリの中を確認してみましょう。

「Visual Studio Code」 - 3


すると、ソースディレクトリの中にいくつかのファイルの他、更に「src」というディレクトリがあるようです。

この中もクリックして展開してみましょう。

「Visual Studio Code」 - 4


ここから「zephyr-sample」の各ソースコードにアクセスできます。

試しに「sample1.c」をクリックすると「Visual Studio Code」のメインビューにソースコードが表示されます。

「Visual Studio Code」 - 5


ここまで来れば、このソースコードのビルドや実行は、一からプロジェクトを作った前回と同じ手順です。

前回の記事のこの項目を参考に「zephyr-sample」のビルドと実行を行いましょう!

但し、今回はデバッガも本格的に使用したいので「Add Build Configuration」の画面の「Board Target」を「nrf7002dk/nfr5340/cpuapp/ns」に設定するのはもちろんのこと…

「Visual Studio Code」 - 6


…「Optimization level」も「Optimize for debugging (-Og)」に設定してから「Genarate and Build」ボタンをクリックしましょう。

「Visual Studio Code」 - 7


これを設定しないと、ブレークポイントを設定しても効いてくれませんのでご注意を!

ちなみに、これを忘れてデバッグしようとすると、以下のように「Debug options not enabled」というポップアップが出ますので、後で気付くことが良くあります…。

警告ポップアップ


さて、不幸にもビルドの過程でエラーが発生してしまった方へ…。

もしや、以下のようなエラーメッセージではありませんでしたか?

私は今まさに、この記事を書いているときに遭遇しました…。

  • C:/ncs/v3.0.2/modules/crypto/mbedtls/library/memory_buffer_alloc.c:602:1: fatal error: opening dependency file secure_fw\partitions\crypto\mbedcrypto\nrf_security_src\CMakeFiles\crypto_service_mbedcry
  • pto.dir\C_\ncs\v3.0.2\modules\crypto\mbedtls\library\memory_buffer_alloc.o.d: No such file or directory
  •   602 | }
  •       | ^
  • compilation terminated.
  • ninja: build stopped: subcommand failed.
  • FAILED: modules/trusted-firmware-m/tfm-prefix/src/tfm-stamp/tfm-build tfm/bin/tfm_s.elf tfm/bin/tfm_s.bin tfm/bin/tfm_s.hex tfm/bin/tfm_s_signed.bin tfm/bin/tfm_s_ns_signed.bin tfm/api_ns/interface/li
  • b/s_veneers.o tfm/api_ns/interface/src/tfm_attest_api.c tfm/api_ns/interface/src/tfm_crypto_api.c tfm/api_ns/interface/src/tfm_fwu_api.c tfm/api_ns/interface/src/tfm_its_api.c tfm/api_ns/interface/src
  • /tfm_platform_api.c tfm/api_ns/interface/src/tfm_ps_api.c tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c C:/cygwin64/home/User/zephyr-sample-ma
  • ster/zephyr-sample-master/build/zephyr-sample-master/modules/trusted-firmware-m/tfm-prefix/src/tfm-stamp/tfm-build C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephy
  • r-sample-master/tfm/bin/tfm_s.elf C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/bin/tfm_s.bin C:/cygwin64/home/User/zephyr-sample-m
  • aster/zephyr-sample-master/build/zephyr-sample-master/tfm/bin/tfm_s.hex C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/bin/tfm_s_signed.bin C:
  • /cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/bin/tfm_s_ns_signed.bin C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master
  • /build/zephyr-sample-master/tfm/api_ns/interface/lib/s_veneers.o C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_attes
  • t_api.c C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_crypto_api.c C:/cygwin64/home/User/zephyr-sample-mas
  • ter/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_fwu_api.c C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_
  • ns/interface/src/tfm_its_api.c C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_platform_api.c C:/cygwin64/home/Ryutaro
  • uMorita/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_ps_api.c C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephy
  • r-sample-master/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/zephyr-sample-master/tfm/api_ns/interface/src/tfm_ioctl_cor
  • e_ns_api.c
  • cmd.exe /C "cd /D C:\cygwin64\home\User\zephyr-sample-master\zephyr-sample-master\build\zephyr-sample-master\tfm && C:\ncs\toolchains\0b393f9e1b\opt\bin\cmake.exe --build . -j 1"
  • [12/231] Generating misc/generated/syscalls.json, misc/generated/struct_tags.json
  • ninja: build stopped: subcommand failed.
  • FAILED: _sysbuild/sysbuild/images/zephyr-sample-master-prefix/src/zephyr-sample-master-stamp/zephyr-sample-master-build C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build/
  • _sysbuild/sysbuild/images/zephyr-sample-master-prefix/src/zephyr-sample-master-stamp/zephyr-sample-master-build
  • cmd.exe /C "cd /D C:\cygwin64\home\User\zephyr-sample-master\zephyr-sample-master\build\zephyr-sample-master && C:\ncs\toolchains\0b393f9e1b\opt\bin\cmake.exe --build ."
  • ninja: build stopped: subcommand failed.
  • FATAL ERROR: command exited with status 1: 'C:\ncs\toolchains\0b393f9e1b\opt\bin\cmake.EXE' --build C:/cygwin64/home/User/zephyr-sample-master/zephyr-sample-master/build

  •  * ターミナル プロセスが終了コード 1 で終了しました。
  •  * ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。


この原因は、アプリケーションの存在するディレクトリのパスが長すぎることです。

この記事を書いている時は「zephyr-sample」のリポジトリからZIPファイルをダウンロードして、それを展開したものを「c:\cygwin\home\<ユーザー名>\」以下にコピーしました。

Windows11で「zephyr-sample-master.zip」を普通に展開してしまうと「zephyr-sample-master」ディレクトリの中に、更に「zephyr-sample-master」ディレクトリが生成され、その中にソースコードが格納されることになります。

この構造を「Visual  Studio Code」に設定し「nRF Connect SDK Toolchain」を使ってしまったのが悪かった!

この場合、アプリケーションのディレクトリは非常に長くなります。

すなわち…


c:\cygwin\home\<ユーザー名>\zephyr-sample-master\zephyr-sample-master\~


…となります。

これは「nRF Connect SDK Toolchain」の制限(というか、バグ?)による問題です。

結構困っている人も多いみたいです。

回避策は、上記のパスを以下のように再配置することです。

つまり、余計なZIPファイル展開の過程で生成されてしまった余計な「zephyr-sample-master」ディレクトリを一階層上げてパスを短くします。


c:\cygwin\home\<ユーザー名>\zephyr-sample-master\~


これで正常にビルドが通るようになります。

とはいえ元のパスでも、それほど非常識な長さとは思えず、Nordic社に改善を求めたいところではあります。

こういうクダラナイ問題で長時間ハマると、気力がゴッソリ削られますので、マジお願いしますよ~。


ともあれ、正しくビルドが通り「zephyr-sample」が動作すると、TeraTermには以下のような表示が現れます。

TeraTerm


そもそも、この「zephyr-sample」は「Zephyr」というRTOSを学習するために、μiTRONとの比較としてTOPPERS/ASP公式のサンプルプログラムを可能な限り忠実に再現したものです。

もちろん、コンフィギュレーションの方法は大分違いますが。

したがって、それ以外の操作方法や処理の流れは「TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトで遊ぼう」の記事とほとんど同じです。

是非、遊んでみていただけると嬉しいです。

見た目の違いといえば、メッセージの「task(タスク)」が「Zephyr」の文化に合わせて「thread(スレッド)」となっている点くらいですかね。


次回は、このシリーズの最終回です。→終わらんかった…。

今回の「zephyr-sample」で判明した「Zephyr」とμiTRONとの違いや、今後「Zephyr」を使用する上で注意しなければならないRTOSの設計思想の違いなどを自分なりにまとめてみたいと思います。

あくまで自分自身のための備忘録や警鐘の意味合いで…。

でも、私のようにμiTRONに長年慣れていて急に「Zephyr」を使わなきゃならなくなった人って、結構いるんじゃないかな?

…Nordicのせいだ。


<続く>

2025年8月17日日曜日

TOPPERS/ASP - PIC24F版 その2

前回からの続きです。


開発環境の構築(MPLAB X IDE/XC16編)

MPLAB X IDE」とは、Microchip社の純正のIDEです。

以前「TOPPERS/ASP - PIC32MX版 その2」でも紹介していますが、大分時間が経ってしまって、バージョンアップもして手順が変わっているかもしれませんので書き直します。

PIC24F版のTOPPERS/ASPを使って開発を行っていく上では、以下の方針を採ります。


1.コーディングとビルドは主に「Visual Studio Code」を使う。

2.デバッグ作業は主に「MPLAB X IDE」を使う。


今回はコーディングとビルドに、いつもの「Eclipse」ではなく「Visual Studio Code」を使ってみましょう。

「私はEclipseが好き!」って方は「TOPPERS/ASP - PIC32MX版 その4」の記事を参考にしてください。

大体、同じ手順でイケルはずです。


では、まずは以下のページで「MPLAB X IDE」のダウンロードをしましょう。


https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide

「MPLAB X IDE」ダウンロード・ページ - 1


上記のページのちょっと下の方に行ってもらって…。

すると「MPLAB X IDE vX.XX Released」という見出しがあります。

その下のテーブルから「Download」の表示をクリックします。

「MPLAB X IDE」ダウンロード・ページ - 2


ダウンロードが完了すると「MPLABX-vX.XX-windows-installer.exe」というファイルが落とせます。

これをダブルクリックしてみましょう。

以下のようにインストーラーが起動します。

Next >」ボタンをクリックして先に進みましょう。

「MPLAB X IDE」インストーラー - 1


毎度おなじみのライセンスの承認です。

当然「I agree the agreement」のラジオボタンをクリックし、「Next >」ボタンをクリックです。

「MPLAB X IDE」インストーラー - 2


この画面、特に事情がない限りは、このまま「Next >」ボタンをクリックしてください。

「MPLAB X IDE」インストーラー - 3


以下の画面では、開発するターゲットのの種類を選ぶチェックボックスがあります。

ディスクスペースに余裕のある方は、全部選択しておいても良いです。

ここで全てのターゲットをインストールしておくと、この先、今回のPIC24F以外のマイコンを使う必要が生じたとき、コンパイラだけ別個インストールすれば良いので、後が楽というのはあります。

とはいえ、かなりの容量を食いますので躊躇してしまいますね。

まあ、最低でも「dsPIC DSCs and 16-bit PIC24 MCUs」だけは選んでおきましょう。

その後に「Next >」ボタンをクリック!

「MPLAB X IDE」インストーラー - 4


以下の画面で「Next >」ボタンをクリックすると、インストール作業が始まります。

「MPLAB X IDE」インストーラー - 5


インストール作業が始まります。

かなりの時間がかかりますので要注意です。

私のポンコツPCで30分位です!

前々回のターゲット選択画面で全部チェック入れちゃったからなぁ…。

「MPLAB X IDE」インストーラー - 6


インストールが終了すると、以下の表示になります。

ここでは、一緒にインストールを行うコンパイラと、それらのセットアップが完了した際に「MPLAB X IDE」を起動するかどうか?をチェックボックスで選択します。

先ほどのターゲットの選択と同じように、ディスクスペースに余裕のある方は、全部選択しておいても良いですが、8-bitや32-bitのPICを使わない人には意味はありません。

最低でも「Install latest MPLAB XC16 compiler vX.XX(16-bit PIC24 devices)」と「Launch MPLAB X IDE vX.XX」だけはチェックを入れておきましょう。

その後に「Finish」ボタンをクリックすると、ひとまず「MPLAB X IDE」のインストールはし完了です!

「MPLAB X IDE」インストーラー - 7


続けざまに、PIC24F用のコンパイラである「XC16」のインストーラーが起動します。

早速「Next >」ボタンをクリック!

「MPLAB XC16」インストーラー - 1


またまたライセンスの承認です。

ここでも「I agree the agreement」のラジオボタンをクリックし、「Next >」ボタンをクリックです。

「MPLAB XC16」インストーラー - 2


ライセンスの種類は初期値の「Free」のままで大丈夫です。

この「XC16」コンパイラには無料版と有料版があります。

無料版である「Free」ライセンスでは最適化が「-O1」まで設定可能で、「-O2」は許可されません。

ホビーユースでは「Free」ライセンスで十分ですが、商用で使用する場合は、有料ライセンスが必要となるでしょう。

えらい高いけど!

Next >」ボタンをクリック!

「MPLAB XC16」インストーラー - 3


以下は特別な事情がない限りは、そのまま「Next >」ボタンをクリックしてください。

「MPLAB XC16」インストーラー - 4


以下の画面では、デフォルトではチェックされていない「Add xc16 to the PATH environmant variable」にチェックを入れてください。

ここでは「XC16」コンパイラのパスをシステムの「PATH」環境変数に追加するかどうかを選択します。

ここにチェックを入れると、手動で「PATH」環境変数を追加しなくて済むのでお得です。

つまり、この作業が要らなくなります。

チェックを入れたら「Next >」ボタンをクリックです。

「MPLAB XC16」インストーラー - 5


ラスト!

Next >」ボタンをクリックでインストール作業開始!

「MPLAB XC16」インストーラー - 6


インストール作業が開始されます。

今回は常識的な待ち時間です。

「MPLAB XC16」インストーラー - 7


作業が終わると、以下の表示となります。

気になるのは「Your Host ID is:」という表示の右にある文字列です。

念のため、スクリーンショットでも保存しておきましょうか。

(後で必要になったことはありません…。)

Next >」ボタンをクリックでしましょう。

「MPLAB XC16」インストーラー - 8


最後の最後、以下の画面で「Finish」ボタンをクリックすれば「XC16」コンパイラのインストールも完了です!

「MPLAB XC16」インストーラー - 9


その後しばらくすると、以下のようなイケてるスプラッシュが表示され…

「MPLAB X IDE」スプラッシュ


…以下のように「MPLAB X IDE」が起動します。

以上でコンパイラを含めた「MPLAB X IDE」のインストール作業は終わりです。

お疲れ様でした~。

「MPLAB X IDE」


次回も「Visual Studio Code」など、残りの開発環境の構築手順などをご紹介します。

この「MPLAB X IDE」は、NetBeansというオープンソースのIDE(統合開発環境)がベースになっていますね。

他のマイコンベンダーは「Eclipse」ベースのIDEがメジャーですので珍しいです。

そのうち、全部今流行りの「Visual Studio Code」に統合されるのでしょうか?

使う側は、操作方法が統一されるので良いことですけどね。


<続く>

μiTRONプログラマーがZephyrに挑戦! その7

前回からの続き です。 このテーマを最初からご覧になる場合は こちら からどうぞ。 μITRONとZephyrの比較 TOPPERS/ASPのサンプルプロジェクトをZephyrに移植し、動かして見てみることで両者を比較し、Zephyrを学ぼう!という今回の趣旨、ここまでお付き合い...