Step8はスレッドの実装。
解説もかなり難しく、スタックの切り替え部分など全部理解できたとは思えない。
コンパイル時にも、リンク時にもエラーが出て対応に苦労した。
とりあえず、動いたログ。
Machine Name:os myaccount$ sudo cu -l /dev/cu.PL2303-00001004 Connected. kzload (kozos boot loader) started. kzload> load ~+lsx kozos Sending kozos, 24 blocks: Give your local XMODEM receive command now. Bytes Sent: 3200 BPS:348 Transfer complete XMODEM receive succeeded. kzload> run starting from entry point: ffffc020 kozos boot succeed! start EXIT. test08_1 started. > echo ABC ABC > echo abc abc > exit test08_1 exit. command EXIT. system error! ~. Disconnected.
コンパイルエラーの対応
コンパイル時に出たエラーは static int setintr(softvec_type_t type, kz_handler_t handler)
の中の次の行。
static void thread_intr(softvec_type_t type, unsigned long sp);
このstatic
がどうもダメなようで、削除。
そして、下の方の thread_intr
の実際の実装部分。
/* 割込み処理の入口関数 */
static void thread_intr(softvec_type_t type, unsigned long sp)
この行のstatic
を削除し、次のように。
/* 割込み処理の入口関数 */
void thread_intr(softvec_type_t type, unsigned long sp)
これでコンパイルは通ったけど、今度はリンクエラー。
リンクエラーへの対応
リンクエラーは次のようなメッセージが出た。
kozos.o: In function `.L14':
kozos.c:(.text+0x115): undefined reference to `___mulsi3'
collect2: ld returned 1 exit status
どうも、.L14
の中でコールしている__mulsi3
が無いということらしい。
しかし、どちらも見覚えのない名前。
gcc -S kozos.c
でアセンブラ出力させると、.L14
はthread_run
の中の(分岐先の)ラベルで、__mulsi3
はthp = &threads[i];
のアドレス計算で使われている34×iの乗算を行う関数らしい。34はTCBのサイズ。
該当場所は、kozos.c
の static kz_thread_id_t thread_run(kz_func_t func, char *name, int stacksize, int argc, char *argv[])
の中の、次の部分。
/* 空いているタスク・コントロール・ブロックを検索 */
for (i = 0; i < THREAD_NUM; i++) {
thp = &threads[i];
if (!thp->init.func) { /* 見つかった */
break;
}
}
で、この部分を乗算を使わないように次のように書き換えた。
/* 空いているタスク・コントロール・ブロックを検索 */
thp = threads;
for (i = 0; i < THREAD_NUM; i++) {
if (!thp->init.func) { /* 見つかった */
break;
}
thp++;
}
筆者の坂井です。ブログ拝見させていただきました。
上記リンクエラーですが、ご指摘のとおり構造体のサイズ計算のために
乗算用のライブラリ関数を呼ぼうとしてしまうためです。
構造体にダミーのメンバを追加して、サイズを2の累乗に合わせることで
回避できます。たしか12ステップ本の第1章あたりで説明していたように
思いますので、そちらも参照いただければと思います。(場所を失念…)
では、失礼いたします。
著者の方直々にコメントいただけるとは、恐縮です。
第1章で説明されていましたか。読みなおしてみます。
ありがとうございました。
ちょっと見てみたところ、第1章p.38にちょっと記述があり、詳しい説明は第11章p.421にありました。p.420のリスト11.9のstruct _kz_msgboxが問題の構造体です。
1章だと思っていたら、詳しい説明は11章でした。問題が起きやすい部分なので、もっと手前で説明しておくべきでした…。
詳しい記述場所まで教えていただいてありがとうございます。
p.38のNoteですね。
確かにp.420からの説明で理解できました。
gcc 4系を使っているのが問題なのかと思っていましたが、H8の制限によるものなんですね。
__mulsi3をライブラリlib.cに定義できたら便利ですね。
後で試してみたいと思います。