FM3マイコンを使ってみる2
一応ねむいさん的にはChaN氏のFatFsといつものTFT-LCDドライバの実装までを目標と
しています。今回はその中継ぎとしてSTM32F4の時に行ったメモリ構成の決定とFM3の
機能であるMFSを使ったUARTを使った標準関数のリダイレクト、そしてOpenOCDを使っ
たデバッグ環境の強化を行いました。
FM3のシリアル通信はMFSというUART,I2C,SPIの機能を柔軟に切り替えて使用可能な
ユニットを通じて行われます。マニュアルやサンプルコードをざっと見た感じでは非常に
めどそうな設定や操作項目が多い感じでした。
●基本の"き"、UART実装
…と言いたいところでしたがIF誌の特設ページを見るとなんとChaN氏自身がFatFsとシ
リアル通信関連のプログラムをFM3移植されていたのでこれを最大限に活用させていた
だき、まずUARTの環境を拵えました。ChaN氏のUARTのルーチンとはバッファ構成が少し
違っていてXMEGAを触った時に覚えたリングバッファをパクで構成しました。
また、ChaN氏は周辺機器レジスタ定義をFujitsuが提供するCMSISのもの(mb9b610t.h)
ではなく自己生成のパブリックドメインな物を使用されていました。こちらも私の都合で
一部だけ利用させてもらい他はFujitsu製のレジスタ定義にしています。
1文字送信関数は動作したのでお次はprintf系の標準関数にリダイレクトを行いました。
●メモリ構成の決定と標準関数(newlib)のリダイレクト
もう何度も何度も言及していますが、GCC環境でARMを初めて触った人が引っかかるの
はprintf系の関数がビルドできない動作できないという点です。尤も今回のFM3マイコ
ン基板に限ってはIF誌を1章から馬鹿正直読み進めてその通りにしてしまうとLED点滅
すらできず(なんでそうなるかはよく読めばわかります)、人の話を聞かないねむいさんのよう
なタイプの人のほうがさっさと先に進めるというのは何とも言い難いところですが、これは
「本やネットに書いてること鵜呑みにして自分の頭で考えないからそんなくだらない所で
嵌るんだよ」というCQ出版の読者に対する挑戦なのでしょうか?もしそうならカンガルー先輩
を本国から再召還して編集部全員にヤキ入れ直しt済みません話逸れ過ぎました
ぇっとprintfの話でしたっけ、GCCのビルド環境でたとえばSourceryCodeBenchでnewlib
を使うためにはいくつかの未定義の関数をユーザーが定義して紐つける(=リダイレクト)
が必要となります。細かい説明はLPC2388の時と同じです。
前回はLEDの点滅ができる程度で適当に決めていましたがnewlibを使用するにあたって
内蔵SRAMの構成をひとまず下のようにしました。

MB9BF618Tの128kByteあるSRAMのうち0x1FFF0000から始まる64kByteはI/Dコードバスに、
0x20000000から始まる64kByte分はシステムバスに接続されているそうです。
まだ未確認ですがDMACがシステムバス経由でしかやり取りできないっぽいのでDMA用
のRAMを確保するために0x20000000から先の64kByte分はまるまるHEAP領域としました。
この構成はFatFsを積んだときにまた変わるかもしれません。

というわけでUART経由のprintf関数も無事動作。もちろんsprintfやscanf等も使用できます。
UARTに使用されるポートはボリ松拡張基板のUART入出力で使用されるMFS3_2なので、
(FRK-FM3ではCN3の33p&34p)ボリ板でも再現可能です。
ところでmankoiって何ですかって?ぐふふ…
●ioviewを使いOpenOCDからペリフェラルレジスタを参照する
Fujitsuが提供しているレジスタの定義は全てがビットフィールドの定義もなされて
いてフツーにプログラミングする際は便利です(mb9b610t.hのサイズが超でかくなっ
てはいますが)しかし、これをこのままioviewに適用するとunionの数が多すぎるのか
参照した瞬間にinsightやGDBが落ちてしまいました。
やはり地道に一つづつ定義していくしかないのかと思っていた矢先、ChaN氏謹製の
レジスタ定義があるのを思い出しこちらを活用させてもらいました!自動生成されて
いるので一部レジスタの定義が二重になっている箇所がありましたがすぐに気付いて
修正し、mb9bf61x_io_view.cの完成です!

