2012.05.26

rx-elf-gccと.rodata.str1.1の問題による不具合

RXduino & 特電HALのデバッグをおこなっていて、問題を見つけました。

どのようなプログラムでバグが起きるかというと、
char tokuden[] = "tokuden hogehoge.....";
のような、初期値を持ったグローバル変数のデータを使うプログラムであって、
printf("%x",
のように16進表示を行う場合です。

printfやsprintfを使うと、libcの中のlib_a-svfiprintf.oというファイルの中にあるコードが呼び出されます。
mapファイルを見ると、.rodataセクションの中に、


・・・
.rodata.p05.2377
0xfff892c0 0xc lib/gcc/libc.a(lib_a-mprec.o)
.rodata.str1.1
0x00000000 0x29 lib/gcc/libc.a(lib_a-svfiprintf.o)
.rodata._svfiprintf_r
0xfff892cc 0x164 lib/gcc/libc.a(lib_a-svfiprintf.o)
.rodata.blanks.3804
0xfff89430 0x10 lib/gcc/libc.a(lib_a-svfiprintf.o)
・・・

と、 .rodata.str1.1というセクションが作られていて、0x29バイトのデータが0x00000000番地に配置されているのがわかります。このデータというのは何かというと、"0123456789ABCDEF"と"0123456789abcdef"と"(null)"が格納されています。問題は、このセクションだけなぜか0x00000000番地に配置されてしまっていることです。

したがって、次の.dataセクションが0x00000000番地に配置されるとすると、問題が生じます。
.dataセクションに配置されるデータというのは、例えば、

 
 char tokuden[] = "tokuden hogehoge.....";
のように、グローバル変数領域に書かれたものです。

まだ詳しいメカニズムはわかっていませんが、とにかく.rodata.str1.1のセクションと.dataセクションが被っていると、だんだんおかしなことになってくるのは間違いありません。

どのように解決すればよいかというと、リンカスクリプト(rx62n_rom_standalone.ld)を開いて、


KEEP (*(.eh_frame))
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
. = ALIGN(4);
__rodataend = .;
}

.data 0x00000000 : AT (__rodataend) {
・・・


のようになっている箇所を

KEEP (*(.eh_frame))
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
. = ALIGN(4);
__rodataend = .;
}

