OSのお試し版(と言っても機能はver.3そのままで、ターゲットのマイコンが3664Fと3694Fに制限されているのみ)を落してきて、手元の3694Fマイコン(例のトラ技の付録基板)上で動かしてみました。OSを使ったアプリケーションを用意できないので、サンプルとして入っている”u-ap”を動かしています。実際にパスワード申請し、落して見てください。この”u-ap”は、3つのタスクを実行します。それぞれのタスクの属性ですが、task01が優先度タスク、task02とtask03はローテーションタスクとして生成され、3つとも初期状態はREADYとなっています。このアプリケーションは何ら出力を持たないので、動作確認にはE8エミュレータを使っています。E8エミュレータ上で動かす時は、RAMの一部の制限領域を避けてセクションを配置する必要があります。このアプリケーションの動作を簡単に説明しますと、1.task01がRUNNING→slp_tskでWAITINGに遷移2.task02がRUNNING→rot_rdqでローテーションタスク内の実行タスクの切り換え3.task03がRUNNING→wup_tskでtask01を起床、そのままREADYに遷移4.task01がRUNNING→しかしすぐにslp_tskでWAITINGに遷移5.task03がRUNNING→しかしすぐにslp_tskでWAITINGに遷移6.task02がRUNNING→wup_tskでtask03を起床、しかしそのままRUNNING7.task02がRUNNING→wup_tskでtask01を起床、そのままREADYに遷移8.task01がRUNNING→しかしすぐにslp_tskでWAITINGに遷移9.task02がRUNNING→しかしすぐにslp_tskでWAITINGに遷移10.task03がRUNNING→rot_rdqでキューを廻すが、特に切り替えるべきタスクが存在しないのので、そのまま11.task03がslp_tskでWAITINGに遷移12.全てのタスクがWAITINGになってしまったので、”idle”が実行される。言った流れで動きます。※実際にはここまで激しく実行状態を他のタスクに依存するプログラムはやらない方が良いと思う。プログラムサイズが大きくなって見通しが悪くなった時、うっかり全部のタスクがWAITINGなんて事になりかねない。デッドロックしてしまう。機能分割と言う点でも、なるべく他のタスクとの繋がりは、疎結合にした方が。※取り敢えず2章の途中まで読んだのですが、もっとも基本的なサービスコールを、図解を使ってみっちり解説されている所が、μITRONの入門本としてきわめて適していると思います。これだけ基本的なサービスコールを解説してあれば、後は拡張機能みたいなもので、自分で使いながら十分習得可能だと思います。単行本(ソフトカバー)いやすいません、まだ購入していなかったのですが、先ほどアマゾンに注文しましたとも。久しぶりにアマゾンの該当ページを見たら、書評が3つになっています。じょじょに評価は高まっているようです。OSの用意が出来ていなかったため、理論面だけで、実際に動かしてみる実践的な要素が少なかった点だと思いますが、なんと森北出版のサイト上で無償版を落せるようになったのですね。事前にルネサス北セミへパスワードの申請が必要ですが、「教育関係、ホビーユースで使用したい方は云々」と、学生さんやホビーユーザー向けの対応も取ってくれるみたいですので、是非これを機会にRTOSを試してみては如何でしょうか。V3を手持ちのH8に入れて試してみたいと思います。※TRON協会の「1時間で判る組み込みリアルタイムOS」もなかなか良いドキュメントです。http://www.assoc.tron.org/jpn/seminar/index.html製作に関わった人の中に武井さんの名前が。シミュレータの提供はルネサスでしょ。単行本(ソフトカバー)発売日はもう少し先と言う事ですな。出版社の解説はここで読めます。うーんあれをμITRONと言って良いのだろうか?。実践に入るまでの解説と、実際の動作の食い違いが混乱を招く様な。OSが入っているのかなぁ。OSがおまけなら、結構欲しい。ついては、先の森北出版のホームページから問い合わせをしてみて下さい。発売前に反響が有れば、著者の方も、出版社の方も嬉しいでしょうから。先程メールが届いて、目次と付録2の製版直前の原稿(縁に合わせマークみたいなのが入っている。)をPDFで頂きました。著作物なので、内容等はこちらからは言えませんけれど。OS、利用できるならとても良いと思いますよ。HOSはRTOSの勉強を最大の性能として、ちゃんと成功しているし、支持もされていますが、商用RTOSなら速度や必要リソースの小ささ、何よりもバグが無い事が最大の性能でしょうからね。あそこのセミナーのドキュメントは良くできているし、昔からTRON協会に何かと言えば協力を求められて来た所ですから。※人を出してくれ~~!とか、ドキュメント作ってくれ~~!とか。OS]今頃になって某誌6月18日号を読んでみました。記事全般は面白かったのです。アナログ放送の停波にはムカッと来ましたが。例によってなんとかアカデミーも読んでみましたが、相変わらず無茶を書く。記事の内容は、高負荷時の割り込みと、それによって発生するスラッシングのメカニズムの解説と言った所でしょうか。記事を転載できないので要約すると、「高負荷時に非同期の割り込みが集中発生すると、スラッシングと言う状態に陥り、実行し損ねた割り込みを実行しようとして、徐々にスタック領域を食いつぶし、最後にはシステムクラッシュに陥る」との事です。うーーん!割り込みって、割り込み処理が終わる度にスタック領域が返却される事になっているので、割り込みが集中したとしても、全体の使用量は決まっているんですけれどね。返却し切れていないスタックが有ったとすれば、それはプログラムに問題が有るのですよ(普通にC言語で開発すればそんな事にはならない筈。アセンブラ等を使って自分でスタックをいじった場合は、返却し損ねは可能性として有る。多重割り込みが発生した時にスタックオーバーフローになると言いたかったのかもしれませんが、本来多重割り込みが発生する事を想定してシステムを作っているのでしょうから、ワーストケースのスタック使用量は事前に盛り込んだ上でシステム設計するのが普通でしょう。最近の統合開発環境ならば、自動的にスタックサイズも計算してくれたりしますし。そこでスタックオーバーフローしているシステムは、高負荷状態でなくともスタックオーバーフローする可能性が有ると言う事になります(非同期割り込みですから。シングとは?になりますが、簡単に言えば、割り込みの出入り口処理の様な、本来の処理に関係しない処理に掛かる時間が、本来の処理に必要な時間を圧迫している状態。対策は!、CPUを速い物に交換してください(*^。処理が間に合わないからそうなっているんだから。後はプログラムを工夫するとか、メモリやメモリ配置を工夫して、メモリアクセスに掛かる時間を減らすとか。他に対策できる要素を検討してみると、結局割り込みの数を減らせばよい訳で、例えば低価格なマイコンのSCIって1byte位しかバッファが有りませんので、転送スピードが速く、転送数が多いと、結構マイコンは苦しくなって来ます。使えるなら、NS16550の様に16byte位のバッファを内蔵している周辺チップを使えば、かなーり楽になる筈です。ネットワークコントローラなんかも、一々パケットを受信する度に対応するのではなく、大概はコントローラ内部に大きなバッファを持っていますので、しばらく放って置いてから複数のパケットをまとめて処理すれば、割り込みのオーバーヘッドをかなり削減できます。DMAを使うのも有効でしょう。TCP/IPなんかはリアルタイム性を保障しなくてもいいので、受信パケットは暫く放って置けます。結局高負荷での実行中に「割り込みを制限する」なんてのは多分無理なので、システム設計の段階で、十分検討し、必要ならばCPUの負担を減らす対応をするしか無いですね。あと、右側の注1)ですが、それはCISC、RISCの違いではないでしょう。割り込みコントローラの違いだと思うんだが。起動時パラメータを試してみる。osには無く、不便だなあ!と思っていた機能(μITRON仕様なら以下の様な静的API、またはサービスコール)が起動時パラメータの引渡しですが、マニュアルの「stack_iniを利用したパラメータ引渡し」に、stackini.cをいじれば可能な事が書いて有りましたので、これを試してみたいと思います。);まずオリジナルは何も引数を渡さない事になっています。16;の下に以下の記述を追加する事で、実行時引数を渡す事が可能となるみたいです。なんとか;tidは勿論タスクIDです。ポインタ型変数のspは、タスクのコンテキスト保存時の構造体で、slos.h内では以下の様に定義されています。TSTACK;つまりこの構造体は、タスクのレジスタを全退避する領域の定義を行っている物です。各タスクは、起動時にはREADYまたはWAITの状態で起動しますので、OSが初期化を行う時に、この領域に必要な情報(実際には戻り先アドレスとスタックポインタ、それ以外は重要では無い)を代入します。タスクの実行関数は基本的に関数なので”引数を持つ事が可能”です。R8Cの場合は(正確に言えばNC30WA)関数の引数の渡し方のルールとして、R1、R2レジスタに値を代入し、それを越える場合はスタック渡しに切り替えます。※引数の型に拠って渡し方のルールが異なるので、コンパイラマニュアルを参照する必要がある。今回のサンプルプログラムは、二つのLEDを独立に点滅させる、ひじょーうに簡単な物です。それぞれのLEDにタスクを割り当て、実行します。そこでtsk01のプロトタイプ宣言を以下の様に変更します。char型なのでR1Lに代入され、dly_timはshort型なのでR2に代入されます。このプロトタイプ宣言の変更は、config.cにも必要です。これを踏まえてstackini.cを以下の様に変更します。※一部のみ表示しています。}tid=1の時は100ms、tid=2の時は200msの遅延時間を引き数として渡します。コンパイラの設定は、SYSTIMEを有効config.cの設定は、タスク1:起動時READYタスク2:起動時READYユーザー初期化関数uinitの設定は、システムタイマーのみ起動します。周期は10msとして置いて下さい。}}あれ!tsk02が無いですね(笑)。実はconfig.cの内容は以下の様になっています。※一部のみ表示しています。*/};つまりタスク1、タスク2共に実行関数はtsk01を指定しています。同じ様な事をするのにわざわざ二つの関数を用意するのは無駄が多いので、一つの関数の中で区別する記述を用意する事で、両方のタスクに対応しています。これは、例えばhttp://hamayan.ddo.jp:8080/でHOSをベースとしたWEBサーバーが実行されていますが、この中のWEBサーバータスクも同様に一つの関数を実行関数として、同時に4つのタスクが起動しています。ここまで修正が完了したらビルドしてみて下さい。ビルドした時に以下の警告が出るかと思います。assignmentこれは、slos.h内の関数のプロトタイプ宣言と、config.c内のプロトタイプ宣言に矛盾が有るからです。このまま実行させても問題無く動きますが、もし気になるようでしたらslos.h内に以下の変更を加えます。osでできる事は、ほぼμITRON仕様OSでも再現できますので、やはり以下の本をどうぞ。HOSは、最も低コストでμITRONを体験できます。OS]この記事は、某SNSで書いているものを転載しています。今回は、イベントフラグのクリアについて解説します。言いましても、既に何度かサンプルの中で使っているので、もう用済みかな。イベントフラグのクリアの方法には、二つの方法が有ります。1.初期化時に、クリア属性を指定。2.ユーザーがタスクの中でclr_flgを使用してクリア。プログラムが一見簡単に構築できそうなのは、1.です。一々プログラムの中でクリアの処理を記述しなくても良いですから。このクリア属性、そのクリアの仕方に落とし穴が有り、符号無し16bitを一気にクリアしてしまう為、もしビットそれぞれに意味が有ったとしたら、その意味を正しく受け取る前に、クリアされてしまうかも知れません。この状況がどの様な時に問題になるのか説明します。一つのイベントフラグに、一つのタスクのみ待ち状態になるなら、wai_flgの戻り値を受ける事で、ビットの意味を失う事は無いでしょう。一つのイベントフラグに複数のタスクが待ち状態になる時、それは起きます。実際にプログラムを動かして、その様子を見てみます。;}さて、二箇所にブレークポイントを設定しましたが、tsk02のブレークポイントに達したでしょうか?。動作を説明すると、まずtsk01が起動し、イベントフラグの待ち状態に入ります。続いてtsk02が起動し、やはり同様に待ち状態に入ります。最後にtsk03が起動し、二つのビットをセットします。このset_flgの中でtsk01がイベントフラグ待ち状態である事を検知したOSは、tsk01の待ち状態を解除し、戻り値に現在のフラグをコピーした後、イベントフラグがクリア属性である為、フラグの内容を全てクリアしてしまいます。その為、tsk02のWAITが解除とならず、このプログラムではそのまま待ち続ける事となってしまいました。この様にクリア属性をうっかり使用すると、思わぬバグとなってしまいます。複数のタスクが一つのイベントフラグの待ち状態になっても事故を起さない方法は、それは勿論無関係なビットのクリアを行わない事!これに尽きる訳です。上のプログラムを下記の様に書き換えて動かしてみます。;}EVTFLG_ATTRマクロのEVFLG_TA_CLRを削除しています。wai_flgの後にclr_flgを追加しています。今度はtsk01、tsk02の両方のブレークポイントに到達した筈です。最近、新しい本が出ましたね。OS]おお、DIGIKEYで689円で1個から購入できるんですね。http://catalog.digikey.com/scripts/partsearch.dll?lang=ja&site=JP&keywords=R5F21256&x=22&y=12もう、海外メーカばかりが安いとは言わせないぞ!ってところでしょうか。開発環境も揃っているし。ちなみにMSP430F4270の価格は、1個で買うと960円。OS]この記事は、某SNSで書いているものを転載しています。今回はイベントフラグの隠れた機能である、タスク間通信について書いてみます。以前通信機能が無い!と書いてしまいましたが、実はリザルトコードの中にこっそり、待ち解除時の受信パターンが存在する事に気が付きまして、ならばタスク間通信についてもご紹介しておこうと言う次第です。受信側のサービスコールであるwai_flgについておさらいしますが、書式は以下の様になります。);戻り値:E_OK(=0)と待ち解除時のパターンのOR。符号付32bitである事から、戻り値の上位16bitが0x0000であれば正常に受信したと判断でき、下位の16bitを待ち解除時のパターンとして取得できます。※マニュアルの記述は間違っていますね。マクロで生成した待ち条件が成立するまでWAITとなります。待ちパターンを0x00ffとし、待ち条件がAND条件ならば、下位の8bit全てセットされるまでWAITを継続します。待ち条件がOR条件ならば、下位8bitの何れかがセットされた時点でWAIT状態が解除されます。イベントフラグは符号無し16ビットなので、戻り値の符号付32ビットに収納可能です。ercd;とすれば、受信パターンが取得できます。※twai_flgの場合は、場合に拠っては上位側のエラーコードを調べる必要が有るかもしれません。この様にデータの受け渡しが可能なのですが、唯一転送できないデータが有ります。イベントフラグは、任意のビットの何れかをセットする事で相手タスクとの同期を取りますので、16bitのいずれもセットされていないと、相手にイベントの通知をしません。0x0000は送れないということになります。前回も書きましたが、ビットパターンは上書きされますので、送るタイミングと受け取るタイミングも重要になって来ます。※単にイベントの発生のみ通知するなら、つまりスイッチが押されている等の”状態”をイベントとする場合は、上書きされてもあまり影響は無いかもしれません。押された数をカウントする場合は、上書きされてしまう事で、数が少なくカウントされる可能性が有ると言う事です。ここまでの説明でなんとなく判ったと思いますので、サンプルプログラムに入ってみたいと思います。;}コメントでブレークを貼る位置を指定しておきますので、そこにブレークポイントを設定します。この時、tsk01のrcv_ptnをWATCHしておくと、その動作がよく判ります。tsk01は起動直後のwai_flgによってWAITに遷移します。この時の起床条件ですが、OR属性で、待ちパターンが0xffffであることから、16bitのいずれかがセットされた場合、待ち状態が解除される事が判ります。tsk01が待ち状態に入ったので、tsk02が起動し、ループの中で10~0までの数字を一回ずつセットします。tsk02で10~1までの数字が送られる度にtsk01の待ち状態が解除され、ブレークポイントの位置で停止しますので、WATCHしているrcv_flgを見てみます。10~1まで受け取っているでしょうか?。最後に0を送信していますが、tsk01は起床されず、またtsk02もその後whileループに入ってしまいますので、結局0を受け取る事は出来ませんでした。上の例題は、受ける側のタスクの優先度を高く、送る側の優先度を低く設定している為に、とりあえず10~1までは正常に受ける事ができました。この優先度を逆にしてしまうとどうなるのか試して見ます。tsk01が送る側であり、tsk02が受ける側です。以下の様にプログラムを変更します。}}今回の結果は、まずブレークポイントでの停止が一回しか行われず(※set_flgを発行してもWAITには遷移しない為)、また受信したパターンを見ると、0x000fとなっている事が判ります。10~0までのすべてのビットがORされてしまった結果です。この事を踏まえて、あらためてタスク間通信の方法を考えてみると、例えば以下の様な方法が有ります。送る側の優先度を低く、受ける側の優先度を高く設定する。送るデータは0~0x7fffの範囲とし、最上位ビットはイベントとして利用する。dataとし、受ける側は待ちパターンを0x8000とすれば良いと言う事です。);CQ出版のセミナーで講師をされている方の本です。OS]この記事は、某SNSで書いているものを転載しています。今回は、使うと便利なイベントフラグの説明に入ります。イベントフラグは、特定の待ちパターン(ビットパターン)を送る側と、受ける側に別れてタスクの同期を取る為に利用します。受ける側は必ずタスクでなければなりません。送る側はタスクの場合と、OS管理下のタスク以外の状態(簡単に言えばOS管理下の割り込みハンドラ)から可能です。送る時は、符号無し16bitの中の任意のbitを1にセットします。0x0001を送る側のサービスコールであるset_flg等の引数とし、bit0をセットします。この時0x0001を連続で10回セットすれば、相手側も10回起床するか?と言えば答えはNOで、実際にはOS内部のフラグに毎回引数がORされる為、相手が即座に起床してそのビットがセットされた事を認識できれば10回可能ですが、相手が起床する前にこちらが上書きしてしまう可能性も有ります。相手がちゃんとこのイベントを認識したかどうかの保証は、プログラマが別の手段で確保する必要が有ります。受ける時は、符号無し16bitの中の任意のビットがセット条件になる事を待ちます。この時、ビットの待ち方には二つの方法が有ります。1.複数のビットの内の1ビットでもセットされれば、待ち状態から解除される物:OR条件。2.複数のビットの全部がセットされるまで、待ち状態を継続する物:AND条件。※既に該当ビットがセットされていたら、待ち状態に入らずに戻って来る。この二つの使い分けは、ユーザー初期化関数(uinit)実行時に決定されます。具体的には「EVTFLG_ATTR」マクロの記述で属性にEVFLG_TA_OR:OR条件EVFLG_TA_AND:AND条件の何れかを記述します。ついでに他の属性を説明します。EVFLG_TA_CLR:受信側が待ち状態から解除される時、ビットパターンをOSがクリアする。※この属性は一見便利に見えますが、複数のタスクが一つのイベントフラグの待ち状態になる場合、注意して使わないと思わぬバグになります。EVFLG_TA_TFIFO:タスクの待ち状態からの解除を、先着順にする。EVFLG_TA_TPRI:タスクの待ち状態からの解除を、優先度順にする。これら属性の指定方法は、以下の様に記述します。(EVFLG_TA_TFIFOまたはEVFLG_TA_TPRI));※属性の先頭の1はフラグID番号。EVFLG_TA_ANDとなっています。osに用意されているサービスコールの使い方を説明します。※ちょっと説明に手抜きしています。);戻り値:有りません。flg_ptn:ビットパターン(複数ビットを一度にセットしてもOK)適用:タスク部で使用可能。割り込みから使用する時は、先頭に"i"を付けたiset_flgを使用します。);戻り値:E_OK(=0)と待ち解除時のパターンのOR。符号付32bitである事から、戻り値の上位16bitが0x0000であれば正常に受信したと判断でき、下位の16bitを待ち解除時のパターンとして取得できます。※マニュアルの記述は間違っていますね。マクロで生成した待ち条件が成立するまでWAITとなります。待ちパターンを0x00ffとし、待ち条件がAND条件ならば、下位の8bit全てセットされるまでWAITを継続します。待ち条件がOR条件ならば、下位8bitの何れかがセットされた時点でWAIT状態が解除されます。);戻り値:E_OK(=0)、またはE_TMOUT(=0x00CE0000L)と待ち解除時のパターンのOR。符号付32bitである事から、戻り値の上位16bitが0x0000であれば正常に受信したと判断でき、下位の16bitを待ち解除時のパターンとして取得できます。逆に上位16bitが0でなければタイムアウトしたと判断できます。flg_ptn:待ちパターン(複数ビットを一度にセットしてもOK)適用:基本的にwai_flgと同じですが、時間管理の仕様はtslp_tskと同じです。);戻り値:有りません。flg_ptn:クリアパターン適用:タスク部で使用可能。EVFLG_TA_CLR属性を使用していない時、OSが管理しているフラグと引数のクリアパターンのAND積を取ります。bit0をクリアしたい時は、~0x0001をクリアパターンとして引数に代入すればよいと言う事です。それでは具体的にプログラムを組んでイベントフラグの動作を実感してみましょう。;/*ここにブレークポイント*/}uinitの中の#if~#elseの条件を切り替えてオンチップデバッカーで試してみて下さい。コメントでブレークを貼る位置を指定しておきますので、そこにブレークポイントを設定します。この時、tsk02のflg_ptnをWATCHしておくと、その動作がよく判ります。1とした時ですが、この時はAND属性となる為に、待ち側では指定したビットの全てがセットされるまで待つ事になります。tsk01は起動直後のwai_flgによってWAITに遷移します。続いてtsk02が起動し、変数flg_ptnの左側から1で埋めていきます。ループを継続している間set_flgにてセットパターンを送信していますが、tsk01の起床条件と一致しない為に、ディスパッチが発生していません。最後のループでflg_ptnが0xffffとなり、そのセットパターンが送信されると、tsk01がWAITからREADYに遷移し、更に優先度からプリエンプトしてclr_flgの位置で停止します。tsk01は、ループが回って再びwai_flgのところでWAITに遷移しますので、READYであったtsk02の実行が再開され、while文のところで停止します。0とした時ですが、この時はOR属性となる為に、待ち側では指定したビットの何れかがセットされるまで待つ事になります。tsk01は起動直後のwai_flgによってWAITに遷移します。続いてtsk02が起動し、変数flg_ptnの左側から1で埋めていきます。ループを継続している間set_flgにてセットパターンを送信していますが、tsk01の起床条件と一致しない為に、ディスパッチが発生していません。9回ループが回ったところででflg_ptnが0xff80となり、そのセットパターンが送信されると、tsk01がWAITからREADYに遷移し、更に優先度からプリエンプトしてclr_flgの位置で停止します。その後7回clr_flgの位置で停止します。osに付いて非難しており、まるで使うな!と書いている様に思えるかもしれませんが、そうじゃあないんです。OSを使おう!」なんですよ。苦言みたいに書いている所は、もっと良くして欲しい!と言う気持ちの表れですから。osを使ってみましょうよ。何よりも応答性や信頼性に付いては問題ないのだろうから、RTOSとしてはちゃんと出来ているものだろうし、そう考えればサービスコールが少ない!なんて小さい事です。osを据えようとしているのでしょう。※ルネサスのサイトでH8/300H用ITRON製品を探したが、あれ!H8S用は有るけれど、H8/300H用が見当たらない。osの利用制限を、日経エレクトロニクス基板限定ではなく、R8C/25を使った非商用利用(ホビーユース)にまで広げてくれませんか。あの基板はどうにもこうにも、、、。あと、、、コンフィギュレータは用意した方が良いと思うよ。最近のコメントこんなものでよろしければ。場合..ありがとうございます。Electronicsアットマークエレ不要なデバイスドライバーを削除ダウンロードInterface付属SH2基板のSRAM有り/無しデバックモニタとHOS-V4同梱バージョンHOS本のサンプルをH8/3048Fでデバックする為のデバックモニタH8/3048Fのセクション情報ファイルインポートして使います。