HOS移植

一念発起してSTK-7125にITRON系のRTOSであるHOSを移植する。
変なところで躓いて、2日ぐらいかかったけど何とか動作成功。
あとから見返せるようにメモ。
HEWの純正SHC用だが、たぶんGCCでも同じだと思う。
なぜかサンプルにSHC用のサンプルが無かったので独自解釈で移植したところも多少。

割込みベクタの数

HOSのサンプルについているSH7045と比べるとSH7125*1は割込みベクタが増えている*2ので、pacint.src内の_hos_vecterXXXを増やしてやる必要がある。
基本動作は呼び出される→R4を退避して自分のベクタ番号をR4に格納→共通部分に分岐となっているので、ベクタ番号と_hos_vecterXXXの部分を書き換えた奴を用意してやればよい。

ベクタテーブル定義

GCCアセンブラで定義されていたが、SHCだと標準ではCの関数ポインタ配列としてベクタテーブルが定義される。
おそらくアセンブラでもいけるのだろうが、安全を見越して標準添付のヘッダとソースを書き換えた。
先ほど用意したアセンブラに沿って各割り込みハンドラをhos_vecterXXXに置き換えてやればよい。
なるべくコメントなどを破壊しないように置き換えたのでThe手作業、順調に行っていた中では一番時間がかかった。

遅延分岐エラー

そして今回の最難関、デバッガが心底ありがたいということを思い知らされた。
遅延分岐の仕様がSH70XXから変わったらしく、SH70XXでは問題にならなかったアセンブラ命令の組み合わせで遅延分岐エラーが出るようになっており、それがアセンブラで書かれた機種依存部分に引っかかっていた。
割込み処理のとこなので、割込み→呼び出し→例外ベクタにジャンプ→呼び出し→例外(略と無限に繰り返してスタックを食い尽くしていたっぽい。


具体的にはpacctx.srcの_hospac_ena_intと_hospac_dis_intの二箇所、標準だと

rts
ldc r0, sr

となっており、これはスロット不当命令例外を発生させる、RTS遅延スロットLDC Rm,SRという組み合わせになっている、今回は少し無駄になるが、間違いなく動く

ldc r0, sr
rts
nop

という形に書き換えた。

例によって省電力レジスタ

OSのタイマティックが動かないから変だと思ったら、タイマ源のCMT0が動いていなかった。
しばらく悩んでふと以前CMTを使った時計のコードと見比べたら、ただ単純に省電力レジスタを解除してないだけだった。
以前も同じようなことで悩んだような…


今回はSTK-7125EVMのXrossFinderが大いに役立った、これが無かったらおそらく遅延分岐エラーは見つけられなかったと思う。
適当に止めつつ見てたらなぜかベクタ6番に時々飛んでる→ベクタテーブルの異常を疑うが異常なし→例外の種類を調べてステップ実行で飛ぶ直前を突き止める→遅延分岐エラー発見というプロセスで見つかった。
まさかエラーの内容が同じCPUで微妙に違うとは…

*1:おそらくSH71XX系全部

*2:161→255、ただし未使用多し