LinuxでPICのプログラムを作る(piklab, gputils, sdcc)

 PICのプログラム開発をLinux上で可能にする、いうなれば「Linux版MPLAB」"piklab"を使用してみました。期待以上に良くできたツールでしたので、導入の参考になれば、と簡単な紹介記事をまとめてみました。

 今回は、piklabのインストールを行い、アセンブラ(gpasm)とCコンパイラ(sdcc)を使用し、小さなプログラムをコンパイル・ダウンロード、そして基本的なデバッグ操作をするところまでをやってみたいと思います。ターゲットとしては、pic16F819を使った簡単なLED表示回路を作ります。


piklabについて

 piklabは、Linuxで動作するPICおよびdsPICの開発統合環境(IDE)です。Microchip提供のIDEであるMPLABを意識した作りとなっていて、MPLABを使用したことがあれば違和感無く使えると思います。フリー、かつオープンソースで、GPLライセンスにより提供されています。


 piklabのホームページは→ こちら

PIC開発環境

ICD2


Microchip ICD2 外観

 PICプログラマは色々なものがありますが、トラブルなく動きそうで、そこそこ信頼性のありそうな純正ICD2を購入して使用しています。特に純正である必要はありません。

 ICD2には、ICSPでプログラムをするための信号がRJ-11 6線コネクタから出ています。ブレッドボード上のターゲットに接続するための簡単な変換コネクタを作っています。



ICSPコネクタ 外観と結線図

 プログラマからの信号(PGC/RB6, PGD/RB7)をターゲットから完全に切り離すためのスイッチをつけています。もうちょっとスマートに電子的に切り離せるようにしたいと思案中ですが、この簡単な方式でも現在のところあまり困っていませんので、予定は未定。


 piklabでの、他のプログラマ、デバッガへの対応については、piklabホームページのサポート情報を参照してください。

 piklabの対応デバイス一覧は、piklabホームページの対応デバイスに一覧があります。デバイスによっては、プログラムは可能だけどデバッグは不可、というものもあるので注意が必要です。

MPLAB

 ICD2やターゲットの動作確認のため、MPLABはWindows環境で用意しておきます。後述のように、デバッグ用のファームウェアを利用するのが主目的ですが、なにか問題が起きたときに、公式ツールが試せる状況にしておくと緊急時に便利です。なお、Wine環境でもMPLABが使えるようですが、今回は未確認です。

 MPLABそのものの説明については、ここでは省略します。

ソフトウェア・インストール

 この記事で使用しているLinuxは、Fedora12です。各ツールのインストール元としてリポジトリにあるものをそのまま使いました。しかし、他のバージョンや、Ubuntuなどでも大きな違いは無いと思います。

  • gputils
  • PIC用のアセンブラ、および関連ツールをインストールします。
    今回のバージョンは、0.13.7 betaです。(gpasm --version により表示)
    gputilsのホームページは→こちら。http://gputils.sourceforge.net/

  • SDCC
  • 8051など各種小規模マイコン用のCコンパイラとして開発されているCコンパイラ、SDCCをインストールします。
    今回のバージョンは、2.9.0です。(sdcc-sdcc --version により表示)
    SDCCのホームページは→こちら。http://sdcc.sourceforge.net/

  • piklab
  • リポジトリ上にあるものをそのままインストールします。
    今回のバージョンは、0.15.9です。(piklab --version により表示)
    上でも書きましたが、ホームページは→こちら。


piklabのGUI

 インストールが完了すると、メニューの「アプリケーション」→「電子工学」→「piklab」で起動できるようになります。起動すると、左のような画面です。


piklabの設定

 piklabを起動して、環境設定を行います。

Toolchain設定

ビルドをおこなうための、アセンブラ、Cコンパイラの設定を行います。
  • gpasmの設定
  •  piklabメニューから、[Settings] -> [Configure Toolchains...] で、設定ダイアログを開き、[Assembler] - [GPUtils] の項目を選択します。

     特に何もしなくても、gpasmが正しくインストールできていれば、gpasm, gplink, gplibコマンドが "found" になっているはずです。

  • sdccの設定
  • 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です。

