OpenOCD フリスクJTAGデバッカーの配付に付いて [ARM&Cortex-M3]
※もっとも近日中に手渡しできる可能性としては、10月8日の品川が有ります。
http://focus.tij.co.jp/jp/mcu/docs/mcusplash.tsp?contentId=61735
ARIESも持って行きます。現地で生パスカルさんにも遭えます!。
※フリスクのケースは欲しいがフリスク食べるのは苦手と言う方向け、空きケースが若干あります。無償(笑)です。
大変長らくお待たせしました。
なかなか商売抜きで販売に至るには難しいらしいので、こちらで数量限定で配付を行います。
手持ちのパーツの関係で6~最大8セットくらいまでです。
基板込みのパーツ代金は2920円(部品集めの手間賃込み)です。
※送料は別です。なるべく安く送れる方法を検討します。
ここを参考に、
http://hamayan.blog.so-net.ne.jp/2009-09-08-2
必要な部品のリストを送っていただければ、その分でパーツ代金を再計算します。
※実装済み、動作確認済みをご希望される方はご相談ください。
あとフラットケーブルですが、以下のリンク先から購入しようかと思っています。
http://www.cabling-ol.net/cabledirect/MIL20SS-F.php
20cmの物で税込み241円ですが、注文するには送料と手数料も込みになりますので、それらを頭数で割る事になります。
http://focus.tij.co.jp/jp/mcu/docs/mcusplash.tsp?contentId=61735
ARIESも持って行きます。現地で生パスカルさんにも遭えます!。
※フリスクのケースは欲しいがフリスク食べるのは苦手と言う方向け、空きケースが若干あります。無償(笑)です。
大変長らくお待たせしました。
なかなか商売抜きで販売に至るには難しいらしいので、こちらで数量限定で配付を行います。
手持ちのパーツの関係で6~最大8セットくらいまでです。
基板込みのパーツ代金は2920円(部品集めの手間賃込み)です。
※送料は別です。なるべく安く送れる方法を検討します。
ここを参考に、
http://hamayan.blog.so-net.ne.jp/2009-09-08-2
必要な部品のリストを送っていただければ、その分でパーツ代金を再計算します。
※実装済み、動作確認済みをご希望される方はご相談ください。
あとフラットケーブルですが、以下のリンク先から購入しようかと思っています。
http://www.cabling-ol.net/cabledirect/MIL20SS-F.php
20cmの物で税込み241円ですが、注文するには送料と手数料も込みになりますので、それらを頭数で割る事になります。
- ショップ: 文房具屋さんワキ文具
- 価格: 2,625 円
STM32F103のDMAの転送タイミングを見てみよう 2 [ARM&Cortex-M3]
DMA転送中はCPUをSLEEPに入れて置いたらどうなるんでしょう?と言う旨のコメントをいただいたので、やってみました。
SLEEPに入れるにはWFIコマンドを実行します。
C言語で実現するにはcortexm3_macro.hの中のvoid __WFI(void);を実行するだけです。
DMA転送が完了するまでWFIでSLEEPに入るようにしている為に、ほとんどの時間はCPUは停止しています。但しシステムタイマー等の幾つかの割り込みは発生する為、完全停止と言う訳ではありません。
WFIで停止したCPUは割り込みで起床されます。
ROM領域からの転送の場合、CPUが停止していなければバスの使用はCPUと仲良く利用する事となりますが、CPUが停止していればDMA側がバスを使い放題となるんでしょう。その為アドレス固定の場合はRAMからの転送並になりました。
しかし依然としてアドレスインクリメントの場合はサイクルが長くなっていますが、これの理由は今一つ判りません。
聞けるチャンスが有ったら、今度聞いてみるかな!。
そう言えば今までのマイコンの場合、DMAにはバーストモードやサイクルスチールモードとかが有って、そのどちらかを選択して来たのですが、このCortex M3のDMAにはその選択が無いのですね。
これはバスの帯域をDMAが独占するのではなく、少なくともCPU側に半分の帯域を保証しているから上記の選択肢が無いのかもしれません。
関係無いけれどこの本、結構出ていますね。
SLEEPに入れるにはWFIコマンドを実行します。
C言語で実現するにはcortexm3_macro.hの中のvoid __WFI(void);を実行するだけです。
転送元をROM領域の先頭とし、転送元、転送先アドレスを固定した場合です。お!、RAM並に書き込みサイクル時間が短くなっているのが判ります。 | |
今度は転送元アドレスをインクリメントしています。こちらは従来とあまり変わり有りません。 |
DMA転送が完了するまでWFIでSLEEPに入るようにしている為に、ほとんどの時間はCPUは停止しています。但しシステムタイマー等の幾つかの割り込みは発生する為、完全停止と言う訳ではありません。
WFIで停止したCPUは割り込みで起床されます。
ROM領域からの転送の場合、CPUが停止していなければバスの使用はCPUと仲良く利用する事となりますが、CPUが停止していればDMA側がバスを使い放題となるんでしょう。その為アドレス固定の場合はRAMからの転送並になりました。
しかし依然としてアドレスインクリメントの場合はサイクルが長くなっていますが、これの理由は今一つ判りません。
聞けるチャンスが有ったら、今度聞いてみるかな!。
そう言えば今までのマイコンの場合、DMAにはバーストモードやサイクルスチールモードとかが有って、そのどちらかを選択して来たのですが、このCortex M3のDMAにはその選択が無いのですね。
これはバスの帯域をDMAが独占するのではなく、少なくともCPU側に半分の帯域を保証しているから上記の選択肢が無いのかもしれません。
関係無いけれどこの本、結構出ていますね。
STM32F103のDMAの転送タイミングを見てみよう [ARM&Cortex-M3]
WEのパルスを見てみました。つまり書き込みサイクルです。
さて転送元にRAM領域、アドレスをインクリメントした場合が掲載されていませんですが、結果から言えばRAM領域でアドレス固定と変わりませんでした。
昨日のフレームレートの話に戻りますが、転送元をRAM領域とした場合のフレームレートは45fpsでした。
計測した書き込みサイクルは168nsなので、これを画面いっぱい分の転送を行うと168ns×480×272時間掛かる事になりますから約45.6fpsですね。
また、転送元をROM領域、アドレスインクリメント有りの場合の書き込みサイクルは210nsなので、
210ns×480×272で約36.5fpsとなります。
おお!大体計算と実測は合っていますね。
ROM領域とRAM領域の転送速度の違いの一つの理由としてアクセス速度の違いが考えられます。
STM32F103の内蔵RAMはno waitでアクセス可能であった筈ですが、ROM領域はRAMより遅く、72MHzで走る場合は2wait挿入されます。
インストラクションコードの場合は一旦バッファされてパイプラインの流れを乱さない様にはなっているみたいですが、データの場合はもろに2waitが効いてしまうのかもしれませんね。
この辺の詳しいところはAMBAと言うのでしたっけ、ARMのバスアーキテクチャを勉強しないと判らないです。
しかしシンクロの波形を見る限り、結構上手く捌けていますよね。
Cortex M3のCPUバス周りのブロック図を見ると結構複雑に思えますが、その分このアービター周りはよく考えられているのだろうと思います。
以下はFSMCの設定例。バンク1にグラフィックLCD ICをSRAM相当で接続。バスは16bitサイズ。
waitは少し多めに入っています。
余談
STM32F103のマニュアルのFSMCの章はやけに長くて読むのは本当に大変、日本語の解説も無いですしね。
と、読むのは大変な割に、設定はそれ程でもない。あ!、でもこれDRAMはサポートされていませんね。
さて転送元にRAM領域、アドレスをインクリメントした場合が掲載されていませんですが、結果から言えばRAM領域でアドレス固定と変わりませんでした。
昨日のフレームレートの話に戻りますが、転送元をRAM領域とした場合のフレームレートは45fpsでした。
計測した書き込みサイクルは168nsなので、これを画面いっぱい分の転送を行うと168ns×480×272時間掛かる事になりますから約45.6fpsですね。
また、転送元をROM領域、アドレスインクリメント有りの場合の書き込みサイクルは210nsなので、
210ns×480×272で約36.5fpsとなります。
おお!大体計算と実測は合っていますね。
ROM領域とRAM領域の転送速度の違いの一つの理由としてアクセス速度の違いが考えられます。
STM32F103の内蔵RAMはno waitでアクセス可能であった筈ですが、ROM領域はRAMより遅く、72MHzで走る場合は2wait挿入されます。
インストラクションコードの場合は一旦バッファされてパイプラインの流れを乱さない様にはなっているみたいですが、データの場合はもろに2waitが効いてしまうのかもしれませんね。
この辺の詳しいところはAMBAと言うのでしたっけ、ARMのバスアーキテクチャを勉強しないと判らないです。
しかしシンクロの波形を見る限り、結構上手く捌けていますよね。
Cortex M3のCPUバス周りのブロック図を見ると結構複雑に思えますが、その分このアービター周りはよく考えられているのだろうと思います。
以下はFSMCの設定例。バンク1にグラフィックLCD ICをSRAM相当で接続。バスは16bitサイズ。
waitは少し多めに入っています。
/*************************************************************************/ /* プロセッサ外部バスを有効にする */ /*************************************************************************/ static void ExtBusInit( void ) { FSMC_BCRx *bcr1 = (FSMC_BCRx *)(FSMC_Bank1 + 0); FSMC_TCRx *tcr1 = (FSMC_TCRx *)((char *)FSMC_Bank1 + 4); FSMC_BWTRx *bwtr1 = (FSMC_BWTRx *)(FSMC_Bank1E + 0); bcr1->BIT.ASYNCWAIT = 0; /*外部waitは使用しない*/ bcr1->BIT.EXTMOD = 1; /**/ bcr1->BIT.MWID = 1; /*16bit bus*/ bcr1->BIT.MTYP = 0; /*sram select*/ bcr1->BIT.MUXEN = 0; /*non multiplexed bus*/ bcr1->BIT.MBKEN = 1; /**/ /*読み込み側設定*/ tcr1->BIT.ACCMOD = 0; /*access mode a*/ tcr1->BIT.DATAST = 9; /**/ tcr1->BIT.ADDSET = 1; /**/ /*書き込み側設定*/ bwtr1->BIT.ACCMOD = 0; /**/ bwtr1->BIT.DATAST = 2; /**/ bwtr1->BIT.ADDSET = 1; /**/ }
余談
STM32F103のマニュアルのFSMCの章はやけに長くて読むのは本当に大変、日本語の解説も無いですしね。
と、読むのは大変な割に、設定はそれ程でもない。あ!、でもこれDRAMはサポートされていませんね。
ARM Cortex‐M3システム開発ガイド―最新アーキテクチャの理解からソフトウェア開発までを詳解 (Design Wave Advance)
- 作者: Joseph Yiu
- 出版社/メーカー: CQ出版
- 発売日: 2009/05
- メディア: 単行本
ARIESのグラフィック能力を測ってみよう。 [ARM&Cortex-M3]
ダウンロードは🎥こちら
|
ダウンロードは🎥こちら
|
それぞれのビデオの最後に出てくる数字が計算されたフレームレートです。全部で272回全画面表示を行って、それに掛かった時間からフレームレートを計算しています。
写真をスクロールするように動かした物は34fps、写真ではなく単色塗りつぶしを行った物は45fps出ています。
写真はROM領域の一部、単色塗りつぶしは変数をグラフィックLCDにDMAで転送していますが、なぜここでフレームレートに差が出るのか、イマイチ判りません。
ですが、描画能力としては十分でしょう。
ちなみにS1D13743自体は60fpsです。
※もちろんこれは固定パターンの展開なので、ほぼ出し得る最大と言えるかもしれません。
画面サイズは480×272ピクセルで、16bitカラーデータを送っています。
今後SDカードから読み出しながら展開とか、計算で座標を求めてのDRAWとかだと、ここからかなり遅くはなるでしょうけれど、まあ上限が判っていれば色々検討し易くなると言うことで。
ARM Cortex‐M3システム開発ガイド―最新アーキテクチャの理解からソフトウェア開発までを詳解 (Design Wave Advance)
- 作者: Joseph Yiu
- 出版社/メーカー: CQ出版
- 発売日: 2009/05
- メディア: 単行本
トホホ、上手く動かないよARMの数値演算ライブラリ [ARM&Cortex-M3]
うーん、駄目だ!、ちょっとお手上げ状態。
Cortex M3でgccのmath.hのsinとかcosとか使おうとやっているのですが、駄目です。
状況はcosとか呼んだ時点でフォールト例外を発生してしまう。具体的には用法フォールトの未定義命令の実行です。
呼んだ先のライブラリがthumb命令ではなくARM命令を実行しているのかな?と思い、lib以下の何とか.aを、その下にあるthumb命令の物と入れ替えたりとかしても駄目です。
何かの設定が違うのでしょうけれど、それが判らない、、、トホホ。
※追記
あれ、これかなぁ。
調べるとCortex M3ではBLXはblx <rm>(※16bit thumb命令)しかサポートしていないみたいだけれど、図の逆アセンブルでは32bitthumb命令だよなぁ。
ここで例外フォールトを発生しているし。
Cortex M3でgccのmath.hのsinとかcosとか使おうとやっているのですが、駄目です。
状況はcosとか呼んだ時点でフォールト例外を発生してしまう。具体的には用法フォールトの未定義命令の実行です。
呼んだ先のライブラリがthumb命令ではなくARM命令を実行しているのかな?と思い、lib以下の何とか.aを、その下にあるthumb命令の物と入れ替えたりとかしても駄目です。
何かの設定が違うのでしょうけれど、それが判らない、、、トホホ。
※追記
あれ、これかなぁ。
調べるとCortex M3ではBLXはblx <rm>(※16bit thumb命令)しかサポートしていないみたいだけれど、図の逆アセンブルでは32bitthumb命令だよなぁ。
ここで例外フォールトを発生しているし。
ARM Cortex‐M3システム開発ガイド―最新アーキテクチャの理解からソフトウェア開発までを詳解 (Design Wave Advance)
- 作者: Joseph Yiu
- 出版社/メーカー: CQ出版
- 発売日: 2009/05
- メディア: 単行本
ARIESに搭載されているグラフィックLCDコントローラICの便利機能を確認 [ARM&Cortex-M3]
これらの機能はレジスタの設定後から有効となるようです。
これ以外にも便利機能が有りますが、それはおいおいで。
OpenOCDフリスクJTAGデバッカーの回路図とシルク図 [ARM&Cortex-M3]
シルク図代わりの画面キャプチャーです。
20pinコネクタの1pinの位置に気を付けてね。
回路図はこちらから。
リンクを右クリックでメニューを出し、コピー先を自分のハードディスクに落として拡張子をpdfに変換してからご覧下さい。
20pinコネクタの1pinの位置に気を付けてね。
回路図はこちらから。
リンクを右クリックでメニューを出し、コピー先を自分のハードディスクに落として拡張子をpdfに変換してからご覧下さい。
STM32F103+カラーLCD評価基板で文字を表示させる編 全角/半角混載OKですぅ。 [ARM&Cortex-M3]
※ソースコードのhtml変換はこれを使わせてもらっています。
http://noritan-micon.blog.so-net.ne.jp/2009-06-11
ASCII文字の表示を出来るようにしました。
ASCII/日本語(Shift-JIS)の区別は、最初の文字コードが0x80を越えるか超えないかで判断できます。
日本語のFontは従来から使わせて頂いているFONTX形式のフリーフォントです。ASCII文字のFontデータは、ネットを探せばフリーの物が有るのでしょうけれど、まあ自分でFontデータを作るのは容易いので、作ります。
まずペイントソフトでスペース(0x20)から~(0x7E)までの文字を描画していき、これを2値のビットマップファイルとして保存します。
※単に文字を並べていっても、なかなか等間隔にならないので、その辺はちまちま調整が必要。今回もなんだかんだで30分位作業時間が掛かっている。
次にこのビットマップファイルをお手製のCソース変換ソフトを通してCソース化し、そのソースファイルをプロジェクトに組み込む訳です。
※以下がその変換ソフトのソース。
これ出来上がったCソースは、やっぱり1ピクセル=1bitのデータなので、先にやった日本語Fontと同様にbit長を16bitに変換して使う必要が有ります。
まあその前にASCIIコードから該当のビットマップデータを取得する処理が必要ですので、それは以下の様にしました。
上記処理はあくまでもFontデータの取得のみなので、実際には1bit→16bit変換がこの後に続きますが、これは既に行っているので省略。
で、ASCII文字と日本語の混載文字列の表示例が冒頭の写真になります。
http://noritan-micon.blog.so-net.ne.jp/2009-06-11
ASCII文字の表示を出来るようにしました。
ASCII/日本語(Shift-JIS)の区別は、最初の文字コードが0x80を越えるか超えないかで判断できます。
日本語のFontは従来から使わせて頂いているFONTX形式のフリーフォントです。ASCII文字のFontデータは、ネットを探せばフリーの物が有るのでしょうけれど、まあ自分でFontデータを作るのは容易いので、作ります。
まずペイントソフトでスペース(0x20)から~(0x7E)までの文字を描画していき、これを2値のビットマップファイルとして保存します。
※単に文字を並べていっても、なかなか等間隔にならないので、その辺はちまちま調整が必要。今回もなんだかんだで30分位作業時間が掛かっている。
次にこのビットマップファイルをお手製のCソース変換ソフトを通してCソース化し、そのソースファイルをプロジェクトに組み込む訳です。
※以下がその変換ソフトのソース。
/* ------------------------------------------------------------------------ */ /* Windows ビットマップファイルをCソースに変換する。 */ /* */ /* 変換出来るフォーマットはWindows BMP、2色、RGBです。 */ /* 上記のフォーマットは、大概のペイントツールで可能でしょう。 */ /* Copyright (C) 2007 - by hamayan */ /* ------------------------------------------------------------------------ */ #include <stdio.h> #include <stdlib.h> typedef struct /*ビットマップファイルヘッダー*/ { char bfType[2]; /*認識文字*/ char bfSize[4]; /*ファイルサイズ*/ char bfReserved1[2]; /*予約1*/ char bfReserved2[2]; /*予約2*/ char bfOffBits[4]; /*ピクセルデータまでのバイト数*/ } BITMAPFILEHEADER; typedef struct /*ビットマップ情報ヘッダー*/ { char biSize[4]; /*BITMAPFILEHEADERのサイズ*/ char biWidth[4]; /*ピクセルデータの幅*/ char biHeight[4]; /*ピクセルデータの高さ*/ char Planes[2]; /*カラープレーン数*/ char biBitCount[2]; /*色数*/ char biCompression[4]; /*圧縮形式*/ char biSizeImage[4]; /*ピクセルデータのサイズ*/ char biXPelsPerMeter[4]; /*水平解像度*/ char biYPelsPerMeter[4]; /*垂直解像度*/ char biClrUsed[4]; /*使用カラー数*/ char biClrImportant[4]; /*重要なカラー数*/ } BITMAPINFOHEADER; typedef struct /*カラーパレット*/ { unsigned char rgbBlue; /*青の輝度*/ unsigned char rgbGreen; /*緑の輝度*/ unsigned char rgbRed; /*赤の輝度*/ unsigned char rgbReserved; /*予約*/ } RGBQUAD; typedef struct /*ファイル全体のフォーマット*/ { BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; RGBQUAD rgb[1]; } BITMAPFILEFORMAT; int main( int argc, char *argv[] ) { char *FileBuffer; char *bmp; int i,j,k,width,line,shift; long FileSz,curpos; BITMAPFILEFORMAT *head; RGBQUAD *rgb; FILE *in,*out; if( argc != 2 && argc != 3 ) { printf( "Parameter Error\n" ); return EOF; } if( argc == 2 ) out = stdout; else { out = fopen( argv[2], "w+t" ); } /*引数のファイルをOPENする。*/ if( (in = fopen( argv[ 1 ], "rb" )) == NULL ) return EOF; /*ファイルのサイズを取得する。*/ curpos = ftell( in ); fseek( in, 0, SEEK_END ); FileSz = ftell( in ); fseek( in, curpos, SEEK_SET ); FileBuffer = malloc( FileSz + 1 ); /*ファイルの内容を取込み*/ curpos = fread( FileBuffer, 1, FileSz, in ); /*ファイルの内容を取り込んだので、CLOSEする。*/ fclose( in ); /*ファイルの情報を表示する。*/ head = (BITMAPFILEFORMAT *)FileBuffer; /*意匠表示*/ fprintf( out, "/* ------------------------------------------------------------------------ */\n" "/* 画像データテーブル */\n" "/* designed by hamayan */\n" "/* Copyright (C) 2003 - by hamayan */\n" "/* ------------------------------------------------------------------------ */\n\n" ); fprintf( out, "/*\tGraphic Info*/\n" ); fprintf( out, "/*\tType:%c%c*/\n" "/*\tFile size=%ld*/\n" "/*\tOffset=%ld*/\n\n", head->bf.bfType[0],head->bf.bfType[1], *((long *)head->bf.bfSize), *((long *)head->bf.bfOffBits) ); fprintf( out, "/*\tHeader size=%ld*/\n" "/*\tWidth=%ld*/\n" "/*\tHeight=%ld*/\n" "/*\tPlanes=%d*/\n" "/*\tCount=%d*/\n" "/*\tImg size=%d*/\n" "/*\tX pics=%ld*/\n" "/*\tY pics=%ld*/\n" "/*\tColor Used=%d*/\n\n", *((long *)head->bi.biSize), *((long *)head->bi.biWidth), *((long *)head->bi.biHeight), *((short *)head->bi.Planes), *((short *)head->bi.biBitCount), *((long *)head->bi.biSizeImage), *((long *)head->bi.biXPelsPerMeter), *((long *)head->bi.biYPelsPerMeter), *((long *)head->bi.biClrUsed) ); fprintf( out, "const long PixWidth = %ld;\n" "const long PixHeight = %ld;\n", *((long *)head->bi.biWidth), *((long *)head->bi.biHeight) ); #define BITCOUNT (*((short *)head->bi.biBitCount)) #define OFFBITS (*((long *)head->bf.bfOffBits)) #define HEIGHT (*((long *)head->bi.biHeight) - 1) /*縦横サイズの調整*/ width = *((long *)head->bi.biWidth); /*横方向のbyte数を計算*/ width = ((width - 1) * BITCOUNT / 8) + 1; line = (((width - 1) / sizeof(long)) + 1) * sizeof(long); /*左下を原点にしている為に、上下方向のみ入れ替えが必要となる。*/ /*画像データをCソースファイルに変換する。*/ fprintf( out, "\n/*\tparameter width = %d height = %d line = %d*/\n", width, HEIGHT + 1, line ); fprintf( out, "const char GraphicBMPTable[] = \n" ); fprintf( out, "{\n" ); for( i = HEIGHT; i >= 0; i-- ) /*逆順に廻して行く*/ { fprintf( out, "\t" ); bmp = (char *)head + (i * line) + OFFBITS; /*パレット番号が登録されたテーブルから読み出し*/ for( j = 0; j < width; j++ ) { fprintf( out, "0x%02X,", ~(*bmp) & 0x00ff ); bmp++; } putc( '\n', out ); } fprintf( out, "};\n\n" ); for( i = HEIGHT; i >= 0; i-- ) /*逆順に廻して行く*/ { fprintf( out, "/*\t" ); bmp = (char *)head + (i * line) + OFFBITS; /*パレット番号が登録されたテーブルから読み出し*/ for( j = 0; j < width; j++ ) { for( k = 0; k < 8; k++ ) { fprintf( out, "%c", (*bmp & (0x80 >> k)) ? ' ' : '*' ); } bmp++; } fprintf( out, "*/\n" ); } /*意匠表示*/ fprintf( out, "\n" "/* ------------------------------------------------------------------------ */\n" "/* end of file */\n" "/* designed by hamayan */\n" "/* Copyright (C) 2003 - by hamayan */\n" "/* ------------------------------------------------------------------------ */\n" ); if( argc == 3 ) fclose( out ); free( FileBuffer ); return 0; } /* ------------------------------------------------------------------------ */ /* Copyright (C) 2003 - by hamayan */ /* ------------------------------------------------------------------------ */
これ出来上がったCソースは、やっぱり1ピクセル=1bitのデータなので、先にやった日本語Fontと同様にbit長を16bitに変換して使う必要が有ります。
まあその前にASCIIコードから該当のビットマップデータを取得する処理が必要ですので、それは以下の様にしました。
/*************************************************************************/ /* ASCII文字の表示 */ /* ASCII文字は、横8ピクセル、縦14ピクセルで構成されている。 */ /* 文字範囲は、スペース(0x20)から~(0x7E)までの95文字。 */ /* 失敗するとNULLポインターを返す。 */ /*************************************************************************/ static char *GetASCII( char *dst, int code ) { int i; char *ptr = dst; if( code < ' ' || code > '~' ) return 0; code -= ' '; /*オフセット分を削除*/ for( i = 0; i < ASCII_PixHeight; i++ ) { *ptr++ = *(ASCII_GraphicBMPTable + code + (i * ASCII_PixWidth / 8)); } return dst; }
上記処理はあくまでもFontデータの取得のみなので、実際には1bit→16bit変換がこの後に続きますが、これは既に行っているので省略。
で、ASCII文字と日本語の混載文字列の表示例が冒頭の写真になります。
ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発
- 作者: 濱原 和明
- 出版社/メーカー: オーム社
- 発売日: 2005/04/25
- メディア: 単行本
STM32F103+カラーLCD評価基板で文字を表示させる編 [ARM&Cortex-M3]
某blogのグダグダした書き込みをLCDに表示させてみました。
Fontの扱いについてはこことか
http://hamayan.ddo.jp/~hamayan/so-net/font.html
こことか
http://hamayan.ddo.jp/~hamayan/so-net/colorlcd.html
を参照してください。まあ過去に通った道なので、
但しまだ半角のFontを作っていないので全角しか表示できません(笑、ずーっとそれだけれど)。
ただ過去にFontを扱った時は開発環境はHEWだったので、Shift-JISのコードを文字列に組み込む事は問題が無かったのだけれど、今回はWindows上で動くgcc環境なので、文字(文字コード)によっては正常に処理できない物もあります。
例えば写真の一番上の行では「開発環境を穀しています」となっていますが、本当は「開発環境を構築しています」です。どうも”構築”の”構”に反応してしまったみたいで、、、。他にも正常に処理できない文字は幾つかあります。
※元々Fontデータ(16ドットFont)は2値(1bit)データなのですが、このLCDには1ピクセルに16bitの情報を与えますので、一旦16×16×2byteのバッファにbit→unsigned shortの変換を掛けて展開を行い、それからDMAでカラーLCDへ転送しています。けれどメモリが少ない(勿体無い)場合はバッファしなくてもできるかな。
※補足
呼び出し側も掲載して置きます。
Fontの扱いについてはこことか
http://hamayan.ddo.jp/~hamayan/so-net/font.html
こことか
http://hamayan.ddo.jp/~hamayan/so-net/colorlcd.html
を参照してください。まあ過去に通った道なので、
但しまだ半角のFontを作っていないので全角しか表示できません(笑、ずーっとそれだけれど)。
ただ過去にFontを扱った時は開発環境はHEWだったので、Shift-JISのコードを文字列に組み込む事は問題が無かったのだけれど、今回はWindows上で動くgcc環境なので、文字(文字コード)によっては正常に処理できない物もあります。
例えば写真の一番上の行では「開発環境を穀しています」となっていますが、本当は「開発環境を構築しています」です。どうも”構築”の”構”に反応してしまったみたいで、、、。他にも正常に処理できない文字は幾つかあります。
※元々Fontデータ(16ドットFont)は2値(1bit)データなのですが、このLCDには1ピクセルに16bitの情報を与えますので、一旦16×16×2byteのバッファにbit→unsigned shortの変換を掛けて展開を行い、それからDMAでカラーLCDへ転送しています。けれどメモリが少ない(勿体無い)場合はバッファしなくてもできるかな。
/*********************************************************************************/ /* LCDディスプレイに文字を描画する処理 */ /* designed by hamayan since 2009/05/21 */ /*********************************************************************************/ #include "delivertive.h" #include "S1D13743.h" #include "dib.h" /*************************************************************************/ /* 端子定義 */ /*************************************************************************/ /*************************************************************************/ /* その他の定義 */ /*************************************************************************/ typedef struct { unsigned short start; /*漢字コードの開始番号*/ unsigned short end; /*漢字コードの終了番号*/ const char *font; /*フォントデータ領域の先頭アドレス*/ } AREA_RECORD; /*************************************************************************/ /* 大域変数宣言 */ /*************************************************************************/ extern unsigned short BGColor; /*背景色*/ /*フォントヘッダー情報*/ extern const unsigned short KanjiXSize; extern const unsigned short KanjiYSize; extern const unsigned short KanjiTnum; extern const AREA_RECORD KanjiAreaRecord[]; static unsigned short font_buffer[ 16 * 16 ]; /*************************************************************************/ /* プロトタイプ宣言 */ /*************************************************************************/ /*************************************************************************/ /* 漢字表示処理 */ /* 一時的に512byteのバッファを必要とする。 */ /*************************************************************************/ void KanjiPrint( const char *msg ) { #define __X_STEP__ 16 #define __Y_STEP__ 20 int i,j,k; int pos_x,pos_y; char *str,*ptr,temp; unsigned short code,*bmp; DrawForm df; str = (char *)msg; pos_x = pos_y = 0; while( *str ) { if( *str < 0x80 ) /*ASCII文字*/ { if( *str == '\r' ) { pos_x = 0; } else if( *str == '\n' ) { pos_y += __Y_STEP__; if( pos_y >= Y_MAX_PIXEL ) pos_y = 0; } else ; str++; /*文字列のポインターを進める*/ } else /*Shift-JISコード*/ { for( i = 0; i < KanjiTnum; i++ ) /*Shift-JISコード表からコードを検索*/ { code = str[ 1 ] + (str[ 0 ] << 8); /*リトルエンディアンなので前後を入れ替える*/ if( code >= KanjiAreaRecord[ i ].start && code <= KanjiAreaRecord[ i ].end ) { ptr = (char *)KanjiAreaRecord[ i ].font + ((code - KanjiAreaRecord[ i ].start) * KanjiXSize / 8 * KanjiYSize); break; /*見付かった時はループを抜ける*/ } else ; } if( i != KanjiTnum ) /*コードが見付かった時の処理*/ { /*fontデータのビットを調べて、16bit長のデータに変換して行く。*/ for( i = 0, bmp = font_buffer; i < 16; i++ ) { for( j = 0; j < 2; j++ ) { temp = *ptr; for( k = 0; k < 8; k++ ) { if( temp & 0x80 ) *bmp++ = WHITE; else *bmp++ = DARKBLUE; temp <<= 1; } ptr++; } } /*文字の表示*/ PutPics( pos_x, KanjiXSize, pos_y, KanjiYSize, font_buffer ); str += 2; /*文字列のポインターを進める*/ pos_x += __X_STEP__; if( pos_x >= X_MAX_PIXEL ) { pos_x = 0; pos_y += __Y_STEP__; if( pos_y >= Y_MAX_PIXEL ) pos_y = 0; } } } } } /*********************************************************************************/ /* end of file */ /* designed by hamayan since 2009/05/21 */ /*********************************************************************************/
※補足
呼び出し側も掲載して置きます。
static const char msg[] = "現在2台のPCにARMの開発環境を構築しています。\r\n" "某アプリケーションを試してみようとサンプルプロジェクトをビルドしたのだけれど、ビルドの途中で「そんなオプションスイッチは有りませーん」と怒られて終了してしまう。\r\n" "しかし別のPC上ではちゃんとビルドできている。\r\n" "\r\n" "さて、この2つの違いは、、、開発環境の構築時期、つまり幾つかのツールチェインのバージョンが上がっている事が真っ先に考えられます。\r\n" "\r\n" "引っかかっているコンパイルオプションスイッチはこれ、\r\n"; KanjiPrint( msg );
ARM組み込みソフトウェア入門―記述例で学ぶ組み込み機器設計のためのシステム開発 (Design Wave Advanceシリーズ)
- 作者: Andrew N. Sloss
- 出版社/メーカー: CQ出版
- 発売日: 2007/08
- メディア: 単行本
ARM Cortex‐M3システム開発ガイド―最新アーキテクチャの理解からソフトウェア開発までを詳解 (Design Wave Advance)
- 作者: Joseph Yiu
- 出版社/メーカー: CQ出版
- 発売日: 2009/05
- メディア: 単行本
arm-none-eabi-gccのバージョンアップ [ARM&Cortex-M3]
某アプリケーションを試してみようとサンプルプロジェクトをビルドしたのだけれど、ビルドの途中で「そんなオプションスイッチは有りませーん」と怒られて終了してしまう。しかし別のPC上ではちゃんとビルドできている。
さて、この2つの違いは、、、開発環境の構築時期、つまり幾つかのツールチェインのバージョンが上がっている事が真っ先に考えられます。
引っかかっているコンパイルオプションスイッチはこれ、
-fpromote-loop-indices
ここで入手できるツールチェインの多分最新版のマニュアルを見ると、上記スイッチはサポートされているらしい。
http://www.codesourcery.com/sgpp/lite/arm/portal/subscription?@template=lite
つまりバージョンが4.3.2には無くて4.3.3には存在するスイッチと言う事か。サンプルプロジェクトを作った人はなんて新し物好きなんだか。
古い環境を入れてあるPCに新しいバージョンのインストーラーをダウンロードし、インストール。
無事ビルドが完了しましたとさ。
※メーカー製コンパイラと言う訳ではないので、こう言うトラブルって使っているユーザー同士で情報を持ち合わないと本当に厳しいですよね。