TipsPIC18F14K50でUSBデバイスを作るのにSDCCを使ってみた。PIC18F2550系とは互換性がないという事前情報だったけど、レジスタ並びやUSB用RAMのアドレスが違うくらいで、基本的にUSB周りのコードはほぼそのまま動きそう。ハマったのはSDCC周辺。このあたり、やっぱり非公式ツールチェインは辛い。大きくハマったのは次の2点。bootloaderを使おうとすると色々細工が必要で、信頼できるコードが書けないUSB用RAMのポインタをアドレスから普通に作ると動かないbootloaderについて、まずtext領域を後ろ(0x800以降)にずらすために専用のリンカスクリプトを用意する必要がある。コンパイラオプションにもそれっぽい--code-locというのがあるが、指定しても動かなかった。割り込みベクタはbootloader側がトラップして後ろのアドレスにフォワードしてくれるので、後ろのずれた位置に割り込みベクタを配置する必要がある。こっちはコンパイラオプション--ivt-loc=0x800が正しく動く。crtが通常の配置を想定したコード(割り込み周りかな?)を持っているようで、ふとしたタイミングで暴走する。stdio/stdlib使ってなくても、例えばcharをやめてintでforループを回すと暴走、とか悩ましい問題が普通に起きる。海外サイトでcrtを同じフラグでコンパイルし直せば安定する、という話も見かけたけど、どこまで信じていいかわからない状態で実験を続けたくなかったので、bootloaderは諦めた。回路側でバランスをとったら、なんとかICSP指しっぱなしで書き込みしつつ、USBバスも安定ドライブできた。USB用RAMについてはコンパイラの問題とは思わずに長時間悩んだ。Tableを構成するコード。コンパイラの仕様が変わったのか、バグなのか、2550の時のコードからアドレス変えただけでは動かなかった。bd*)0x0200;的な事をやってアドレスを作ってたんだけど、今回はこのポインタで読み書きしても値が変わっていなかった。起動すれば一応USBはしゃべるんだけど。アドレスリセットとパワーセーブ関連の割り込みだけ届いて、その後はだんまり。トランザクションが届かないってことはエンドポイントが正しく初期化できてないのかなぁ・・・というあたりから問題の目星をつけた。結局コンパイル結果を眺めながらの間違い探し。原因が判明してからは、正しい出力を出せそうな表記を勘を頼りに探すお仕事。通らないと承知で間違ったキャストをコンパイラにかけると、内部的な秘密の型がエラーメッセージを通して推測できるのでオススメ。...とか書くと正しくアクセスできない。1;って感じの__sfr*という特殊な指定が必要。特定用途レジスタの略だと思う。こっちはシステムヘッダを眺めて予想。