ビット単位の参照が可能なのは現状PDORx系のレジスタのみです。私の動作検証が
進むにつれて主要な物はレジスタのビット参照可能なようにして行きます。
ということで長々とお話ししましたが前回のLED点滅プログラムに+αを加えた物は
すでに更新しています。以前のプログラムを使用してprintfとかしようとした人は
リンカスクリプトがまだ適当だったので多分できなかったと思いますすみません。
また、新井氏(絵描きのaraiさんと名前が被るので混乱を招かないためにこちらの
新井さんは以後漢字記名で統一させていただきます)のSystemCoreClockUpdate()
周りの修正も今回の更新にあたり反映させていただきました。
東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野)
うn、今このページ開いた君が今がっかりしてる理由はわかる。FM3マイコン基板関連
の記事が更新されてると思ったらいつもの写真ベタベタ貼り付けてる東海自然歩道の
クッソ重い記事なんだから。でもこれ単なるハイキングではなくて、れっきとしたGPSロ
ガーの実践動作検証なのは分かる人には分かってくれていると思う(逆切れ)。
そして中部地方ステージ前半の最終区間の記録なのでじっくりと見てほしい。
●2012.03.25 田口〜四谷

さて、今期最終区間の田口〜三河大野を往くわけですが、この区間は一般的に東海
自然歩道の三大難所の一つと呼ばれています。残り二つは丹沢縦走と鍋倉山です。
尤も鍋倉山が難所だった理由は前世紀までは鍋倉山<->池田山の連登ルートだった
からで、野原谷が整備難によって廃され池田山の麓を迂回するルートになってから
は格段に難易度が低下してます。ねむいさん的にはアクセスが非常に悪くなり道も
ガタガタになってしまった鈴鹿峠周辺を新たな難所に推したいと思います。
すみません前置き長すぎましたが名古屋駅から本長篠までは格安で新幹線を利用で
きる新城・本長篠往復切符(新幹線版)を利用しました。新幹線は早いのですがすれ
違い待ちがやたらと多い飯田線が苦痛です...

やっとこ飯田線から解放されたら今度はバスで40分ほど…もうケツが痛いです…
この写真はバスの車窓から取った鳳来寺山門です。かつてはここは田口線の線路
でした。

そして終点の田口バス停に着いたころには雪が!!
三月下旬の忘れ雪ですか…

今回は先にちょっと寄り道をしてきました。以前田口に行きついた時にはスルー
していましたが田口線で使用されていた車両が保存されている奥三河郷土資料館
です。いわばもう一つの三河田口駅です。

車両内は田口線のちょっとした資料館となっています。

郷土資料本館内を見てる時間はさすがに無いので車両だけ見てこの場を去りました。
こんどこそさらば。今回もやはりタイムアタックな山行なのです。

エントリポイントの福田寺に。雪がやむどころかさらに勢いを増してきやがりました。

ルートは田口の街の外周をぐるっと回って和市へと向かいます。
なんか通行止めの橋がありましたが下を通過しクリア。

設楽ダムの"縄張り"が多数ある集落を抜けて和市へ向かう山道へ…!


雪は止みましたが標高が高まってくると今度は積雪が目立ってきます。
ルート上で一番高くなる地点で池葉守護神社に。ここからまた下って
いきます。

和市のバス停の分岐に。ここから先は岩古谷山への本格的な登山道になります。

十三曲がりと呼ばれる九十九折りの道を越えて堤石峠に。こっから先、非常に
過酷な岩尾根の縦走ルートになります!!

標高高くなるとすぐに雪が目立ってきましたが私まだこの地点では冷たい風雪に叩
かれつつも"あれ余裕じゃん"と思ってました…が!

この木組のスロープがまぢでやばかったです。晴れで乾燥していたら大したことは
無いはずですが、この日は雪解けが再び凍りつき踏ん張ろうにも踏ん張れません
また左側面の岸壁も微妙に隙間ができており寄りかかりながらの通過もできません!
このスロープは岩肌の側面に巻きつくように付いており、万が一落ちたら確実に
死にます。それでも私は勇気を絞って右側の金属の柵に自分の運命を細腕に全力を
こめて一歩一歩確実に歩を進mズルッ
ひぃゃあああぁAあaaぁあああああぁあぁぁぁ!!

まぁでもこのブログ書いてるってことは滑ったけど落ちずに無事生還したってこと
ですね。残念でした!
と悪態付きつつもさらに難関は続きます…この季節に強い風雪くらうとは思っても
みませんでしたが、堤石峠で前もって体幹に新聞紙を巻きつけて対策しておいたので
トレランの軽装備ながらも体温の低下は避けられました。

