PIC18F2550
PIC入門 目次
内容は入門というよりむしろハッキングに近いですが、私はPIC18Fの使用経験がほとんどありませんので入門としております。
PIC日記?
PIC18F関連覚え書き
sdccを飼い馴らす。
- sdccのコード効率はお世辞にも良いといえるものではありません。
- これを根本的に改善するにはコンパイラをさらに改良するべきなのですが、一朝一夕に出来ることではありません。
- そこで、Cとasmの混在が有効なのですが、PIC18Fシリーズはアーキテクチャー上の問題を多く抱えています。
- これは、それを回避する手法のメモです。
(1)BANKSEL問題を回避する。
- asm側での一時変数参照にBANKSEL(movlb)を多用すると効率が低下しますので、AccessBank上のRAMを積極的に使います。
- sdccではr0x00〜r0xXXという形で仮想的なレジスタを使用しているようです。これは0番地から数個あるいは10個程度割り当てられるようです。
- コンパイル結果の LSTファイルで確認できます。
; Internal registers .registers udata_ovr 0x0000 r0x00 res 1 r0x01 res 1 r0x02 res 1 r0x03 res 1
- r0x00〜の呼称は、その絶対番地と対応していて、グローバルなものです。
- これと衝突しないように16バイトほどずらして自分用の変数を定義していきます。
#define uchar unsigned char uchar at 0x0010 r10 ; uchar at 0x0011 r11 ;
- 変数名称は機械的な名前よりも意味のある名前にしたほうが読みやすいと思います。
- 利用できるアドレスは 0x10〜0x5fまでです。AccessBankの0x60以降はSFR(I/O PORT)になります。
- アセンブリ記述内(__asm 〜 __endasm;)で変数を参照する場合は 先頭に '_'(アンダースコア)を付加します。
- このルールはCとasm間のやりとりでは必須です。
- こうしておいて、asmとCの両方でBANKSEL(BSR)に依存せず常にアクセスできる変数が確保できます。
- C言語側の参照もBANKSELが不要になるようです。
(2)Cからasmへの引数問題、戻り値問題。
- これも結局効率重視の観点からはスタックPUSH,POPを避けたいので上記のグローバル変数を介すか、レジスタ渡しになるような気がします。
(3)call --> rcall にしたい。
- どこかのレベルで相対分岐の距離検査とrcall置換を行いたいところですが・・・、これについては検討中です。
(4)C言語の関数内でr0xXXレジスタが使われる場合、使われる個数分のr0xXX領域をスタックに保存し、関数戻り時に回復している。
- この効率低下はかなり無視できないものです。
- 本来ならば、r0x00〜r0x03まではtemporaryで関数をまたぐ場合は破壊されても文句なし前提、r0x04〜はセーブレジスタ(関数の呼び出し前後で破壊されないことを前提とする)、のようにコンパイラが使い分けるべきだと思っています。
- コンパイラを直すしかありません。
追記 2009-05-02
- kuga様からのご指摘がありましたので追記いたします。
- 実はコンフィギュレーションビットXINST=1(拡張命令有効)のときにはAccessBankの0x00〜0x5f番地アクセスが絶対番地ではなく FSR2 相対アドレス化するという問題(?)があります。
- すなわちXINST=1でPICを使用する場合は、上記(1)は的外れとなります。
- sdccではXINST=1のときのコードを吐く機能は今のところ実装されていないようです。
- MicroChip製C18コンパイラに関しての事情ですが
- XINST=1用のオブジェクトコードを吐く機能は有償版のみにしかありません。
- 30日体験版の期間内ではこの機能は有効になっているそうです。
- 無償版もしくは期限切れ版ではXINST=0のコードしか吐けないのでコード効率はsdccとさほど変わらないだろうと思われます。
以下FSR2相対アドレッシングに関する個人的な見解です。
- XINST=1にすると、00〜5f番地を仮想的なスタックフレームとして使用することは可能になります。
- しかし、同等の効果を得るにはそうするのではなくて、すなおに(FSR2+nn)というアドレッシングモードを追加すべきだったはずです。(命令マップ空間が不足していたのでしょう)
- AVRでは、auto変数は可能な限りGCCがレジスタ割付してくれます。
- PICでは、スタックフレーム上のメモリーアクセスになるので効率は落ちます。
- さらに、ポインタ変数やポインタ引数については、スタックフレーム上に置いたままではポインタとして機能しませんので問題になります。(FSR0,FSR1をうまく使えるのでしょうか?)
続:sdccを飼い馴らす。
別項にしました。
read more: sdcc
HIDmon-2550
- 2kBに収まっている HID Bootloader 兼 HID monitor お勧めです。
read more: HIDmon-2550
NEC78K基板をPIC専用ライターにしてみました。
- 写真はトランジスタ技術2008年8月号付録のNEC78K基板です。
- NEC78Kのファームはでんし研さんのものを使用させていただきました。
- このファームでPICとAVRの両方の書き込みが出来ます。
- ISPコネクタ部分は、不要になった互換機用のシリアル外出しケーブル(9P)のしっぽを再利用しています。
- 一応AVRの6PIN仕様で配線しました。PIC用の配列ではありませんがAVR/PIC共用です。
- LVP(5V書き込み)専用となります。
- ほんとにあつらえたような書き込み器になります。(NEC78K基板)
- 書き込みソフトはWriter509を使用しています。
- 書き込みターゲットは秋月のAE-18F2550です。
- 裏面は、ISPコネクタを配線しただけとなっています。
裏側写真
PIC18F2550用のファームウェア
- とりあえず動作確認のために、Gainer miniを焼いてみました。
- 一応動作したようです。(teratermで確認しただけでGainerとして動作させたわけではありません)
- PICでは、AVRのFUSEに相当するConfiguration Memoryの設定はHEXファイルに含まれるので、別に設定する必要はないようです。
UBWを試す。
UBW (USB Bit Whacker)公式サイト
- USB bit 打ち付け機? --- USB接続の18F2550のポートを上げ下げしたり、ビットセンシングするファームウェア。
- 端的に言うと Gainerの改良版!です(^_^;;;
- firmware-Bと呼ばれるbootloaderを入手(インストール)することで毎回PICライターを接続する煩わしさから開放されます。
read more:UBWを試す
Microchip FSUSB サンプルを試す
【準備中】
- MicrochipのサイトにあるUSBサンプルを片っ端からコンパイルして試そうという企画です。
- 全てsdccコンパイラを使う予定。
何故sdcc+gputils?
- MCHIPの奴(MPLabのこと)はGUIなので苦手。
- MCHIPの環境はLinuxとMacでは使えません。
- C18コンパイラは有償(比較的高価)なので敬遠します。(仕事でPICを使わざるを得ない場合、ではありません)
- sdccはコード効率について決して良いとは言えませんが、将来良くならないとも限りませんし、自分で直すことだって出来ないことではありません。試用期間を過ぎたC18よりはましであれば、こちらを選択するというのもありかとおもいます。
- gputilsもGNU GPLなので改造可能です。
但し、現時点で調べた限りでは、C18用(あるいはMPASM)に書かれたソースをsdcc+gputilsに直すのはかなりの手間が掛かる(おまけに困難を伴う)ことが分かっています。
−−−−> かなりコツを会得しました。
- sdccのコード効率の悪さはC言語内に積極的にインラインアセンブラ記述を取り入れる、
- あるいはC言語では不得意な処理を別モジュールにまとめて、そのなかでインラインアセンブラを多用するということで克服できるということが分かってきました。
- むしろsdccの最適化がどんなに良くなっても本質的にPIC18Fのアーキテクチャー上の問題によりC言語だけでは効率向上が難しいと言えます。
参考リンク
FSIJ
PIC 18F2550 ¶
秋月電子で18F2550のボードが売られてるのでこれで遊ぶ環境をGNU/Linuxで整備しようという話。
アルゴ算法堂:PIC18F概要
Porting Microchip MCHPFSUSB v1.3 CDC to use sdcc on Linux: C18のソースをsdccに移植する方法
semifluid:かなりのPICマニア?18F2550自作オシロスコープなど。