Д`)シクシク...なので今迄はHtermで書き込みしていましたが、さすがにHtermの書き込みはキツイ!(OSとか、USBシリアルとの相性が有る?)ので、コマンドラインの書き込みツールを作った。Windows10上のBCC32Cで開発。Windows10とXPでやってみたが、ちゃんとXPでも動くのだね~。USERPROGRAM.motと言う訳で置いておきますので、試しにどうぞ。うまく行った!とか、全然ダメ!とか、報告を是非。https://1drv.ms/u/s!AgxfaDqma1yrhkrnI3M3g5FcizyO※添付してあるファイルの、exeファイルが書き込みプログラム。w7045s.motはSH2のRAM上で動作するユーザープログラムのローダー。[RX&SH&H8]前回のマルチタスクではC言語で標準サポートされているsetjmp、longjmpを使って実現していました。この方法の良いところは、setjmp、longjmpがC言語で標準でサポートされている事から、どの様なマイコンでも容易に利用できる点です。逆アセンブルの結果や、そもそも目的が異なる点から不満が無い訳でもありませんでした。最大の問題はやはり無駄が多い点で、この無駄がコードサイズやRAMサイズ、実効速度の足を引っ張る事となります。なれば自分でコードを書くしかない訳で、コンテキストを入れ替える処理とタスクをスタートさせる処理のみアセンブラで記述してみました。アセンブラと言う事で難しい印象はありますが、極めて限定的な処理のみ記述しています。以下はタスクをスタートさせる処理です。/*r6-r14を復帰*/rtsリターン命令を入れても、3行でできます。以下はコンテキストを切り替える処理です。/*r6-r14を退避。/*r6-r14を復帰*/rtsリターン命令を入れても、5行でできます。この2つをC言語から呼び出しています。スタックやレジスタの操作のみアセンブラで記述し、それ以外は全てC言語で記述できます。setjmp、longjmpを使った方法と異なり、今回の方法は汎用レジスタはタスクスタックに保存しています。スタックポインタのみ大域変数領域に保存します。以下の図と同じ展開となります。今回の方法はスタックに退避される為、汎用レジスタの具体的な退避アドレスを予め知る事は困難です。その為スタックポインタのみ、アドレスが判明している領域に保存するのです。言い換えれば宝物を何処かに埋めて、その地図を作成する様な物です。宝物を掘り返す時は地図でその位置を見付けます。カリブの海賊みたいな話ですネ。スタックに退避する長所は、複数レジスタを一発で退避、呼出しできる命令を使える点です。r14」がそれで、R6~R14までの汎用レジスタを、スタックポインタが示す位置から1命令で退避や呼出しします。その他、PCも自動的にスタックに退避され、また、スタックから読み出しを受けるので、特殊な領域を用意してそこに保存するより、スタックに保存する方が全体的に自然な感じです。R6~R14のレジスタのみ退避する理由は、おそらくこのコンパイラでは関数の呼出しで値の保障が必要とされるレジスタがR0、R6~R14だと思われます。他のレジスタの値は関数の前後で保障する必要は無い筈です。必要なレジスタのみ退避する事で、処理時間の短縮や必要なメモリサイズの削減ができます。今回の改造ではコンテキストの切り替えの最適化以外に、起動時引数を最大4個まで渡せる様にしました。綺麗な方法ではありませんが、この機能が有ると様々な目的で使用する事ができます。以下の様な関数でタスクを登録する時、この起動時引数を指定します。);タスクID、タスクの起動アドレス、スタック領域アドレス、スタックサイズに続いて引数を渡します。);ちょっと上手い方法が思いつきませんでした。以下の様な方法で起動時引数をタスクの中で得る事ができます。pin番号が入っているVP_INT型の配列を宣言してget_par関数の引数とします。数字の2は引き取りたい引数の数です。pinModeで配列の一部のデータを引数に渡しています。このデータはPIN番号です。一例を挙げて置きます。以下はLEDを点滅させるだけのタスクの記述例です。GR-SAKURAには4つの青LEDが有りますので、それぞれのLEDに付き1つのタスクで制御しています。