岩古谷山の頂上に到着です…天気がいい時はここは絶景の場所で、ネット上の登山記
を散見すると年配の夫婦もダブルピースで写真を取られてたりしてますが私はとても
じゃないけどそんな余裕ありませんでした…
早く岩尾根群を越えないとゴールの滝上バス停の時間に間に合わない!

この階段の奥に昔使われていた梯子みたいな角度の旧階段があります。
ねむいさんは高所恐怖症なので視界に入れないようにしました。



なおも続く岩岩岩
雪で滑らないようにヤモリのようにへばりついて黙々と進んでいきました!

障子岩と呼ばれる地点に。ここまで来たら鞍掛山の頂上まであと少し!!!

っ着いた―!!!鞍掛山の頂上に到着です。
実は私は和市からここまで新しい足跡をずっと追いかけてきていたのですがここで
足跡の主の方たちに追いつきました。

ここから先は岩尾根から解放されひたすら下山のルートとなります。雪がところ
どころ残っているので慎重に下りました。


下るにつれ雪も無くなり道も走りやすくなってきたのでかしやげ峠を越えたら
さらに駆け下りるスピードを上げていきました!

山道を抜けると一気に視界が広がり棚田が見えてきました。四谷の千枚田です。

アスファルト舗装された車道を駆け下り、仏坂峠への分岐で東海自然歩道から
離脱しました。次回のエントリポイントはここです。ただ、最寄りの公共交通
機関である滝上バス停まで5km以上あります。


時間も依然としてやばいです。15:19のバスを逃すと次は18時台(最終)。
急いで駆け下りないと…いいつつ僅かな時間を見つけしっかり千枚田の
下部ビューポイントから棚田と鞍掛山の姿をデジカメに収めました。


ひたすら車道を走る!!下りだからまだ楽ですが次回はここを登りなので今か
ら非常に気が重いです…と思慮にふけってるうちに大きい道路の交差点に出て、
滝上バス停に到着しました…間に合った…!

悪路な上に時間にも追われる厳しいルートである田口〜三河大野の前半でしたが、
何とか予定通りにクリアできました。
●2012.04.01 四谷〜三河大野

今期ラストとなる山行です。奮発してミューチケット買って名鉄で豊橋に。


前回と同じく豊橋から飯田線天龍峡行きに乗って本長篠に、さらにそこから
豊鉄バスで滝上へ…。

ご多忙に漏れず今回も帰りの飯田線に乗るための時間制限があります。
事前調査では17時には三河大野駅に着かないと次の電車は19時台になってしまい、
またまた帰りが超遅くなってしまいます…そして今回も岩尾根を進むコースで
ゆうに7時間ほど掛るらしいとのこと…。そこで私はルートの最初と最後にある
走りやすいアスファルト道を全力で走り一気に時間を稼ぐ作戦を立てて実行しました!
というわけで写真はその道中にある馬頭観音の説明板。


走って走って千枚田下部ビューポイントに到着。前回は車道を走り降りましたが、
今回は千枚田の男坂一本道を駆けあがっていきます!



千枚田の春はまだ先のようですね〜

さらに車道と合流し駆けあがって東海自然歩道とのエントリポイントに。

さらにさらに駆けあがって仏坂峠トンネル手前の登山道に!!…はぁはぁ…
でも予定時間を45分早めることができました♥

少し水分を取った後仏坂峠に。実は前回の鞍掛山からここまで千枚田を経由せず
直に来られたのですが現在はご覧のとおり崩壊しています。

急な山道をさらに登って行って海老峠に。しかしもっと登ります!

道が少しなだらかになったところで宇連山の分岐に出ました。もうこの
時点で17時の電車に間に合うほど時間を切り詰められて余裕ができたので
宇連山の頂上まで行きました。


宇連山の頂上です。

宇連山分岐に戻りどんどん下ると林道に。

大島の滝を越えたところで人間の建造物もちらほらと。


正体は棚山高原のバンガロー村の跡地です。いかにも豊かで日本がまだ元気
だった昭和中後期に出来た夢の跡って感じですね…ていうか東海自然歩道自身も
最初は土建屋さn達がうっはうはのバブリーな…


ゲフン…他の方のレポートによると、この今にも崩れそうな詰所には確か描き置き出来る
ノートがあったはずですが…ありました!
しかも数日前の書き込みまである!もちろん私も書いていきました。


さて、ここから先は再び厳しい岩尾根の道になります。標高は下がるのですが
道は遥かに険しくなります。

玖老勢峠に到着。少し小休止。


この日は前回と打って変わって晴れていてよく乾燥していたので
岩場も難なく攻略できました!

この犬戻りって書いてある個所の次の急坂がめっちゃきついです‥。



