October 29, 2005

EZUSB Keilからsdccへ、EZUSB.lib等の移植

とりあえずA/D変換データがパソコンから読めるようになったUSB-ADCですが、u-bloxのGPS基板をつなげて全て1つのシステムとして統合しようと考えています。ところがCypressから無償で入手できる開発環境の評価版Keilでは生成でせきるオブジェクトのサイズが4KBまでという制限があり、少し大きなことをやろうとするとこの制限に引っかかってしまいます。

ということで評価版のKeilからフリーの開発環境であるsdccに移行することにしました。しかしながら、sdccはフリーということもありサンプルコードが少なく、なかなか敷居が高いのが現状です。また、KeiにはEZUSBで必要となるUSBまわりの処理がかなり丁寧に書いてあるので、特別なことをしなくても簡単に開発を行えるのが魅力でした。

そこでKeilで使ってきたコードをsdccに移植することを考えました。普通のCコードはほぼそのままでもsdccでコンパイルできるのですが、Keilに依存している以下のコードが移植の際に問題となります。

  • EZUSBのSFRのアドレス等が記載されたヘッダファイル、ezusb.hezregs.h
  • USBやI2Cの便利なライブラリであるEZUSB.lib
  • USBインタラプトまわりのジャンプコードが記載されているUSBJmpTb.OBJ
  • USBディスクリプタやエンドポイントの情報が記載されているDSCR.A51
これらのコードを中心に移植をすすめることにしました。

※その後EZUSB FX2LPにおいてもsdccへの移植に成功しました。

移植方法については続きをどうぞ。

それぞれのファイルに対してみていくことにします。

まずヘッダファイルEZUSB.libについてですが、これについては移植例がありました。EZ-USB board on Linuxというページで、EZUSBをLinuxで開発するためにsdccでコンパイルすることができるヘッダーならびにEZUSB.libが公開されています。詳細は上のリンクのページに譲りますが、シンタックス的な移植がほとんどのようです。
sdccでコンパイルできることを確認しましたが、一箇所だけ修正が必要でした。EZUSB.libを構成するファイルの中で1msecウェイトをおくためのdelayms.asmというコードがあるのですが、ここに記載されたSFRのdpsはasx8051(sdccの8051互換アセンブラ)では定義されていないので、_DPS=0x86と定義を書き加えました。
ヘッダファイル、ならびにMakefileをつけたEZUSB.libのソース、バイナリを公開します。

次にUSBインタラプト関係のジャンプコードが記載されているUSBJmpTb.OBJです。なぜこのようなコードがあるかというと、EZUSBはUSBインタラプトに対してAutovector(マニュアル 9.10参照)という方法を用いており、数が多いUSBインタラプトを8051インタラプト(CPUコアのみのインタラプト)にカスケード接続することによって対応しています。そのため8051ベクタテーブルの他にUSBインタラプト用のベクタテーブルを用意する必要があり、さらにはUSBインタラプトが発生した際にUSBインタラプト用のベクタテーブルをひくよう、8051ベタクテーブルからUSBベクタテーブルにジャンプするようにしなければなりません。これがUSBJmpTb.OBJの役割です。
USBJmpTb.OBJのソースをsdccのアセンブラであるasx8051むけになおすと、USBJmpTb.asmのようになります。USBベクタテーブルはページ境界(0x?00となる位置)に配置する必要があるようで、ここでは絶対位置指定(ABS)で0x1A00に配置していますが、もう少しうまい書き方("PAG"とかを使う)があるかもしれのません。

そしてUSBディスクリプタやエンドポイントの情報が記載されているDSCR.A51ですが、これはsdccのアセンブラasx051向けになおすとdscr.asmのようになります。基本的にシンタックス修正のみですみます。

以上をもって全ファイルの移植が完了しましたが、実はこれだけでは動くコードがでてきません。インタラプト処理を行う関数で2点修正を行う必要があります。
まず、sdccはインタラプトの処理についてはmain()関数があるのと同じファイルに書かなければならないという規則があるようです(参考 sdccのマニュアル3.8.1)。ということで全てのインタラプト処理を行う関数はextern void hoge(void) interrupt 0;のようにmain()があるファイルに書くようにします(例 main()があるfw.c)。
そして、USBインタラプト処理ですが、KeilのコンパイラC51ではインタラプト番号の重複が許されているのでinterrupt 0;を乱発していますが、sdccではそれを許さないのでinterruptの番号を全て固有にする必要があります。例えばperiph.cを見てください。

