少し時間が出来たので、FreeRTOS をポートして、自分の環境で動かし始めた。
詳細は、
「RXマイコンで、FreeRTOS を使う場合の要点
に投稿している。
自分のブログでは、今回「はまった」点にフォーカスしてみたい。
そもそも、FreeRTOS は RX マイコンをサポートしており、RX マイコン用コードもアーカイブに含まれる。
しかし、それは、ルネサスさんの環境用で、自分のように、gcc を自前でコンパイルして使っている場合、そのままでは使えない。
それと、ルネサスさんの環境用なので「iodefine.h」定義が必要なのも、敬遠する理由となっている。
※ハードウェアー定義は C++ クラスで独自に実装してある。
なので C++ ベースの制御クラスを定義して、そのコンテキストを FreeRTOS に使ってもらうようにしたい。
最初は、「簡単」だと思ってやっていたが、勘違いから、かなり時間を使ってしまった・・・
FreeRTOS では、ソフトウェアー割り込みも使う。
今まで、ソフトウェアー割り込みは使った事がなく、割り込み関係クラスもサポートしていなかったので、それらを追加した。
※これが、間違いの始まり・・・
「SWINT」はベクター番号27で、この割り込み許可と、割り込みレベル設定は、ICU 関連レジスターにある。
割り込み許可は、問題無かったが、割り込みレベル設定は、IPRのベースアドレス+27と思い込み、そのような設定にして、何の疑いもしなかった。
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief IPR レジスタ @n
全て、下位4ビットが有効
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <uint32_t base>
struct ipr_t {
rw8_t<base + 27> SWINT;
};
static ipr_t<0x00087300> IPR;
そして、ようやく、主要な部分が出来て、簡単なサンプルを用意して、マイコンに書き込み起動するが動作しない・・・
その過程で、色々「マズイ」部分も見つかり、直すが、全く動かない。
デバッグ用コードを入れて、どこまで動いているか確認すると、定義したタスクが起動していない・・・
そして、なぜ起動しないのか、ソースを追うと、どうやら、ソフトウェアー割り込みが怪しい事に気がつき、単独で、ソフトウェアー割り込みの動作を確認してみた。
当然のように「動かない」・・・
そこで、ハードウェアーマニュアルを見直したら、ベクター27のソフトウェアー割り込みレベル設定は、+3である事が判った・・・
それを修正したら、動作するようになった。
rw8_t<base + 3> SWINT;
そこで、不思議に思った事がある・・
ソフトウェアー割り込み(SWINT)を使う場合、「asm("int #27");」を実行するハズだけど、どこを探しても、それらしい実装が見つからない。
よくよく調べると、ICU レジスターには、ハードウェアーから、SWINT を発生させる機能があり、それをハードコードしていた。
※「portmacro.h」
#define portYIELD() \
__asm volatile \
( \
"PUSH.L R10 \n" \
"MOV.L #0x872E0, R10 \n" \
"MOV.B #0x1, [R10] \n" \
"MOV.L [R10], R10 \n" \
"POP R10 \n" \
)
「0x872E0」 に「1」をライトするのがそれだー、これは痛い・・・
何で、iodefine.h をインクルードしているのに、こんな事してるのか?
それに、こんな面倒な事しなくても、「asm(int #27);」で良くない??
疑問は残るけど、FreeRTOS に戻って、実験したらようやく動作したーー(ヤレヤレ~)
そもそも、ハードウェアー依存部分は、完全に外部に出せるから、「port.c、portmacro.h」に含める必要性は無いのに・・・
そんなこんなで、動くようになったので、github に上げた。
これから、色々マルチタスク対応にしていこうと思う。
追記:
「ソフトウェアー割り込み命令(int #27)」と「SWINT ハードウェアー割り込み」は動作が異なるとの知見(RXマイコン内の動作がどのように異なるのか不明なので、完全に理解している訳ではないが・・)を受けて、とりあえず以下のように変更した。
※気になっていたのは、32ビットリードなので・・
#define portYIELD() \
__asm volatile \
( \
"PUSH.L R10 \n" \
"MOV.L #0x872E0, R10 \n" \
"MOV.B #0x1, [R10] \n" \
"CMP [R10].UB, R10 \n" \
"POP R10 \n" \
)