2013年01月27日

SDCC Tips 2013

SDCC Tips 2013

* はじまり
* SDCCツール群
* バグや注意点
* MPLAB でSDCC。 使えない
* MPLABX で SDCC。 標準装備
* SDCC 最新バージョン
* SDCC / C18 / HI-TECH Cでソース・コードをある程度共通化する時のTIPS
* "Microchipのヘッダファイル、ライブラリ"とGPL問題
* SDCCコマンドライン・コンパイル・プロジェクト
* ダウンロード
    使い方:


* はじまり
Pinguinoプロジェクトで採用されているC言語コンパイラ、SDCC。
http://sdcc.sourceforge.net/

動作に不審な点があったので、まずはSDCCで簡単なプログラムをコンパイルしてみようと
試したところ、意外にハマってしまって大変でした。

以下は、SDCCをPIC18Fで使ってみた時に遭遇した問題点や、
コンパイル方法等をメモする。

* SDCCツール群
2013/01時点で取得できる最新のWindows用のインストーラ付バージョンを使用する。
SDCC:   v3.2.0 #8008 (Jul  6 2012) (MINGW32)
        http://sourceforge.net/projects/sdcc/files/sdcc-win32/ 
        後述の最新バージョンを使って下さい.。
gplink: gplink-1.0.0 #925 (Dec 23 2012)
    パッケージ名は「gputils-n.n.n.exe」。
        http://sourceforge.net/projects/gputils/files/gputils-win32/
上記2つの場所からインストーラ(*.exe)を取得、実行します。
後述の理由から、全てインストーラのデフォルト設定を選択します。
すなわち、
SDCC:
インストール先: C:\Program Files\SDCC
実行パス:       C:\Program Files\SDCC\bin (パスの自動設定を選択します)
gputils:
インストール先: C:\Program Files\gputils
実行パス:       C:\Program Files\gputils\bin

フォルダ名にスペースが入るのがイヤですが、我慢してここにインストールします。:D