ICD2プログラマの設定

  • 接続ポート(USB)の設定
  •  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/ICD2のアクセス権について
  •  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だったりします。)
    グループへの加入は、システムのメインメニューから、[システム] → [管理] → [ユーザーとグループ]で行います(Fedora12 日本語UI設定の場合)。

ICD2デバッガの設定

 ICD2デバッガを、同様に設定します。

  • 接続ポート(USB)の設定
  •  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]に、コピーしたフォルダを指定します。

ICD2の接続テスト

 画面左側の[Project Manager]ペーンから、プログラマとして[ICD2 Programmer]を選択します。そして、piklabのメニューから、[Programmer] -> [Connect] で接続します。

 この時点で接続すると、ターゲットがないため電源電圧やデバイスIDのエラーがでてしまいますが、プロジェクトを作成して、ターゲットを接続すれば準備OKになるはずです。ということで、以下、ターゲット・ボードを用意してからの手順を進めます。

ターゲットとソフトウェアの仕様

 さて、いよいよターゲットを用意して、実際に動作するプログラムを書いてみます。最初のターゲットはブレッド・ボード上に作成しました。デバイスは、たまたま箱に転がっていたpic16f819です。LEDの点灯をするだけなので、ポート出力とタイマー機能しか使いません。

 pic16f819のデータシートなどは こちら → Microchip PIC16F818/819 (www.microchip.com)

ターゲット回路図

 こちらが、今回テストに使用した回路です(LEDの直列抵抗は1kΩ程度。他は10kΩ)。7セグメントLEDを4桁、ダイナミック表示用に配線しており、ポートB(RB0..7)で数字の形を、ポートA(RA0..4)で表示する桁を選択します。桁ドライバは、デジタル・トランジスタでシンプルに配線しました。システムクロックはシンプルにするのとブレッドボードという条件のため、内部RC発振で4MHz設定と低く設定することにします。(速度が遅くなりますが、そのかわり、電池2個でも動作します)


ターゲット基板 回路図概要

ソフトウェアの仕様

7セグメントLED4桁をタイマー割り込みを使って切り換え、数字を桁ごとに順次点灯表示します。
  • interrupt
    1. TMR0のリセット
    2. tickerのカウントアップ
    3. ドライブするLEDの桁をシフトする
    4. 当該の桁へバッファの値を出力
  • main
    1. ポート、タイマー、システムクロック、ウォッチドッグの初期化
    2. ticker、LEDバッファの初期化
    3. TMR0割り込み設定、および許可
    4. main loop
      1. tickerの値を10進数に変換
      2. 各桁をLEDバッファに書き込む
      3. main loop を永久にくりかえし

 今回は、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でのテストにいきます。(←要するに、根性が無いのです。すみません・・・)

プロジェクトを作成 (C言語編)

sdccを使用するプロジェクトを作成

 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."を選択
 アセンブラのプロジェクトとツールチェインの指定が違うだけです。まったく同様に、骨組みだけのソースファイルが自動的に生成され、基本的な割込みとメインルーチンからなるプログラムがすぐにビルド可能です。

sdccでソースを記述

 さて、できあがったソースはこちら。最適化などは考えずに、つらつらと書いたのでサイズが大きくなっていますが、労力を考えると、Cで作成できるというのは非常に便利ですね。インラインでアセンブラ・コードも書けるので、非常に楽ちん。自分の目的にはアセンブラよりもあっているようです。C言語というよりは、高級アセンブラという感覚で使っています。

ビルド、プログラム・ダウンロード

 アセンブラのプロジェクトとまったく同様です。プログラマを接続して、ダウンロード、実行で完了です。

 さて、作成したプログラムが期待通りに動作するまでには、テストとデバッグを幾度か繰り返さなくてはなりません。次節では、デバッガを使用した基本的なデバッグを試してみます。

デバッグ

 ICD2を使って、デバッガの基本機能を試してみます。piklabのデバッグ機能は開発途上で、まだ完全なものではないそうですが、必要最小限の機能が動作していて、バグの原因究明には非常に強力です。小さな家内制プロジェクトであれば、大抵これだけで足りてしまうように思います。

