(H8移植編その2第20回)エンディアン対応のバグ修正

2012/04/29

あなたは 人目のお客様です.

本日は「第6回 12ステップ組込みOS自作本もくもく会」をやっております.

で,前回のエンディアン対応でバグがあって通信できなくなっていたので修正. エンディアンをひっくり返す ntoh4() という関数(ntohl()に相当する)が 16ビットint型を考慮していなくて,H8だとうまくエンディアン処理ができて いなかった.(そして前回は動作確認をしていなくてまあ動くだろう的な感じだったが 実際動かず,今回修正した)

で,以下が修正.

まずは ntoh4() の修正として,以下のようなのを入れた. 従来は p[0] << 24 のようにしてたけどこれだと16ビットCPUの場合には p[0]がint型に格上げされたときに16ビットしかないので, 24ビットシフトで値が消えてしまう(コンパイラもワーニングを出していた). なので(uint32)にシフトしてから処理するように修正.

--- h8_2/h8_19/os/lib.c 2012-04-09 20:51:22.312454000 +0900
+++ h8_2/h8_20/os/lib.c 2012-04-29 15:37:08.296400000 +0900
@@ -180,8 +180,13 @@
 
 uint32 ntoh4(uint32 n)
 {
+  uint32 h;
   uint8 *p = (uint8 *)&n;
-  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+  h  = (uint32)p[0] << 24;
+  h |= (uint32)p[1] << 16;
+  h |= (uint32)p[2] <<  8;
+  h |= (uint32)p[3];
+  return h;
 }
あとこちらで説明 しているが,従来はリンカスクリプトに不備があって binutils-2.21.1 以上だと うまく動作するブートローダーを作成できない(OS側には問題ない). これは面倒なので,この際にリンカスクリプトをアラインメント補正するように 修正する.これはブートローダー側とOS側の両方に修正を入れる. (OS側には問題なく修正は不要だが,アラインメントされていたほうがいいのと 同期して修正したほうがいいので,OS側にも修正を入れる)
--- h8_2/h8_19/os/ld.scr        2012-04-09 20:51:22.312454000 +0900
+++ h8_2/h8_20/os/ld.scr        2012-04-29 15:37:08.296400000 +0900
@@ -42,6 +42,7 @@
                *(.strings)
                *(.rodata)
                *(.rodata.*)
+               . = ALIGN(4);
                _erodata = . ;
        } > ram

いちおう実機で動作確認した.バッチリ動いててとりあえずは安心だ.


メールは kozos(アットマーク)kozos.jp まで