モニタ内ではmallocやsbrkのようなヒープ領域を使う関数を一切利用していない。動的メモリはすべてスタック領域から確保される。
しかし、mallocやsbrk自体はモニタとともにROMに格納される。ユーザープログラムはこれらの関数を使用する前にmonitor_set_heap_end()によってsbrkにヒープ領域の末端を通知しなければならない。
機械研のプログラマーの平均的なレベルを考慮すると、この部分は隠蔽されるべきであると考えられるのでサンプルプログラムではservice.cでこの処理を行なっている。
newlibのmallocもしくはsbrkの仕様もしくはバグによって、適切なアライメントでメモリーが確保されないような気がする。とりあえず、sbrkを改造してダブルワード境界に整合されたアドレスを返すようにしたので、標準関数は問題無く動くようになっている。が、正しい方針であるとは思えない。むしろリンカスクリプトを書き換えてheap_endをダブルワード境界に整合すれば正しく動作する気がする。いまのところ実用上の問題はないのでそのままだが、v1.3では修正してテストを行なう予定だ。
EEPROMにプログラムを書き込む際に圧縮を行なっている。DRAMの容量が16Mbitに対しEEPROMの容量は最大で2Mbitなので、DRAMの容量が殆んど無駄になっていると考えたからだ。
まずLZ法で圧縮し、その後Huffman法で圧縮する。LZ法はスライド式の辞書を用い、位置情報に6bit,一致長に2bitを使っている。S-record形式のファイルでは一行の長さが40文字程度であり、一行周期でアドレス情報を格納する為に、ここに規則性があるからである。
一致長は2bitであり、最短一致長が2文字であるので2〜5文字の一致を検出することが出来る。S-record形式のファイルは使用されている文字にかなり偏りがある(S0123456789ABCDEF\n\r\0しかない)ので、8バイト毎に特殊バイトを置いて、続くデータが素のデータか展開すべきデータかを識別するようにしている。
これによって後段のHuffman法で効率的に圧縮がかかると考えたからであるが、実験による根拠は無い。
検出距離を長くし、これ以上検出距離をあげると、H8のパワーではしがたい圧縮速度になりそうなので検出距離を最低限に抑えている。
位置情報に多くのビットを使うと圧縮率が向上することはパソコンでの実験で確認済みである。現状では50-60%程度の圧縮率が10%程度改善する。
探索にツリーを使ったアルゴリズムなら実用的な速度で動くものと思われるが、(問題になるとは思えないけれども)何かややこしい特許の問題もあるようだし、プログラムを複雑にしてまで圧縮率を上げる必要もなさそうなので、馬鹿正直に一致を調べている。
Huffman法による圧縮はS-record形式のファイルに良く効く。圧縮率は平均で45%程度。LZ法を併用ことによる圧縮率の向上は数%に過ぎず、総合的に考えるならHuffman法のみによる圧縮かLZ法のみによる圧縮のどちらかにするべきであると考えるが、せっかく作ってしまった物を捨てるのも勿体無いと思ったので(^^;両方とも実装している。
トラブルが起きたら圧縮機能はすぐさま切り捨てるべきだ。
そもそもS-record形式で2Mbitを超えるプログラムを機械研では作らないし、必要が無い機能なのだ(^^;
当初はシリアルEEPROMの書き込みが遅かったので圧縮するメリットは十分にあったのだが、eeprom.cの改善によってこのメリットは殆んど無くなっている。
秋月で売っているシリアルADCのMCP3208とH8のSCIを繋ぐ場合の注意事項だが、上位ビットと下位ビットが通信時に ひっくり返る。送信データは上位ビットと下位ビットを入れ換えてから送信し、受信データは受信してから上位ビットと下位ビットを入れ換えなければ望むデータが得られないと知っておくべきである。
モニターと直接の関係はないが、忘れてしまいそうなので今のうちにメモしておく。