ICD2をデバッガとして接続

 画面左側の[Project Manager]ペーンから、プログラマとして[ICD2 Debugger]を選択します。(注)すべてのデバイスでデバッグに対応しているわけではないようです。詳細は、piklabのホームページを参照してください。


DEBUG_ONでビルド

 ソースのコンフィグ・ワードの設定に"DEBUG_ON"を指定してビルドします。エラー無くビルドが完了したら、ICD2に接続してデバッグ準備完了です。

ブレークポイントの設定

 ブレークポイントを設定してみます。ブレークしたい行にカーソルを移動して、ブレークポイントを設定します。デバッグを開始すると、設定した位置を実行した際に動作が中断します。


ブレークポイントの設定


ブレークポイントで実行が停止したところ

ウォッチの設定

 変数のウォッチは、左のペーンから監視したい変数を選択するだけです。ブレークがかかるごとに変数の内容が前回のブレークから変更されていれば、表示が更新されます。


ウォッチの設定

ステップ実行

 ブレーク状態でステップ実行をおこなうと、1命令実行後、再びブレークします。「アセンブリ言語での1命令ステップ実行」になっているのか、C言語の場合は複数ステップ実行しないと、次の行に移動しないようです。面倒な時は、ブレークポイントを設定しなおして実行継続するのが手っ取り早いです。

生成されたコードを見る

 SDCCが、Cソースから生成したアセンブラ・コードを見ることができます。 ソースコードの対象行にカーソルを合わせて、右クリック -> Show disassembly location でアセンブラのコードを見ることができます。

補足

一般的な注意事項

 MCLR端子をI/Oとして使用するコンフィグの場合、端子によるリセットでデバイスを待機状態にできないので、ダウンロード完了と同時にプログラムが開始されます。ICSPの各端子をI/Oとして使用する場合、ターゲットやプログラマを破損することのないように回路設計に注意してください。

レジスタ定数などのヘッダファイル

 他のコンパイラ用の書かれたソースでは、PICのレジスタや周辺回路のアドレスなどのシンボルがSDCCと異なっているかもしれません。これらのシンボルは、ヘッダファイルに記述されています。他のコンパイラのソースなどで未定義エラーがでる場合は、まず各デバイスのヘッダの記述を確認してみることをおすすめします。

 ヘッダ・ファイルは、 /usr/share/gputils/header にあります。(Fedora12)

コマンド・ラインからの制御

 コンパイル済みのファイルを書き込みしたい、などの用途の場合、コマンドラインでの操作ができると便利ですね。 以下に、コマンドラインでの操作について抜粋しておきます。

  • (sdcc) 単一ソースファイルのコンパイル
  • sdcc-sdcc -mpic14 -p16f819 pictest.c
  • (piklab) プログラマに接続
  • piklab-prog -c connect -p icd2 -d 16f819 -t usb
  • (piklab) コンパイル済みHEXファイルのダウンロード
  • piklab-prog -c program -p icd2 -d 16f819 -t usb pictest.hex
  • (piklab) ターゲット・デバイスをリセットして実行
  • piklab-prog -c run -p icd2 -d 16f819 -t usb

あとがき

 PICマイコンは、その豊富なラインナップ、入手性・経済性の良さ、そして参考文献の多さから、日本国内ではホビー用途に広く採用されているようです。PICの特徴は、昆虫の進化のごとく、各機能を細分化したデバイスの多様性でもって、様々な用途にコスト面から最良の選択肢となる場合が少なくありません。

 お手軽にお安くチョイチョイと組めるのが小規模マイコンの魅力ですが、それを最大限に利用するには、習得時間の短さが非常に重要と思います。そのうえで、非常に重要になってくるのが、標準的な文法を使用するC言語の存在です。なかでも、フリーでオープンソース、また、Linuxネイティブで動作する手軽な選択肢としてpiklab,gputils,sdccの組み合わせは、PIC開発には欠かせないものと思います。それぞれ、すばらしいツールの開発に尽力されている諸氏に感謝します。



表紙に戻る