目次
機種固有
H8-Tinyのシリアル通信
TxD,RxDは共に汎用IOポートと兼用ピンです。RxDの方が、受信許可(RE=1)で有効になってくれるので問題ありませんが、TxDの方は、ちゃんとポート設定レジスタを使用しなくてはなりません。忘れると送信は成功しても、マイコン外には何も信号が出ません。プログラムも問題無く走ってしまうので、うっかり忘れていると原因特定に何時間もかかります。
C言語で...(H8S)
ポインタ注意!
C言語の問題というよりマイコンの仕様なのですが、注意しないとハマってしまいがちな罠を将来の自分の為に記録しておきます。H8は奇数アドレスにワード型のデータを書き込もうとすると、勝手に偶数アドレスに変更してしまいます。アセンブラで記述している時は 、型を意識するので引っ掛かりにくいのですがね。char *p を使ってデータを作っていくプログラムの一部です。
char buff[xxx], *p; p = buff; *(int*)p = 0x1234;
みたいな感じで引っかかりました。それまでx86系が主だったのが災いしました。buff[0] = 0x12, buff[1] = 0x34 となるのを期待したのですが。もしbuffのアドレスが奇数の場合、偶数アドレスに変更されてしまい、
buff[-1] | buff[0] | buff[1] |
0x12 | 0x34 | ?? |
となってしまいます。(添字が負の場合は不定ですけど、この場合 &buff[0] の1コ手前という意味で)
つまり、WORDやDWORD単位でメモリにアクセスすると、アドレスのLSBが強制的にゼロに見なされてしまいます。
構造体注意!
構造体でパディングされるのは割と意識する問題ですが、ビット構造体を使った場合に見落としてしまったので記録しておきます。
struct A { long x:24, y:24, z:24; } *a; struct B { char data[9]; } buff;
このような構造体AとBを作り、BにあるデータをAにキャスト。a = (*struct A)buff; のようにして、a->x, a->y, a->z で読み出そうしたのです。ここで問題が発生しました。
問題は構造体Aにパディングが行なわれていた点。long型を24bitで宣言してあっても、通常のlong型と同様に32bit分確保されていました。つまり、sizeof(struct A) != sizeof(struct B) となってしまい、意図と異なったコードになってしまったということです。
ビット構造体のパディングにも要注意です。