TAP-PicMicrocontroler
c2cコンパイラを中心としたPICに関する情報を掲示しています。
PICでCコンパイラを使う利点は、わずらわしいページング処理を自動で行ってくれるということがあります。メモリがリニアではないためにあいたところに変数を作ってくれます。もちろん、アセンブラの方がタイトなコードが記述できますが、常に仕様変更が起こる可能性のある場合などにおいては、よりすばやくコーディングが可能となると思います。
c2cコンパイラに関しては、フリーであることが最大の利点です(Linux版のみ)。作者曰く、最近のバージョンはWin版は期間のみ制限で機能はフル機能だそうです。まあ、アセンブラより速く開発ができるかもしれないといった感じです。いくつかの注意点さえ守れば結構ドメインな処理ができるので私には使いやすいです。またあたらしいチップができたときやバグの対策も早いです。(私のときはメール送って3,4日で解決してくれました)
PICをc2cで開発する |
c2cコンパイラーの使い方 |
●c2cコンパイラーについて
c2cコンパイラーはPIC,SXなどのための専用Cコンパイラーです。
c2cコンパイラーはLinux版に限りフリーソフトとなっているようです。
The Linux version of the compiler is free for non-profit use and
shareware for commercial use.
とのことです。現在のバージョンは3.27.8であり、結構使えるものとなってきているようです。
不都合(バグ?)もいくつかありますが、そこだけ注意すれば使えるのではないかと思います。いずれにせよこのようなすばらしいソフトをフリーで公開していただけるだけでも、作者のPavelさんはじめ関係者に感謝したいと思います。
Win版の最新版はポインタなども使えたり、c++やパスカルまであります。
●インストール
インストールといっても展開してできた実行ファイルを実行するだけです。どこかのフォルダに展開してシンボリックリンク(c2cという名前にしておきましょう)を作ってパスを通しておきましょう。
ためしに
c2c
と実行してみると
C2C-plus 3.27.8e C-compiler. Copyright(c) 1998-99,2000 by Pavel Baranov. pavel@worldonline.nl Free copy for non-profit use Shareware copy for commercial use -I<include file> assembler include file name -o<output file> output file name -vs<num> variable start address -ndi no default interrupt handler -ols one local space -lib output is a library -P<processor> generate code for <processor> -SXHEX generate hex-file for Scenix target -md mul/div as separate functions(not inline) -nosc generate code for all functions -Ox extra optimization levels(0,1 or 2) -SRC insert C-code into assembler -D<string> defines the <string> -nsc don't save context during interrupt -? or -h this help Supported processors: SX18L SX28L SX18 SX28 PIC12C508 PIC12C508A PIC12C509 PIC12C509A PIC12CR509APIC12CE518 PIC12CE519 PIC16C52 PIC16C54 PIC16CR54 PIC16C55 PIC16C56 PIC16CR56 PIC16C57 PIC16CR57 PIC16C58 PIC16CR58 PIC16C61 PIC16C62 PIC16C62A PIC16C62B PIC16CR62 PIC16C63 PIC16C63A PIC16CR63 PIC16C64 PIC16C64A PIC16CR64 PIC16C65 PIC16C65A PIC16C65B PIC16CR65 PIC16C66 PIC16C67 PIC16C71 PIC16C72 PIC16C72A PIC16CR72 PIC16C73 PIC16C73A PIC16C73B PIC16C74 PIC16C74A PIC16C74B PIC16C76 PIC16C77 PIC16F83 PIC16CR83 PIC16C84 PIC16F84 PIC16F84A PIC16CR84 PIC16C620 PIC16C620A PIC16CR620APIC16C621 PIC16C621A PIC16C622 PIC16C622A PIC16CE623 PIC16CE624 PIC16CE625 PIC16F627 PIC16F628 PIC16C641 PIC16C642 PIC16C661 PIC16C662 PIC16C710 PIC16C711 PIC16C712 PIC16C715 PIC16C716 PIC16C773 PIC16C774 PIC16F873 PIC16F874 PIC16F876 PIC16F877 PIC16C923 PIC16C924
こんな感じでバージョン、対応機種などが表示されます。説明書も入っています。
実行ファイル形式で公開されてるせいか、Slackware7.0では動きましたがそれ以前のバージョンでは動きませんでした。Vineでは動きました。RedHat系で開発されているようです。
●使い方
ためしに何かコンパイルしてみましょう。
test.c : **********
int x; char func(char a); void main(void) { char i; x = 0; for(i = 0;i < 10;i++){ x = x + func(i); } } char func(char a) { return (a + 1); } void interrupt(void) { x = x + 1; }
ここで
c2c -PPIC16F877 test.c
と実行するとtest.asmができます。*.asmファイルはそのままMPLABに読み込んで*.hexファイルを作りライターで書き込むことができます。
test.asm : **********
; This file was generated by C2C-plus compiler version 3.27.8e include "p16F877.inc" ;Variables ***************************************** _intr_tmp_0000 equ 0x70 _code_tmp_0000 equ 0x71 _code_tmp_0001 equ 0x72 _code_tmp_0002 equ 0x73 __int_save_cont_W equ 0x74 __int_save_cont_STATUS equ 0x75 __int_save_cont_FSR equ 0x76 __int_save_cont_PCLATH equ 0x77 param00_func equ 0x78 _i_main equ 0x79 _x equ 0x7a ORG 0 clrf PCLATH goto start__code ORG 4 _interrupt _interrupt__code movwf __int_save_cont_W swapf __int_save_cont_W, F swapf STATUS, W movwf __int_save_cont_STATUS swapf FSR, W movwf __int_save_cont_FSR swapf PCLATH, W movwf __int_save_cont_PCLATH clrf PCLATH movf _x+1, W movwf _intr_tmp_0000 movlw 0 addwf _intr_tmp_0000 , F movf _x, W addlw D'1' btfsc STATUS, C incf _intr_tmp_0000 , F movwf _x movf _intr_tmp_0000 , W movwf _x+D'1' swapf __int_save_cont_PCLATH, W movwf PCLATH swapf __int_save_cont_FSR, W movwf FSR swapf __int_save_cont_STATUS, W movwf STATUS swapf __int_save_cont_W, W retfie _interrupt__end _func goto _func__code start__code _main__code clrf _x clrf _x+D'1' clrf _i_main label_0000 movlw D'10' subwf _i_main, W btfsc STATUS, C goto label_0001 movf _x+1, W movwf _code_tmp_0000 movf _x, W movwf _code_tmp_0001 movf _i_main, W movwf param00_func call _func bcf PCLATH, 3 bcf PCLATH, 4 addwf _code_tmp_0001 , W btfsc STATUS, C incf _code_tmp_0000 , F movwf _x movf _code_tmp_0000 , W movwf _x+D'1' incf _i_main, F goto label_0000 label_0001 _main__end _func__code clrf _code_tmp_0002 movf param00_func, W addlw D'1' btfsc STATUS, C incf _code_tmp_0002 , F return _func__end END
このような出力になりました。割り込みも使えます(コンテクストの保存・復帰もやってくれます)。またPICのアセンブラコーディングの際の例にもなりそうです。ただCコンパイラとしての汎用性のためかアセンブラよりも冗長な部分が多いのは確かです。(基本がC言語が関数でくくる仕様のためでしょうか)
●コンパイラについて
c2cコンパイラーの特徴および注意点(バグではなくて仕様です的な)をまとめてみたいと思います。
・プロセッサの指定について
コンパイルオプションで-PPIC16F877としてみましたが、-PPIC16F84とした場合とはまったく異なるコードを吐き出します。F877でコンパイルした場合は毎回RAMページングやCODEページングテーブルの参照をしていますが、F84でコンパイルした場合にはこのようなコードは見当たりません。よってF84の場合にはRAMページング(TRISAなど)を明示的に行う必要があります。
これに関しては私もF877のプログラム時にPavelさんにmailを送ってpage correctionを改良していただきました。毎回correctionを行うように提案したのですが、このためか少し冗長なコンパイルを行うようになってしまったようです。このあたりがPICとCコンパイラーの相性の悪いところでしょう。(ほかのコンパイラはどうなってるんでしょうか?)
・割り込みに関して
通常ホビーで使うのはF84とF877くらいでしょうか。F877では0x70以降のバンク共通メモリにコンテキストをsaveしてくれます。(3.27.6以降)
・プログラム上の注意
できないこと(バグではなく実装がされていないものも含む)をあげたいと思います。
----コードページングの問題----
コードがページングをまたがる際に処置をしてくれません。つまり1関数内でページングを超えてはいけないということです。別関数として別コードページに関数をおくことは可能です。そこで関数の開始番地をある程度指定(制御)しなくてはなりません。ただしこの仕様の方がコードを管理しやすいと思います。
----算術命令について----
++,--などはありますが+=,-=などはできません。またC言語的な美しさ(トリッキーさ)を求めたような?命令は避けたほうがよいでしょう。
使える演算子は
+,-,*,/,<<,>>,++,--
くらいと思ったほうがよさそうです(現状では実際に使えません)。また入れ子をすると余計にRAMを食いますのでこれも避けたほうがよさそうです。
----変数、標準関数について----
配列についてですが、配列の番地の指定時に変数を使うとFSRを使ってIndirectアクセスを行います。そうするとスピードがかなり遅くなってしまいます。数字で指定したときはそのままdirectにアクセスしているようです。
またswitch(x)のxに配列を使うことはできません(たぶんバグですが、もうだいぶPavelさんにメールを送りつけてしまったので、これ以上送るのは申し訳ないです、笑)。またswitch後はbreakしなくてもswitchを抜けてしまいます(これにもはまりました)。
----機能レジスタについて----
最近になって拡張された機能レジスタはユーザー側が作るほうがよいという見解を示しているようです。たとえばF877のEEPROMアクセスについては、
char _EEDATA@0x10c;
char _EEADR@0x10d;
char _EEDATAH@0x10e;
char _EEADRH@0x10f;
char _EECON1@0x18c;
char _EECON2@0x18d;
といった感じで再定義しなおしています。この仕様でいいと思います。ただしどのPICにも実装されていてしかもアドレスが同じもの(FSR,OPTIONなど)は実装されています。
----ライブラリや関数について----
ライブラリはほとんどありません。(説明書を参考ください、ソフトウェアシリアル通信はbuilt
inされています。)
また関数のコールは避けて迷わすgoto命令を使ったほうがすっきりして早いです。PICはスタックが浅いのでこの方がよいでしょう。
----const charについて----
このバージョンでは使用しないほうがいいと思います。0x00-0xff,0x100-0x1ffといった境界でバグります。これらの対処はなされていませんので(現バージョンでは)、自分でルーチンを作ったほうがよさそうです。(関数にラッピングして関数の開始番地を指定するなど。)
----continue文について----
continue文を実行するとfor(i=0;i<4;i++)文などでiをインクリメントしてくれません。for文の最後にジャンプ(goto文などで)するようにしないといけません。
----インラインアセンブラについて----
インラインアセンブラ上ではページング処理はもちろん行ってくれません。そこで、アセンブラを書くときは
はじめに char page0@0x20 char x@0x21; と変数の番地を設定しておきCプログラム中で page0 = 0;/*dummy*/ といった形でダミーの書き込みを行ってページングを合わせます。 (コンパイラ自身にページングを認識させるため)その後、 asm:start_asm asm{ movf _x,w addlw d'10' movwf _w } asm:end_asm
のようにすればページングを処理できます。アセンブラで扱う変数のアドレスを合わせることとアセンブラに入る前にページをあわせるためのダミー処理を入れれば大丈夫です。
----ビルトインdelay_sについて----
引き数のパラメータがページ0以外に設定されたとき動きません。delay_ms,delay_usは動くので秒単位のディレーは自分で作成したほうがいいです。
・まとめ
大体以上の点を守ればとても便利な感じです。基本はアセンブラの拡張のようなものだと思います。早く手軽にプログラムが作れる点ではよい選択になるのではないかと思います。
●書き込みまでの流れについて
コンパイルしたアセンブラファイルをMPLABに読み込みコンパイルします。できたものを書き込みます。私はSAMBAを利用してWIN95からLinux上のファイルを更新し、コンパイルして、WIN95へ持ってきて後の作業をWIN95で行っています。けれどもはじめは文字コードを変換するのを忘れて少しはまりました、笑。秋月の書き込みキットをバージョンアップしながら使用しています。
・追伸(2000/06/16)
と書たところ、Linuxで秋月ライタを使えるプログラムを作成されている方からメールをいただきました。宮本さんのページです。早速使ってみたところGoodでした(秋月ライターより早い?)。F877やF84その他主要なPICはgpasmに対応しているのですべてLinux上で開発できそうです。とても快適です。
c2c-lib |
プログラムの例をおいておきます。
16F877用です。これくらいのプログラムが可能です。
LCD,ADC,シリアル通信,EEPROMアクセス,タイマー割り込みなどの例と関数があります。
const charも使っていますが、これは実際は使用しないほうがいいです(上述)。私はEEPROMに書き込み時に書いておきそれを文字列として使用しています。
c2c -PPIC16F877 test.c
でコンパイルします。
注意点 :
・プログラム開始番地を指定してページングがプログラムの流れの中で起こらないようにしている。
・最初にペリフェラル関連の定義をしている。
・ディレイ用の#pragmaを指定している。
感想 |
C2Cコンパイラは作者いわく、最も低価格なコンパイラだそうです。私にとってはとてもダイレクトな構造のコンパイラでとても使いやすいです。バグは多いですし(多分上記のでほとんどだと思う)、ライブラリに期待するような短期間の開発には向かないかもしれませんが、ライブラリは自分で書くよとか、インラインアセンブラでバリバリという時にはいい選択になるかも知れません。Win用のものはもう少し進んでいるはずなのでそれはまた別の機会に調べてみたいと思います。