以上をもって移植がうまくいきました。あとは全コードをおいておきますので、参考にしてください。#DEFINE SDCCを活用しているのでKeilでもsdccでもコンパイルできます。sdccでコンパイルするときはMakefileを添付してあるのでmakeを使ってください。

あと注ですが、ホストのカメレオンUSBライブラリはデフォルトではFWは0x1000までしかEZUSBに転送しないようです。今回はUSBベクタテーブルを0x1A00に配置しまっている関係で0x1000を超えてしまっているのでcsub.hCUSB_DWLSIZEを0x2000くらいにしておけばOKです。

11:39 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | この記事をdel.icio.usでブックマーク | トラックバック
このエントリーのトラックバックURL: http://fenrir.naruoka.org/mt/mt-tb.cgi/438
コメント

評価版Keilにはそういう制限があるのですね。非常に参考になります。sdccですか、フリーというのがいいですね。しかし、「以上をもって移植がうまくいきました。」って、またあっさりとやってしまわれますね。

Posted by: Fujiwara : October 29, 2005 10:49 PM

Keilはお高いですからね…
お金のためならがんばります(笑)

Posted by: fenrir : October 30, 2005 09:45 PM

すばらしい!sdccへの移植は,私は技術力不足であきらめてました.
今まで,参考になるようなサンプルソースも少なかったので
こちらで勉強させて頂きます.FX2に対応させたいなぁ.
いとも簡単に実装されているようで,羨ましい限りです.

Posted by: hama : December 12, 2005 05:15 PM

こんにちは、hamaさん。
自分の備忘録程度に書きなぐったものですが、参考になれば幸いです。やはりソフトウェアに制限があるとそれが絡んでくるハードウェアの魅力が半減してしまうと思います。そういうわけでフリーのコンパイラにはとてもがんばって欲しいと思っています←現在某DSPのフリーコンパイラにチャレンジ中。

Posted by: fenrir : December 13, 2005 01:34 AM

素晴らしい!4kの壁に泣いて投げ出してしまった自分が恥ずかしいですよ。
また意欲が湧いてきましたので参考にさせていただきます。

Posted by: bunbun : January 24, 2006 12:26 AM

bunbunさん、コメントありがとうごさいます。
是非ともチャレンジしてみてください。今度僕の方ではFX2をsdccで使ってみようと思っています

Posted by: fenrir : January 25, 2006 01:37 AM

> 今度僕の方ではFX2をsdccで使ってみようと思っています

お久しぶりです.いつも更新を楽しみにしています.
fenrir さんのソースを参考にして,
sdcc 使って FX2 の Keil テンプレートを
コンパイルできるようになりました.
まだ実際に動かしてはいませんが.

新しい基板が届いたようですが,
もう FX2 に対応されましたか?
もしよろしければ参考までにソースを送ります.

Posted by: hama : January 31, 2006 03:06 PM

hamaさん、こんにちは。
お役に立てたようで幸いです。FX2の方ですが、半導体本体の入手が遅れているためまだ動作確認できていません。ソースの方ですが、興味ありですので、よろしければ送ってくださると助かります。

Posted by: fenrir : January 31, 2006 09:14 PM

FX2への移植に参考にさせていただきました。
最初は、keilテンプレートの動作に手間取りました。注意点は、公開されているfx2regs.hのsfr xx xx = xx -> sfr at 0xxx LABELに変更する事と、dscr.asmのデスクリプタ定数を.odd配置する程度です。
FX2も16KBRAMになりましたので、FPGAと組合せて余裕のシステムが構築できるようになり、もっと利用したいチップですね。(趣味でサウンドと画像の相関マッチングをやってます。自前設計基板(PROTEL))

以上お礼かたがたご報告まで。

Posted by: hang : February 24, 2006 12:38 AM

hangさん、こんにちは。
お役に立てたようで嬉しいです、加えて追加情報ありがとうございます。現在FX2LP(68013A)を試しているところですが、USBまわりにとどまらずFPGA等色々組み合わせて遊んでみたいと思っています。
基板を自作されているのですか。どのようなシステムなのでしょう? 興味ありです!

