はじめに
PICの開発環境はメーカーのMicrochip Technology Inc.
よりフリーのIDEが提供されています。しかしながらアーテクチャーが独特のものでプログラム
開発はアセンブリ言語が主流のような気がします。サブルーチンコールのネストが
8段までだとか、バンクやページを切替えてのアドレッシング等、他のマイコンに比較して
Cコンパイラを作る上でもまた使う上でも制約があることを感じてなりません。
とは言っても、非常に魅力のあるデバイスであることは間違いありません。とっつき難さは
ありますが、安価でフラッシュ搭載でSDIPパッケージもあるので電子工作などには
もってこいですね。
さて、本題です。PIC用Cコンパイラはほとんどが有償です。PIC関連の書籍でもC言語で
開発を.. などありますが、有償のCコンパイラを使用したものです。
個人が手を出すにはいささか立ち止まってしまうのが現状ではないでしょうか?
そのためにちょっと癖があってもアセンブラを余儀なく使うことになります。
でも世の中にはスゲー技術者もいて、フリーのPIC用Cコンパイラを作るプロジェクトが
あります。SDCC : Small Device C Compiler
がそのプロジェクトです。
2004/12/25現在、SDCCのPIC対応はまだ完全ではなく、私でも手を出せるデバイスでもある
PIC16F84, PIC16F84Aのミッドレンジ(PIC14)においてはコンパイルが通りません。
ですが、三岩幸夫氏が雑誌「Software Desigen」
の2004年7月号〜10月号の「Linuxパワーアップ講座」で詳しく対応方法を解説して下さいました。
これが非常に目からウロコで、早速 NetBSD、Windows環境でPIC16F84(A)に対応さえてリビルド
させてみました。おかげさまで案外すんなりとできて、PIC16F84Aにてタイマ割り込みの
ハンドラも含めて確認ができました。感謝しております。
ということで、まだ PIC16F84,PIC16F84Aの2デバイスしか対応していませんが、
Windowsの実行ファイルをアップしたいと思います。ソースも後日アップする予定です。
それでは、SDCCでPICをお楽しみ下さい。。。
ダウンロード
2004/12/25にsourceforgeよりcvsで獲得したソースにPIC16F84, PIC16F84A を対応させたSDCCです。
Windows2000(SP4)上で、VC++6.0(SP5)でビルドしました。
インストール
本家のSDCCはインストーラーが(NSISで)作成されていますが、
私が配布するセットにはインストーラーはありません。
ビルドして必要なものだけをアーカイブしてるだけすので適当な場所に展開して下さい。
以下、C:\ に展開したものとして進めます。
C:\sdcc 以下に bin, include, lib, doc ができるはずです。
- 環境変数 PATH に c:\sdcc\bin を追加します
- 環境変数 SDCC_HOME に c:\sdcc を設定します
- 環境変数 SDCC_INCLUDE に c:\sdcc\include を設定します
以上で SDCC のインストールは完了です。
アセンブラやリンカのインストールはお済み?
既にMPLABや、gputilsをイントールしている場合は読み飛ばして下さい。
アセンブラはMicrochip Technology Inc.純正の
MPLAB IDE v7.00又は、
GNU の
gputils で確認済みです。
何れかをインストールしておく必要があります。
Windows環境ならおそらくMPLABを使用されている方が多いかと思いますが、sdccの吐く
アセンブリソースに対してデフォルトのリンカ・スクリプトそのまま使うと
リンカがエラーを出すことがあります。リンカ・スクリプトを修正すればOKです。
一方、gputilsは今のところ程よく適応してくれているようですんなり通ります;-)
最後にPATHを通していることも確認しておいて下さい。
サンプルビルド
手っ取り早く
サンプルソースで確認してみましょう。
すごく手抜いてるソースですが、確認ということで...
- gputilsを使う場合
sdccに gpasm, gplink まで通しもらって foo.hex を得ます。
リンカスクリプトは 16f84a.lkrをそのまま使用します。別途用意はしていません。
C:\home\sdcc> sdcc -V -mpic14 -p16f84a foo.c
Processor: 16f84a
+ c:\sdcc\bin\sdcpp.exe -nostdinc -Wall -std=c99 -DSDCC=1 -DSDCC_MODEL_SMALL -DSDCC_pic14 -D__pic14 -I"c:\sdcc\include" -I"c:\sdcc\include\pic14" -I"c:\sdcc\bin\..\include\pic14" -I"c:\sdcc\include" -I"c:\sdcc\bin\..\include" "foo.c"
+ C:\gputils\bin\gpasm.exe -c "foo.asm"
+ C:\gputils\bin\gplink.exe -o foo.ihx "foo.o"
message: using default linker script "C:\gputils\lkr\16f84a.lkr"
|
[sdccのオプションの説明]
- -V
- 処理の詳細を表示します
- -mpic14
- ミッドレンジ(1ワード=14bit長)のPICを指定します.
- -p16f84a
- デバイスにPIC16F84A を指定します。
- MPASMを使う場合
MPASMを使用する場合、sdccはアセンブリソースを吐くまでが仕事です。
それ以降は、MPASM, MPLINK を使用します。ということで、sdcc はアセンブリ
ソースを出力した時点で終了させます。そのためにオプション -S を指定しておきます。
mplink に指示するリンカスクリプトはこれ用に作成したものです。デフォルトの
リンカスクリプトではエラーになります(ベクタはベクタとして0x0〜0x5まで使うように
しないとエラーを吐くようだ。実情問題はないのだが..。sdccが吐くアセンブリソースは
後方の0x04から始まる割り込みベクタには*よく皆がするように*そこからハンドラコード
を記述しているため vectors ではなくてpage になっている。そこをmplinkは厳しくしているようだ)。
C:\home\sdcc> sdcc -S -V -mpic14 -p16f84a foo.c
Processor: 16f84a
+ c:\sdcc\bin\sdcpp.exe -nostdinc -Wall -std=c99 -DSDCC=1 -DSDCC_MODEL_SMALL -DSDCC_pic14 -D__pic14 -I"c:\sdcc\include" -I"c:\sdcc\include\pic14" -I"c:\sdcc\bin\..\include\pic14" -I"c:\sdcc\include" -I"c:\sdcc\bin\..\include" "foo.c"
C:\home\sdcc> mpasmwin /q /o foo.asm
C:\home\sdcc> mplink foo.lkr foo.o /m foo.map /o foo.hex /v
MPLINK 3.90, Linker
Copyright (c) 2004 Microchip Technology Inc.
Errors : 0
Warnings : 0
MP2COD 3.90, COFF to COD File Converter
Copyright (c) 2004 Microchip Technology Inc.
Errors : 0
Warnings : 0
MP2HEX 3.90, COFF to HEX File Converter
Copyright (c) 2004 Microchip Technology Inc.
Errors : 0
Warnings : 0
|
PIC Writer
上記の両サンプルのhexファイルをPIC Writerで書き込んで動作確認しました。
私が使用したライタは
秋月電子の
AKI-PICプログラマ Ver.3
および
Ver.4で
書き込んで動作することを確認しました。
最近は、
USB・シリアル変換ケーブルまで
あるので232CコネクタがないノートPC等でもUSBがあれば使えるようです。安価なので
持っておくと便利ですね。IO DATA の
USB-RSAQ2や、
ストロベリーリナックスの
USB⇔シリアル変換モジュールも
OKのようですが価格面では秋月の方が魅力あります;-)
マニュアル
sdccの
マニュアルは
使い方だけでなく、ソースを眺める上でも非常に重要な情報も記載されています。
是非、一読されたし。
PIC用Cソースのコーディング留意点
どうしても組み込み用マイコンのCソース記述となると、ある意味マイコン依存する
コーディングも必要となってくる。これが著しくなると可搬性が低下するので避けたいの
だがそうわけにもいかない。。
通常はこいった方言的な記述は #pragma を多用するんだろうでども、sdccは #pragmaも
使うけど、パーサーまで届くような文法(仕様)もある。
PIC16F84A を例に紹介します。
- __CONFIGの書き方
int at 0x2007 __config = _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF;
- SFRのビットアサイン(PORTA,PORTB等)
例えば、RA3(PORTAのbit3) に LED1 を割り当てるような場合。
BIT_AT(PORTA_ADDR,3) LED1;
とすると、0,1の代入でポート出力が可能になります。
LED1 = 1;
ここは、PicAntCなどよりは気が利いています。
SDCCのこの仕掛けは吐き出したアセンブリソースを見るとすぐわかります。BIT_AT(..)は、
(アドレス<<3 | bit位置) として`_LED1'を定義しています。(Cでのシンボルはアセンブリソース
以降はprefixにアンダースコア`_'が付与されます)。アドレスとbit位置を一定数(ID)に
エンコードしているわけです。
_LED1 EQU ( (0x05<<3)+2)
で、ポートLED1に 1 を出力するアセンブリソースは、アドレスとbit位置にデコードして、
「BSF アドレス,bit位置」の命令を吐いています。そして、注目する点はマメに(ある意味無駄に..)
バンクを切り替えていることです。これらは最適化のやる仕事として割り切って、現状は
十分満足させてくれます。
; LED1 = 1;
BCF STATUS,5
BSF (_LED1 >> 3), (_LED1 & 7)
- 割り込みハンドラの記述
void timer(void) interrupt 0
{
/* body */
}
その他
デバイス固有のヘッダファイル(ex: pic16f84a.h)は、sdccが同梱しているPerlスクリプト
inc2h.pl を利用して生成します。
MPLABや gputils をインストールしたらアセンブラ用のインクルードファイルが同梱されて
いますが、これを inc2h.pl に通すとヘッダファイルができるように配慮されています。
しかし、Windows環境ではこのPerlスクリプトは通りません。PC-UNIX等で作成するのも
もちろんありですが、Windows環境用に inc2h.pl を変更しました。sdccのアーカイブに
含めています。sdcc/include/pic14/inc2h.pl です。
このPerlスクリプトは、MPLAB の インクルードファイルを使用するように変更しています。
インクルードファルのデフォルトパスは、C:\Program Files\Microchip\MPASM Suite にしています。
必要あればこのパスを変更してください。(手抜いています)
- 使用方法です。
-
D:\hogehoge> C:
C:\>cd \sdcc\include\pic14
C:\sdcc\include\pic14> jperl inc2h.pl 16f84a > pic16f84a.h
|
(※)当然ですが、事前でにPerl(JPerl)をインストールしておく必要があります。
2004/12/25
2004/12/29 mod
Copyright(C) 2004 masu, All rights
reserved.
massun.masumoto@nifty.ne.jp