ラベル ARM7TDMI の投稿を表示しています。 すべての投稿を表示
ラベル ARM7TDMI の投稿を表示しています。 すべての投稿を表示

2010年3月9日火曜日

空気清浄機のホコリセンサーをイジッテみました。


花粉症に悩まされる季節になりました。部屋には壊れた空気清浄機があり、モータ等の部品取り用に捨てずに置いてあります。
 購入時、絶大の期待を持っていたのですが、実際には、それほどの効果はありませんでした。3年で、円筒形のファンの軸受けが破損、あっけなく、使い物にならなくなりました。
 そんな、空気清浄機から、ホコリセンサーを取り出し。花粉モニターが出来ないかと思い。色々試してみました。

1.ホコリセンサを調べる。
 空気清浄機に電源を入れ、センサの端子(3ピン)をの電圧を調べる。テスターを適当に当てる。Pin1とPin2で最大電圧。Pin2とPin3で最小電圧。
 ==> Pin1 電源12V (Vdd) 
     Pin2 グランド  (Vss)
     Pin3 電圧出力  (Vout)
2.ホコリセンサ出力電圧調整回路
  出力電圧が最大で5V程度であった(現時点での実測値)。しかし電源電圧の出力も考慮し、電圧の調整回路を組みました。素人の考えですが、抵抗値が高い可変抵抗を使うことで、センサの出力電圧降下を最小にする。抵抗の分圧を有効にするために、オペアンプで、ボルテージフォロア回路を構成
(ADCの内部抵抗が40KΩ(LPC2388 Product data sheet)なので 10KΩ程度の可変抵抗のみでも)
    可変抵抗 100KΩ
    オペアンプ Vdd(Vs) 2.7~(3.3)~5.5V (不意の高電圧に備え?)

  *色々やっているうちに、LPC2388のADCに12Vを流してしまい、「チッ」と言う音とともにLPC2388はクラッシュ。以前使用していたLPC2388(DAC不調)を現役復帰。
 
3.LPC2388 1CHオシロスコープの改修
 長時間の測定に備えるため、測定値をPCに送信する機能を追加しました。
  液晶の表示のタイミング(1024サンプリング)で、サンプルデータの平均をとり、UART0でPCにデータを送信。

4.PCアプリケーションの作成。
 1)Microsoft Visual C++ 2008 Express Edition
 2)シリアルポートのイベント(DataReceived)処理で、LPC2388から送信されたデータと受信時刻を蓄積する。
 3)グラフ表示は、パネル(System::Windows::Forms::Panel)に行う。

※グラフ表示が跳ね上がったところ、食事の支度(野菜炒め)をした結果。

----------------------------------------------
VC++テクニカルメモ 
(一部 ソースコードのカットアンドペーストで表示出来ない部分があります。)
1.実行時エラー
 1)メッセージ
    有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール '***' がアクセスされました。
 2)内容
  どうもシリアルポートのイベント処理はボタン、タイマ等のイベント処理とは異なり、イベント発生時に立ち上げられたスレッドで実行されるようです。つまり、Form上の各コントロール(オブジェクト)を管理しているスレッドと異なるため、シリアルポートのイベント処理で、Form上の各コントロールを操作することは安全でないと判断されているようです。
 3)対処
  ・Invoke等の関数でスレッド セーフな呼び出しを行うそうですが、今一つ不調
  で、応急的対処を行った。
  ・Formのコンストラクタに以下のコードを追加。
this->CheckForIllegalCrossThreadCalls = false;
   (前述のスレッドチェック機能をOFFにするようです。)

2.グラフ描画
 1)グラフィックの宣言
   System::Drawing::Graphics^ GrpChart; ポインタで宣言
 2)グラフィックの初期化
   Formにパネル( pnlChart )を置き、このパネルにグラフィックを生成する。
     this->GrpChart = this->pnlChart->CreateGraphics();
 3)Drawツールの宣言
  ・ペン
     System::Drawing::Pen^ PenChart;
  ・ブラシ
     System::Drawing::SolidBrush^ BrsChart;
  ・フォント
     System::Drawing::Font^ FntChartItem;
 4)Drawツールの初期化
  ・ペン
     this->PenChart = gcnew System::Drawing::Pen( System::Drawing::Color::Black,1.0f );
  ・ブラシ
     this->BrsChart = gcnew System::Drawing::SolidBrush( System::Drawing::Color::Black);
  ・フォント
     this->FntChartItem = gcnew System::Drawing::Font("MSゴシック",10.0);
 5)グラフィック描画
  ・ライン
     Point point1 = Point(50,50);
     Point point2 = Point(200,100);
     this->GrpChart->DrawLine( this->PenChart, point1, point2 );
  ・文字(String)
     this->GrpChart->DrawString("Draw String",this->FntChartItem,this->BrsChart,10.0,10.0);
※久々にグラフィック表示のWinアプリを作成しようとして、少々戸惑ったのでここにメモります。

※CQ出版2010年6月号が付録基板SH-2Aで、期待しています。このマイコン(型番)限定でコードサイズ制限なし、期間限定無しのHewが添付されることを密かに期待しています。
 また、RAM1Mバイト等の予告情報より、SH7262/SH7264あたりが搭載されるのでしょうか?
NECエレクトロニクス、ルネサステクノロジ統合記念の大盤振る舞いを期待します。

2009年12月3日木曜日

GNU GCC 開発環境整備(For ARM7TDMI and Cortex-M3)

以前、ARM LPC2388 (CQ出版Interface誌付録基板) 用にGNU GCCの開発環境を整備しました。
今回、複数のタイプのARMプロセッサのアプリケーション開発に対応するため、再度開発環境を整備し直しました。
主な留意点は、
・浮動小数点演算コプロセッサ搭載、非搭載とMPUを2つに区分して、開発環境を整えます。

1.浮動小数点演算コプロセッサ非搭載(-msoft-float / -mfloat-abi=soft)
  ①インストール先ディレクトリ作成
   ・cd /usr/local
   ・mkdir arm-tools-sfp
  ②各パッケージの解凍(c:\DownLoad\GNUに各サイトよりダウンロード済み)
   ・tar jxvf /cygdrive/c/DownLoad/GNU/binutils-2.20.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gmp-4.3.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/mpfr-2.4.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gcc-4.4.2.tar.bz2
   ・tar zxvf /cygdrive/c/DownLoad/GNU/newlib-1.17.0.tar.gz
 1)binutilsパッケージのインストール
  ①cd binutils-2.20
  ②./configure --target=arm-elf --prefix=/usr/local/arm-tools-sfp ・・OK
  ③make  ・・失敗  2.19でOK
  ④make install ・・2.19でOK

 ※binutils-2.20の場合 ③のmakeでエラー ・・・インストール失敗
 
gcc -DHAVE_CONFIG_H -I. -I. -I. -I../bfd -I./config -I./../include -I./.. -I./.
./bfd -DLOCALEDIR="\"/usr/local/arm-tools-sfp/share/locale\"" -W -Wall -Wstrict
-prototypes -Wmissing-prototypes -Werror -g -O2 -MT tc-arm.o -MD -MP -MF .deps/t
c-arm.Tpo -c -o tc-arm.o `test -f 'config/tc-arm.c' || echo './'`config/tc-arm.c