Posted by: fenrir : February 24, 2006 11:42 PM

fenrirさん はじめまして。

えーと、まず前記に間違いがありました。
dscr.asmの定数配置は.evenダイレクティブを使用します。
他に、SDCCコマンドの--data-loc 0x20オプションが無視されてしまうようなので、バンクエリアを不使用とするためにBYTE notuse[32-8];のようなダミー変数を最初の変数宣言にします。大体このような修正で、KEILからSDCC変換でFX2が動いています。さすが、300Mbpsクラスは利用価値が高いですね。
また、EZ-USB Control PanelへのロードはBIXフォーマットが安定してロードできます。HEXは不安定です。

>基板を自作されているのですか。
ほとんど、思いついたらプロテルDXP画面を開いてしまいます。回路を書いて、パターンアートワーク->Pbanというように、やってしまいますので、金のかかる事はハンパじゃないです。
前記のFPGA+FX2基板は、ビデオデコーダチップと大容量高速SRAMが載っているもので、自己相関関数を逐次比較アルゴリズムで演算しパターン認識するものです。

昔は大規模CPUで開発する傾向がありましたが、最近は悟りを開いて、小さなCPUで利用価値のあるものを短時間で開発する事に意義を見出しています。

これからも、あれこれやっていきますので、よろしく。

Posted by: hang : February 25, 2006 12:29 AM

はじめまして。

私もKeilからSDCCへコード移植を行いました。
しかしながらコンパイル結果が少々悪くスピードがKeilより1割ほど遅かったので最近はKeilに走っていました。

離れた原因は他にもあって、ソースコードが大きくまた複数ファイルになっていくにつれて、動作が全くできなくなるという状態になる。。。。ということがあったのですが、fenrirさんの環境でも一度試してみようかと思います。

バルク転送+GPIFでベンチマーク24MB/sが現在のMAXです。SDCCでこれに匹敵するようなスピードが出せるか挑戦してみようかとww

Posted by: nob : March 14, 2006 09:35 PM

nobさん、こんにちは。

そうですね、やはりsdccはフリーであるがゆえに、Keilよりもスピードが劣るという話は聞いたことがあります。とりあえずこちらはsdccで今のところ動作不良はおきていません。
今度、Keil vs sdccでスピード競争をしてみようかと思います。スピード競争といえば、gccの8051版ができればまた面白いのですがね。

Posted by: fenrir : March 16, 2006 10:48 AM

素人が自分用のキーボードとトラックボールの複合デバイスを作成しようとしています。参考にさせていただいております。オプティマイズさんのMINI EZ-USB(AN2131SC)を利用しています。fenrirさんの記事やファイルを参考にしてcypressのezcomboをSDCCでコンパイルしてみたのですが、
memory overlap near 0x0 for HOME
といった表示が出てきます。ezcombo.hexは作成したみたいです。
もしご教示いただけるのであれば詳しい情報を書かせていただきます。
どうかよろしくお願いいたします。
場違いであれば申し訳ありません。。。

Posted by: te : April 3, 2006 01:12 PM

teさん、こんにちは。ここは情報交換の場だと考えておりますので、遠慮なさらずにご質問ください。
問題の件ですが、おそらくどこかのコードの配置が重なってしまっているのだと思います。USBJumpTbl.asmの.orgが0x1A00となっているのを0x1B00としてみてどうでしょうか。なお、0x1B00以上にすると、EZUSBのメモリ容量の関係で動作しなくなりますので、ご注意ください。

Posted by: fenrir : April 3, 2006 11:32 PM

fenrirさん 早速のお返事ありがとうございます。
USBJumpTbl.asmの.orgが0x1A00となっているのを0x1B00としてみて、Makefile中で
SRCS_ASM = dscr.asm USBJumpTbl.asm
としてみました。
やはり同じメッセージが出ます。
memory overlap nearの次には
0x0 0x20 0x40 0x60 0x80 0xA0 0xBE 0xDE 0xC1 0xCB 0xEB 0xED 0xF3 0x113 0x117 で始めの6個が for HOME、
次から8個がGSINIT0からGSINIT4、最後がGSFINALとなっています。