クロ岩に到着。前回と同じく岩岩岩の連続。


瑠璃山とそこからの絶景です。ここまでくれば鳳来寺山山頂まであと少し!


道の岩肌が少なくなったところで鳳来寺山山頂についに到着しました!



お次は本堂を目指して奥の院から下りていきます。途中でカラフルな登山の
格好をした人たちにも多数すれ違いました。



本堂と徳川家康が祀られているとされている東照宮です。


東照宮にあるわき道から鳳来寺パークウエィを越えて行者越に
ここからは下り一辺倒となります。


湯谷峠を越えて山道をずんずん駆け下りていくとだんだんと走りやすい
道となりアスファルトに変わったところで集落に出ます。

飯田線を一度横切りますが、正規ルートは豊橋方面とは逆方向に進路を取ります。


宇連川に掛るつり橋と荒沢不動明王です。痛恨のピンボケorz

荒沢不動明王を出て国道と合流したこの地点で東海自然歩道と離脱します。
11月から再開した時はここがエントリポイントとなります。


国道を南下して大野橋で宇連川を渡り返し、今期のゴールである三河大野駅に
ついに到着です!!スタート時の到着目標時間は最低17時5分でしたが最終的に
16時台発の飯田線に到達するかの時間(16:22)まで大幅な短縮を達成しました!

後はゆっくりと着替え身支度をして駅周辺を散策した後に17時台発の飯田線に
ゆられて豊橋(から京都に)帰りました(BGM:飯田線ブルース)
というわけで最後までギリギリでしたが今期で中部地方の前半となる岐阜・愛知県内の
ルートをほぼすべて走破しました!続きは気温が低くなる11月からの再開となります。
それまでは私事も相まってトレランのような大きな負荷がかかる運動はお休みとなります。
しかしながら、山"歩き"くらいはできるので京都周辺の山を現在も歩き回っています。
田口〜四谷 GPSログ

四谷〜三河大野 GPSログ

おしまいっ
…といいたいところですが実は岐阜県内にあと1ルート残ってるんですよね…gff
FM3マイコンはぢめました

富士通製Cortex-M3なARMマイコンのFM3シリーズであるMB9BF618T。これが実装された
付録基板が付いているInterface誌6月号の明日の販売を控え、帰宅途中に"たまたま"ふらっと
寄った新大阪の某所で売られていた6月号を購入しさっそく基板を動かして見ました。

…なんかねむいさん変てこりんなこと言ってるような気がしますが多分気のせいです。
あと国産マイコンは絶対に扱いませんといっときながらFM3は使うのかという突っ込
みに対しては中身は英国製ARMコアなのでノーカウントとさせていただきmasu!
…さて戯言はこの辺にして、今年1月ごろにはすでに基板に関する情報が出回っていた
ので先回りしてデータシートやマニュアルを熟読しSystickを使用した簡単なプログラム
を作成、いわば予習はすでに行っていました。
とはいえそれ程仰々しいものでもなく、最早慣れ親しんだCortex-M3だったのでLPC1343
とSTM32F107の物をベースにしたスタートアップコードやデータシート首っ引きでリンカ
スクリプトをこしらえGCCでビルド・デバッグ出来る物をサクッとやっけつました。
正直LPC1788の時の方がむずかしかったです。
そしてビルドして出来たバイナリをMB9BF618Tに書く手段ですが‥‥、これが都合よく少し
前にOpenOCDにFM3マイコンのフラッシュ書き込みルーチンが実装されていました。
なおかつjujurou氏が別型番のFM3マイコンにてOpenOCDからの書き込み・デバッグを
した時の成果をすでに残されていたのでこちらもありがたく使わせてもらい、MB9BF618T
のフラッシュ書き込みにも対応したOpenOCDを作成し、万全の体制で今日を迎え撃ちました。
で、結果ですがOpenOCDからプログラムの書き込み・デバッグに無事に成功しました!