config/tc-arm.c: In function `make_mapping_symbol':
config/tc-arm.c:2488: warning: empty body in an if-statement
make[4]: *** [tc-arm.o] Error 1
make[4]: Leaving directory `/usr/local/binutils-2.20/gas'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/usr/local/binutils-2.20/gas'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/usr/local/binutils-2.20/gas'
make[1]: *** [all-gas] Error 2
make[1]: Leaving directory `/usr/local/binutils-2.20'
make: *** [all] Error 2

 *まあ、よくわからないので、前回と同じbinutils-2.19で試す。
こちらは成功。
 *全てのパッケージのインストール後に再度binutils-2.20のインストールを試すが、やはりmakeで失敗した。

 2)gmpパッケージのインストール
  ①cd ../gmp-4.3.1
  ②./configure --prefix=/usr/local/arm-tools-sfp ・・OK
  ③make ・・OK
  ④make check ・・OK
  ⑤make install ・・OK

 3)mpfrパッケージのインストール
  ①cd ../mpfr-2.4.1
  ②./configure --prefix=/usr/local/arm-tools-sfp --with-gmp=/usr/local/arm-tools-sfp ・・OK
  ③make・・OK
  ④make check・・OK
  ⑤make install・・OK

 4)gccパッケージのインストール
  ①cd ..
  ②mkdir BuildGcc
  ③cd BuildGcc
  ④../gcc-4.4.2/configure --target=arm-elf --with-float=soft --with-gmp=/usr/local/arm-tools-sfp --with-newlib --with-mpfr=/usr/local/arm-tools-sfp --prefix=/usr/local/arm-tools-sfp --enable-interwork --enable-multilib --enable-languages=c --disable-libssp ・・・OK
  ⑤make ・・・OK
  ⑥make install ・・・OK

  *ここで/usr/local/arm-tools-sfp/binのディレクトリにパスを通す。
  (newlibパッケージのインストール makeでの失敗対応)
  ・cd     ユーザーホームディレクトリへ移動
  ・.bash_profileを編集し、/usr/local/arm-tools-sfp/binのディレクトリにパスを通す。
   ( PATH=/usr/local/arm-tools-sfp/bin:${PATH} を追加)
  ・Cygwinを一旦終わらせ、再稼動させる。

 5)newlibパッケージのインストール
  ①cd /usr/local/newlib*
  ②./configure --target=arm-elf --with-float=soft --prefix=/usr/local/arm-tools-sfp ・・・OK
  ③make・・・失敗
  ④make install
 
  ※③のmakeでエラー ・・・インストール失敗
  
touch stmp-targ-include
Making all in libc
make[4]: Entering directory `/usr/local/newlib-1.17.0/arm-elf/newlib/libc'
Making all in argz
make[5]: Entering directory `/usr/local/newlib-1.17.0/arm-elf/newlib/libc/argz'
arm-elf-cc -B/usr/local/newlib-1.17.0/arm-elf/newlib/ -isystem /usr/local/newli
-1.17.0/arm-elf/newlib/targ-include -isystem /usr/local/newlib-1.17.0/newlib/li
c/include -B/usr/local/newlib-1.17.0/arm-elf/libgloss/arm -L/usr/local/newlib-1
17.0/arm-elf/libgloss/libnosys -L/usr/local/newlib-1.17.0/libgloss/arm -DPACKAG
_NAME=\"newlib\" -DPACKAGE_TARNAME=\"newlib\" -DPACKAGE_VERSION=\"1.17.0\" -DPA
KAGE_STRING=\"newlib\ 1.17.0\" -DPACKAGE_BUGREPORT=\"\" -I. -I../../../.././ne
lib/libc/argz -O2 -DARM_RDI_MONITOR -fno-builtin -g -O2 -c -o lib_a-dumm
.o `test -f 'dummy.c' || echo '../../../.././newlib/libc/argz/'`dummy.c
/bin/sh: arm-elf-cc: command not found
make[5]: *** [lib_a-dummy.o] Error 127
make[5]: Leaving directory `/usr/local/newlib-1.17.0/arm-elf/newlib/libc/argz'
make[4]: *** [all-recursive] Error 1
make[4]: Leaving directory `/usr/local/newlib-1.17.0/arm-elf/newlib/libc'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/usr/local/newlib-1.17.0/arm-elf/newlib'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/usr/local/newlib-1.17.0/arm-elf/newlib'
make[1]: *** [all-target-newlib] Error 2
make[1]: Leaving directory `/usr/local/newlib-1.17.0'
make: *** [all] Error 2

  *確かに arm-elf-cc は存在しなかった。
  *再度gccのインストール(上書き) make all も実行 ・・・同じエラー
  */usr/local/arm-tools-sfp/binのディレクトリにパスを通すと成功。


 6)gccパッケージの補足インストール
  ①cd ../BuildGcc
  ②make
  ③make install

 7)その他 
  ①cd     ユーザーホームディレクトリへ移動
  ②.bash_profileを編集し、 PATH=/usr/local/arm-tools-sfp/bin:${PATH} を削除
  ③Cygwinを一旦終わらせ、再稼動させる。
  

2.浮動小数点演算コプロセッサ搭載(-mhard-float / -mfloat-abi=hard)
  ①インストール先ディレクトリ作成
   ・cd /usr/local
   ・mkdir arm-tools-hfp
  ②各パッケージの解凍
   ・tar jxvf /cygdrive/c/DownLoad/GNU/binutils-2.20.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gmp-4.3.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/mpfr-2.4.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gcc-4.4.2.tar.bz2
   ・tar zxvf /cygdrive/c/DownLoad/GNU/newlib-1.17.0.tar.gz
 1)binutilsパッケージのインストール
  ①cd binutils-2.19
  ②./configure --target=arm-elf --prefix=/usr/local/arm-tools-hfp ・・OK
  ③make  ・・OK
  ④make install ・・OK

 2)gmpパッケージのインストール
  ①cd ../gmp-4.3.1
  ②./configure --prefix=/usr/local/arm-tools-hfp ・・OK
  ③make ・・OK
  ④make check ・・OK
  ⑤make install ・・OK

 3)mpfrパッケージのインストール
  ①cd ../mpfr-2.4.1
  ②./configure --prefix=/usr/local/arm-tools-hfp --with-gmp=/usr/local/arm-tools-hfp ・・OK
  ③make・・OK
  ④make check・・OK
  ⑤make install・・OK

 4)gccパッケージのインストール
  ①cd ..
  ②mkdir BuildGcc
  ③cd BuildGcc
  ④../gcc-4.4.2/configure --target=arm-elf --with-float=hard --with-gmp=/usr/local/arm-tools-hfp --with-newlib --with-mpfr=/usr/local/arm-tools-hfp --prefix=/usr/local/arm-tools-hfp --enable-interwork --enable-multilib --enable-languages=c --disable-libssp ・・・OK
  ⑤make ・・・OK
  ⑥make install ・・・OK

  *ここで/usr/local/arm-tools-hfp/binのディレクトリにパスを通す。
  ・cd     ユーザーホームディレクトリへ移動
  ・.bash_profileを編集し、/usr/local/arm-tools-hfp/binのディレクトリにパスを通す。
   ( PATH=/usr/local/arm-tools-hfp/bin:${PATH} を追加)
  ・Cygwinを一旦終わらせ、再稼動させる。

 5)newlibパッケージのインストール
  ①cd /usr/local/newlib*
  ②./configure --target=arm-elf --with-float=hard --prefix=/usr/local/arm-tools-hfp ・・・OK
  ③make・・・OK
  ④make install・・・OK
 

 6)gccパッケージの補足インストール
  ①cd ../BuildGcc
  ②make
  ③make install

 7)その他 
  ①cd     ユーザーホームディレクトリへ移動
  ②.bash_profileを編集し、 PATH=/usr/local/arm-tools-hfp/bin:${PATH} を削除


3.2つの開発環境について 比較。
 1)コンパイラー等開発ツール
 ◎/usr/local/arm-tools-sfp/bin、/usr/local/arm-tools-hfp/binの主要ツール
 ・arm-elf-gcc.exe( 519708Byte)
 ・arm-elf-as.exe (2757595Byte)
 ・arm-elf-ar.exe (1804448Byte)
 ・arm-elf-objcopy.exe(2303260Byte)
についてバイナリサイズは2つの環境とも同じでした。浮動小数点演算コプロセッサー使用、非使用で各ツール自体に異なることはないと推測。
 2)ライブラリ
 ◎/usr/local/arm-tools-sfp/arm-elf/lib、/usr/local/arm-tools-hfp/arm-elf/libの主要ライブラリ
 ・libc.a(soft:3174978Byte hard:3169002Byte)
 ・libg.a(soft:3174978Byte hard:3169002Byte)
 ・libm.a(soft:953244Byte hard:876948Byte)
 ◎そのほかのライブラリ
 ・libgcc.a (soft:363326Byte hard:357882Byte)
 ・libgcov.a (soft:30906Byte hard:30906Byte) ・・・同じ
 についてライブラリサイズは若干、浮動小数点演算コプロセッサ使用のほうが小さい。

2009年11月29日日曜日

LM3S8962 Evaluation Kit! を試す。



STMicroelectronicsの評価キットを色々操作しているうちに、テキサス・インスツルメンツの評価キット LM3S8962 Evaluation Kit が届きました。
この評価キットは Cortex-M3コアの LM3S8962(メインボード)と、LM3S2110(サブボード)の2つのマイコンでCAN(Controller Area Network)通信を試せる構成になっています。
また、Ethernet、microSDカードスロット、スピーカー、128×64ドットOLED(グラフィック表示)等が搭載されていて、多彩なアプリケーションの開発が手軽に出来るのではと期待できます。


とりあえず一通り試します。

1.準備
 1)付属のDVDをPCにセットする。
   ○LUMINARY MICROのHTML画面
   ○Document/Read Me First - Viewで「LM3S8962 EVALUATONKIT README FIRST」を開く。

2.「README FIRST」記載に従う。
 1)付属フラットケーブル(10線)で LM3S8962 Evaluation Board(本体ボード)とLM3S2110 CAN Device Board(サブボード)のお互いのCANポートをつなぐ。
 2)付属USBケーブルでPCと LM3S8962 Evaluation Board P4をつなぐ
   ○微妙なサウンドと、液晶にLUMINARY、IARのロゴが表示された後ゲームが始まった。
   ○ゲームを一通り試す、敢え無くGame Over 注目すべきは、IPアドレスが表示される事、さらにスクリーンセーバも表示(詳細、後述)
 3)デバイスドライバのインストール
   ○PC側で新規デバイスの検出。
  ①デバイスドライブソフトウエアインストールを始める。
  ②ドライバの検索先をDVDドライブに指定する。
    「Stellaris Evaluation Boad A」のインストール完了を確認。

 ※ゲーム(サンプルアプリケーション)
   ①起動時、サウンドと伴にLUMINARY、IARのロゴが表示、Ethernet接続で、DNSからIPアドレスの割当を受ける、そのアドレスが表示される。
   ②一見パックマン風のゲーム、[SELECT]ボタンでゲーム開始 [SW3-6]ボタンで上下左右移動。[SELECT]ボタンでミサイル発射、モンスターを撃破
   ③ゲーム開始前、ゲームOver後、に一定期間経つと、スクリーンセーバが表示される。スクリーンセーバも消えた後、本体ボードLED1がゆるい点滅、CANサブボードLED100が点滅する。
   ④起動時、ゲームOver時のサウンドの音量はCANサブボードの[SW100,101]で調整できる。
   ⑤起動時、シリアルポートからWelcomeが出力される。ゲーム開始でスコア0、ゲームOverでスコアがシリアルポートに出力される。
     (PC並びにターミナルソフト設定 bau:11520 data:8bit parity:non stopbit:1 flow:non)
   
 ※あまりこのサンプルアプリケーションにはまると、本格的なアプリケーション開発前に基板が壊れてしまいそうなので注意。

