2009-04 ← → 2009-05PIC
現在進行中のスレッド:
続:HIDmonを改造してA/Dにする。 / デジタルテスター
5月になるとマイコンを作りたくなる病気? --- 何それ。
今月の目標
- 今月も相変わらずUSBクッキング。
- これまでと違うのは、LowSpeedを卒業してFullSpeed USBに移行したこと。
- テーマとしては、ARM LPC2388 と PIC 18F2550 のUSB同時進行を行う。
~
- とりあえずメーカー提供のUSBサンプルソースをビルドできるようにするところから始めようと思う。
~ ~ ~ ~
続:PIC入門 C18とsdcc
- sdccへの移植作業というものをやってみた。
- 結構骨が折れる。
- というか、いまだにビルドが通らない。
- 別のソースツリーと適度に混ぜ合わせたのが敗因なのだろう。
- もっと機械的にやらないとだめか。
- C18用に書かれたbootloaderのソース全てに mplab2sdcc.pl というperlのスクリプトを適用。
- Makefileはsdcc版firmware-dのものを借用。
- いろいろエラーする。構造体関係がボコボコ。
- union内の複数の構造体メンバーで名前衝突があると駄目。
- byte data[SIZE]; がだめだった。これもたぶん名前空間の衝突。
- ごにょごにょ直したり、あるいはスルーしたり(動かないけど)
- リンカースクリプトもだめっぽい。
- これもsdcc版firmware-dのlkrを見ながらみようみまね。
- 結局、以下のような書き方がだめなので、だめだった。
extern volatile far BDT bdt_data.ep_bd_pairs[0].ep_bd_out; //Endpoint #0 BD Out
extern volatile far BDT bdt_data.ep_bd_pairs[0].ep_bd_in; //Endpoint #0 BD In
extern volatile far BDT bdt_data.ep_bd_pairs[1].ep_bd_out; //Endpoint #1 BD Out
extern volatile far BDT bdt_data.ep_bd_pairs[1].ep_bd_in; //Endpoint #1 BD In
extern volatile far CTRL_TRF_SETUP bdt_data.SetupPkt;
extern volatile far CTRL_TRF_DATA bdt_data.CtrlTrfData;
つまり、構造体のメンバーをexternする書き方だ。
- いまのところここがだめなのでリンク出来ない。
しかし、 mplab2sdcc.pl というperlのスクリプトはそれほど悪くない。手でやるのに比べると比較的安全。
~ 感想?
- 同じC言語なのに文法(表記方法)がかなり違うってどうよ。
- 違うのは文法のほんの一部だけだけれど、その違いによる問題が全体ソースの30%くらいに散在しているので苦痛。
- Makefileとかリンカースクリプトの違いを合わせるのは、かなり苦痛。
- とても生産的な作業とは思えない。
~ 一応ビルドだけ出来た。
- コードサイズは限りなく4Kに近い。
- ためしに、strcpy(t,s) {while(*t++=*s++);} みたいな1行コマンドをsdccに食わせて、-mz80 , -mpic14 , -mpic16 , -mmcs51 などをやってみた。
- 結果は、惨憺たるものだった。
教訓
- sdccがサポートしているMPU様におかれましては、16ビット以上の整数変数やポインタを使用するのは著しくコード効率を落としますので、お覚悟。
- まして2つ以上のポインタを使用した処理などを書いてはいけない。
- 結局、変数は全部uchar とかbyteで我慢して、定数を使用したコーディングを心がける。
- 基本的にやっていいのは8bitポートのbitアゲサゲとtimer waitだけということで。
~ ~ ~ ~
C級出版:Lattice キター!
- 届きました。
写真(省略されました)
- 難易度はさらに上がっている。
- 3.3Vが必要。
- 33MHzのオシレータが必要(これも3.3V動作品)
- JTAGインターフェースを持ってないとダメ。
- 論理合成ツールはライセンスが必要。6ヶ月更新。
LatticeMico32 というCPUマクロが使えるらしい。
-
2200LUT程度で実装出来るらしいので、付録基板でもOK。
-
主な特長と利点
ラティスFPGAデバイス用に最適化 特長を性能強化した項目 RISC アーキテクチャ 32 ビット・データ・パスと32ビット命令 32 汎用レジスタ 最大32個の外部割り込みを処理 オプション命令とオプションのデータ・キャッシュ 二重WISHBONEメモリ・インターフェース(命令及びデータ)
-
エリアと性能を最適化する3つの構成
-
ベーシック構成
乗算器無し マルチサイクル・シフタ キャッシュ無し
-
標準構成
乗算器有り パイプライン型シフタ 8Kの命令(I)キャッシュ有り、データ(D)キャッシュ無し
-
フル構成
乗算器有り パイプライン型シフタ 8Kの命令(I)キャッシュ有り、8Kのデータ(D)キャッシュ有り
-
面白そう?
-
LatticeMico32用のuCLinuxもあるとか。
~ ~ ~ ~
別のページが出来ていた。
AVR-USB is now V-USB
V-USB was formerly known as AVR-USB.
The project has been renamed to avoid conflicts with a trademark of Atmel Corporation.
少し安心した。
心のよりどころが消滅したかと思った。
~ ~ ~ ~
【ESC SV 2009レポート】 Atmel vs Microchip
- 市場占有比はおいといて、個人的見解として
- 同一クロックのAVR:PIC18Fのパフォーマンス比は10:1くらいではないかと感じている。
- つまり基本的にPICのCPI(cycle per instruction)は4なので、同一クロックのAVR:PIC18Fの命令実行速度の開きは4:1なのだが、
- さらに、同じことをするのに必要なステップ数がPIC18Fの場合AVRの2.5倍くらい必要だと見た。
- ステップ数の比率がもろに実行時間に響くので10:1ということだ。
- 何よりPICのUSBの遅さがまずこれを証明しているのではないか。
~
- うそだと思ったら、sdccとavr-gccの両方で、ポインタを引数にする簡単な文字列処理の短い関数を書いて、アセンブルリストを見比べるなり、ステップ数を数えてみよう。
- この2.5倍の非効率さの大半はsdccの最適化のやる気のなさが原因なので、C18にするとすこしはましになるのかもしれないが、
- PIC16Fシリーズだとどんなにコンパイラが頑張ったところで無駄なので意味が無い。
結局のところ、PICを使う(選ぶ)人たちは、PICの変態アセンブラが好きなのか、それともデバイス選択上のしがらみとか(PIC18Fの場合ではUSBエンジン付きで安いとか)でしかたなく使っているのだと思う。
~ ~ ~ ~
- NEC78K版AVR/PICライター に昇圧アタッチメントを
つけてその先にPIC 16F84/16F84A用の書き込みアタッチメントを作ってみた。
- 作ったといっても単にICソケットを配線しただけなんだけど。
- 手持ちのPIC 16F84Aと16F84を認識して読み出しが出来た。
- 最初は16F84Aの設定で16F84を読もうとして全く動作しなかったのであせった。
~
- HIDaspxライターがデバイスを自動認識してくれるのがこれほど便利だということに今頃気づいたのだった。
- それから、もうRS232C接続の古い秋月PICライターを使うことは無いだろう。
- 転送も遅いし、書き込みソフトが非常に使いにくかった。
- writer509のw509.exeは快適だ。
~
- 今更PIC16でもないだろうと思ったけれど、sdccが使えるので、ちょっと使う分にはそれほど困らないはずだ。
- 16F84Aのアセンブラは完全に忘却の彼方にある。ものすごく使いにくかったことだけは覚えている。
~ ~ ~ ~
FPGAは己を映す鏡
- そうなのか?
- まあ1からCPUを作れといってもたいしたパフォーマンスのものは作れまい。
- パイプラインステージの設計とか面倒くさいからな。
- バグ取りも大変だし。
- そいで、どっかからフリーIPを借りてくるとかお手本見ながらやることになる。
- 一応LatticeMico32 はオープンIPコアライセンスで無償。ハードウエアの実装と配付は別個のライセンス契約が不要らしい。コンパイラはGNU GPLのもの(gcc)が使える。
- 一見MIPSに似ているし。
- まあ、コンパイラとか揃えるのが面倒くさいんだったら、既存のMIPSそのものにしておくのもありだ。--個人でやるぶんには。
- だとして、次の問題がメモリーインターフェースとか周辺の設計。
- FPGAを使うことで設計の自由度が大きくなるということは、自分が面倒をみなきゃならない守備範囲があまりに広くなりすぎるというわけだ。
- 一人でピッチャーと内野と外野を全部こなすようなもの?。
~
- そのまえにパラレルインターフェースが絶滅した世界でどうやってJTAG書き込みを行うかという命題をまず解かなければならない。
~ ~ ~ ~
続:PIC入門 C18とsdcc
相変わらず、無駄なハッキングを続けている。
~
- どっかのサイトで拾ってきたフルアセンブラのブートローダーをビルドする試み。
- 失敗。
- MPASMWIN.EXEの文法と、gpasmの文法が違いすぎてだめ。
- どこが違うんだろう。よく分からないけど、全面的にだめな感じ。
- ニモニックは同じなので、擬似命令系に互換性がないのか。
- ぱっと見た限り、たいした違いはないような気がしたが・・・。
- とりあえず解決した。
- 原因:#define MACRO(x) (x+1) がだめなようだ。
- gpasmでは引数付きのマクロ展開はサポートされていない。
- 他の原因は gpasm に -yオプションを入れないとPIC18Fの命令を解釈しない。 -p CPUでPIC18F2550と書いても無駄だ。
- さらに-勝手に改蔵-+-勝手に改蔵-+-勝手に改蔵-+-勝手に改蔵-+
- bootloaderからbootloadHIDをデバッグしたいので、アドレスを0x800に移す。
- アドレスじか撃ちのorgが多くて困った。
- PICが4455だったので、2550に変更。これもINC決め撃ちだったので困った。
- ビルドはOK。
- しかしbootloadHIDとしては動作せず、不明デバイスになる。
- LEDも点灯しない。
- たぶん、こいつも暴走しているのだろう。
- もちろん Junper判断はコメントアウトしているし、こいつも割り込み使っていないっぽいし、じゃあ何が悪いのか。
- MPASMWINでやれって?・・・うむむ。
~ ~ ~
- MCHIPのfirmware-B相当のブートローダーのsdccビルド。
- 一応ビルドだけ完了。
- 但し、Flashへの書き込みの部分のソースがコンパイルエラーになるのでコメントアウトしている。
- bootloaderを書き換えるテストは面倒なので、アプリケーション側にアドレス変更して書き込み。
- 起動してみたがだんまり。
- こういう場合、どうやってデバッグすればよいのだろう。
- シリアルポートはPC接続側に余計な回路を制作しなくちゃならないので面倒だ。
- メモリーに足跡を残したいけれど、bootmonがないのであとで見る手段が無い。
- シミュレータが使えれば良いのだけれど、USB側のシミュレートなんかやってくれるはずが無い(と思っている)ので多分無理だろう。
じゃあLEDチカチカしか、ないな。
~ ~ ~ ~
続:PIC入門 LEDがチカチカしない
- bootloaderのmain()関数の頭にled_blinkを埋め込んだが、一切反応しない。
- firmware-dのmain()関数の頭に同じようにled_blink()を埋め込むと正しく(?)チカチカする。
- ところで、両者のcrt0.cとlinker scriptとは完全同一だ。
- Makefileは、ソースのファイルセットが異なるところと -D __18F2550 が追加されているところ以外は同じ。
- あと、割り込みハンドラーが異なっているが、そもそもbootloaderのほうは割り込みが使われていないっぽい(?)のでこれでいいのか?
- 割り込むったって、main()の先頭ではUSBのInitializeすら呼ぶ前なので、割り込みリソースはないはずだ。
結局、調べ方としては、正しく動いているほうと、だめなほうをしらみつぶしに見比べていくしかないのか。
- 少しだけ進展
- io_cfg.hが異なっていた。これによりLEDのピン配置が異なるという罠。
- 入れ替えると、LEDチカチカはパスした。
- しかし、mybootを起こしてreadを実行するとfailする。
- ブート領域内でしか、Flashの読み出しが出来ないというのか?それともコンパイラの違いによる動作不良???
~ ~ ~ ~
- http://slashdot.jp/it/09/04/18/1241233.shtml
- シェーダーバリバリなのでGeForce 8800GTXまたはRADEON HD4850以上がないと実行出来ないが、ビデオがYouTubeに上がっているので誰でも見ることが出来る。
- 4Kイントロとは思えない。64Kでも無理だろうと思うレベル。
- 実際コードは7zipとか高圧縮に圧縮され自己展開するので、17Kとかそれくらいだと思うけれど
- コードサイズ無制限だとしても、こんなコード書けそうに無い。
- こちらのPICのコードもサイズが4K以上あるが、まだびくとも動かない。
~ ~ ~ ~
続々:PIC入門 だだだ駄目だった。
相変わらずアホな試行錯誤中
- 一体何をやっているのか?
- diolanというところが作成して、GPLで公開しているHIDなbootloaderがある。
- これはフルアセンブラ(MPASM用)で書かれた、PIC18F4455用のHID bootloaderだ。
- こいつを秋月AE-18F2550で動かそうとしているのだが、
- 動かない。
- LEDの点灯はOK。
- USBが不明なデバイスになり、PCから認識しない。
- 最初はgpasmの問題かと思って、MPASMWINでビルドしなおしたが、駄目だ。症状は同じ。
- 原因として考えられるのは、コンフィグレーションの抜けとか、微妙にだめなところがあるとか(たとえばXtalの周波数が違うとかfuseの設定値が違うとかそんなやつ)
- あと、試す環境がMCHIPのbootloader(Firmware-B)から起動して試しているので駄目という可能性も残っている。
- 一応org命令は全部書き換えたけれど、もしかしたら0x0000〜0x07ffのどこかをアドレス決め撃ちで叩いていたら駄目なんだろう・・・。
- PICライター引っ張り出すのは面倒くさいなぁ。
FullSpeedのUSBって、難しいよぉ・・・
~ ~ ~ ~
続々々:PIC入門 アドレス決め撃ちするなボケぇ!
- 予想は的中した。
- USBディスクリプタを割り込みベクターの直後アドレスに置いて、そこを決め撃ちしている。
- そのような書き方をされると、bootloaderから動かすときにポインタの上位アドレスがゼロ以外になる
場合を考慮していないので、当然バグる。
- でたらめなディスクリプタを返されて、おかしくなるわけだ。
がっがりだ
原因はgpasmのせいではなかった。 一応晒しておこう。
-
usb.asm
;-------- Get DSC_DEV descrptor address usb_sm_ctrl_setup_dsc_dev movlw LOW(USB_DEV_DESC) movwf pSrc movlw USB_DEV_DESC_SIZE bra usb_sm_ctrl_setup_sdtrq_getd_end usb_sm_ctrl_setup_dsc_dev_end ;-------- Get DSC_CFG descrptor address usb_sm_ctrl_setup_dsc_cfg movlw LOW(USB_CFG_DESC) movwf pSrc movlw USB_CFG_TOTAL_SIZE bra usb_sm_ctrl_setup_sdtrq_getd_end usb_sm_ctrl_setup_dsc_cfg_end ;-------- Get DSC_STR descrptor address usb_sm_ctrl_setup_dsc_str ; Get String Descriptor ; Point to wValue low byte movf (SetupPktCopy + bDscIndex), W ; String Descriptor Index, Z flag affected bnz usb_sm_ctrl_setup_dsc_str_mfg usb_sm_ctrl_setup_dsc_str_lng movlw LOW(USB_LANG_DESC) movwf pSrc movlw USB_LANG_DESC_SIZE bra usb_sm_ctrl_setup_dsc_str_end usb_sm_ctrl_setup_dsc_str_mfg movlw LOW(USB_MFG_DESC) movwf pSrc movlw USB_MFG_DESC_SIZE usb_sm_ctrl_setup_dsc_str_end bra usb_sm_ctrl_setup_sdtrq_getd_end .... ;-------------------------------------------- usb_sm_ctrl_setup_sdtrq_getd_end movwf Count bsf ctrl_trf_mem, _RAM bra usb_sm_ctrl_setup_sdtrq_end .... #
-
LOW(xxx) だけ設定して、HIGH(xxx)を使っていないところを見ると、置き場はゼロページ限定だ。
-
しかもやたらそんなコーディングが多い。心配になってきた。
-
そこまでしないと2Kに入らないのかなぁ・・・。
~ ~ ~ ~
続々々:PIC入門 降参だ。
- しかたがないので、MPASMWINでビルドして、0番地からリンクするようにリンカースクリプト等を戻し
- PICの型番だけを18F4455から18F2550に変えた。
- fuseも注意深くセットし20MHz HS_PLLにした。
- diolanのオリジナルソースとの差分も取って、自分の変更箇所が本当に間違っていないかを再確認した。
- 外部のPICライター(高電圧プログラミングモード)で焼いてベリファイも行った。
しかし、USBに繋ぐと「不明なデバイス」になってしまう。
- こうなると、もうどこが悪いのか何も分からなくなってしまった。
- LEDはちゃんと点灯するので、起動していることだけは確かだし、USB挿抜を行うと「不明なデバイス」が出たり消えたりはするので、全く動いていないわけではないと思う。
- 考えられるのはディスクリプタの書き損ないとかアドレスが100番地より上になったとかそんな原因しかないけれど、リンカーMAPを見る限りではそのような問題は起きていない。
一体、なんなんだ!
~ ~ ~ ~
続々々:PIC入門 方針変更
- diolan製のbootloadHIDは、もう諦めた。
- firmware-Bのsdcc版の作業に戻る。
~
- とりあえず、firmware-B(sdcc:org 0x800)をfirmware-B(C18:org 0x000)で書き込めるバージョンにして、
ビルド。
- ・PIDを変えて書き込み、起動。OK。
- ・PCに繋ぐとドライバーを要求される。
- ・ホスト側のプログラムを用意。これはAVR_monitを改変したものだ。
- ・ドライバーはlibusbを入れる。
- ・ホスト側のプログラムにバルク転送のベンチマークテストを用意した。
- ・CMD=00 ReadVersionの戻りパケットが4バイトサイズだったので、これを64バイトに増加。
-
・ベンチマーク実行。
AVR> bench bulk write start bulk write end 64000 2000 s 32000 byte/s AVR> AVR>
-
AVRじゃなくてPICだけど。
-
それから、64byteのバルクパケットの送信1000回に2秒掛かっている理由は、ホストPCからの送信とデバイスからの送信を1mSフレームごとに交互に行っているからなので、送受の合計で言うと転送量はこの倍になり、64kB/秒である。
- 片道で送り続けるような転送だと2回目のWriteはハングする。
- PIC側ではバルク転送のくせに転送順序が暗黙に決まっているのだ。
- しかも、1パケットは64バイトまでで、それより長いと(つまり分割されるような送信は)だめだ。
- また、UHCIだと遅いんだろうなぁ・・・おそらく。
- LowSpeedのときのちょうど8倍にしかならないのが、これまた笑える。
- 12Mbps / 1.5Mbps のそのまんま。
~
分かったこと
- ReadVersion のような、ほんの3行ですむようなCMDの実行は、PIC内部で実質オーバーヘッドなしで実行されているようだ。
- では、仮想COM:ポートだとなぜ16〜20kB/秒しか出ないのか?
- 予想される理由は、1mSフレームに64バイトのバルクパケットを最大1回までしか送信できないファームウェア仕様だからではないか。
- しかも、RS232送信バッファが空であることを伝えるためのヌルパケットも間に入れたりとか、あるいは送受を交互に行う必要があるならば64kB/秒の1/2とか1/4にならざるをえないので、そのような結果になる。
- RS232Cのボーレート換算で112kbpsしか出ない理由はおおかたその辺だろう。
ということはLowSpeedで、しかもソフトウェアだけで行っているAVR-USBの仮想COM:ポートが38400bpsの速度を保っているのはほんとうに奇跡だな。
~ ~ ~
AVR> bench 4000
bulk write start
bulk write end 256000 2000 s 128000 byte/s
AVR> q
Bye.
- 128kB/s なので1Mbit/sくらい。
- これは下りだけのトラフィックなので、両方をあわせると256kB/s
- ハブ無しと比較すると4倍速い。
- LowSpeedだけでなく、FullSpeedデバイスも、USB2.0Hubを通すことでPCから見てHighSpeedに見えるわけか。
CDCも原理的に速くなれるはずだ。LowSpeedではUSB規格違反なのでHub(?)が通してくれなかったが・・・。
- はずだとおもって試したら、逆に少し遅くなっていた。変だな。
~ ~ ~ ~
続々々:PIC入門
- 今回作成したPICのUSB転送ベンチマークを公開します。
read more:PIC入門
続:PIC入門 というかPIC変態アセンブラ入門
- めげずにdiolanのUSBデバイスが不明デバイスになる件を追求中。
- PICアセンブラにだいぶ詳しくなった。
- しかし、これまた役に立たない知識なんだな。
~ PIC18では、データメモリーの上位8ビットアドレス指定はバンクセレクトレジスタBSR(8bit)を使用して行うことが出来る。
- 下位8ビットはmovwfなどのオペランドで指定する。
- ところが、PIC16からPIC18になって追加された1bit修飾子{a}により、これが
例外だらけとなる。
- a=1のときはまさに上記のとおりのアドレス指定(BSR*256+offset)だが、
- a=0のときはAccess Bankが使用されBSRの値は完全無視される。
- Access Bankとは、 0x0000〜0x005fまでのRAMと 0x0f60〜0x0fffまでのSFR(ポート)をくっつけたようなページだ。
- 言い換えると、0x0000〜0x005fのイメージ(虚像)が0x0f00〜0x0f5fに現れて、アドレス上位が0x0fに固定されたアクセスである。
で、diolanのローダーはどのようなBSR管理を行っているか調べてみた。
- DATAメモリーの変数領域は(ハードウェア固定のUSBバッファを除けば)0x00〜0xffまでのページ内に収まっている。
- そのうち、0x00〜0x5fまでの範囲であれば a=0 でアクセスする。
- 0x60〜0xff までの範囲のRAMをアクセスしたい場合は a=1 でアクセスする。
- おそらくMPASMWINが自動でaのビットを決めているのではないかと思う。
- もちろん、SFR(ポート)を叩く場合は a=0 でアクセスする。
そういうわけで 通常は BSR=0 固定という使い方だ。
- ハードウェア固定のUSBバッファを触るルーチンに限っては、直前にBSR=4(USB RAM:0x0400)にして、終わったらBSR=0に戻していた。
- あとは、BSRに依存しないアクセス方法(movffというメモリーtoメモリー転送。これは両方のオペランドが12bitづつ存在するアブソリュートアドレッシングだ)あるいはインデクスレジスタを使用するアクセス(これもBSRに依存しないリニアなアクセス)となっていた。
- 一応BSR=0の初期化は入れたし、BSRがらみのBugではないことも確認済み。
- でも、「不明なデバイス」は直らない。
いろいろ調べたが原因は見つからない。
- ためしにdiolanのオリジナルソースをそのままMPASMWIN上でビルドし、出来上がったhex
のfuseビットだけ、Mchipのブートローダーの値に差し替えて焼いてみた。
- でも、「不明なデバイス」は直らない。
- これって、いったい。
最初から動かないソースがUPされていたのか?
- それとも、回路そのものが違うのか?
- 4455と2550はたしかに異なるが、incヘッダーを比較した限りでは、増えたピンの定義部の追加だけだった。
- ブートローダーのモードスイッチ、あるいはモード記憶EEPROMの値によってユーザーアプリケーションに分岐する処理が入っているが、これが発動した場合は無限ループを実行する。
- その場合USBも初期化しないので、単なる電源コードになる(筈)
- 誰かdiolanのbootloadHIDを動かした人、居ないかな?
~
続:PIC入門 しつこくbootloadHIDの続き
-
LEDチカチカしかできないので、それで追ってみるテスト。
-
べつにハングしているわけじゃあない。main loopにled blinkを入れるとちゃんと点滅を繰り返している。
;-------- Process STANDARD request usb_sm_ctrl_setup_sdtrq
-
のところでUSB Setup Phaseを見ていると、bRequest=9 (SET_CFG)だけが1回呼び出されていた。
-
普通はGET_Descriptorとか呼ばれるはずなのに。
- で、SET_CFGするとHID_ENDPOINT(interrupt IN)を設定する処理が走るが、このへんはべつにどうということはない。
- まあとにかく、USBがconfigureされずに、PIDもVIDも取得できないで0000,0000の状態なのでパケットキャプチャも出来ない。
- それはいいんだけれどSnoopyProが不調で、libusbのデバイスに対してパケットキャプチャが何も表示されなくなった。
- MCHIP-USBドライバーのデバイスに対してはちゃんとキャプチャーできるのに。
- 昔はできてたんだけどなぁ。libusbを新しくしてからなのか?
- 逆に、sdcc版のコードを縮めるとかasmに落とすとか出来たらいいのにと思いつつ。
まあ、端的に言ってしまうと、PIC18は不幸だ
~ ~ ~ ~
続々々:PIC入門 もう諦めた。
- diolan製のbootloadHIDは、ほんとうに、もう諦めた。
- 現象としては、ホストPCからのGET_Descriptorに対して反応してくれない。
- なので、VID,PID=0000,0000のままであり、「不明なデバイス」となる。
- しかし、PIC側のコントロールリクエスト受付ルーチンには、SET_Configだけが
受け付けられていて、GET_Descriptorのリクエストが届いてないという感じだ。 - ホストPCからはSET_Configなど発行していないので、どこかでアドレスが狂っているとか、破壊されたとか、USB SIEの扱いが間違っているとか、そんな感じだが、もう試行錯誤は疲れた。 - asmソースはやや古いMicroChip製のMchipUSBがベースになっているようで、微妙に処理がバグっているらしい。 - が、アセンブラとCを見比べながら原因を探るのはもう限界にきたようだ。
- しかたがないので、sdcc版bootloader(PICmon)のほうのソースをすこしきれいにして、
ブートエリアにも焼けるように修正してPIC入門 のページに置いた。
- ただし、まだFlashを焼くことはできない。
~ ~ ~
続々々:PIC入門 Cとasmの混在が微妙に不便である件。
sdccとgpasmの混在ソースを書こうと思った。
- 理由は、コードサイズ削減のためである。
- しかし、微妙に不便なので、やめようかと思っている。
どういうことか?
- diolan製のbootloaderのコードはコンパクトであるが、正常機能していない。
- sdcc版のbootloaderは(ほぼ)正しく機能するが、コードサイズがでかい。
そこで、両者の合体を考えた。
- ドライバー的な、触らなくても良いようなコードはasmで書く。
- メインルーチン的な部分だけをCで書く。
- あるいは、バグっているパーツだけを、別の実装と差し替えて凌ぐ。
ところがだ。
- PIC18Fにおいては、Cとasmを混在して記述する場合には問題を抱えている。
- その問題とは、BANKSELあるいはBSRレジスタ問題だ。
- その他には大きな問題はない。(引数スタックの扱い問題がややあるが)
- asm側では BSR=0であることが強く要請されていて、局所的にBSR!=0にした場合でも局所ブロックから抜ける際にBSR=0の初期化が必要だ。
- C側では BSRの値は全く保証されないのであって、変数アクセスの前には常にBANKSELを行っている。
- このため、asm側のルーチンのエントリー全てにmovlb 0 を入れなければならない。
- しかし、グローバル変数をCとasmで共有した場合に、asm側で参照する変数がBSR=0の場所にあるという前提がくずれるので、asm内の各所にBANKSELを入れるはめになるかもしれない。
- 結果的に、コードを縮めることができない(かもしれない)
- 不幸だ!
- しかし、打開策を思いついた。
read more:PIC入門
~ ~ ~ ~
- SH4なgccをMinGWでビルドしなくちゃいけなくなった。
- やったことないぞ。というかMinGWでクロスgccを作るってどうやるのかな。
- MSYSで出来るのかな?
そうだ、google先生に聞いてみよう。(ぁれ?)
~ ~ ~
- gccとbinutilsを展開したディレクトリの根元で
$ ls
gcc-3.3/
binutils-1.24/
$ mkdir _gccbuild
$ mkdir _binbuild
$ cd _binbuild
$ ../binutils-1.24/configure
...(略)....
$ cd ../_gccbuild
$ ../gcc-3.3/configure --target=sh-elf \
--prefix=/usr/local/sh-gcc \
--exec-prefix=/usr/local/sh-gcc \
--enable-languages=c,c++ --with-gnu-as --with-gnu-ld \
--with-newlib --with-gxx-include-dir=/usr/local/sh-gcc/H-i686-pc-cygwin/sh-elf/include
みたいなことをやるんだけれど、一発でmakeが通ったためしがない。
- なんかstdio.hがないとか言われる。
- やっぱりnewlibも一緒にやんないとだめかな。
- でもgccが出来てないのにnewlibが作れるはずがないので、
- やっぱり鶏卵だよね(Y/y)
- 結局どっかからincludeをコピってきて適当につじつまをあわせる俺。
ビルドは出来たんだけどね。Cygwinで。
これからMinGWに挑戦。
- やっぱり不安になってgoogle先生に聞いてみた。
MinGW - クロスコンパイル環境
- http://www.yynet.org/~yokota/INSTALL/MinGW/
- ふむふむ。つまり、Linuxで全部やれ、と。
~ ~ ~
- こ、これは何かの暗号にちがいない。
早速、解読だ。
- G .. G .. E
- O .. O .. L
GGEOOL?いったいどういう意味なんだ。
~ まてよ、
- G .. O .. O .. G .. L .. E グーグル!
- サミュエル・モールスさんの誕生日だった。
~ ~ ~
- http://www.yynet.org/~yokota/INSTALL/MinGW/
- すこしコツがわかってきた。
- ターゲットCPUで使用するヘッダー類はあらかじめインストール先のディレクトリにインストールしておかないとだめなのだ。
- でないと、gccのビルドのときに失敗する。
- Linux上でのクロスコンパイラのビルドは非常に速く感じるし実際に速い。
- cygwin上では1時間以上掛かる。何が違うのだろう。CPUのクロックはさほど変わらないのに。
~
- できたてのほやほやのクロスコンパイラに、古典的な"Hello World"をprintfするプログラムを入力してみた。
- a.exeが出来た。
- Windowsマシンに転送したら、見事、"Hello World"が表示された。
- あたりまえのことだけれど、ちょっと感動。
- だって、全部Linux上でWindows PEの実行ファイルがリンクまで出来るんだよ。
- 理論的にはコンパイラの教本のとおりなんだけど、すごいなぁ。
- http://d.hatena.ne.jp/yamaguchi_yo/20051127
- Linux環境が快適なので、host,build,targetが全部異なるコンパイラをビルドしようとした
- しかし、binutilsが作成できずに断念。
- じゃあMSYSでやってみる?
- なんだか二転三転して進まない・・・。
~
- 上記のWinAVRのビルド方法を参考にしながら、MSYSベースでbinutilsのビルドに成功した。
-
intl/localealias.cのビルドにて
-DLOCALE_ALIAS_PATH=\"$(aliaspath)\"
-
の定義がおかしな文字列になってエラーするのだが、適当にお茶を濁してスルーしただけで
-
他は大丈夫だった。
-
- 基本的にMSYSでクロスコンパイラが作れるようだが、
- いくつか問題があるようだ。
- fork pipe SIGNALのいくつかが使えない。
- このため、fixincl.exe とかいくつかのツールのビルドが通らない。
- 適当にスルーしてみたが、collect2がもろにそれらに依存しているため、作れない。
- どこかにパッチがあるのだろう・・・おそらく。
ここで、素朴な疑問
- collect2では fork pipeを使っているにも拘らず、Windows上でMingwのcollect2.exeが動いているのは何故?
- WinARM,WinAVRその他MinGWベースのクロスコンパイラでは、collect2.cをどのように改造してビルドしているの?
- MinGWのサイト(実際はSourceForge)にgccバイナリーはあるけれど、gccのソースは見当たらない。---何故?
~
Cygwin + MinGW + GCC 相談室 Part 3
~ AVR-gcc on mingw32構築法
Building GNU-Toolchain on Windows systems
抜粋 9. FAQ
I have Problem with Collect2.exe during the built of GCC.
Open with a standard text editor the following file:
x:\msys\[MinSYS-Version]\home\[PcName]\gcc-[Version]\gcc\config\avr\t-avr
and add the follwing line to the file:
USE_COLLECT2=
I have Problem with fixinc.sh and fixinc.o during the built of GCC
Open with a standard text editor the following file:
x:\msys\[MinSYS-Version]\home\[PcName]\gcc-[Version]\gcc\fixinc\mkfixinc.sh
and add the bold marked line at the shown position:
# Check for special fix rules for particular targets
case $machine in
alpha*-dec-*vms* | \
arm-semi-aof | \
avr-*-* | \
hppa1.1-*-osf* | \
hppa1.1-*-bsd* | \
i370-*-openedition | \
_ m68k-coffをキメた
~ ~ ~
- gcc-3.3 と並列な場所に用意したビルドディレクトリ (例 _gcc_build/ )の
_gcc_build/gcc/Makefile 内の USE_COLLECT2 = collect2$(exeext) を USE_COLLECT2 = に変更したらなぜかビルドが通ってしまった。
- だけど make install が通らない。 include以下をtarで固めてコピーするフェーズが失敗する。(展開先ディレクトリは存在する)
- collect2.exeがないけれどいいのかな?
~ 結局のところ、
- CygwinはPosixエミュレーションレイヤーがあるためにこれらの問題は起きないが、パフォーマンスが低下することと、CygwinのDLLが必要(つまり単独exeでは実行できない)という欠点を持つ。
- MinGWはそのようなレイヤーを必要としない素のWin32アプリが作成できる点で優れているが、Linuxからの移植はやりずらい。
- で、MSYSの出番となる。一言で言えば軽量CygwinDLLのようなもので、ひととおりのUnix系ツールが移植されており、Linuxのconfigureとかを動かせるので、移植には便利。
- 但し、落とし穴があって、MSYSとMinGWとは実行形式が異なるらしい(?)つまりMSYSのファイルはmsys-1.0.dllが必須のアプリケーションのようだ。
- そして、MSYS専用のfstabでファイルシステムをマウントしているのでC:/bin が /c/bin になったり、 / が MSYSをインストールしたディレクトリになる。
- つまり、MSYSとそうでないEXE間でファイルシステムがかみ合わない場合があるようだ。
- Cygwinでも同様の問題が発生しそうだが、一応CygwinのDLLがmount系とC:\系の相互変換を行ってくれるようだ。
- では、MSYSでのファイルが見つからない問題は原因は何なのだろう?
- とりあえず、PATHの管理をもっと厳密にやって、非MSYSのexeが混じらないようにしてみよう。
~ ~ ~ ~
続々々・:PIC入門 diolan製bootloaderが動かない理由がほぼ特定できた。
-
たぶん、信じられないと思うが、
subfsr FSR2 , 3
-
とか
addfsr FSR2 , 4
-
が全く機能していない!
-
自分も信じられない。
-
と思ったら、これらの拡張命令セットはXINSTコンフィギュレーションビットをOnにしてROMを焼かないと
使用できないらしい。
~
- 結局のところ、オリジナルソースを再度取得して、18F2550化するための必要最小限の変更を加えたのち、
XINSTのconfigを1にして外部ライターから焼いたところ、ちゃんとUSBデバイスとして認識するようになった。
- ホストPC側のソースがVC++2003で書かれているためビルドできていない。
- 一応binディレクトリにあるコンパイル済みのEXEで試したところ、ファームの読み出しは出来ているようだ。
- ----- 日記が長くなりすぎたので分割 ------
~