PICのプログラム開発をLinux上で可能にする、いうなれば「Linux版MPLAB」"piklab"を使用してみました。期待以上に良くできたツールでしたので、導入の参考になれば、と簡単な紹介記事をまとめてみました。
今回は、piklabのインストールを行い、アセンブラ(gpasm)とCコンパイラ(sdcc)を使用し、小さなプログラムをコンパイル・ダウンロード、そして基本的なデバッグ操作をするところまでをやってみたいと思います。ターゲットとしては、pic16F819を使った簡単なLED表示回路を作ります。
piklabは、Linuxで動作するPICおよびdsPICの開発統合環境(IDE)です。Microchip提供のIDEであるMPLABを意識した作りとなっていて、MPLABを使用したことがあれば違和感無く使えると思います。フリー、かつオープンソースで、GPLライセンスにより提供されています。
piklabのホームページは→
こちら
PICプログラマは色々なものがありますが、トラブルなく動きそうで、そこそこ信頼性のありそうな純正ICD2を購入して使用しています。特に純正である必要はありません。
ICD2には、ICSPでプログラムをするための信号がRJ-11 6線コネクタから出ています。ブレッドボード上のターゲットに接続するための簡単な変換コネクタを作っています。
プログラマからの信号(PGC/RB6, PGD/RB7)をターゲットから完全に切り離すためのスイッチをつけています。もうちょっとスマートに電子的に切り離せるようにしたいと思案中ですが、この簡単な方式でも現在のところあまり困っていませんので、予定は未定。
piklabでの、他のプログラマ、デバッガへの対応については、piklabホームページのサポート情報を参照してください。
piklabの対応デバイス一覧は、piklabホームページの対応デバイスに一覧があります。デバイスによっては、プログラムは可能だけどデバッグは不可、というものもあるので注意が必要です。
ICD2やターゲットの動作確認のため、MPLABはWindows環境で用意しておきます。後述のように、デバッグ用のファームウェアを利用するのが主目的ですが、なにか問題が起きたときに、公式ツールが試せる状況にしておくと緊急時に便利です。なお、Wine環境でもMPLABが使えるようですが、今回は未確認です。
MPLABそのものの説明については、ここでは省略します。
この記事で使用しているLinuxは、Fedora12です。各ツールのインストール元としてリポジトリにあるものをそのまま使いました。しかし、他のバージョンや、Ubuntuなどでも大きな違いは無いと思います。
PIC用のアセンブラ、および関連ツールをインストールします。
今回のバージョンは、0.13.7 betaです。(gpasm --version により表示)
gputilsのホームページは→こちら。http://gputils.sourceforge.net/
8051など各種小規模マイコン用のCコンパイラとして開発されているCコンパイラ、SDCCをインストールします。
今回のバージョンは、2.9.0です。(sdcc-sdcc --version により表示)
SDCCのホームページは→こちら。http://sdcc.sourceforge.net/
リポジトリ上にあるものをそのままインストールします。
今回のバージョンは、0.15.9です。(piklab --version により表示)
上でも書きましたが、ホームページは→こちら。
インストールが完了すると、メニューの「アプリケーション」→「電子工学」→「piklab」で起動できるようになります。起動すると、左のような画面です。
piklabを起動して、環境設定を行います。
piklabメニューから、[Settings] -> [Configure Toolchains...] で、設定ダイアログを開き、[Assembler] - [GPUtils] の項目を選択します。
特に何もしなくても、gpasmが正しくインストールできていれば、gpasm, gplink, gplibコマンドが "found" になっているはずです。
sdccは、最近のバージョンではコマンド名が変更されていて、sdcc-sdcc でないと実行できません。ところが、piklabのツール・チェイン設定では、コマンド名自体を変更できないので、やむを得ず今回は以下の様にリンクを作ることにしました。
$ su # cd /usr/bin # ln -s sdcc-sdcc sdcc # exit
piklabメニューから、[Settings] -> [Configure Toolchains...] で、設定ダイアログを開き、[C Compiler] - [Small Device C Compiler] の項目を選択します。sdccが "found" になっていればOKです。
PCにICD2を接続します。piklabのメニューから、[Settings] -> [Configure Programmers...] で、設定ダイアログを開き、[ICD2 Programmer]を選択します。[Port Selectoin]タブの接続ポートから、[USB]を選択し、"Connection: Ok"となれば準備ができています。
WindowsにインストールしたMPLABから、ファームウェアのディレクトリ(デフォルト設定では、C:\Program Files\Microchip\MPLAB\ICD2)とその内容を適当なディレクトリにコピーします。[ICD2 Programmer]の[Specific]タブの[Firmware directory]に、コピーしたフォルダを指定します。
USBポート(シリアルで接続している場合は、シリアルポート)へのアクセス許可を正しく設定しておかないと、プログラマ/デバッガと通信が出来ません。 piklabからICD2にUSB接続できない場合、"Connection: Error"となってしまいます。
まずは、USBバスにつながっているデバイスとしてICD2を確認してみましょう。
$ lsusb Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 002: ID 04d8:8001 Microchip Technology, Inc. ICD2 in-circuit debugger Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 003: ID 062a:6301 Creative Labs Bus 002 Device 002: ID 04d9:0022 Holtek Semiconductor, Inc. Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub上記の例では、ICD2がBus 003上の Device 002として認識されているのが確認できています。この場合、デバイス・ファイルは /dev/bus/usb/003/002 でアクセスできます。次に、アクセス権を見てみます。
$ ls -l /dev/bus/usb/003/002 crw-rw-r--. 1 root root 189, 257 2010-04-21 13:06 /dev/bus/usb/003/002上記のように、アクセス権が「グループに対してRW許可」になっていると思います。そこで、piklabを使用するユーザー(すなわち自分)を当該のグループに加入させてもらいます。(グループはシステムによって異なるかもしれません。uucpだったり、lpだったり、rootだったりします。)
ICD2デバッガを、同様に設定します。
PCにICD2を接続します。piklabのメニューから、[Settings] -> [Configure Programmers...] で、設定ダイアログを開き、[ICD2 Debugger]を選択します。[Port Selectoin]タブの接続ポートから、[USB]を選択し、"Connection: Ok"となれば準備ができています。
WindowsにインストールしたMPLABから、ファームウェアのディレクトリ(デフォルト設定では、C:\Program Files\Microchip\MPLAB\ICD2)とその内容を適当なディレクトリにコピーします。[ICD2 Debugger]の[Specific]タブの[Firmware directory]に、コピーしたフォルダを指定します。
画面左側の[Project Manager]ペーンから、プログラマとして[ICD2 Programmer]を選択します。そして、piklabのメニューから、[Programmer] -> [Connect] で接続します。
この時点で接続すると、ターゲットがないため電源電圧やデバイスIDのエラーがでてしまいますが、プロジェクトを作成して、ターゲットを接続すれば準備OKになるはずです。ということで、以下、ターゲット・ボードを用意してからの手順を進めます。
さて、いよいよターゲットを用意して、実際に動作するプログラムを書いてみます。最初のターゲットはブレッド・ボード上に作成しました。デバイスは、たまたま箱に転がっていたpic16f819です。LEDの点灯をするだけなので、ポート出力とタイマー機能しか使いません。
こちらが、今回テストに使用した回路です(LEDの直列抵抗は1kΩ程度。他は10kΩ)。7セグメントLEDを4桁、ダイナミック表示用に配線しており、ポートB(RB0..7)で数字の形を、ポートA(RA0..4)で表示する桁を選択します。桁ドライバは、デジタル・トランジスタでシンプルに配線しました。システムクロックはシンプルにするのとブレッドボードという条件のため、内部RC発振で4MHz設定と低く設定することにします。(速度が遅くなりますが、そのかわり、電池2個でも動作します)
今回は、piklabでの開発・デバッグについての説明のため、単純な機能にとどめておきます。この回路を使って、何か実用的なもの(時計やカウンターなど)にするには、キー入力などを用意して、ユーザー・インターフェースを設計する必要があります。
gpasmでビルドできるプロジェクトを作成します。
piklabのメニューから、[Project] -> [New Project...]を選択すると、プロジェクト作成のウィザードが起動します。下記の内容を各項目に入力します。
Basic Settings: | ||
---|---|---|
Name: | プロジェクトの名称 | |
Directory: | プロジェクトのフォルダ | |
Device: | ターゲットのPICデバイス。例:"PIC16F819" | |
Toolchain: | 使用するツールチェイン、ここでは"GPUtils" | |
Programmer: | 使用するプログラマ。例:"ICD2 Programmer" | |
Source Files: | ||
ソースファイルの作成 | テンプレートを使用:"Create template source file."を選択 |
エディタを使って、ソース中のコンフィグ・ビットをターゲットにあわせて正しく設定変更し、割込み処理とメイン処理を記述していきます。
出来上がったソースはこちら。(なお、このアセンブラ・ソースでは、後述のように全機能が完成していません。)
出来上がったソースをセーブして、ビルドします。メニューから、[Build] -> [Build project]でビルド開始します。"Success"となれば、ダウンロード可能な実行ファイルが完成です。
プログラマの接続は、[Programmer] -> [Connect]です。自動的に、ターゲットの電源電圧、デバイスIDをチェックします。
メニューから、[Programmer] -> [Program]で、ダウンロード、完了後、[Programmer] -> [Run]でリセットが解除され、ターゲット上でプログラムがスタートします。
以上で、アセンブラ編は終了です。ソースは完成していないのですが、PICのアセンブラで長いコードを書くのはもう能力の限界、助けて。というわけで、アセンブラの基本テストはこの辺で打ちきって、Cでのテストにいきます。(←要するに、根性が無いのです。すみません・・・)
sdccでのプロジェクトを作成します。
piklabのメニューから、[Project] -> [New Project...]を選択すると、プロジェクト作成のウィザードが起動します。下記の内容を各項目に入力します。
Basic Settings: | ||
---|---|---|
Name: | プロジェクトの名称 | |
Directory: | プロジェクトのフォルダ | |
Device: | ターゲットのPICデバイス。例:"PIC16F819" | |
Toolchain: | 使用するツールチェイン、ここでは"Small Device C Compiler" | |
Programmer: | 使用するプログラマ。例:"ICD2 Programmer" | |
Source Files: | ||
ソースファイルの作成 | テンプレートを使用:"Create template source file."を選択 |
さて、できあがったソースはこちら。最適化などは考えずに、つらつらと書いたのでサイズが大きくなっていますが、労力を考えると、Cで作成できるというのは非常に便利ですね。インラインでアセンブラ・コードも書けるので、非常に楽ちん。自分の目的にはアセンブラよりもあっているようです。C言語というよりは、高級アセンブラという感覚で使っています。
アセンブラのプロジェクトとまったく同様です。プログラマを接続して、ダウンロード、実行で完了です。
さて、作成したプログラムが期待通りに動作するまでには、テストとデバッグを幾度か繰り返さなくてはなりません。次節では、デバッガを使用した基本的なデバッグを試してみます。
ICD2を使って、デバッガの基本機能を試してみます。piklabのデバッグ機能は開発途上で、まだ完全なものではないそうですが、必要最小限の機能が動作していて、バグの原因究明には非常に強力です。小さな家内制プロジェクトであれば、大抵これだけで足りてしまうように思います。
画面左側の[Project Manager]ペーンから、プログラマとして[ICD2 Debugger]を選択します。(注)すべてのデバイスでデバッグに対応しているわけではないようです。詳細は、piklabのホームページを参照してください。
ソースのコンフィグ・ワードの設定に"DEBUG_ON"を指定してビルドします。エラー無くビルドが完了したら、ICD2に接続してデバッグ準備完了です。
ブレークポイントを設定してみます。ブレークしたい行にカーソルを移動して、ブレークポイントを設定します。デバッグを開始すると、設定した位置を実行した際に動作が中断します。
変数のウォッチは、左のペーンから監視したい変数を選択するだけです。ブレークがかかるごとに変数の内容が前回のブレークから変更されていれば、表示が更新されます。
ブレーク状態でステップ実行をおこなうと、1命令実行後、再びブレークします。「アセンブリ言語での1命令ステップ実行」になっているのか、C言語の場合は複数ステップ実行しないと、次の行に移動しないようです。面倒な時は、ブレークポイントを設定しなおして実行継続するのが手っ取り早いです。
SDCCが、Cソースから生成したアセンブラ・コードを見ることができます。 ソースコードの対象行にカーソルを合わせて、右クリック -> Show disassembly location でアセンブラのコードを見ることができます。
MCLR端子をI/Oとして使用するコンフィグの場合、端子によるリセットでデバイスを待機状態にできないので、ダウンロード完了と同時にプログラムが開始されます。ICSPの各端子をI/Oとして使用する場合、ターゲットやプログラマを破損することのないように回路設計に注意してください。
他のコンパイラ用の書かれたソースでは、PICのレジスタや周辺回路のアドレスなどのシンボルがSDCCと異なっているかもしれません。これらのシンボルは、ヘッダファイルに記述されています。他のコンパイラのソースなどで未定義エラーがでる場合は、まず各デバイスのヘッダの記述を確認してみることをおすすめします。
ヘッダ・ファイルは、 /usr/share/gputils/header にあります。(Fedora12)
コンパイル済みのファイルを書き込みしたい、などの用途の場合、コマンドラインでの操作ができると便利ですね。 以下に、コマンドラインでの操作について抜粋しておきます。
PICマイコンは、その豊富なラインナップ、入手性・経済性の良さ、そして参考文献の多さから、日本国内ではホビー用途に広く採用されているようです。PICの特徴は、昆虫の進化のごとく、各機能を細分化したデバイスの多様性でもって、様々な用途にコスト面から最良の選択肢となる場合が少なくありません。
お手軽にお安くチョイチョイと組めるのが小規模マイコンの魅力ですが、それを最大限に利用するには、習得時間の短さが非常に重要と思います。そのうえで、非常に重要になってくるのが、標準的な文法を使用するC言語の存在です。なかでも、フリーでオープンソース、また、Linuxネイティブで動作する手軽な選択肢としてpiklab,gputils,sdccの組み合わせは、PIC開発には欠かせないものと思います。それぞれ、すばらしいツールの開発に尽力されている諸氏に感謝します。