.data 0x00001000 : AT (__rodataend) {
・・・


と変更して、.dataセクションの開始番地を0x1000番地に移動してください。

.rodata.str1.1自体を然るべき場所に移動する方法はまだわかっていません。
この問題は次のrxduino-071でFIXする予定です。

| | コメント (1)

2012.05.20

RXduinoライブラリを公開します

ようやく公開できるレベルまでたどり着きました。

バージョンは0.70となり、前回から比べて大幅に更新されました。あまりにも大掛かりな改良だったので、何かあるとまずいので古いバージョンも一応消さずに残しておきます。

・RaXino♪の方はライブラリがダウンロードできます。
rxduino-lib-070.tgz ライブラリのダウンロードはこちらから
・究極のRX62Nボードの方と、RX-MEGAの方はソースコードもダウンロードできます。
rxduino-src-070.tgz ソースコードのダウンロードはこちらから

主な改良点は以下のとおりです。
●全体的な改良点
 ・RX63N対応
 ・常にスーパーバイザモードで動作させるようにした
 ・ボードのGPIOの構成やメモリ容量などをbrd_***.hとして分離した
    (tkdn_gpio.cやtkdn_gpio.hがボードに依存しないようになった)
●RXduinoライブラリにおける更新点
・PROGMEMマクロ実装
・analogWriteでPWM出力ができるようになった
・shiftIn,ShiftOutの実装
・tone関数の実装
・attachInterruptとinterrupts関数の実装
・wiring互換の低レベル関数実装
・算術演算関数実装
●特電HALにおける更新点
・シリアルポートが複数チャネル開けるようになった
・pwmの実装
・tone関数の実装
・ピン割り込み機能とグローバル割り込み許可/禁止
・数学関数のsqrtを呼び出した際にリンカでエラーが出る問題を防止

ダウンロードページはこちらにあります。
http://rx.tokudenkairo.co.jp/download.html

これで、Arduino環境に近づけるベースが出来上がりました。
これからも足りない機能をどんどん作っていきます。

ArduinoからRXduinoに差し替えて、さくっと動く、そんな環境を目指しています。

| | コメント (0)

2012.05.19

delayが効かない

RXduinoの開発をしていて、相当悩んだバグを紹介します。

音を鳴らすプログラムです。


Serial.print("C");
tone(tonepin,262,wait) ; // ド
delay(wait) ;
 
Serial.print("D");
tone(tonepin,294,wait) ; // レ
delay(wait) ;
 
Serial.print("E");
tone(tonepin,330,wait) ; // ミ
delay(wait) ;
 
Serial.print("F");
tone(tonepin,349,wait) ; // ファ
delay(wait) ;
 
Serial.print("G");
tone(tonepin,392,wait) ; // ソ
delay(wait) ;
 
Serial.print("A");
tone(tonepin,440,wait) ; // ラ
delay(wait) ;
 
Serial.print("H");
tone(tonepin,494,wait) ; // シ
delay(wait) ;

♪「ドッ レッ ミッ ファッ ソッ ラッ シッ」
と鳴って欲しいのですが、
♪「ドッ レッ ミッ ファソッ ラッ シッ」

のようになってしまって、ファとソの間のdelayが効きません。
さて、なぜだか分かりますか?
正直、このバグには2日間くらい悩まされました。

答えはこちら↓


objdumpで逆アセンブラしてみてようやく気が付きました。
「ソ」の次の行のdelayがオブジェクトファイルから無くなっているのです。

理由はコメントにありました。
tone(tonepin,392,wait) ; // ソ

Shift-JISで「ソ」という文字の2バイト目は制御記号\なので、次の行もコメントとして扱われてしまうのです。
そのため、delay(wait)もコメントアウトされてしまうのです。

tone(tonepin,392,wait) ; // ソ.
とすれば解決です。

良く見ると、GCCのWarningが出ていました。
tone_test.cpp:46:31: warning: multi-line comment [-Wcomment]
そういう意味なんですね。

Shift-JISで2バイト目に\が含まれる文字はほかにもたくさんあります。
皆様もどうかご注意ください。

| | コメント (2)

2012.05.18

RXduinoと特電HALの大幅バージョンアップ

現在、RXduinoと特電HALの大幅バージョンアップを実施中です。

どのような点が改善されたかというと、ArduinoにはあるけどRXduinoに無かったようなクラスや関数を補って、Arduinoのスケッチがそのまま動くような互換ライブラリを開発しようというわけです。

現在までに追加で開発できた機能は
・PROGMEM
・analogWrite(pin, value)で任意のピンからPWMが使えるようになった
・analogReference(type)
・tone関数を実装して音が鳴る
・shiftIn、shiftOutで簡易シリアルパラレル変換
・min,max,lowByteなどの数学関数
・ピン割り込み
・Wireクラスの実装
・シリアルポートが複数持てるようになった
などです。

■シリアルポートの機能強化
シリアルポートはRX62NにあるSCI0、SCI1、SCI2A、SCI2B、SCI6A、SCI6B、USB0が使えるようになりました。

RXマイコンを使って、USB→シリアル変換のようなことをやりたいときに、いままでの特電HALでは1ポートしかSCIが開けなかったので、できませんでした。

今回のライブラリでは、いままでの関数に加え、複数のSCIのポートを扱えるような拡張関数を用意しました。
つまり、
sci_t *sci1 = sci_init_ex(SCI_USB0,115200);
sci_t *sci2= sci_init_ex(SCI_SCI6B,115200);
とハンドルを取得しておいて、
while(1) {
if(sci_rxcount_ex(sci1)) {
sci_putc_ex(sci2,sci_getc_ex(sci1));
}
if(sci_rxcount_ex(sci2)) {
sci_putc_ex(sci1,sci_getc_ex(sci2));
}
}
のようにすることで、USB→シリアル変換が作れるわけです。これならRXマイコンを介してXBeeの設定なんかもできるようになります。

■PWMの実装
苦労したのはPWMの実装です。ArduinoとRXマイコンはやはりアーキテクチャが違うので、ArduinoがPWMに使う端子(3とか8とか11だったっけ?)からPWM出力を出すことはできません。この課題を解決するため技巧的なことをしています。
RXマイコンにあるMTUというタイマを動かして、様々なポイントでコンペアマッチを仕掛けて割り込みを発生させ、その割り込み処理ルーチンの中でPWMに指定されたポートを動かすようにしました。
MTUは複数のチャネルを同期させて動かすことができて、それぞれのMTUで4個とか7個とかのコンペアができます。つまり6~20個程度の割り込みを発生させることができます。
いわばソフトウェアPWMともいうべき感じなのですが、このおかげで任意の端子からPWM信号を発生させることができるようになりました。ArduinoのPWMは490Hzの周期なので96MHz動作のRXマイコンにとっては余裕なのです。

toneという関数も同様に、コンペアマッチタイマを使って実現し、任意のポートから音を鳴らすことができるようになりました。
MTU0とMTU1はPWM用、MTU2はtone用です。


現在、リリースに向けて最終的な調整を行っています。もう少しでリリースできるようになると思います。
お楽しみに!

| | コメント (0)

2012.05.08

KPITのGCCで特電HALとRXduinoをコンパイルしてみる

ちょっと訳があって、KPITのGCCを使ってみることになりました。
特電HALやRXduinoのライブラリを使ったアプリをビルドできるでしょうか?

まず、KPIT GCCを落としてきてインストールします。

[GNURXv12.01-ELF]->[rx-elf Toolchain]を起動します。
Kpit_1

KPITのGCCがコマンドラインで起動します。
Kpit_2

そして、RXduinoと特電HALのアーカイブを解凍したディレクトリに移動し、適当なサンプルプログラムをmakeしてみましょう。
KPITのこの環境が起動したら、rx-elf-gccへのパスは既に通っているので、makefileの
CCPATH = /usr/local/tkdn-20110720/rx-elf/bin/
をコメントアウトして、
#CCPATH = /usr/local/tkdn-20110720/rx-elf/bin/
にしておきます。

で、ビルドしてみると・・、-lstdc++ -lsupc++ -lc -lsim -lgcc -lmがないと言ってエラーが出ます。
Kpit_3

リンカのオプションを調べるために、試しにHEWとKPITでプロジェクトを作ってビルドしてみました。すると、lstdc++ -lsupc++ -lc -lsim -lmのライブラリをリンクしていないことがわかりました。KPITをインストールしたフォルダのどこかにはあるのでしょうが、とりあえずは以前自分でビルドしてきた.aファイルを使うことにします。

C:\cygwin\usr\local\tkdn-20110720\rx-elf\lib\gcc\rx-elf\4.6.1やC:\cygwin\usr\local\tkdn-20110720\rx-elf\rx-elf\libのフォルダから.aのファイルをいろいろと探してきて、RXduinoのトップディレクトリのlibにgccというフォルダを作って、libc.a libgcc.a libm.a libsim.a libstdc++.a libsupc++.aを入れておきます。
Kpit_4

そして、makefileの


LFLAGS = -L/usr/local/tkdn-20110720/rx-elf/rx-elf/lib
-L/usr/local/tkdn-20110720/rx-elf/lib/gcc/rx-elf/4.6.1
-L./ -lstdc++ -lsupc++ -lc -lsim -lgcc -lm ../../lib/librxduino.a
-nostartfiles

の行を、

LFLAGS = -L../../lib/gcc -lstdc++ -lsupc++ -lc -lsim -lgcc -lm
../../lib/librxduino.a -nostartfiles

に書き換えます。

これでビルドが通るようになりました。
Kpit_5_2

このときの全リンカオプションを見てみると、


-Map serial-hal.map
../../lib/start.o serial-hal.o ../common/intvect.o \
T ../common/rx62n_rom_standalone.ld \
L../../lib/gcc -lstdc++ -lsupc++ -lc -lsim -lgcc -lm \
../../lib/librxduino.a \
-nostartfiles \
-o serial-hal.elf \

となっていることがわかります。まとめると、

KPITのGCCで特電HAL&RXduinoのアプリをビルドする方法
① rxlib-gcc.lzhを展開して、中にあるgccフォルダをRXduinoのトップページのlibフォルダの下に格納する。(lib\gcc\libc.aなどというファイルが6個できる)
② makefileのCCPATHをコメントアウトする
③ makefileのLFLAGSに-L../../lib/gcc を追加する。その代わり、LFLAGSにある-L/usr/local/tkdn-20110720/rx・・・の指定は外しても良い。

というわけです。
これでKPITのGCCでも特電ライブラリを使えるようになりました。


| | コメント (0)

2012.05.02

EZ-USB FX3基板の再出図

EZ-USB FX3とFPGAをつなぐ基板の設計をやりなおし、今日、P板に出図しました。
日本が連休中でも、海外(台湾)は動いているだろうから、連休明けにはできているかなシメシメ・・と思って出図したら、なんと!日本の休日中は海外もお休みなのですと。

クイックコースで頼んでいるのに出来上がりが5/16日になってしまうという事態になりました。金フラッシュとかレジスト色変更とかのオプションもつけているので、時間がかかってしまうのは仕方がありません。とりあえずは今の基板でもFX3は動いているので、のんびり待つことにします。

次の基板はこんな感じです。見た目はあまり大きな違いはありません。
Np1052a

修正した箇所は次のとおりです。
・シルクの追加
・ジャンパピンの配線間違いを直す
・ESD保護ダイオードのパターンを直す
・VBATTにダイオードを入れる
・I2C ROMの配線を直す

見た目で大きく変わるのは、DIP SWの設定方法をシルクで記入したことです。シルクがあると説明書を読まずに使えるので、結構大事だと思います。
Np1052a2

基板が出来るまで2週間あるので、それまでの間にFX3の最高速度を出すデザインを考えることにします。

| | コメント (0)

2012.04.26

Android携帯からJTAGバウンダリスキャンを行う

JTAGバウンダリスキャンの結果を、Android携帯に出すための方法を研究しています。

これができると、移動中でもどこでも、AndroidにUSB-JTAGアダプタを接続して、バウンダリスキャンがFPGAの書き込みができるようになります。

どうやっているかというと、
・RXマイコンをUSB(ホスト)にして、AndroidとADBプロトコルでつなぐ
・RXマイコンでJTAGバウンダリスキャンを行って、その結果をAndroidに送る

というわけです。

今回作ったRXマイコンのプログラムでは、I/O端子からJTAG信号がでてきます。


最初は、自分自身のJTAG端子に入れてセルフJTAGスキャンしてみます。
ちゃんとJTAGのIDCODEが認識されて、その結果がAndroid携帯の画面に表示されました。
Adb_jtag_1

拡大してみましょう。

Adb_jtag_2

なにやらエラーが出ていて、「R5F562N8BDBG.bsdというファイルがない」と言っています。今回実装したシステムは、SDカードの中のファイル名を8.3形式に限定しているのでロングファイル名が認識できないためです。本質的な問題ではありません。

次に、他のボードをつないでみます。とりあえず手元にあったSpartan-3のPCI Expressボードをつないでみました。
Adb_jtag_3

問題なく認識できました。IDCODE=21C2E093のデバイスがみつかったと言っています。
Adb_jtag_4

次はSpartan-6ボードをつないでみます。
Adb_jtag_5

ちゃんとIDCODEを認識して、デバイス名を言い当てています。
Adb_jtag_6

最後に、XCF02S→XC3S200という2つのデバイスがつながっているボードで試してみました。(古いですね・・)

Adb_jtag_7

自動認識はされたのですが、XCF02SのBSDLファイルをロードしにいったまま固まってしまいました。
ファイルシステムに何かバグがありそうです。

| | コメント (0)

RXマイコンでJTAGコントローラを作ろう

RXマイコンは、USBを備えていて、内蔵メモリもたくさんあり、そのうえ高速です。
これはスタンドアローンで動くUSB-JTAGアダプタを作るのに最適なマイコンだと思います。

そこで、RXマイコンをインテリジェントなUSB-JTAGアダプタにするプログラムを作ろうと思います。
目標は、
①JTAGで接続されたデバイスを自動認識できること
②バウンダリスキャンで接続されたデバイスの端子状態を読めること
③SVFプレイヤーとして動作させることができること
④XILINXのFPGAやCPLDに書き込みができること
⑤BSDLファイルを読み込む機能を持たせて、未知のデバイスにも対応できること
⑥パソコンからでも、Android携帯からでも上記の操作ができること
です。

これができれば、電車の中でFPGAのコンフィギュレーションが出来ますゆえ。

そういうわけで、開発をスタートしました。

以前、MITOUJTAGのライブラリをSH4に移植したことがあった(スタンドアローンのJTAG検査装置として受託開発した時のもの)ので、それをさらにRXマイコンに移殖してみました。

JTAG信号はRX62Nボードの汎用I/Oポートから出てくるようにしたので、それを自分のJTAGポートに入れます。
まさにセルフJTAGスキャンって感じです。

Rxjtag_1

TCKと、TDOをオシロで見てみると、ちゃんと出ています。
こんな感じでポートを操作したところ、
PORT0.DR.BIT.B0 = 1;
PORT0.DR.BIT.B0 = 0;
TCKの速度は約1MHzでした。
Rxjtag_2

JTAGライブラリはRXでもちゃんと動いてくれて、TeraTermの画面には検出されたデバイスのIDCODEが表示されました。
Rxjtag_3

BSDLファイルやSDカードの中に入れておいたものを読み込めるようにしました。
とりあえず、JTAGライブラリ、SDカード、USBのすべてが連携して動きました。
SDRAMを使わなくてもRAMが足りそうなので、RaXino♪でも動けばいいなと思います。

現時点でのプログラムのサイズは130kBくらい。内蔵RAMも70kB以上余っているので、まだまだ入ります。FPGAの書き込みアルゴリズムくらいは入るんじゃないかと思います。

連休中に少し進めたいと思います。

| | コメント (0)

«RXマイコンからAndroidを操作するプログラムを公開