* バグや注意点
#pragma config 問題
(1) PIC18Fのconfig設定は、単一行にしか書けない。
これは、このバージョンのバグの様だ。(でも以前からあった風 :D )
複数行に書くと2行目以降の設定値は無言で無視されます。orz (注1)
#pragma config CP0=OFF,OSCS=ON,OSC=LP,BOR=ON
上の書き方はOK。 以下の書き方も実質1行なのでOK。
#pragma config  PLLDIV=2 ,\
CPUDIV  =    OSC1        ,\
OSC     =    INTOSCPLL   ,\
WDTEN   =    OFF         ,\
STVREN  =    ON
(2) PIC18Fのconfig設定は、「const修飾子」と同居できない このバージョンのSDCCのバグの様で、「#pragma config」を記述したファイルを コンパイルすると、余分の「codeセクション」が定義されていまい、(注1) 「const修飾子」を伴った定数、文字列等が同じファイル内にあると、 「codeセクションの多重定義」でコンパイルエラーになる。 orz gplink問題 gplink単独でリンク(最終的にHEXファイルを生成)すると、動作不良のHEXファイルが生成される。 これ今回、最も大きくハマリました。orz orz orz ソースコードの状況によって、動作したり、しなかったり、中途半端に動作したりという、 かなりイヤな状況に陥りました。 orz 回避策: リンクする時も「sdcc.exe」を使います。(sdcc.exeが内部でgplinkを呼び出す) そうすれば大丈夫でした。(注2) * MPLAB でSDCC。 使えない MPLAB用のSDCCプラグインがあるものの、MPLAB(v8.87)やgputilsが新しくなったので もう使えませんでした。 http://kanga.gerbilator.org/Microcontrollers/MicroChip-PIC/PIC%20from%20Sony%20stick/SDCC/ わざわざ、古い環境に戻す気になれないので放置します。 :D (2013/02) SDCCのコマンドライン・コンパイル方法やMPLAPXの設定から得たノウハウを元に、もう一度MPLABの 設定を見直したところ、うまくコンパイル可能になりました。 設定方法は、そのうちまた。 * MPLABX で SDCC。 標準装備 MPLABX v1.60では、SDCCプラグインが標準装備されています。(注9) ただし、アセンブラレベルのデバッグしかできないのと、デバッガはかなり使いにくい印象です。(現時点では) 「Tools」-「Plugins」-「Avaiable Plugins」画面で、SDCCにチェックを入れて 「Install」ボタンを押した後、MPLABXを再起動します。 「Tools」-「Options」-「Embedded」-「Build Tools」タブの「Toolchain」リストに SDCCがなければ、「Scan for Build Tools」を実行します。(リストに表示されるのに時間がかかる気がします) この時、上の方で書いた「SDCCとgputilsのデフォルト設定インストール」が、 「以前のMPLABX SDCCプラグイン」では必須でした。(最新版で必須かどうかは未確認です) IDEでの設定: 内容は何でもいいので、例えば「PIC18F26J50」のプロジェクトをMPLABX上で作ったとします。(注8) プロジェクトのプロパティ画面を開くと(注7)、右下の「Compiler Toolchain」に「SDCC Toolchain」が追加されているので、 選択して「Apply」ボタンを押します。 オプション設定: 画面左のCategories:で「sdcc」を選択、画面右下あたりの「Additional options」に「libc18f.lib」を追加します。 その他はデフォルト設定のままで良いです。すなわち、注目点として General -「Use non free libraries/header」:「--use-non-freeオプション」なので 必須。 PIC16 exclusive options - 「Stack-size」: Smallを選択。 を最低限選択します。(デフォルトで設定済み) 注意ポイント: コンパイラをSDCC以外に変更したままMPLABXを終了すると、変更を加えたSDCCオプションを忘れてしまうので、 再設定が必要です。(libc18f.lib等) * SDCC 最新バージョン ここから、毎日の最新バージョンが取得出来るようです。 http://sdcc.sourceforge.net/snap.php 試しに以下の最新版をインストールしてみたら、 sdcc-20130127-8398-setup.exe 上記、「#pragma config問題 (1),(2)」は見事に解決されていました。 もっと早く気づくべきでした。 orz orz あと付属マニュアルもかなり増補されている様です。 特に最初の方の「Compatibility with previous versions」は、SDCCの古いバージョン2.x系,3.X系との 差異が書かれているので必読。 * SDCC / C18 / HI-TECH Cでソース・コードをある程度共通化する時のTIPS これは、凝りだすときりがないのでほどほどにします。 :D ソースコード中で以下の定義済みマクロを使って状況を判別します。(注10) コンパイラを判別する: SDCC: __SDCC_pic16 PIC18F用コンパイラであることを判別できます。(__SDCC_pic14(PIC16F系用)もあります) SDCC v3.20以降では最初にアンダースコア2個付けるのが標準となりました。 C18: __18CXX C18コンパイラであることを判別できます。 XXのところはそのまま"XX"と書きます。 HI-TECH PICC18: __PICC18__ HI-TECHのPIC18F用Cコンパイラであることを判別できます。 PICの種類を判別する: 「PIC18F26J50」を例にします。 SDCC: __18f26j50 全部小文字です。他の書き方はマニュアルを参照してください。 C18 / HI-TECH PICC18: __18F26J50 全部大文字です。(オイ 大文字でも小文字でも、どちらかに統一してほしいです。 上記定義群を使って、「#ifdef文」や「#if defined()文」で判別します。 * "Microchipのヘッダファイル、ライブラリ"とGPL問題 SDCCにはMicrochipが提供している「マイコンごとのヘッダ・ファイルとライブラリ・ファイル」が含まれている。 これらのファイルがGPLに適合しないので(注4)、最近のSDCCでは「non-freeフォルダ」に分離されている。 Debian SqueezeではSDCC自体が排除されてしまっている。(apt-getで標準インストールできない)(注3) ざっと見た限りGPLの日本語FAQでは、以下の項目に関連すると思われます。 http://www.gnu.org/licenses/gpl-faq.ja.html#WhatDoesCompatMean http://www.gnu.org/licenses/gpl-faq.ja.html#TOCGPLIncompatibleAlone http://www.gnu.org/licenses/gpl-faq.ja.html#TOCMereAggregation 結局、SDCC自体は「non-free」に分離することで難を避けたものの、 問題はこれらのヘッダ・ファイル、ライブラリを利用するユーザ側に発生するとになります。 (この問題は根源的なもので、当初から発生する状況だった) 例をあげれば、純粋なGPLモジュール(例外事項なし)をどこからか持ってきて、 上記Mirochipのファイル群をインクルードして使った時点で、GPL違反となる。(再配布不可)(注6) 大丈夫なのは、上記Microchipのファイル群に対する例外条項付GPLのモジュールを使うか、 自分でスクラッチからコードを書いて例外条項付のGPLを付与した場合のみである。 このGPL問題は今回のSDCCに限らず、Microchipの提供するヘッダ・ファイル、ライブラリを 使用する場合に必ず発生するのである。(注5) 今回の調査により、PIC用のプログラムがGPLに絡むときは要注意であることが分りました。 * SDCCコマンドライン・コンパイル・プロジェクト MakefileとSConsを使ってビルド出来るサンプルプロジェクトを作りました。(注11) コンパイルするための雛形なので内容は、あまり意味がないです。 内容: タイマー割込みを基準に周期関数を登録して実行出来るようにしました。 Arduinoのタイマーイベント関数(MsTimer2)の様な感じになると思います。(詳細未確認) 周期関数は10個まで登録(create)できます。 登録した周期関数の「sleep」「resume」「delete」ができます。 PIC18F26J50/PIC18F2550/18F14K50、MPLAB、MPLABX、及びコマンドライン(make,SCons)からコンパイル実行できます。 コンパイラは、SDCC,C18,HI-TECH PICC18に対応しています。(#ifdef文で自動判別するようにしています) メイン関数は以下の様な感じです。 UART経由で周期関数の「sleep」「resume」「create」をするデモです。 UARTを「stdio.h」のprintf()関数に接続してあるので簡単なデバッグ用途に使えると思います。
/********************
 * main_loop
 ********************/