↓書き込み時に出るOpenOCDのメッセージはこんな感じです。
> "C:¥Devz¥AVR¥WinAVR¥utils¥bin¥make.exe" program
openocd -s C:/Devz/ARM/OCD/tcl -f interface/jtagkey2.cfg -f target/mb9bf618t_flash.cfg -c "mt_flash main.elf"
Open On-Chip Debugger 0.6.0-dev-00527-gf908bae-dirty (2012-04-24-21:47)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
trst_only separate trst_push_pull
500 kHz
cortex_m3 reset_config sysresetreq
verify Capture-IR is disabled
Info : device: 6 "2232H"
Info : deviceID: 67358712
Info : SerialNumber: 22222222A
Info : Description: Amontec JTAGkey-2 A
Info : max TCK change to: 30000 kHz
Info : clock speed 500 kHz
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : mb9bfxx8.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000114 msp: 0x20000000
auto erase enabled
Info : Fujitsu MB9Bxxx: Sector Erase ... (0 to 0)
Info : Fujitsu MB9B500: FLASH Write ...
wrote 16384 bytes from file main.elf in 2.046889s (7.817 KiB/s)
verified 804 bytes in 0.421877s (1.861 KiB/s)
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
shutdown command invoked
MB9BF618T向けのOpenOCDスクリプトはまだPLLでクロック上げておらずリセット時の…ぇ?俺も早くOpenOCDビルドして試してみたいですって?
内部発振4MHzで動いてる状態です。今後クロックアップさせる予定なのでもう少し
使い勝手が良くなるでしょうね♥
…ふっふっふ、とっくに対応済ですよぅ?
という所で本日試したPORTF3にぶら下がったLEDを点滅するだけのものすごく単純な
FM3基板(FRK-FM3でしたっけ)向けのGCCでビルドできるプログラムはこちらに。
また、↑をビルドするための超分かりやすいビルド方法はこちらになります。
そうだね宣伝d(ry
今はLED点滅だけですがこれにUART経由の文字列出力等の基本的なのを順次アップ
デートしていきます。私はSTM32F4弄るのがメインなのでFM3にはそこまで興味は
無く、予定は大幅に伸びるでしょうけども6月の半ばにはいつものがおきぱに現れ
て皆が利用できる状態になるとおもいます。
20120425追:
●OpenOCDからのフラッシュ書き込み速度をアップさせる試み
system_mb9bf61x.c内のSystemInit(でしたっけ?)関数のPLLを使ってクロックアップ
しているルーチンをOpenOCDのスクリプトに落としてみました。
ただし、汎用性を保つために大元のメインクロックは外部のシリコン発振器からの4MHz
ではなく内部RC発振の4MHzを使用し叩きあげるようにしました。
↓で、こちらが昨日と同じバイナリを書き込んだ結果です。
> "C:¥Devz¥AVR¥WinAVR¥utils¥bin¥make.exe" program
openocd -s C:/Devz/ARM/OCD/tcl -f interface/jtagkey2.cfg -f target/mb9bf618t_flash.cfg -c "mt_flash main.elf"
Open On-Chip Debugger 0.6.0-dev-00529-gf28a5d9-dirty (2012-04-25-13:27)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
trst_only separate trst_push_pull
500 kHz
cortex_m3 reset_config sysresetreq
verify Capture-IR is disabled
Info : device: 6 "2232H"
Info : deviceID: 67358712
Info : SerialNumber: 22222222A
Info : Description: Amontec JTAGkey-2 A
Info : max TCK change to: 30000 kHz
Info : clock speed 500 kHz
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : mb9bfxx8.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000114 msp: 0x20000000
Rize up to Internal PLLed Clock!
6000 kHz
auto erase enabled
Info : Fujitsu MB9Bxxx: Sector Erase ... (0 to 0)
Info : Fujitsu MB9B500: FLASH Write ...
wrote 16384 bytes from file main.elf in 1.671886s (9.570 KiB/s)
verified 804 bytes in 0.421878s (1.861 KiB/s)
Info : JTAG tap: mb9bfxx8.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
shutdown command invoked
wrote 16384 bytes from file main.elf in 2.046889s (7.817 KiB/s)
だったのが
wrote 16384 bytes from file main.elf in 1.671886s (9.570 KiB/s)
と結構改善してます。比較元のサイズが小さいので分かりにくいですが、バイナリのサイズ
がさらに大きくなると違いがさらに出てくることでしょう。
もちろんこちらにも反映済みです。
●毎年恒例の電源ラインは大丈夫か?
※使用したもの
・PCのUSBポート
・Interface2012年6月号付録のFM3マイコン基板(LED点滅書き込み済み)
・5mのUSBA-miniBケーブル+1mのUSB延長ケーブル
・テクトロのオシロ
※USBコネクタを指してPCのUSBポートから+5V電源を供給した時の+5Vラインと
レギュレータ出力の+3.3Vラインの電圧波形を見る

+3.3vの立ち上がり時に+5Vラインが一瞬突入で1Vほどドロップしてるけど
以前みたく上に跳ねてはいないので基板単体で見たら大丈夫だ、問題無い。
※144MHzで動作中の時の+5Vラインと+3.3Vラインの電圧波形を見る

大丈夫だ、問題無い。
※USBコネクタをPCのUSBポートから引き抜いて+5V電源を断った時の+5Vラインと
レギュレータ出力の+3.3Vラインの電圧波形を見る

大丈夫だ、問題無い。
※総評
大丈夫だ、問題無い(イーノックみたいな顔で)
…ってねむいさんが太鼓判押したら大抵悪いこと起きるんですよね〜
STM32F4シリーズを使ってみる5 -libpngを実装する-

誘惑に負けて買ってしまった…盈钰電子のSTM32F4ボード…
176pinなSTM32F407IGT6,1MBSRAM,NAND&NORFlash,HS-USBPHY,Ethernet,I2SCodec,camera....
そして3.2inchのTFT-LCDまでついてオトクな699RMB!
日本円単純換算でも10000円以下の超格安です(2012/5上旬現在)
本来ならばREDBULLの基板をベースにやるべきですが費用対効果が最高なので購入した
方が早いっちゅーことで…しかもSTM3240G-EVALの回路にほぼ互換なのでSTさん提供
のサンプルなんかもほとんど素で動かせられますのでこいつでいろいろ学習していきましょ♥
だめだ私すっかりSTM32漬けだ…
さて、前回さらっとご紹介しましたが、libpngのSTM32F2/4への移植についてお伝え
します。私たち虹メにとってpng形式の画像ファイルはコラ等で非常に身近なもので、
jpeg形式と同じく大量に扱われています。それをマイコンでデコードし表示できる
というのはとても有用性があるわけで、かねてからの悲願がかなった形でもあります。
今回は実際の移植の手順も合わせてご紹介します。
●必要なもの
libpng
これは必須ですね。少し前にlibpngのセキュリティホールが発見されているためバー
ジョンには気を付けてください。今回は"libpng 1.5.10"を使用します。
zlib
pngファイルの実画像データは可逆圧縮されていてDeflateと呼ばれる圧縮技術が使用
されています。libpngはDeflateアルゴリズムを処理するためそのライブラリである
zlibの一部コードを必要としています。今回は"zlib 1.2.6"を使用します。
MCU
libjpeg(IJG Jpeg Library)と同じくlibpngはRAMを大量に消費します。
内部SRAMが96kByte以上あるマイコンならQVGAサイズまでなら何とか表示可能です。
●ファイルI/O
こちらはlibjpeg(IJG Jpeg Library)と同じ要領でChaN氏のFatFsと連動させます。
sirius506氏、そら。氏のlibjpegの移植例を参考にしています。
実際にどうやってるかは私のサンプルの./lib/display/abstract/src/ts_fileloads.c
にあるload_png関数の上にあるfatfs_read_data()を読み進めてください(丸投げ!)
●makefileに追加するCソースファイル
こちらのSTM32F4サンプル中にあるlibpng.mkを見ていただければわかりますが、
pngファイルの読み取りのみに限ると以下のファイルだけが必要となります。
-libpng
png.c
pngerror.c
pngget.c
pngmem.c
pngpread.c
pngread.c
pngrio.c
pngrtran.c
pngrutil.c
pngset.c
pngtrans.c
上記のうちpngerror.cは一部内容の書き換えが生じます(後述)
-zlib
adler32.c
crc32.c
inffast.c
inflate.c
inftrees.c
zutil.c
ヘッダファイルの方については念のためオミットせずに全部ぶっこんどいてください。
また、libpngを解凍したディレクトリ中の./scripts/pnglibconf.h.prebuildをリネ
ームしpnglibconf.hとしてソースと同じディレクトリにぶっこんでください。
●ARMマイコン上で動作させるための少しの変更
x86なWindowsシステムで動作させるわけではないため、エラー表示などのコンソール
I/Oの処理のオミットは必須です。
pnglibconf.h中のPNG_CONSOLE_IO_SUPPORTEDとPNG_STDIO_SUPPORTEDの定義は
コメントアウトしておき、さらにpngerror.c中のpng_default_error関数はfprintfから
printfに変えておきます。
(printfのリダイレクトが必要無い場合はすっからかんでもいいです)
ねむいさんの環境では書き換えたファイルはpngerror_std.cとしています。
また、txtとハードウエアの倍精度浮動小数点演算、インターレースのサポートも
行わないのでpnglibconf.h中の以下の定義もコメントアウトです。
PNG_READ_INTERLACING_SUPPORTED
PNG_FLOATING_ARITHMETIC_SUPPORTED
PNG_WRITE_zTXt_SUPPORTED
PNG_WRITE_iTXt_SUPPORTED
PNG_READ_zTXt_SUPPORTED
PNG_READ_iTXt_SUPPORTED
PNG_zTXt_SUPPORTED
PNG_iTXt_SUPPORTED
元からコメントアウトされていたものについてはそのままにしておいてください。
さらにpnglibconf.h中のZBUFFERの確保量(PNG_ZBUF_SIZE)をSDカードのセクタサイズで
ある512バイトに合わせてください。これ以上の値にすると512バイト以上読み込んだ際
にエラーになってしまいデコード不可能になります。
残念ながらlibpngにはlibjpegのような1/(2^x)にするサイズスケーリングはないようです。
●libpngを呼び出し、画像データを表示する
大まかに分けて以下の順番で実行します。これらは必須です。
1.png_create_read_struct関数でpngファイル全般を制御するポインタ確保
2.png_create_info_struct関数でpngファイルの情報に関するデータをストアする
ポインタ確保(IHDRとIENDチャンクの分)
3.エラーハンドリングの設定
4.png_set_read_fn関数でfatfsのpngファイルポインタと連結
5.png_get_IHDR関数でIHDRチャンクの読み出し
6.画像の形式を24bitRGBに変換する。
7.画像のx,yサイズのチェック(1280pixel以上は撥ねる)
8.png_get_rowbytes関数で1行あたりのバイト数取得
9.png_malloc関数で"6."で取ったバイト数分の配列確保
10.png_read_row関数でIDATチャンクを一行ずつ読み出し、さらにRGBデータ幅を24bit->16bit
に落としてTFT-LCDに表示していく
11.表示が終わったらpng_free関数"7."で確保した配列を解放
12.png_read_end関数でIENDチャンクを読みだす。
13.png_destroy_read_struct関数で"1.""2."で確保したポインタの解放
気を付けなければならないのは各処理ごとにエラーを検知しておかしい場合は先の
処理に進ませないようにすることです。これを怠るとHardFaultに簡単に陥ってし
まいます。またIDATを読み切ってない場合にpng_read_endを実行すると即座にエラ
ーになりますのでTFT-LCDの解像度より画像サイズが大きい場合でも必ず空読みして
読み切ってください。この手順は24bitのpngを想定していますが異なる形式の場合は
24bitに変換するために"5.""6."の間に各種transformの処理が必要です。
実際にどうやってるかは私のサンプルの./lib/display/abstract/src/ts_fileloads.c
にあるload_png関数を読み進めてください(丸投げ!)
一回の表示で消費されるRAMはlibpng自体が必要とする量が約33kByte(デバッガの
追跡により使用量を算出),それに加えてTFT-LCDに表示する際のデコード済みの
データを置くバッファも必要とされるため結局以下の計算式で総消費量が求められます。
NEEDED_RAM_AMOUNT = ((XSIZE-1)*4)Byte+33kByte
式中のXSIZEはTFT-LCDのX軸方向最大ピクセル数ではなくpng画像データのX軸方向最大
ピクセル数です。つまり幅が広くなればなるほど使用するRAMの量が増えます(libjpegも
この点は同じ)。また、今回のデモはアルファチャンネルを強制付与しているため(RGBAの
ならびになるため)(XSIZE-1)*3ではなく((XSIZE-1)*4)になります。
●実際の表示

今回の検証用のTFT-LCDとして320x480なTFT1P2797-Eを使用します。大規模マイコン
用のディスプレイとしてねむいさんのイチオシです♥

検証用の画像はこれ。こちらのサイトのキャラクタージェネレーターを使って作成した画像に
さらにコラージュを加えた私服のいないさんです。メイド服にコラしたかったのですが髪型
だけで力尽きましたorz…これをTFT-LCDに表示してみます。ビット深度は24bitのトゥルー
カラーです。
表示ルーチンとしてまず画面左上に画像の情報を出すようにしました。
col_depthはビット深度で8*(RGB)で上記の24bitとなります。
col_typeはpngの画像タイプで0がグレイスケール、3がインデックスカラー、
2がトゥルーカラー、6がアルファチャンネル付トゥルーカラーです。
実際の表示に関し、グレイスケールやビット深度が小さい画像も24bitに変換してい
ます。また透過pngやアルファチャンネルつきの物はいったんアルファチャンネルに
変換して、1ピクセルごとのアルファチャンネルを示すバイトは書き込み時に無視して
います。インターレースpngの表示はは私のサンプルではサポートしていません。
誰か腕に覚えのある方実装おねがします…。

てわけでPCとまったく遜色ないレベルでいなちゃんを表示することができました!
メモリが豊富な環境ではpng_read_image関数で一気に読み込みできるのですが、STM32
等のマイコンでは到底足らないので、1行ずつバッファに読みだして表示を行います。
読みだしたデータはRGBの順番で並んでいて8+8+8=24bitで1ピクセルとなっています。
最終的にTFT-LCDにはビットシフト演算で5+6+5=16bitにして書き込み、表示させます。

透過PNGを表示させるとこんな感じになります。前述の通りアルファチャンネルは
読み捨ててるので透過部分はRGB(0,0,0)の黒色で表現されています。また解像度の
関係で表示が隠れてしまったのですが、アルファチャンネル付トゥルーカラーに
変換された透過pngを示しています(赤で囲った部分)。

TFT-LCDのサイズよりオーバーする場合の画像では当たり前ですが画面外のデータは
表示できません。また画面からはみ出ている部分もpng_read_rowで全部読み切ってし
まわないとエラーになったりHardFaultに陥ってしまうので注意です。
ChaN氏のbmp表示ルーチンを見習って大きい画像でもUARTからのコマンドで仮想的な
表示開始位置を変えて表示できるようにするのが今後の課題ですね〜
ちなみのこのaraiさんの描いたねむいさんの絵はアダルツなのでこのブログ的にも
見えてない部分は…ゲフンゲフフン失礼
減色とかグレースケールにした時の比較です(注:表示の際はすべて24bitのトゥル
ーカラーに変換されています。左上の数値は変換前の情報です)。

ビット深度24bitトゥルーカラーの標準的なねむいさんです。
col_depthが8になってますが実際は8bit*3で24bitとなります。

256色のインデックスカラーはこんな感じに。

24bitのグレースケールはこんな感じ。

8bitに落とすとこんな感じ。

さらに4bitに落とすとこんな感じです。
というわけで通常のPCと同じようにpngファイルの表示もSTM32F4上で可能となりました。
しかしながらメモリはかなり食いますので内蔵SRAMが豊富にあるSTM32F4専用の機能で
すね〜。libjpegと絡めるとあいた時間でお茶が飲めてしまうくらいビルド時間も倍加されて
しまいますのでご注意を。

連絡・質問は↑のリンクに
クリックしてくだち!
- ARM/STM32 (53)
- ARM/Atmel (1)
- ARM/Fujitsu (2)
- ARM/NxP (19)
- AVR/ATXmega (4)
- Lattice (4)
- MISC (21)
- おきぱ (1)
- 無謀 (18)
- FM3マイコンを使ってみる2 (05/13)
- 東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野) (05/03)
- FM3マイコンはぢめました (04/24)
- STM32F4シリーズを使ってみる5 -libpngを実装する- (04/15)
- FM3マイコンを使ってみる2
⇒ jujurou (05/20) - 東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野)
⇒ ねむい (05/13) - 東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野)
⇒ ひかわ (05/13) - 東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野)
⇒ ねむい (05/11) - 東海自然歩道を徃く16(田口〜四谷/四谷〜三河大野)
⇒ がた老 (05/09) - FM3マイコンはぢめました
⇒ ねむい (04/30) - FM3マイコンはぢめました
⇒ 竹本 浩 (04/29) - FM3マイコンはぢめました
⇒ ねむい (04/28) - FM3マイコンはぢめました
⇒ 竹本 浩 (04/26) - STM32F4シリーズを使ってみる3 -FatFsと下部レイヤ(SDIO・MMC)ドライバたちの実装-
⇒ ななし (04/26)
- May 2012 (2)
- April 2012 (3)
- March 2012 (2)
- February 2012 (3)
- January 2012 (3)
- December 2011 (5)
- November 2011 (3)
- October 2011 (2)
- September 2011 (2)
- August 2011 (2)
- July 2011 (2)
- June 2011 (2)
- May 2011 (2)
- April 2011 (2)
- March 2011 (2)
- February 2011 (2)
- January 2011 (3)
- December 2010 (7)
- November 2010 (1)
- October 2010 (1)
- September 2010 (1)
- August 2010 (3)
- July 2010 (4)
- May 2010 (1)
- April 2010 (2)
- March 2010 (2)
- February 2010 (2)
- January 2010 (3)
- December 2009 (3)
- November 2009 (8)
- October 2009 (7)
- September 2009 (5)
- August 2009 (4)
- July 2009 (6)
- June 2009 (6)
- May 2009 (14)
- January 1970 (1)
Copyright(C) B-Blog project All rights reserved.