2009年7月9日木曜日

LPC2388 GNU GCC 浮動小数点の扱い

CQ出版、Interface誌 付録基板 LPC2388 を あいも変わらず、暇をみてはいじっています。
 以前に組み込んだプログラムの一つに不具合があり、これを調べていて、その原因が浮動小数点(float、double)の扱いにあることが判りました。

 今のところ、まだ解決の目途は立っていません。

1.コンパイルオプション -mhard-float について。
 LPC2388を触り始めたころ、浮動小数点の扱いで、-mhard-float  をコンパイルオプションに加えるようになった。
 どうもこのコンパイルオプションが問題と思われるようになった。
 1)コンパイルオプション -mhard-float なしで、問題のプログラムを Make する。
   標準Cライブラリ(libc.a、libm.a、、)の関数を使用しているサブルーチン、関数、では、依然、不具合は解消されず。しかし、標準Cライブラリ(libc.a、libm.a、、)の関数を使用しないサブルーチンでは不具合は解消していた。
 2)コンパイルオプション -msoft-float を加えて、問題のプログラムを Make する。
   Make時、リンクでエラーが起こる。(標準Cライブラリが不適合)

2.msoft-float 環境のgcc開発環境について、
  標準Cライブラリを msoft-float で構成すれば、問題解決と思い。gcc開発環境の再インストールを行った。
 (gccのインストールで、configure の オプションに --with-float=soft を加えた。)
 1.2)のMakeエラーは解消、でも不具合は残った。


3.ARM7TDMI-Sの浮動小数点対応について。
 Interface 2009/5 P58 の 「機能を拡張するコプロセッサ」の節 表2 コプロセッサ番号 CP11、CP12 で 倍精度/単精度浮動小数点 の記載があり、LPC2388が浮動小数点処理機能をハードで実現すると思われ、コンパイルオプション -mhard-float  は妥当と思われた。
 しかし ARM7TDMI-S Revision r4p3 Technical Reference Manual の 4.1.1 「Coprocessor abailability」では、CP14 Debug controller と CP15 System contorol だけの記載  やはり コンパイルオプション -msoft-float が正解なのか。。。


※ もともと、gccの開発環境は、同じCQ出版 DW誌の STM32F103(Cortex-M3)の開発環境です。
 LPC2388で使う場合、CPUのアーキテクチャの差異を考慮して、gccの再インストールしなければならないと思います。

 今回、-msoft-float 対応 で gccのインストールのみ、configure の オプションに --with-float=soft を加えたが、newlibについては行わなかった。(makeが通ったのでかまわなかったと判断)
 次は、newlibの再インストールでも行おうと思います。(指定可能かどうか不明ながら)。。

 現時点では コンパイルオプション -mhard-float  の適否は不明。(-msoft-floatが正解と言い切る自信無し。)


ひまを見てボチボチと、、、、

 >>追加検証 
  gccとnewlibのインストール configureオプションに --with-float=soft を追加。 + コンパイルオプション -msoft-float の make。
   浮動小数点でこけていた箇所が通るようになった。 一応動作確認。(7/10)

2009年6月25日木曜日

LPC2388 GCCによる開発 メモ 中間まとめ

未だ、CQ出版 Interface誌 LPC2388付録基板のベースシステムの構築が出来ていません。


1.IRQによる割り込み処理のハンドリング。
 1)実装するIRQ

  ベースシステムのIRQ例外処理のはとりあえず。
  ・システムの稼動チェック(ハートビート)用に TIMER0の割り込み。 
  ・LCD(SG12864ASLB-GB-R01)のリフレッシュ用に TIMER1の割り込み。
  ・Key入力用(タクトスイッチのON/OFFスキャン用)に TIMER3の割り込み。
  ・システム汎用にTIMER2の割り込み。
  ・シリアル通信受信用のUART1の割り込み。
  を、使用します。

 2)IRQのハンドリング(手法1)  >> 今のところ不調
    I誌のgcc用のサンプルを利用
  (1)IRQハンドリング関数は CPU_IRQInterrupt(void)を使用 
     gcc_sample.cで定義/宣言され、startup.sでIRQ割り込みとして呼び出される。   
  (2)IRQハンドリング関数で VICIRQStatus による分岐で各IRQ割り込み処理を実行する。

   /* CPU割り込み処理 */
    void CPU_IRQInterrupt(void)
    {
     switch(VICIRQStatus)
     {
       case INT_IRQ_TIMER0:
        // for Timer0 IQR Interrupt
        TIMER0_IRQInterrupt(); // システム監視 ハートビート
        /* タイマ割り込みクリア */
        TIMER_InterruptReset(&TIMER_0);
        break;
       case INT_IRQ_TIMER1:
        // for Timer1 IQR Interrupt
         Lcd_IRQ_Handler();   // LCDリフレッシュ
        /* タイマ割り込みクリア */
        TIMER_InterruptReset(&TIMER_1);
        break;
       case INT_IRQ_TIMER2:
       ----------------------------

 3)IRQのハンドリング(手法2)
  (1)ハンドリング関数は CPU_IRQInterrupt(void)を使用 (手法1と同じ)
  (2)それぞれのIRQ例外処理関数のアドレスを VICVectAdd4,VICVectAdd5,,,にセットする。
  (3)IRQハンドリング関数で VICVectAddr にセットされた関数のアドレスを使用して、各タイマー、UARTのIRQ例外処理を実行する。
   ※IRQ例外処理側 (関数ポインタの扱い)
      void (*pfunc)(); // 関数ポインタ宣言
      pfunc = VICVectAddr; // 関数のアドレスを代入
      (*pfunc)(); // IRQ例外処理関数のCall
      VICVectAddr = 0x00000000; //IRQアドレスクリア(※訂正)
   ※IRQ設定側
      extern void Sys_IRQInterrupt( void ); //IRQ例外処理関数(TIMER0)
       /* ↑ 同一ソースファイル内で定義されていれば不要 */
      --------------
      VICVectAddr4 = (u32)Sys_IRQInterrupt; // IRQ例外処理関数のアドレスをセット


2.ARMモード/Thumbモードについての注意事項
 1)ARMモードでの標準ライブラリ(libc.a, libm.a等)の指定
    LIBRARY_DIRS = -L /usr/local/arm-tools/arm-elf/lib -L /usr/local/arm-tools/lib/gcc/arm-elf/4.4.0
 2)Thumbモードでの標準ライブラリ(libc.a, libm.a等)の指定
    LIBRARY_DIRS = -L /usr/local/arm-tools/arm-elf/lib/thumb -L /usr/local/arm-tools/lib/gcc/arm-elf/4.4.0/thumb
   ※一部でもARMモードのモジュールがあると、標準ライブラリを組み込む場合、リンク時にinterworkのワーニングが出、動作が怪しくなる。
   ※gccパッケージのインストールでconfigureオプション--enable-interworkを指定しているのにワーニングが出るのが不可解。


3.リンクスクリプトファイル
  FreeRTOSのサイトから次のソースをダウンロード
  FreeRTOSV5.2.0/デモ/[ARM7_LPC2368_Eclipse]/RTOSDemoの lpc2368.ld を修正し利用。
 1)ramサイズを64Kに変更   
 2)usbramを16Kに変更


※※※※訂正※※※※
  手法2の動作確認 不調 >> 最初の1歩に戻り再検証
  ①再度 CQ出版 I誌から再び、gcc_sample を 入手
     ● 5/13 gcc用サンプル・プログラム アップデート(gcc_sample.zip)
  ②gcc_sample.zipを解凍、gcc_sampleをビルド
  ③基板上のLEDの点滅を確認 [手法1の IRQで呼び出される関数でLEDを点滅]
  ④gcc_sample.cを手法2で出来るように修正

**修正箇所**

a. define

  /* 割り込みコントローラ(VIC) */
  #define VIC_BASE_ADDR 0xFFFFF000
  #define VICVectAddr4 (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x110))
  #define VICVectAddr (*(volatile unsigned long *)(VIC_BASE_ADDR + 0xF00))

b.IRQハンドラー関数

  /* TIMER0 割り込み処理 */
  void TM0_IRQInterrupt(void)
  {
    if( toggle == 0 ) {
      toggle = 1;
      *FGPIO_FIO1PIN =0x00000000; /* P1[18,19] '0' -> LED ON */
    } else {
      toggle = 0;
      *FGPIO_FIO1PIN =0x000C0000; /* P1[18,19] '1' -> LED OFF */
    }
    *TIMER_T0IR =1;  /* タイマ割り込みクリア */
  }

  /* CPU割り込み処理 */
  void CPU_IRQInterrupt(void)
  {
    void (*pFunc)();
    pFunc = (void*)VICVectAddr;
    (*pFunc)();

    VICVectAddr = 0x00000000; // VICVectAddr のクリア ※1 追加
  }

c.Main関数
     検証用にポート1の19ピンに繋がるLEDの点滅を加える。

