Super Sylphide 進捗状況(2) -- sdcc Maniacs
Super Sylphideの全機能のうち、センサ、C8051F340、SDカードを利用して完璧にセンサのログをとれるようになりました。SDカードのハンドリングは、前の記事『MMC/SDのSPIモードでのbusy信号』にあるように色々と模索した結果解決しました。またログを記録したSDカードをPCでも読めるようにする為のFATですが、これはリファレンスとした純正のUSB-MSD-RDのFATが遅いため、ELMのFatFs-Tinyに置き換えることによって解決できました。
そのうちソースコードを今回しようと考えていますが、今回の記事ではその開発を行うのに利用したフリーのCコンパイラsdccの技をいくつか紹介しようと思います。
続きをどうぞ。
※その後、サーボ用基板が完成しました。
まずは絶対アドレス指定についてです。プロセッサのC8051F340ですが、マニュアルの9.2 Memory Organizationにあるとおり、拡張メモリ(sdccだとxdata領域に相当)を0x0000から0x0FFFまで4096Byteほど内蔵しています。しかしながらUSBを利用するとなると全部を自由に使うことはできず、中間の0x0400から0x07FFまでの1024ByteがUSBのFIFO領域となってしまい、ここを避けて利用する必要があります。
このような場合、とりあえずsdccのコンパイルオプションの中でxdata領域の開始アドレスを指定する--xram-loc、並びにその大きさを指定する--xram-sizeを利用して解決することが考えられます。例えば
とすると、USB FIFO後の2048Byteについてはsdccリンカの裁量でメモリをうまく割り当ててくれます。しかしながら、これではUSB FIFOよりも前の1024Byteの領域は割り当てられず、無駄となってしまいます。
そこで、絶対アドレス指定をすることによってこれらの領域を活用することができるようになります。例えば512Byteのバッファを通常では活用されていないxdata領域の0x0100におくためには
とすることによってbufがその領域に割り当てられ、無駄を回避することができます。今回はUART(シリアル通信)用のバッファをこの方法で確保しました。
あとは小技の紹介のみなので、箇条書きで行きたいと思います。
__criticalキーワードというものがあります。これを利用すると、このキーワードで囲まれた範囲は割り込みを禁止できるので、排他制御をしたい場合はこれでくくるとよいと思います。結局SFRのEAビットを立てたり下げたりしてくれています。
次のTipsは8051に限った話ですが、sdccはビットの比較とビットクリアを一命令で実行、つまりアトミックアクションとしてくれます。例えば
some_bit = 0;
...
というコードを書くと、コンパイラはJBC bit, relという1つのマシンコードに翻訳してくれます。このコードは8051マニュアルの9.1 Instruction setによるとJump if direct bit is set and clear bitだそうです。これを利用してセマフォが簡単に実現できます。
最後にですが、sdccが提供するサポートライブラリによって実現しているintやlongの掛け算、割り算、剰余は、標準ではnon-reentrant、すなわち複数からの同時呼び出しをサポートしていません。つまりintの割り算をしている最中に割り込みがかかり、割り込みルーチン内でintの割り算を行うと、割り込みから復帰後に返るintの演算結果は化けてしまっているということです。これを回避するにはサポートライブラリを--stack-autoでコンパイルしなおし、--int-long-reentでターゲットをビルドしなおせばよいそうですが、これは面倒くさいので、割り込みルーチン内ではこのようなnon-reentrantな計算は行わないという自分規約を作ったほうがよいかと思います。
以上sdccについて気になった部分を述べてきましたが、とても奥が深いと感じました。sdccが吐くアセンブラのコードを読むのも最近は楽しいです。
コメント
コメントする
- 匿名でのコメントは受け付けておりません。
- お名前(ハンドル名可)とメールアドレスは必ず入力してください。
- メールアドレスを表示されたくないときはURLも必ず記入してください。
- コメント欄でHTMLタグは使用できません。
- コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
- コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。
- 投稿ボタンを押してエラーがでなければ、投稿は成功しています。反映されるまでには少し時間がかかります。