|
|
PDAがブームの昨今これをお読みの皆さんも 携帯情報機器に興味をお持ちと思います。 その中でもPalmは非力なハードウェアながら、 さまざまなサードパーティ製品によって とても使いやすいものとなっています。 本稿では、そのPalm向けのソフトウェアを LinuxなどのUnix系OS上で開発するための情報を prc-toolsというgccのクロス環境を中心に ご紹介したいと思います。 なを、具体例が必要な場合には、筆者がメインの環境としている Kondara/MNU Linux 1.2を使って説明します。 また、java、pythonなどの環境やツールについても 触れたいと思います。
PalmOS向けソフト開発ツールの概要PalmOS向け開発の特徴は、そのほとんどがOpen Sourceのツールで行える点でしょう。 コンパイラはgcc,binutilsなどのGNU Tool Chain、ポストリンカーbuildprc、 リソースコンパイラpilrcなど、全てソースコードとともに入手できます。 また、サンプルのソース、ヘッダファイル、各種ライブラリ(zlib,sslなど)、 ドキュメントなど多数の開発リソースが公開され、自由に利用できます。 ちょっとwebなどで検索すれば容易に参考となるページなども見つけることが出来ます。
prc-toolsはPalm ComputingがOpen Sourceとしてリリースしている
PalmOS向けにモディファイされたgccとbinutils, gdbなどの
MC68000向けクロス開発ツールで、
crt,libcなどのランタイムライブラリ、
リソースデータベースファイルを生成するポストリンカーが含まれます。
図1:開発環境の概要 Palmの実行形式はプログラムコード、UIのリソースや 文字列などのデータをprc形式という独自の形式にまとめたものです。 gccでコンパイルした結果からプログラム部分をコードリソースとして 取り出し、リソースコンパイラで作成したリソースデータを ポストリンカbuild-prcで結合して作成します。 出来たファイルは実機にダウンロードしたりPose(PalmOS Emulator)に ロードしてデバッグします。 デバッグにはgdbが使用できます。 必要なもの
開発環境の構築
prc-tools元々は開発者の有志がgcc 2.7.2をベースに修正を行った prc-tools 0.5.0が使われていました。 長い間、公式にバージョンアップされないままだったのですが、 現在はPalm,Inc.が引き継ぎgcc 2.95.2ベースの2.0がリリースされています。 浮動小数点周りに問題があるようですので、フィックスも同時に入手してください。 また、Source Forgeでは2.1のbeta版が配布されています。 簡単なプログラムてテストした限りでは問題なさそうです。 こちらのほうもお試し下さい。
pilrcPalmOSで使用する実行ファイルは MacOSに似たリソースデータベースという独自の構造を持ち、 リソースタイプとID番号で管理されるバイナリデータの集まりです。 FormやButtonなどのUIオブジェクトやバージョン情報、 ビットマップなどが含まれます。 このリソースデータをテキスト形式のソースからコンパイルし 作成するツールがpilrcです。 元はWes Cherry氏が作成され、現在はAaron Ardiri氏が引き継いで 開発されています。日本語もShiftJISで使用できます。
Pose
PoseはPalm,Inc.から配布されているPalmのエミュレータです。
Windows,Mac,Unix用の各バージョンがPalm,Inc.のホームページから入手できます。 インストールはちょっと手間がかかりますので、インストールの手順を示します。 付属のドキュメントにも目を通してインストールして下さい。
Mesa,FLTKのインストールFLTKはqtやgtkと同じくGUIのToolkitです。 探せばバイナリパッケージが入手できるかもしれませんが、 ここはソースからコンパイルすることにします。 FLTKはOpenGLライブラリのMesaを必要とするので、 まずMesaをインストールしてください。 MesaはほとんどのOSで標準的に入手出来ると思いますので、 パッケージなどからインストールしておいてください。 RPMをお使いのかたはMesa-develも一緒にインストールしなくてはいけません。 fltk-1.0.10とMesa-3.2.2で動作を確認しました。
PoseのインストールWindows版、Mac版はバイナリがありますが、Unix版はソースのみの配布ですので 自分でコンパイルする必要があります。 ちなみに筆者のKondara 1.2環境では問題なく動作しましたが、 Jirai(glibc2.2,X4.0.1)環境ではコンパイルは通るのですが、 出来たバイナリが実行途中にSEGVで落ちて使えませんでした。
ROMイメージの吸い出しPoseでPalmのプログラムを実行するにはPalmOSのROMイメージが必要です。 ROMイメージは実機から吸い出すか、Palm,Inc.のDeveloper Seedingで 配布されているDebugROMを申し込むと入手できます。 ここでは比較的手軽な方法として実機のROMイメージを吸い出すことにします。 方法は2通りです。
Pose起動
poseを起動すると"Right click on ... "と書かれた白いWindowが出現します。
右クリックで"New"を"New"を選びメモリサイズなどとともに、さっき吸い出した
ROMイメージを指定します。
全てうまくいっていると無事巨大なPalmが画面上で起動するはずです。(図2)
あとは、pilot-xferでバックアップしたファイルをインストールしたり
デバッグ中のプログラムを入れることが出来ます。
テスト中の不安定なプログラムで実機のデータを
破壊する危険性がなくなります。 図2:Pose起動画面 その他のツール類pilot-templateアプリケーションの雛形となるCソースとリソースファイル、Makefileなどを 生成してくれるperlスクリプトです。 もとはIan Goldberg氏が作成されGPLで公開されています。 ただし、このツールはprc-tools 0.5.0にしか対応しておらず、 メンテナンスもされていないようです。 いろいろな方が自分むけに手直しして使用されていますので インターネットで検索などすればすぐに見つかるでしょう。 筆者もprc-tools 2.X向けに若干手直ししたバージョンを公開していますので 参考にして下さい。
pilrceditjava環境で動作するpilrc形式のリソースデータのWYSIWYGなエディタです。 RADツールのように部品を配置して画面のリソースが作成できます。 まだ全てのリソースが取り扱えるわけではありません。 必須ではありませんが、開発の初期段階では便利でしょう。 jdk 1.2.2で動作確認しました。
本稿を書いている2001年3月に調べたときには 本家はバージョン0.42,SourceForgeでは0.41と 本家のほうが少し新しいバージョンが入手できます。 parデータベースやリソースファイルを分解したり組み立てたりできるツールです。 データベース周りのデバッグ時に便利です。 リソースディスコンパイラ
両方ともprcファイルからpilrc形式のソースコードを得ることが出来るツールです。 後述のRsrcEditなどと組み合わせて、実機での調整結果を ソースに反映したり、 英語のアプリケーションからリソースを取り出し、 文字を書き換えたり日本語化したり出来ます。 双方ともjava環境が必要です。
ptoolsリソース、データベースの表示プログラムです。pilrcのソースコードに変換するのにも使えます。 java環境で動作します。 palmのデータはバイナリベースですので内容の確認に便利です。Palm上で動作するソフトウェアPalm上で動作するツールです。 実際の画面表示で確認できるので重宝します。
Palmハードウェアの概要Palm機のCPUはMotrola社のDragonBallシリーズを使用しています。 このCPUはコアにMC68000を用い、LCDコントローラやシリアルなどの I/Oをワンチップにしたものです。 メモリはOS搭載用のFlashROM又はMaskROMが2-4MByte、 ストレージとワークを兼ねたRAMが1M〜8M程度です。
Hello Worldこの記事をお読みの読者の方々は既にUnix系のOSに精通されている方が 多いと思いますが、PalmOSでのプログラミングには特有の考え方と 制限があります。 "68KMacの頃のMacOSに非常によく似ている部分が多い" と書けばある程度想像がつかれる方も多いと思います。 ともあれ、実際のプログラムを見てみるのが一番です。 ここでは、おなじみの"Hello, World."を作成して 実際に動作するアプリケーションを例に 説明していきましょう。
ソースをゼロから書くのは面倒なのでpilot-templateで雛形を作成し、 これに肉づけしていくと非常に楽です。 この雛形はコンパイルしてPalmにインストールしても 空のFormを表示するだけで何もしません。 この雛形はよく出来ていますので、これを使って説明します。 以下のようにpilot-templateを実行します。
pilot-template Hello.prc Hello Hello HeLo
引数は、それぞれmakeの結果出来る実行ファイル名、アプリケーション名、 ランチャー上のアイコンにつく名前、クリエータIDを示します。 以下のソースが生成されます。
リスト1: リソースファイル
画面の中央に"Hello, World."と表示してみましょう。 エディタでHelloRsc.rscを開いてTITLE "Hello"のあとに
と追加します。 これでmakeすれば"Hello, World"の出来上がりです。 pilrcuiで画面の確認を行ってダウンロードすると 見事画面の中央付近に"Hello, World."が表示されます。 プログラムを見てみましょう。 Hello.cの一番最後の関数PilotMainから実行が始まります。 StartApplication関数で内部データやデータベースの読み込みを行い、 Formをロードします。 問題がなければイベントループへと進みます。
リスト2: PilotMain()
PalmOSのイベントループはとてもプリミティブで、 アプリケーションが直接OSからのイベントをハンドリングしなくては いけません。 そのためEveltLoop()ではイベント取得後、システムのハンドラ、 メニューのハンドラを呼び出し、 その後アプリケーション全体に関するハンドラ(Formの読み込みなど)を 処理し、最後にFormのハンドラを呼び出します。 各ハンドラは自分に関係のないイベントであったら戻り値にfalseを返し 次の処理へイベントを渡さなくてはならないことを示します。 FormはいわゆるコンテナでGUIの要素を含みます。 リソースでは"FORM <FormID>"から始まりBEGIN-ENDでくくられた間に ボタンなどを配置します。 個々のFormにはイベントハンドラが設定でき、FrmDispatchEventから呼び出されます。 MainFormHandleEvent関数を見てください。 frmOpenEventからmenuEvent,ctlSelectEventと各GUIのイベント処理がswitchで並びます。 ここで各UIに対応するイベントを処理するわけです。 ボタンを追加してみるこのままではつまらないので、ボタンを作り、押されるとHello, Worldが 表示されるようにしてみましょう。 先のLABELの後ろに以下の1行を加えてみます。
pilrcuiで確認してみると確かにbuttonが追加されています。 PalmOSではbuttonが押されたときにはctlSelectEventを通知してきます。 従ってHello.cのctlSelectEventに以下のようなコードを 書くことになります。
これをコンパイルし、インストールし、"Hello!"ボタンを押すと、 画面に"Hello, World"と表示されます。(図3) 図3:Hello.prc 基本的にPalmにおけるGUIオブジェクトはリソースに納められた静的なもので、 Formの生成時にOSによって画面に配置されます。 GUIリソースはそれぞれユニークな4バイトのタイプと2バイトのIDで管理され、 プログラム参照できるようになっています。 実行時に動的なGUIのオブジェクトの生成も可能で、PalmOS 3.0以上からサポートされています。 PalmOSには上で説明した以外にもいろいろなUIオブジェクトがあります。 Popup、Selector、Field、ScrollBarなど、大半のオブジェクトは容易に 理解できると思います。が、Tableだけはちょっと難しいので、 SDKドキュメントだけでなく稿末に挙げたO'ReillyのDeveloper's GUIDEなどを読まれるとよいでしょう。 テンプレートの説明もうすこし詳しくテンプレートを見ていきましょう。アプリの起動アプリーケーションが起動されると PalmOS -> crt0 -> PilotMain という順で制御が渡ってきます。 PilotMainには引数があり、 起動コードとパラメータブロックとフラグが渡されます。 PalmOSはアプリケーションのエントリをいろいろな局面で呼び出します。 起動コードとは、その"いろいろ"を示すコードで、 通常の起動、HotSyncやリセット、検索などの種類があります。 また、その時に必要なパラメータがパラメータブロックで引き渡されます。 詳細はPalmOS SDKのドキュメントを参照ください。 各関数を順を追って説明すると PilotMain()
StartApplication()ここではメインのFormを開きます。 実際のFormの初期化処理は行われず、イベントだけが発生し、 後述のイベントループ内で実際の処理をします。 EventLoop()イベントはスクリーンタップやグラフィティの文字入力、ボタンの押下などで 発生します。以下のように、そのイベントを処理してやります。
システムやアプリは自分に関係のないイベントならば戻り値にfalseを返し、 まだ処理する必要があることを示します。 システムやメニュー処理では、ハードウェアボタンやシルクボタン、 画面上部のタップ、ショートカットなどさまざまな処理が行われます。 実際のメニューの内容の処理はmenuEventで行います。 StopAllication() -- 終了処理開かれているFormのハンドラに対しデータのセーブを指示 開かれているFormを全て閉じる ApplicationHandleEvent() --Applicaionのイベント処理先のFrmGotoFormで発生したfrmLoadEventを処理します。 Formをリソースから読み込み初期化(FrmInitForm()) アクティブなFormにセットします。アクティブなFormとは 現在画面の一番上に表示されているFormのことです。 また、eventのformIDからその画面に必要な初期化やForm毎のイベントハンドラを セットします。 MainFormHandleEvent() -- フォーム毎のイベント処理FrmInitFormで初期化されたFormにはfrmOpenEventが発生します。 FrmGetActiveFormで発生したFormを取得し、描画(FrmDrawForm)を行います。 ボタンの押下、メニューの選択、画面のタップ、リストの選択などの 主要なイベントを処理します。イベントと対象のIDを判断し適当な処理を行います。 データベースとメモリ管理テンプレートには出てきませんでしたが、 PalmOSプログラミングのもう一つの重要な部分である データベースとメモリ管理を簡単に説明します。メモリの構成PalmOSに管理されるメモリは2種類にわかれます。 アプリケーションの実行時に使用されるダイナミックヒープと保存データのための ストレージヒープです。 スタック領域ローカル変数を納めるための領域です。 大きさは固定でOSのバージョンにより2.5-3.2Kバイトほどですので 大きな配列などを取らないようにして下さい。 ダイナミックヒープダイナミックヒープは実行時に確保される領域で使用方法はmallocと似ています。 違うのはHandleと呼ばれる間接ポインタで管理されていることで、 メモリはロックされてポインタとして使用されるまで、 メモリ不足などによりOSが移動する可能性があります。 大きさはやはりOSのバージョンにより異なり32K-256Kバイト程度です。 ストレージヒープストレージヒープにはデータベースと呼ばれるファイルのようなものがあります。 データベースは管理のための情報とユーザ定義のレコードの集まりで、 アプリケーションのためにAppInfo,SoftInfoなどの情報を持っています。 各レコードは64Kまでの大きさの可変長な領域です。 おのおののレコードが3バイトのUniqueIDと1バイトのフラグ(カテゴリなど)を持ちます。 基本的に通番でアクセスします。 レコードはファイルと異なっておりダイナミックヒープ上のメモリと似ています。 データベースからハンドルを取得し、ロックして使用します。 ただし、ストレージヒープは書き込み保護されており システムコールを介して書き込み可能です。 また、当然ながらアプリケーションが終了しても内容は保存されます。 機種依存機能の使用についてPalm, Visor, TRGPro, CLIEなど、それぞれメーカごとに機能が拡張されています。 アプリケーションはできる限り機種依存がないほうがいいのですが、 拡張機能も魅力的です。 PalmOS4.0はまだ見ていませんが、 他機種の拡張機能はおおむね以下の様にして実装されています。
各メーカからSDKがダウンロードできますので、ご覧ください。 拡張機能を使ったプログラムを作製する際は、他機種との互換性に注意してください。 機種の判別がはっきり出来るようなAPIはありませんので、 JogDialのような操作系の拡張を使用する場合、 操作を完全に拡張部分に依存しないようにしたほうがいいでしょう。 また、拡張ライブラリを必要とするものに関しては、 SysLibFind,SysLibLoad関数などを使用してライブラリを 読み込む必要がありますので、見つからない場合にはその機能をDisableにします。 拡張機能が必須のアプリケーションでもプログラムを終了することはせず、 エラーを表示して、ユーザの終了を待つようにしたほうがいいでしょう。
なを、PalmOS 4.0では標準で拡張ストレージをサポートしましたので、 今後発表される機種では共通化されていくと思います。 gdbでデバッグするアプリケーションの作成時に "-g" オプションをつけてコンパイルしておくと gdbを使ってソースレベルデバッグが出来ます。 当然クロスデバッグです。 デバッガを"m68k-palmos-gdb Hello"などとして起動。
gdbとターゲットが繋がれば、あとは通常のgdbと同様にデバッグが出来ます。 emacsの中から (defun pi-gdb () "gdb for palm" (interactive) (setq gdb-command-name "m68k-palmos-gdb") (call-interactively 'gdb)) などとして使うと便利です。 開発ディレクトリに".gdbinit"を作成し"target pilot /dev/ttyS0"などとしておくと、 更にいいかもしれません。
*実行例
CreatorIDの登録CreatorIDとは、データベースに付加されている情報の1つで、 リソースタイプなどと同じような、全てのアプリでユニークな4バイトの識別コードです。 PalmOSはこのIDを用いてアプリケーションの識別を行います。 また、アプリケーションが作成するデータベースのCreatorIDも同じものとなり、 ランチャやメモリ管理ツールが一覧を表示する際、 データベースをまとめるのに使用したりします。 CreatorIDは大文字小文字の区別があり、全て小文字のIDはPalm Incが 予約しています。従ってそれ以外の文字の組み合わせとなります。 www.palmos.comのDevelopersのページに行き、"Quick Index"から"Creator ID"を選ぶと CreatorIDのページにたどり着きます。 他のアプリケーションが使っていないか重複を確認して登録してください。
全てのアプリケーションでユニークでないといけないので
プログラムを公開するような場合には必須となります。
ご紹介したprc-tools以外にも以下のようなフリーの開発ツールがあります。 メモリが少ない分機能が縮小されたりしていますが、 結構遊べるものも多いので楽しんでみてください。
Palm本体で動作する開発環境などもあります。 "PalmPilot Software Development - Alternatives to C" -- http://www.winikoff.net/palm/dev.htmlなど を参考にしてください。
やはりPalmのSDKのドキュメント、英文ですが。 少し内容的に古い部分もありますが、GNU Pilot How toなど。 メーカの開発者サポートサイト
オンラインで入手できるドキュメントなど
日本語の開発者向けメーリングリスト
英語の情報源
|