/* タイマ割り込みLED点灯制御プログラム */
  int main(void)
  {
    *SYS_SCS = *SYS_SCS | 1; /* FGPIO Select */

    /* LED点灯制御設定 */
    *FGPIO_FIO1DIR =0x000C0000; /* P1[18,19] OutPut */
    *FGPIO_FIO1MASK=0x00000000; /* P1[18] Non Mask */
    *FGPIO_FIO1PIN =0x000C0000; /* P1[18,19] '1' -> LED OFF */
    ----------
    *TIMER_T0MR0 = 1000000;      /* 供給クロック周波数=1秒 */
    *TIMER_T0MCR = 0x00000003;    /* Match時にTCクリア&割り込み */

    VICVectAddr4 =(unsigned long )TM0_IRQInterrupt;
    *TIMER_T0TCR = 1;         /* タイマスタート*/
toggle = 0;
    ----------
**動作検証**
 結局不調       
 TIMER0 割り込み処理 TM0_IRQInterrupt(void) の最初の割り込みの実行は確認
 でもそれっきり。

**さらにもがく**
    VICVectAddr = 0x00000000;(※1)をIRQハンドリング関数(IRQInterrupt)に追加

※※動作検証※※
  ようやく成功。





2009年5月25日月曜日

FreeRTOSV5.2.0(LPC23xx)を解析する。

CQ出版 Interface誌 2009.5付録基板 LPC2388を何とか使えるようにしたいと思い、悪あがきを続ける。

1.GNU GCCによる開発環境の整備
 ・バージョン4.3.0 4.4.0 いづれも LED点滅など簡単なプログラムは可能
 ・複数割り込み等、少々込み入ったプログラムは、一定時間稼動後ハングする。

2.FreeRTOSによる開発プロトタイプの構築
 ・http://www.freertos.orgにアクセスし、ダウンロードサイト(http://sourceforge.net)からFreeRTOSV5.2.0.zipをダウンロードする。
 ・zipファイルを展開し、ARM7_LPC2368_Eclipse,Common,SourceのフォルダをCopyし、プロトタイプの構築を試みる。
 ・ARM7_LPC2368_Eclipse/RTOSDemoのフォルダでバージョン 4.4.0 でmakeを実行
 ・configPINSEL2_VALUEの未定義エラーが起こる、FreeRTOSConfig.h の #define confinPINSEL2_VALUEのコメントをはずす。
 ・再度ビルド、 no memory region specified for loadable section `.eh_frame' が起こる。
 ・適当に、lpc2368.ld(リンカスクリプト)を修正
    ※追記内容
     .eh_frame_hdr : ALIGN (4)
     {
     KEEP (*(.eh_frame_hdr))
     } >ethram          <<(ramをethramに変更)
     .eh_frame : ALIGN (4)
     {
     KEEP (*(.eh_frame))
     } >ethram          <<(ramをethramに変更)

     (ramでは「RTOSDemo.elf section .eh_frame will not fit in region ram」ビルドエ- で ethramに変更 これも適当)

 ・再度ビルド実行 成功 ただし、「does not support interworking」のワーニング表示
 ・このディレクトリをCopyしRTOS開発環境のプロトタイプとする。
    ARM7_LPC2368_Eclipse >> ARM7_LPC2388_Prototype
RTOSDemo >> RTOS_Prototype
    lpc2368.ld >> lpc2388.ld ファイル名変更
    Makefileの内容も併せて変更 lpc2368 を lpc2388 に変更
    ビルドを試す。 >OK

3.FreeRTOSによる開発プロトタイプの構築 その2
 プロトタイプへの修正内容
  ・LCD関連の無効化(将来 SG12864に対応)
  ・TCP/IPプロセスの無効化
  ・LEDを 基板LED1 Port1 Pin18に変更
 1)FreeRTOSの分析
  ・main.cの分析

4.自作関数の組み込み
 1)LEDコントロールの組み込み
 2)LCD(グラフィック)コントロールの組み込み。
  不具合
  ・memset,strcpy,strncpy,strlen,strcatでハングする。
  ・memset等の関数を自作する。LPC_memset等 とする。
    >>一応 動作OK
 *memset,strcpy等の標準関数は今後必須としたいので、>>
  ・コンパイルオプション検討(自作関数用 LPC23Lib.a )
    COMPILE_OPTS = -O1 -mcpu=arm7tdmi-s -fomit-frame-pointer -mthumb-interwork
       を
    COMPILE_OPTS = -mthumb -O0 -v -mhard-float に変更。
    (-mcpu=arm7tdmi-s で エラー Error: selected processor does not support requested special purpose register -- `mrs r3,CPSR'... )
    でようやくOK

5.デバッグ用にLOGのLCD出力
  FreeRTOSの関数 xTaskCreate() 正常に実行される。
   〃       vTaskStartScheduler() ほどほどに動作。
    ・タイマー0の割り込みで実行される関数を portISR.c (ARMモードでコンパイル)から自作関数(thumbモードでコンパイル)に置き換えると、VICVectAddr4に設定されるアドレスが1バイトずれる。> 仕方なく、portISR.c にコードを書き込む。(原因不明)
    ・このタイマー割り込み関数は、最初の割り込み時に実行される。しかし、それ以降の割り込みは確認出来ず。

6.泥沼。
  1)thumbモードをARMモードにしたり、thumbモードに戻したり。(Makefileをいろいろイジル)
  2)etc.

7.現時点でのLPC2388の壁
 1)割り込み関連の扱い VICVectAddrX, VICVectCntrlX,,,etc.
 2)命令系がARMモードとThumbモードの2ある事。
    参考にするサンプルコード(プロジェクト)が両方使っているケースが多い。
 3)startup.s , boot.s 等のスタートアップ用のアセンブラコードが難解。
 4)リンクスクリプトファイルも難解。
 5)とにかくタイマー0の割り込みが安定的に動かない。。。。。
 6)GNU GCC の地雷 >> 単に変数を追加するだけで動作が異なる。









    





 

2009年5月14日木曜日

GNUによる開発環境の整備(for ARM7TDMI)

組み込み用の開発環境として、GNUによる開発環境の整備を試行します。
問題はWindowsVISTA 64bit、失敗覚悟で行います。

1.linux環境の構築(Cygwinのインストール)
 1)"http://www.cygwin.com"にアクセス
 2)「Install or update now!」のアイコンをクリック ダウンロードで「実行」
    [Cygwin Setup]インストーラが立ち上がる。
 3)「Choose A Dounload Source」で Install from Internet を選択
 4)「Select Root Install Directory」は デフォルト"C:\cygwin"のまま設定
 5)「Select Local Packege Directory」は 適当にディレクトリ"C:\DownLoad\Cygwin"を設定
 6)「Select Your Internet Connection」で Direct Connection を選択
 7)「Select Download Site」で 適当にダウンロードサイトを選択
 8)「Select Packeges」先頭の"All"の横の"Default"はそのまま。
   ①パッケージの追加
    再度[Cygwin Setup]インストーラが立ち上げ以下のパッケージを追加する。
     ・"Archive" zip等のファイルの圧縮/解凍
     ・"Devel"  gcc、make等の開発ツール
     ・"Editors" vi等のエディター
     ・"Net"/"inetutils" telnet等のネットワークツール

--アンインストールの場合  
( ⑧「Select Packeges」で 先頭の"All"の横の"Default"をクリックして"Uninstall"に変更する。)
     

2.GNU開発環境のインストール
 1)GNU関連パッケージの入手
  ①"http:://www.gnu.org"にアクセス
  ②[DownLoad]をクリック
  ③「How to get GNU software」の[・Download it from the web or via FTP:we....]をクリック
  ④「GNU mirror list」の[Asia/Japan ftp://ftp.ring.gr.jp/pub/GNU]をクリック
  ⑤gccパッケージの入手
   ・[gcc]をクリック
   ・[gcc-4.4.0]をクリック(最新版にトライ)をクリック
      ※IE8.0では不調 [Apr 22 09:39 gcc-4.4.0]の表示
   ・[gcc-4.4.0.tar.bz2]をクリック
   ・c:\Download\GNUに保存
  ⑥binutilsパッケージの入手( ④のFTPサイトより。)
   ・[binutils]をクリック
   ・[binutils-2.19.1.tar.bz2]をクリック
   ・c:\Download\GNUに保存
  ⑦gmpパッケージの入手( ④のFTPサイトより。)
   ・[gmp]をクリック
   ・[gmp-4.3.1.tar.bz2]をクリック
   ・c:\Download\GNUに保存
  ⑧mpfrパッケージの入手
   ・"http://www.mpfr.org/”にアクセス
   ・[Latest release: download]をクリック
   ・[mpfr-2.4.1.tar.bz2]をクリック
   ・c:\Download\GNUに保存
  ⑨Insightパッケージの入手
   ・"ftp://sourceware.org/pub/insight/releases/”にアクセス
   ・[insight-6.8.tar.bz2]をクリック
   ・c:\Download\GNUに保存
  ⑩newlibパッケージの入手
   ・"ftp://sourceware.org/pub/newlib”にアクセス
   ・[ newlib-1.17.0.tar.gz]をクリック
   ・c:\Download\GNUに保存

 2)インストール (Cygwinでの作業)
  ①インストール先ディレクトリ作成
   ・cd /usr/local
   ・mkdir arm-tools
  ②各パッケージの解凍
   ・tar jxvf /cygdrive/c/DownLoad/GNU/binutils-2.19.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gmp-4.3.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/mpfr-2.4.1.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/gcc-4.4.0.tar.bz2
   ・tar jxvf /cygdrive/c/DownLoad/GNU/insight-6.8.tar.bz2
   ・tar zxvf /cygdrive/c/DownLoad/GNU/newlib-1.17.0.tar.gz