私の恥ずかしいサイトからファイルを見ていただけるようにしてみようと思います。
準備できましたらまたコメントさせていただきます(夜になると思います)。
HOMEやGSINIT0でSDCCやcypressのDOCなどを検索してもめぼしいものがでてこないのでたいへん困っていました。
ありがとうございます。

Posted by: te : April 4, 2006 01:44 PM

>teさん
リンクの結果を記録したマップファイル(拡張子が.map)が生成されると思いますが、その中にHOMEやGSINIT0等があるかと思います。その配置順序を見る限り、恐らくコードのサイズが大きすぎて問題が発生しているのではないでしょうか。

Posted by: fenrir : April 6, 2006 12:05 AM

fenrirさま
時間がかかってしまいましたが、Webにアップしました。
http://members.jcom.home.ne.jp/btron-taichi/ezusb/index.htm
コードのサイズが大きすぎるということは、smallではなくてlargeでコンパイルすればいいのかなと、やって見ます。
ありがとうございます。
(Webページの作成に超漢字というOSと、とあるアプリケーションの設定が悪くてなんだかおかしなファイル名で表示保存されます。気持ち悪いので修正を検討します。また、buildしたフォルダの内容も見ていただけるようにしたほうが情報になるかと思い、これも検討中です)

Posted by: te : April 10, 2006 05:10 PM

>teさん
コード拝見いたしました。interrupt番号が僕のものと異なっているような気がします。EZUSB内蔵の8051固有の割り込みとの関係でUSB関連の割り込み番号は13以降です。また、コードサイズについては問題ないかと思います。

Posted by: fenrir : April 11, 2006 01:55 AM

fenrirさま
アドバイスありがとうございます。
割り込み番号を13以降にしてみましたが、まだ同じメッセージが出ます。
http://members.jcom.home.ne.jp/btron-taichi/ezusb/index.htm
ファイルを更新しましたのでご覧いただき、ご意見を頂戴できますとうれしいです。

Posted by: te : April 12, 2006 10:30 AM

>teさん
そちらのサイトから全ソースを落として検討してみましたが、funnykbd.cでBOOLを返す関数のエラー(BYTEに変更すればOK)以外は問題なくコンパイルできました。こちらで生成されたmapファイルをみたところ、正常に配置されている(GSINIT0等のオーバーラップなし)ようです。
結論として、おそらくコンパイラのバグだと思います。僕が使用しているのは
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.5.0 #1020 (Sep 24 2005) (CYGWIN)
でした。
あと、ご希望でしたらこちらでコンパイルしたソースをお送りします。

Posted by: fenrir : April 13, 2006 01:05 AM

fenrirさま
ありがとうございます。
cygwinとSDCCの両方がかかわっているので難しいですね。
SDCCを新しくしたり、fenrirさんのヴァージョンにしてみたり、してみます。
まずは「funnykbd.cでBOOLを返す関数のエラー(BYTEに変更すればOK)」を直しておきます。
また進展があったらご報告させていただこうと思います。
本当にお手数をいただきありがとうございました。
今後ともよろしくお願いいたします。

Posted by: te : April 13, 2006 01:43 PM

fenrirさま
ご報告が遅くなりすみません。

結果:うまく動くようになりました。

経緯:cygwin, SDCCともにインストールしなおして、cygwinにawkがインストールされていなかったことに気づきました。パッケージカテゴリのところでinstallにしてもinstallされないものがあるなんてびっくりしました。そういうものを念のためにすべてインストールするように(ヴァージョンが表示されるように)してSDCCをインストールしたところ、無事に動くようになりました。

謝辞:ありがとうございました。このあわて者をお許しください。

Posted by: te : April 22, 2006 08:22 PM

>teさん
おめでとうございます、うまく動くようになったのですね!
困ったときはお互い様ということで、今後ともよろしくお願いします。

Posted by: fenrir : April 22, 2006 10:28 PM
コメントする









名前、アドレスを登録しますか?
(次回以降コメント入力が楽になります)
  • 匿名でのコメントは受け付けておりません。
  • 名前(ハンドル名可)とメールアドレスは必ず入力してください。
  • メールアドレスを表示されたくないときはURLも必ず記入してください。
  • コメント欄でHTMLタグは使用できません。
  • コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
  • コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。