void main_loop(void)
{
    switch( getch() ){
        case 's':    /* スリープ とレジュームをトグル */
            event_state( led_id )    == RUN ? event_sleep( led_id ):   event_resume( led_id );
            event_state( print_id )  == RUN ? event_sleep( print_id ): event_resume( print_id );
            break;
        case 'd':    /* 周期関数の削除 */
            event_delete( led_id );
            break;
        case 'c':    /* 別周期の周期関数として再登録実行 */
             event_delete( led_id );
             led_id  = event_create( led_toggle , 100);
            break;
        default:
             break;
    }
}

/********************
 * main
 ********************/
void main( void )
{
    sys_init();
    setup();
    GIE_enable();
    PEIE_enable();

    led_id      = event_create( led_toggle , 500);   /* 500msecの周期関数を登録 */
    print_id    = event_create( print_task , 3000);  /* 3秒の周期関数を登録 */

    while(1){
        event_dispatch(); /* ディスパッチャの実行 */
        main_loop();
    }
}
* ダウンロード 準備中 使い方: (注1)生成されたアセンブラ・ファイルを見るとわかる。 (注2)サクッと書いてますが、かなり大変でした。(TT) (注3)Squeezeより後のDebianでは改善される模様。 (注4)使用はMicrochipのデバイスに限るという制限事項。 (注5)当然、BSDやMITライセンス系なら問題ない。 (注6)そのGPLモジュールの作者から許諾を取るという手もなくはないが...。 当然、再配布しなければ問題ない。 (注7)画面左上の「Projects」領域でプロジェクト名を選択、右クリックで「Propaties」を選択する。 (注8)MPLABからMPLABXに既存のプロジェクトをコンバートするのも簡単にできる。 (注9)MPLABX用のSDCCプラグインはこのページがオリジナルのようです。 https://sites.google.com/site/rmaalmeida/mplabx-sdcc-toolchain (注10)詳細はコンパイラのマニュアル参照。 (注11)MPLAB、MPLABXでもコンパイル可能な様にしました。 参考リンク: PIC18F: 超効率Cコンパイラ CPIK


posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(0) | PIC関連 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。