(arm-tools以下をバックアップ)
  ③binutilsパッケージのインストール
   ・cd binutils*
   ・./configure --target=arm-elf --prefix=/usr/local/arm-tools
   ・make
   ・make install
  ④gmpパッケージのインストール
   ・cd ../gmp*
   ・./configure --prefix=/usr/local/arm-tools
   ・make
   ・make check
   ・make install

  ⑤mpfrパッケージのインストール
   ・cd ../mpfr*
   ・./configure --prefix=/usr/local/arm-tools --with-gmp=/usr/local/arm-tools
   ・make
   ・make check
   ・make install

  ⑥gccパッケージのインストール
   ・cd ../
   ・mkdir BuildGcc
   ・cd BuildGcc
   ・../gcc-4.4.0/configure --target=arm-elf --with-gmp=/usr/local/arm-tools --with-mpfr=/usr/local/arm-tools --prefix=/usr/local/arm-tools --enable-interwork --enable-multilib --enable-languages=c --disable-libssp
    (--with-newlib を追加 */* 下記参照)
    (--with-float=soft を追加 7/10 )
   ・make
   ・make install

   (/usr/local/arm-tools/binにPATHを通す。 <== newlibインストール失敗対応 12/4 )

  ⑦newlibパッケージのインストール
   ・cd ../newlib*
   ・./configure --target=arm-elf --prefix=/usr/local/arm-tools
    (--with-float=soft を追加 7/10 )
   ・make
   -- インストールの中断(エラーによる)

     エラー発生
       内容
         lib_a-dummy.oのコンパイル時
/bin/sh: arm-elf-cc: command not found

     エラー解析
      a.現在GNU開発環境があるPCでnewlibのconfigureを実行、出力Makefileを今回のMakefileと比較(diff)
       > CC_FOR_TARGET=$(STAGE_CC_WRAPPER) arm-elf-gcc $(FLAGS_FOR_TARGET) 
       < CC_FOR_TARGET=$(STAGE_CC_WRAPPER) arm-elf-cc $(FLAGS_FOR_TARGET) <=今回
       なぜ arm-elf-cc になったのか?
      b.config.logを確認
       591行目 CC_FOR_TARGET があった。
      c.configureの確認
       8539行以降にCC_FOR_TARGETの設定が記述

対処
      a.深く考えなく、GCCのバージョン を 4.3.3 に入れ替える。
             ==>変わらなかった。
      b.GCCのインストール 各オプションを変える。
             ==>検討中 ==> 解決
次のオプションでgccの configure を実行 (--with-newlib を追加)
     ../gcc-4.4.0/configure --target=arm-elf --with-gmp=/usr/local/arm-tools
         --with-mpfr=/usr/local/armtools --prefix=/usr/local/arm-tools
         --enable-interwork --enable-multilib --enable-languages=c
         --disable-libssp --with-newlib
       で gccとnewlibのインストール作業をやり直した。

※newlibでの再ビルドは make clean では不十分、newlib-1.17.0.tar.gz の解凍からやり直したほうが良さそう。

   --インストールの続き
   ・make install

  ⑥gccパッケージの補足インストール
   ・cd ../BuildGcc*
   ・make all
   ・make install

3.GNU検証
 1)newlibインストール失敗(未解決)での検証
   ① TIMERでLEDを点滅プログラム
             ==> 成功
 ② LCD表示プログラム
     ・リンクで、-lc オプションがエラー  llibc がリンクできず。

その他
 1)NXP LPC2388用 ダウンローダー 「Flash Magic」のインストール
   ①"http://www.flashmagictool.com/"にアクセス
   ②Download FlashMagic.exe (ページ右側)をクリック
   ③インストールプログラムを実行
 2)CP2102_USB ドライバのインストール
   ①LPC2388基盤をUSB接続
   ②ドライバインストールを促されるので、インターネットでドライバを検索する方法でインストールを行う。

2009年5月4日月曜日

フェーズ3 Key入力テスト NXP LPC2388

4つのスイッチを押すと、それぞれに応じて、LEDが点灯する。
※このプログラムも数秒でハングする。
1.キー入力使用 main()関数 ソース
/****************************************************************************
タイマ割り込みサンプルプログラム(オンボードLED点灯制御)
****************************************************************************/
#define _EXTERN_
/* Includes ------------------------------------------------------------------*/
#include "LPC_BaseLib.h"

/* LED点滅用変数*/
int toggle0;
/* CPU割り込み処理*/
void CPU_IRQInterrupt(void)
{
  switch(VICIRQStatus)
  {
  // for Timer0 IQR Interrupt  ハートビート用割り込み
    case INT_IRQ_TIMER0:
      if(toggle0 == 0)
      {
        toggle0 = 1;
        Led_0_ON();
      }
      else
      {
         toggle0 = 0;
         Led_0_OFF();
      }
      /* タイマ割り込みクリア*/
      TIMER_InterruptReset(&TIMER_0);
      break;
    case INT_IRQ_TIMER1:
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
    case INT_IRQ_TIMER3:
      // for Timer3 IQR Interrupt
      Key_Sarch();
      /* タイマ割り込みクリア*/
      TIMER_InterruptReset(&TIMER_3);
      break;
    default:
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

/* タイマ割り込みLED点灯制御プログラム*/
int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIMER_InitTypeDef TIMER_InitStructure;

    SYS_Initialize();

    /* LED点灯制御設定*/
    Led_Init();

    Key_Init();

    // タイマ設定 Timer0 Use for Hart Beet
    TIMER_StructInit(&TIMER_InitStructure);
    TIMER_InitStructure.TIMER_ID = TIMER_ID_0;
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
2.LPC用Key入力関数側
#include
#include "LPC_BaseLib.h"

void Key_Init()
{
  key_gpioinit();
  Key_Proc_Mode = KEY_MODE_MAIN;
}

// 前回GPIOがLow今回Highの場合 キー入力(Push)とみなす。
void Key_Sarch()
{
  if(Ref_Key_0 == VAL_KEY_ON && KEY_VAL_0 == VAL_KEY_OFF)
  {
    Key_Intrrupt(ID_KEY_0);
  }
  Ref_Key_0 = KEY_VAL_0;

  if(Ref_Key_1 == VAL_KEY_ON && KEY_VAL_1 == VAL_KEY_OFF)
  {
Key_Intrrupt(ID_KEY_1);
  }
  Ref_Key_1 = KEY_VAL_1;

    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

//キー対応GPIO設定
void key_gpioinit(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  // GPIO 0
  GPIO_InitStructure.GPIO_ID = GPIO_Port_0;
  GPIO_InitStructure.GPIO_Pins = GPIO_Pin_0 GPIO_Pin_1 GPIO_Pin_10 GPIO_Pin_11   GPIO_Pin_17;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FAST;
  GPIO_InitStructure.GPIO_ModeIO = GPIO_Mode_INPUT;
  GPIO_InitStructure.GPIO_ModePin = GPIO_ModePin_PULLUP;

  GPIO_Init(&GPIO_0,&GPIO_InitStructure);
}

3.キー入力動作定義
#include

#include "LPC_BaseLib.h"

unsigned int icnt;

voidKey_Intrruptint key_id)
{
  switch(key_id)
  {
    case ID_KEY_0:
      Led_1_ON();
      Led_2_OFF();
      Led_3_OFF();
      break;
    case ID_KEY_1:
      Led_1_OFF();
      Led_2_ON();

    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

2009年5月2日土曜日

フェーズ1 GPIO テスト NXP LPC2388

NXP LPC2388の GPIO を以下のとおり検証した。


概要 4つのLEDをTIMER0で点滅させる。


タイマ割り込みハンドラは startup.s で設定されたハンドラ CPU_IRQInterrupt を main() ソースファイルに、準備する。


1.GPIO使用 main()関数側
  1)初期設定
    GPIO_InitTypeDef GPIO_InitStructure;
     // GPIO 0
    GPIO_InitStructure.GPIO_ID = GPIO_Port_0;
    GPIO_InitStructure.GPIO_Pins = GPIO_Pin_27;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FAST;
    GPIO_InitStructure.GPIO_ModeIO = GPIO_Mode_OUTPUT;
    GPIO_InitStructure.GPIO_ModePin = GPIO_ModePin_PULLDOWN;
    GPIO_Init(&GPIO_0,&GPIO_InitStructure);

 ※ システムコントロールレジスタ SCS(0xE01FC1A0) に0x01をセットするとGPIO0,GPIO1はFGPIOに設定されるが、設定の有無による違い未だ実感出来ず。(高速IFが必要にならない限り実感できないと思う。)

 2)GPIO出力 
   GPIO ポート1の18番ピンに1出力 付録基板LED1消燈
   GPIO ポート1の19番、22番ピンに0出力 外付けLEDが点灯
     GPIO_SetBits(&GPIO_1,GPIO_Pin_18);
     GPIO_ResetBits(&GPIO_1, GPIO_Pin_19 GPIO_Pin_22);
2.GPIO使用 LPC用GPIO関数側
 1)GPIO設定構造体
    typedef struct
    {
    GPIOPortID_TypeDef GPIO_ID;
    u32 GPIO_Pins;
    GPIOMode_TypeDef GPIO_Mode;
    GPIOModeIO_TypeDef GPIO_ModeIO;
    GPIOModePin_TypeDef GPIO_ModePin;
    }GPIO_InitTypeDef;

 2)GPIO構造体
    typedef struct
    {
    vu32 *pIOPIN;
    vu32 *pIOSET;
    vu32 *pIODIR;
    vu32 *pIOCLR;
    vu32 *pFIODIR;
    vu32 *pFIOMASK;
    vu32 *pFIOPIN;     
    vu32 *pFIOSET;
    vu32 *pFIOCLR;
    } GPIO_TypeDef;


    EXTERN GPIO_TypeDef GPIO_0;
    EXTERN GPIO_TypeDef GPIO_1;
    EXTERN GPIO_TypeDef GPIO_2;
    EXTERN GPIO_TypeDef GPIO_3;
    EXTERN GPIO_TypeDef GPIO_4;


 3)関数 GPIO_Init
    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
    {
     u32 i;
     u32 *pPINSEL_H;
     u32 *pPINSEL_L;
     u32 *pPINMODE_H;
     u32 *pPINMODE_L;
     vu32 bitpattern;
       
    switch(GPIO_InitStruct->GPIO_ID)
    {
      case GPIO_Port_0:  //ポート0のピン選択レジスタポインタをセット
        pPINSEL_L = (u32 *)(PINSEL_BASE_ADDR + 0x00);
        pPINSEL_H = (u32 *)(PINSEL_BASE_ADDR + 0x04);
        pPINMODE_L = (u32 *)(PINSEL_BASE_ADDR + 0x40);
        pPINMODE_H = (u32 *)(PINSEL_BASE_ADDR + 0x44);
        break;
      case GPIO_Port_1:
        pPINSEL_L = (u32 *)(PINSEL_BASE_ADDR + 0x08);
        pPINSEL_H = (u32 *)(PINSEL_BASE_ADDR + 0x0c);
    ///////////////////////////////////////////
      default:
         return;
    }
      /* Setting Low Bits . for use GPIO (Bit Patern "00")*/
    for(i=0;i<16;i++)
    {
      if( GPIO_InitStruct->GPIO_Pins & (0x00000001 << i))
      {  // ピン選択レジスタの設定 Pin0-15
        bitpattern = 0x0000003 << (2*i);
        bitpattern ^= 0xFFFFFFFF;
        *pPINSEL_L &= bitpattern;
        //Bit Clear and Pin use GPIO
        *pPINMODE_L &= bitpattern;
        //Bit Clear
        bitpattern = GPIO_InitStruct->GPIO_ModePin << (2*i);
        *pPINMODE_L = bitpattern;
      }
    }
    for(i=0;i<16;i++)
    {
      if( GPIO_InitStruct->GPIO_Pins & (0x00000001 << (i+16)))
      { // ピン選択レジスタの設定 Pin16-31
        bitpattern = 0x0000003 << (2*i);
        bitpattern ^= 0xFFFFFFFF;
        *pPINSEL_H &= bitpattern;
        //Bit Clear and Pin use GPIO
        *pPINMODE_H &= bitpattern;
        //Bit Clear
        bitpattern = GPIO_InitStruct->GPIO_ModePin << (2*i);
        *pPINMODE_H = bitpattern;
      }
    }
    if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_REGACY)
    {
      switch(GPIO_InitStruct->GPIO_ID)
      { // GPIOレジスタポインタのGPIO構造体への登録
         case GPIO_Port_0:
          GPIOx->pIOPIN = (u32 *)(GPIO_BASE_ADDR + 0x00);
          GPIOx->pIOSET = (u32 *)(GPIO_BASE_ADDR + 0x04);
          GPIOx->pIOSET = (u32 *)(GPIO_BASE_ADDR + 0x04);
          GPIOx->pIODIR = (u32 *)(GPIO_BASE_ADDR + 0x08); // Pin Control Reg. (0:input 1:output)
          GPIOx->pIOCLR = (u32 *)(GPIO_BASE_ADDR + 0x0c); // Output Clear Reg.
         break;
        case GPIO_Port_1:
          GPIOx->pIOPIN = (u32 *)(GPIO_BASE_ADDR + 0x10);
          GPIOx->pIOSET = (u32 *)(GPIO_BASE_ADDR + 0x14);
          GPIOx->pIODIR = (u32 *)(GPIO_BASE_ADDR + 0x18);
          GPIOx->pIOCLR = (u32 *)(GPIO_BASE_ADDR + 0x1c);
          break;
        default:
          return;
      }
      GPIOx->pFIODIR = NULL;
      GPIOx->pFIOMASK = NULL;
      GPIOx->pFIOPIN = NULL;
      GPIOx->pFIOSET = NULL;
      GPIOx->pFIOCLR = NULL;
      for(i=0;i<32;i++)
      {  // 各ピンの入出力の設定
        if( GPIO_InitStruct->GPIO_Pins & (0x00000001 << i))
        {
          if(GPIO_InitStruct->GPIO_ModeIO == GPIO_Mode_INPUT)
          {
            bitpattern = 0x0000001 << i;
            bitpattern ^= 0xFFFFFFFF;
            *(GPIOx->pIODIR) &= bitpattern; // Input Mode bit off
          }
          else
          {
            bitpattern = 0x0000001 << i;
            *(GPIOx->pIODIR) = bitpattern; // Output Mode bit on
          }
        }
      }
    }
     else
    {
     /* Fast GPIO Mode */
      switch(GPIO_InitStruct->GPIO_ID)
      {  // GPIOレジスタ群のポインタをGPIO構造体へ登録
        case GPIO_Port_0:
          GPIOx->pFIODIR = (u32 *)(FIO_BASE_ADDR + 0x00); //Pin Control Reg. (0:input 1:output)
          pFIOMASK = (u32 *)(FIO_BASE_ADDR + 0x10); //Pin Mask Reg. (0:input 1:output)
          GPIOx->pFIOMASK = (u32 *)(FIO_BASE_ADDR + 0x10); //Pin Mask Reg. (0:input 1:output)
          GPIOx->pFIOPIN = (u32 *)(FIO_BASE_ADDR + 0x14); // Pin Value Reg.
          GPIOx->pFIOSET = (u32 *)(FIO_BASE_ADDR + 0x18); // Output Set Reg.
          GPIOx->pFIOCLR = (u32 *)(FIO_BASE_ADDR + 0x1c); // Output Clear Reg.
          break;
          case GPIO_Port_1:
          GPIOx->pFIODIR = (u32 *)(FIO_BASE_ADDR + 0x20);
       ///////////////////////////////////////////
         default:
           return;
      }
      GPIOx->pIOPIN = NULL;
      GPIOx->pIOSET = NULL;
      GPIOx->pIODIR = NULL;
      GPIOx->pIOCLR = NULL;
      for(i=0;i<32;i++)
      {  // 各ピンの入出力の設定
        if( GPIO_InitStruct->GPIO_Pins & (0x00000001 << i))
        {
          if(GPIO_InitStruct->GPIO_ModeIO == GPIO_Mode_INPUT)
          {
            bitpattern = 0x0000001 << i;
            bitpattern ^= 0xFFFFFFFF;
            *(GPIOx->pFIODIR) &= bitpattern; // Input Mode bit off
          }
          else
          {
            bitpattern = 0x0000001 << i;
            *(GPIOx->pFIODIR) = bitpattern; // Output Mode bit on
          }
          bitpattern = 0x0000001 << i;
          bitpattern ^= 0xFFFFFFFF;
          *(GPIOx->pFIOMASK) &= bitpattern; // Mask bit off
         }
        }
       }
       return;
    }
 4)関数 GPIO_SetBits ポート単位でのPin設定 
   GPIO ポートビットセットレジスタを使い Pinに”1”(High)を設定
    void GPIO_SetBits(GPIO_TypeDef* GPIOx, u32 GPIO_Pin)
    {
     if(GPIOx->pFIOSET != NULL) // FGPIOの判断
     {
        *(GPIOx->pFIOSET) = GPIO_Pin; 
      }
      else
      {
        *(GPIOx->pIOSET) = GPIO_Pin;  
      }
    }
 5)関数 GPIO_ResetBits ポート単位でのPinクリア
   GPIO ポートビットクリアレジスタを使い Pinに”0”(Low)を設定
    void GPIO_ResetBits(GPIO_TypeDef* GPIOx, u32 GPIO_Pin)
    {
       if(GPIOx->pFIOCLR != NULL)
      {
        *(GPIOx->pFIOCLR) = GPIO_Pin;
      }
      else
      {
        *(GPIOx->pIOCLR) = GPIO_Pin;
      }
    }

3.タイマ設定 main()側
 1) タイマ設定および 割り込み設定
    /* タイマコントローラへの供給クロック分周設定 */
    *CLK_PCLKSEL0 = (*CLK_PCLKSEL0 & 0xfffffff3); /* 1/4 */ /* タイマ0のパラメータ設定 */
    *TIMER_T0PR = 0x00000000;    /* プリスケール無し */
    *TIMER_T0MR0 = 1000000;    /* 供給クロック周波数=1秒 */
    *TIMER_T0MCR = 0x00000003;    /* Match時にTCクリア&割り込み */
    *TIMER_T0TCR = 1;   /* タイマスタート*/
    /* 割り込みコントローラ設定 */
    *VIC_IntSelect = *VIC_IntSelect & (~0x10); /* IRQ選択 */
    *VIC_IntEnable = *VIC_IntEnable 0x10; /* タイマ0のみ有効 */
    /* 割り込み許可 */
    CPU_EnableInterrupt();
  2)割り込みハンドラ
    IRQ割り込みでCALLされるハンドラをTIMER0の割り込みハンドラとして利用。
    void CPU_IRQInterrupt(void)
    {
      if( toggle == 0 ) {
        toggle = 1;
    ***************************************  
     *TIMER_T0IR =1; /* タイマ割り込みクリア */
    }

4.startup.s
   ここで IRQ割り込みを登録
 CQ出版IF誌のサンプル使用
.text
.extern main
.extern _sp_base
#======================================
# Initialize vectors
#======================================
    B _startup
    nop
    nop
    nop
    nop
    nop
    B _IRQ_handle
    nop
    .org 0x20
    .global _startup
_startup:
#IRQ通知を受け取るように設定する
    MRS R0, cpsr
    eor R0, R0, #0x80
    MSR cpsr, R0
#プロセッサモードをIRQモードへ
    MRS r1, CPSR
    BIC R1, R1, #0x1F
    ORR R1, R1, #0x12
    MSR CPSR, R1
#例外ハンドラ用スタックを設定
    LDR sp, = _exception_sp_base
#プロセッサモードをスーパーバイザモードへ戻す
    MRS r1, CPSR
    BIC R1, R1, #0x1F
    ORR R1, R1, #0x13
    MSR CPSR, R1
# スタックを設定
    LDR R13,=_sp_base
    BL main
    .align 0x4
_IRQ_handle:
#例外用スタックにレジスタ退避
    STMDB sp!,{r0-r12, r14}
    MRS r0, spsr
    STMDB sp!, {r0}
    bl CPU_IRQInterrupt
#例外用スタックからレジスタ復帰
    LDMIA sp!, {r0}
    MSR spsr_cf, r0
    LDMIA sp!,{r0-r12,r14}
    SUBS PC, R14, #4

フェーズ2 TIMERテスト NXP LPC2388

NXP LPC2388 のタイマー機能の検証を以下のとおりおこなった。

概要 4つのLEDを4つのタイマー(TIMER0~TIMER3)で異なるインターバルで点滅させる。

※10秒程度チカチカしてプログラムはハングする。

1.タイマ設定 main()関数側

    // タイマ 設定 Timer0
    TIMER_StructInit(&TIMER_InitStructure);
    TIMER_InitStructure.TIMER_ID =TIMER_ID_0;
    TIMER_InitStructure.TIMER_INTVL_MR0 = TIMER_INTVL_1mS * 5;
    TIMER_InitStructure.TIMER_INTVL_MR0_TCR = TRUE;
    TIMER_InitStructure.INTRPT_HANDLR = Tim0_InterruptHnd;
    TIMER_Init(&TIMER_0,&TIMER_InitStructure);
    *(TIMER_0.pTPR) = 0xF;
    TIMER_Start(&TIMER_0);

2.LPC用タイマ関数側。
 1)タイマ設定構造体

    typedef struct
    {
    TIMER_ID_TypeDef TIMER_ID;
    TIMER_PCLK_TypeDef TIMER_PCLK;
    u32 TIMER_PRCMAX;
    u32 TIMER_INTVL_MR0;
    u32 TIMER_INTVL_MR1;
    u32 TIMER_INTVL_MR2;
    u32 TIMER_INTVL_MR3;
    bool TIMER_INTVL_MR0_TCR;
    bool TIMER_INTVL_MR1_TCR;
    bool TIMER_INTVL_MR2_TCR;
    bool TIMER_INTVL_MR3_TCR;
    u32 INTRPT_HANDLR;
    }TIMER_InitTypeDef;

 2)関数 TIMER_StructInit

   1)のタイマ設定構造体に初期値を設定

 3)関数 TIMER_Init

  ①TIMER0~3のタイマレジスタ群のポインタを設定。
  ②割り込みレジスタVICIRQStatus、VICIntEnableの設定
  ③割り込みレジスタVICVectCntlxxとVICVectPriorityxxに割り込みハンドラー、プライオリティを設定する。(効果なし)
  ④プリスケーラのMAX値の設定(今のところ0を設定:プリスケールなし)・・・よく解らない
  ⑤タイマーインターバルの設定。
  ⑥タイマ一致コントロールレジスタの設定。(タイマ割り込みを設定、タイマカウンタリセットを設定)
    void TIMER_Init(TIMER_TypeDef* TIMERx, TIMER_InitTypeDef* TIMER_InitStruct)
    {
    Timer_Interval_Rate= TIMER_INTVL_RATE;
    switch(TIMER_InitStruct->TIMER_ID)
    {
    case TIMER_ID_0:
        PCLKSEL0 &= 0xFFFFFFF3;
        PCLKSEL0 = TIMER_InitStruct->TIMER_PCLK <<>
        TIMERx->pTIR = (u32 *)(TMR0_BASE_ADDR + 0x00);   ①
        TIMERx->pTTCR = (u32 *)(TMR0_BASE_ADDR + 0x04);
        TIMERx->pTTC = (u32 *)(TMR0_BASE_ADDR + 0x08);
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

        VICIntSelect = VICIntSelect & ~(0x1<<4); ②
        VICIntEnable = VICIntEnable (0x1<<4);
        VICVectCntl4 = TIMER_InitStruct->INTRPT_HANDLR; ③
        VICVectPriority4 = 0x04;
        break;

    case TIMER_ID_1:
        PCLKSEL0 &= 0xFFFFFFCF;
    ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

        VICVectCntl27 =TIMER_InitStruct->INTRPT_HANDLR; ③
        VICVectPriority27 = 0x07;
        break;

    default:
        return;
    }

    /* Prescale Register */
    *(TIMERx->pTPR) = TIMER_InitStruct->TIMER_PRCMAX;  ④
    if(TIMER_InitStruct->TIMER_INTVL_MR0 != (u32)NULL)
    {   
     *(TIMERx->pTMR0) = TIMER_InitStruct->TIMER_INTVL_MR0 * Timer_Interval_Rate; ⑤
     *(TIMERx->pTMCR) = *(TIMERx->pTMCR) & ~(0x07);
     if(TIMER_InitStruct->TIMER_INTVL_MR0_TCR )
     {
         *(TIMERx->pTMCR) = *(TIMERx->pTMCR) (0x03); ⑥(TCリセットあり)
     } else {
         *(TIMERx->pTMCR) = *(TIMERx->pTMCR) (0x01); ⑥(TCリセットなし)
     }
    }

    if(TIMER_InitStruct->TIMER_INTVL_MR1 != (u32)NULL)
    {
     ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
     ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
     return;
    }

 4)関数  TIMER_Start

  TIMER_Initでポインタが設定されたタイマコントロールレジスタ TxCR でTIMERカウンタ Enable設定。

    void TIMER_Start(TIMER_TypeDef* TIMERx)
    {
        *(TIMERx->pTTCR) = *(TIMERx->pTTCR) 0x00000001;
        return;
    }

3.タイマー割り込み処理


    本来 1.で指定したタイマ割り込みハンドラ(Tim0_InterruptHnd)でLEDの点滅を実現したいが不調、IRQ割り込みで(タイマ割り込みをIRQ割り込み指定)実行されるハンドラで実現。

    void CPU_IRQInterrupt(void)
    {
        switch(VICIRQStatus)
        {
            case INT_IRQ_TIMER0:
                if(toggle0 == 0)
                {
                     toggle0 = 1;
                    GPIO_ResetBits(&GPIO_0,GPIO_Pin_27);
                } else {
                    toggle0 = 0;
                    GPIO_SetBits(&GPIO_0,GPIO_Pin_27);
                }
                TIMER_InterruptReset(&TIMER_0);
                break;
             case INT_IRQ_TIMER1:
                if(toggle1 == 0)
                {
                    toggle1 = 1;
                    GPIO_ResetBits(&GPIO_1,GPIO_Pin_19);
                } else {
                    toggle1 = 0;
                    GPIO_SetBits(&GPIO_1,GPIO_Pin_19);
                }
                TIMER_InterruptReset(&TIMER_1);
                ・・・・・・・・・・・・・・・・・・・・・・・・・・・

2009年5月1日金曜日

悪戦苦闘 LPC2388

このベースボード等の情報は次。
http://www.ac.auone-net.jp/~w-cloud/Index.htm



CQ出版 Interface 2009/5 付録のARM(LPC2388)基板を試しています。

備忘録的に記します。

開発環境 GNU
gcc 4.3.0 newlib 1.17.0 binutils 2.19.1 mpfr 2.4.1 gmp 4.2.4
開発UI Cygwin   GNU bash, version 3.2.48(21)-release (i686-pc-cygwin)

過去のV850で試したプログラムが100KByte超えのため、IAR Embededd Workbenchの利用は見送りました。

0.フェーズ0.(準備)
  付録基板の部品組み付け。

  [ドジ]
    CN5,CN6,CN7のUSBのコネクタを間違えて裏面に装着。CN5のみ表に付け替え。
一旦取り付けたコネクタを外すのはなかなか困難。

  [不具合]
   1) FlashMagicによる、書き込み失敗。
    ・Interface誌サイトからダウンロードしたサンプルプログラム(gcc版)をLPC2388
     に書き込む。
    ・このサンプルプログラムを再コンパイルし、LPC2388(No.1基板)に書き込む。
            書き込み不能になる。
   2) 対処
    ・LPC2388のダウンローダーがつぶれたと思い、I誌2冊目を購入(No.2基板)
    ・前述、再コンパイルのプログラムをNo.2基板に書き込む。
    ・再度、No.2基板に書き込む。
            書き込み不能になる。
      <ほとんど諦め気分>
    ・数日後 再挑戦、なぜか、No.2基板に書き込む。
            書き込み成功。
    ・あれやこれやと試す。 再び書き込み不能に。。。。
    ・基板JP2のコネクタを抑えながら(奥に・手前に)押しながらリセットボタン(JP1)
を押し、FlashMagicによる書き込みを試行。
           書き込み成功。
      結局のところ、JP2のピンヘッダーの半田付け不良が原因。
      基板No.1、No.2とも半田付けをやり直し。で解決。

      CN1,CN2,,等の他のコネクタの半田付け不良は今のところありません。
      2つの基板で両方ともJP2の半田付けに ミス るとは、。。。(無念)

1.フェーズ1.GPIOテスト
  GPIO: GPIO_0 Pin_27 GPIO_1 Pin_18,19,22  GPIO_2 Pin_8
  TIMER: TIMER_0
 
各GPIOににLEDを接続し(GPIO_1 Pin_18は基板LED1) TIMER_0 の インターバル割り込みでLEDを点滅。

 [Tech.Memo ]
  1)TIMER割り込みについて。    
    IRQ割り込みを使用、無条件でTIMER_0の割り込みとして利用
  2)LEDについて。
    +3.3V --(R200Ω)-- LED -- GPIO_n Pin_n で接続 GPIO Lowレベルで LED点灯   
  
2.フェーズ2 TIMERテスト
  GPIO: GPIO_0 Pin_27 GPIO_1 Pin_18,19,22  GPIO_2 Pin_8
  TIMER: TIMER_0 TIMER_1 TIMER_2 TIMER_3

 TIMER_0 で GPIO_0 Pin_27 (LED0)、TIMER_1 で GPIO_1 Pin_19 (LED2)、TIMER_2 で GPIO_1 Pin_22 (LED3)、TIMER_3 で GPIO_2 Pin_19 (LED4)のLEDを点滅。
 [Tech.Memo]
   1)TIMER割り込みについて。
       IRQ割り込みを使用、レジスタ VICIRQStatus で TIMER_0~3の割り込みを判断
      する。
      ex. TIMER_0の割り込みはVICIRQStatusと ((u32)0x00000010)でANDをとり、割り込
        みの有無を判定。
   2)TIMER_2,3の利用について。
     パワーコントロールレジスタ(PCONP)の設定が必要。
 [不具合]
   1)現象 複数のタイマーを稼動させると一定時間で LPC2388はハングする。
     タイマーインターバルに比例して停止までの時間は変化、インターバルの組み合わせでも変化
     する。
   2)対処 ・・未解決
     VICVectAddr4 VICVectPriority4(TIMER_0の場合)を適当に設定するが改善せず。
     そもそもこれらのレジスタの使い方、割り込み(IRQ)理解度が不足。

3.フェーズ3 KeyInテスト
  GPIO: GPIO_0 Pin_27 GPIO_1 Pin_18,19,22  GPIO_2 Pin_8 (LED用)
      GPIO_0 Pin_0 Pin_1 Pin_10 Pin_11 Pin_17  (Key入力用)
  TIMER: TIMER_0(Heat Beet用)  TIMER_3(Key Scan用)

 GPIO_0 Pin_0...に接続した、タクトスイッチのON/OFFをTIMER_3のインターバルでチェックし、押されたスイッチにより、各LEDの点灯を切り替える。
 
 [Tech.Memo]
   1)キー入力について。
    GPIO_0 Pin_0,1,,,には、3.3V(100KΩ+1KΩ)で接続、スイッチONでGRND(1KΩ)に接続。  
 [不具合]
   1)現象 2.フェーズ2と同様に一定時間後、LPC2388はハングする。
   2)対処 未解決
    (6/25)解決 割り込み時にVICVectAddrにセットされるアドレスを使って割り込みハンドラー関数を起動させることで解決。

 [不具合2]
   1)FlashMagic書き込みエラー発生。
    「Error Programing the Hex file RAM locations 0x40000120 to 0x400001FF are...」
   2)対処
    リンクスクリプトファイルの「.data 0x40000000: {」を「.data 0x40000200: {」に変更


4.フェーズ4 LCDテスト
  GPIO: GPIO_0 Pin_27 GPIO_1 Pin_18,19,22  GPIO_2 Pin_8 (LED用)
      GPIO_0 Pin_0 Pin_1 Pin_10 Pin_11 Pin_17  (Key入力用)
      GPIO_2 Pin_0,1,2,3,4,5,6,7 GPIO_4 Pin_24,25,28,29,30,31  (LCD用)
  TIMER: TIMER_0(Heat Beet用) TIMER_1(LCDリフレッシュ用) TIMER_3(Key Scan用)

 グラフィカルLCD SG12864 に キー操作にあわせ文字列を表示する。
 [不具合]
   1)現象 2.フェーズ2と同様に一定時間後、LPC2388はハングする。
   2)対処 未解決
      使用タイマをTIMER_0のみに変更  タイマカウンタ数で各機能を振り分け。
    (6/25)解決 前述

5.フェーズ5 LCDグラフィカルテスト。
 LCDにチャートを描画する。グリッドと、グラフ(サンプルデータによる。)の描画。
 [不具合]
   1)現象 描画位置決めの、座標計算(float)でハングする。
   2)対処 未解決。
   (7/9)解決 GCCのインストールのやり直し、インストールのオプション指定を変更。
[不具合]
   1)現象 基板のUSBケーブルを一旦外すと、次のプログラム起動でハングする。
         (電源OFFで書き込まれたプログラムの一部が消えた。。と考え勝ちな現象)  
   2)対処 リンクスクリプトファイルを変更するが変わらず。 未解決。
    解決(6/24)の 3.リンクスクリプトファイル         
6.フェーズ6 UARTテスト。
  UART: UART1
 PC Windows/アクセサリ/通信/ハイパーターミナル でCOM1接続 ハイパーターミナル キー入力を基板側LCD表示、基板側スイッチ操作で文字列をUART出力、ハイパーターミナルで表示。

 [Tech.Memo]
   1)RS232CドライバIC ANALOG DEVICES ADM3202AN について。
    GPIO_0 Pin_15をUART1 TX、同 Pin_16を UART1 RXとして使用。
   2)UART割り込み設定(IRQ)。
    
 [不具合]    
   1)現象 PCからキーニュー力データを受けた時にハング(50%前後の割合でハング)
        UARTの割り込みが前述のタイマ割り込み同様な原因と思う。
   2)対処 未解決。
    (6/25)解決

※ ここまでの試行で、割り込み、各タスク等のスケジュール、マイコン資源、、、等の管理が必要と思いRTOSの導入が必要と思うようになる。

7.フェーズ7 RTOS 導入テスト
 7-1.Toppers ASPを調べる。 まったく手が出せない。
 7-2.FreeRTOSを調べる。
   1)導入 SOURCEFORCE.NET 「FreeRTOS Real Time Kernel」 から FreeRTOSV5.2.0.zip
     をダウンロード (The FreeRTOS.org Project)
   2)サンプルコードを調べる。   
     Demo\ARM7_LPC2368_Eclipse\RTOSDemo\main.c を調べる。
   3)サンプルコードを改造
    ・全般 Ethernet関連のコードをコメント化、または、ダミー化
        TIMER0をFreeRTOS専用に(サンプルコードに従い)
    ・main.cの改造 関数xTaskCreate( vuIP_Task, ,,をコメント化、同関数で指定さ
れる vLCDTaskの内容 を LED点滅の簡単なものに改造。
    ・lpc2368.ld(リンクスクリプト)の改造
         ram, __stack_end__のアドレス、サイズ等を修正。
    ・Makefileの改造 Ethernet関連のファイル指定を削除。
    ・・・
   4)結果
     ・main()内の vTaskStartScheduler()まで正常終了本来、この関数で待機する
はずが終了してしまう。
     ・TIMER_0の割り込みが不調 タイマの稼動自体不明。。。

    ただ単にプログラムがハングしているのか不明。
    
    <プログラム概要>
     元プログラム  
        Ethernetの機能タスクの構成 => LCD関連の環境構成 => LCD機能タスクの
        構成  => タスクスケジューラの起動
              で
        Ethernetの機能、LCDの機能の稼動。
     改造プログラム
        LED点灯のタスクの構成 => タスクスケジューラの起動
              で
        LEDが点滅するハズだった。 

「その他 課題」
 * ADC での 値表示を試そうとして、C言語関数 sprintf()を使うと即座にプログラムはハングする。 (リンクスクリプトを修正しないと、リンクは通らない。エラーメッセージにある「‘end」をリンクスクリプト追加するが、その正誤もわからない。)
  解決(7/10)newlibのインストールのやり直し。

 * float,doubleの計算でプログラムがハングするケースが多い。
 * タイマー等の割り込みを使いながら、main()内のwhile(1)ループで何かをさせると。プログラムはハングする。
   

     
※本Blogは、組み込み素人の、趣味レベルの内容です。電子ブロック世代(発売当時)でITエンジニアが、近年、たまたま、Interfaceの付録基板に出会ってはまってしまった、そんな中年男が暇をみて書き込んでいます。 エキスパートの皆様からみて、内容に間違いも多いと思いますがご容赦願います。
 誤字脱字等、乱文、書きかけ等、も併せてご容赦願います。