STL vector の事、BMP PNG JPEG

色々動くようになって、では、そろそろ自分フレームワークをコンパイルしようかと思い、進めてみたものの、基本的部分が動かない・・

調べると、STL vector が死ぬ!

こんな簡単なプログラムを作ると、死んでしまう・・・

std::vector pad;

pad.push_back(1); // ---> 死ぬ!

又、

pad.resize(10); // ---> 死ぬ!

一方、

std::vector pad(10);

とかで、初期化段階でサイズを指定すると、使える。

基本的に、KPIT v10.02 の C++ ライブラリーにバグがあるとしか思えないが、こんな基本的なとこで死ぬのはおかしい??
多分、vector のアロケーターに SH2 で不味いコードが含まれているのだと思われるが、KPITのソースコードをダウンロードして不具合を見つけるのは、ちょっと骨が折れるので、とりあえず放置状態であるが、一応、KPIT にバグレポートを送った。

gcc のツールチェインを自分で構築してみようか・・
※時間と手間がかかるので余りやりたくない。

-----
そんで、vector が動かないと自分のフレームワークも全滅と思うが、画像操作系など、コンパイルだけはしてみた。

それに先だって、基本のライブラリー、Z、PNG、JPEG ライブラリーをソースコードからコンパイルして、ライブラリーを作ってみた。
この手の汎用ライブラリーは、configure によって開発環境の状態を取りこむのだが、クロス環境で自動で行うには、configureを改造する必要がある為、手作業で作ってみた。

それで、jpeg ライブラリーを使って純粋に C のコードで簡単な読み込みを書いて、テストしてみた。
SH-2AにはFPUが入っているハズだが、思った程高速では無い・・・
FPUを使う為におまじないが必要なのかもしれない・・

見た目では分からないけどJPEG画像を表示させてみたー

アーカイブにライブラリーなどをアップしておく。
PNG はテストしていないが、動くと思う。
※BMP のデコードは C++ のコードなので、vector 待ちです。

しかし、vector が使えないのは痛すぎる!

ソフトウェアー・アップデートなど

syscalls API の実装も進み、何とか普通に使えるようになってきた。

シリアルコミュニケーションインターフェースの API は、雑誌の記事にあったソースコードをコピーしたものだったので、全面書き換え、元々ポーリングだった動作を、送信、受信割り込みに変更した。
これで、パフォーマンスはある程度期待できると思われる。

SH72620 では、シリアルインターフェースは16バイトの FIFO 付きなのだが、16バイトでは少なすぎるので、ソフト処理で FIFO を実現している為、バッファサイズはいくらでも大きくできる、パフォーマンスはハードで処理するFIFOよりは悪いと思うが、まぁそれでもポーリングよりはずっと良いと思っている。

暇になったら、DMAC を使ってみたい~

-----
AVR の RTC だが、低消費な V タイプでは無いが、結構電気食う。
やっぱ 4MHz で動作させてるのが悪いと思うが、クロックを落とすと、通信の速度が出ないと思うので、4MHzとしたのだが・・
※4時間くらいのバックアップで 0.1V も落ちてるし・・・(涙)
この感じでは、実用性に問題あるかも・・
少なくとも、6ヵ月くらいはバックアップ出来ないと・・
※まぁ色々試せるのが試作ならではだしね・・
※I/Oプロセッサーの考えは悪く無いしね・・
雰囲気としては、AVR にさらに RTC を接続するとゆー本末転倒な事になりそう(笑)まぁ でもI/O プロセッサなんでー

-----
インクルードガードの話:
インターフェース誌のサンプルプログラムとか、色々観たけど、サンプルとは言え、品質が良くないなぁと感じる。
※いいかげんな書き方や、厳密では無い書き方が、あちこちに観られる。
※FatFsは「ELM」さんの実装だが、これはプロダクトとしては非常に考えられていて良く出来てる~
http://elm-chan.org/fsw/ff/00index_j.html
素晴らしい~(ありがとう~)

さて、本題!、良くヘッダーを多重にインクルードしないように、インクルードガードを書くけど。

#ifndef XXX
#define XXX

・・・

#endif

この「XXX」で、みんな、こんな書き方をしてる、ファイル名が、「init.h」なら、「__INIT_H__」とか・・
このアンダースコアーをダブルで加える書き方は、システムライブラリーなどで予約された書式なので、アプリケーションレベルのソースコードには書いてはいけない。
この事実を知らない人が多いようだ・・・

あと、プロトタイプの宣言でも、C++ から呼べるように、数行加えておいて欲しいものだ・・

加えて、API の説明や引数、戻り値の説明も書いておいて欲しい。
※自分のソースコードでは、Doxygen で展開すると幸せになれるようになるべく記述してる。

基本の「const」も必要なら、ちゃんと書こう!
※それだけで、バグを減らせるのだから。

困った時の AVR

コンパクトなシステムを作るには AVR は最適です。

C 言語(gcc)でプログラム出来、高速で安くて、使いやすい。

たとえば、LED の点滅を考えても、タイマーIC 555でやるより、ATTINY2313 とかの方が安くてプログラマブルです(笑)

今回、SH-2Aで、バックアップ可能な RTC をどうするか色々考えました、秋月とかで入手できる、RTC でも良いのですが、どうせなら、変わった事がしたいので、あえて、AVR を RTC として使う事にしました。

SH-2Aとのインターフェースは、シリアル TXD、RXD を使い、インテリジェントな I/O プロセッサとして機能するようにします。

RTC の他、AVR 内臓の EEPROM を利用する事で、オドメーターの保持などにも使い、12ビットの A/D も欲しいので、その変換なども受け持たせる予定でいます。
今回、仮に ATMEGA88 でやってますが、もっと PIN 数が多くて高機能なデバイスでも良いかもしれません・・
※ATMEGA88 は秋月で230円です。

AVR-RTC モジュール

AVR-ISP 接続した様子

AVR-ISP は以前に作ったものですが、まだまだ使えます~

syscalls の実装

現状2010年8月8日のアーカイブで、時間関係を除いて、syscalls 関係の実装がだいぶ進みました~

printf、fopen、fclose、などなど、通常のファイル読み込みと書き込みは出来るようになってます。
※時間関係ハードが無い為、書きこんだファイルは、2008-1-1、0:0:0になります。

本当は、テストプログラムを一通り作る必要があるのですが、簡単なテストのみで済ませています。
※「mainloop.cpp」にある。
なので、まだバグを含んでいると思います、何か不具合があれば、この BBS に書き込んで下さい、対応したいと思います。

そろそろ、C++の自分フレームワークをコンパイルして組み込もうかと思いますが、RTC が先ですかね・・・
RTC は、ほんとどうしようかと思います・・・

SH72620 のハードウェアーマニュアルを読んだけど、RTCのバックアップ動作に関しての項目を見つけられませんでしたが、内臓RTCはバックアップは考えられていないのでしょうか???
でも、そんなの意味無いですよね。

前から思ってたのですが、RTC って、なんでハードロジックで全て構成するのが多いのか、ただのバイナリーカウンターだけで良いと思いますが・・・

マキシムのRTCには、32ビットのバイナリーカウンターだけで構成されたRTCのデバイスがあるようですね、チップワンストップとかでも購入できるので買ってみようかと思ったけど、電圧タイプが不明なんで(1.2V、3V、3.3V仕様などがある)スルーしました。

次にちょっと考えたのが、AVRなどのワンチップマイコンを使って、RTCのバイナリカウンターを構成する試みです、これはアイデアとしては、前からありましたが、消費電流がどのくらいで、3Vのリチウムボタン電池でどのくらい持つものなのか・・
SHとのインターフェースとか、解決する事も多いですけどね・・
値段としては、100円のマイコンなんで、コストは安いですよね、秋月のRTCは500円しますから(笑)

aitendo のキャリーボードの事

aitendo の液晶キャリーボード、確かに便利で安いし、あれば重宝する事間違い無しなのだが、色々問題もある。

1)LEDバックライト用のDC/DCコンバーターに問題あり
・電流の大小で明るさが変化するLEDデバイスに対して、定電圧の回路になってる。
この液晶のバックライトは、白色LEDが6個直列に接続されたものみたいなので、23Vなら、妥当な値かもしれないが、バラツキで高い電圧が出て、LEDを壊す事が無いよう、パターンを切って、直列に抵抗を入れておいた、大体100オームくらい入れておいたが、もう少し少なくして明るくしても良いかもしれない。
・回路図では、出力側に、22uF、0.1uFのコンデンサが入っているようなのだが、この表面実装部品、ほんとに22uFもある?って感じで、実際、電源入れると、安定しない(寄生発振してるようだ)、コイルやダイオードが凄く発熱する。
そこで、並列に10uFのコンデンサを入れてみたら、安定した。

2)液晶モジュールのロジック電源がいいかげん過ぎる
・この液晶モジュールは2.5V~4.5Vまでの定格なのだが、この基板では、LCD-POW(自分は5Vで使っている)から、抵抗を直列に入れていきなり繋いである。
ロジックは3.3Vなので、この抵抗を外して、3.3Vの電源ラインを繋いでおいた。
※LCD-POWERは3.3Vで使うものなのかもしれない・・

DC/DC クローズアップ

以上の改修で、問題無く使えるようになっている。

3)コネクターのピン名の不思議
・この拡張ボードで、ピンの名前として、R0~R7、G0~G7、B0~B7と、RGBの8ビットぽくネームが振られているが・・・
LCDのモジュールとは、まるで、イジワルしてるかのように接続されている・・・・・
「R0~R7」は赤ではなく、青へ、「B0~B7」は青では無く、赤へ、つまり、赤、青が逆になっていて、さらに、LSB、MSBも逆になっている。
なんで、こんな余計な事するのか、不思議でならない・・・
※はい、これを知らずに、間違った結線しましたよ・・・

4)RGB565からRGB888への拡張
・この液晶、RGB888で1600万色フルカラー対応なのだが、SH-2Aは16ビットカラー出力(RGB565)なので、5ビットを8ビットへ、6ビットを8ビットに拡張する必要がある。
その拡張は、上位ビットをそのまま下位ビットに順番に繋ぐだけなのだが、思いついた時には、クールだと思った(笑)
キャリーボードには、2.54ミリピッチと2ミリピッチ用コネクターが出ているので、使わない2mmピッチ側で拡張しておいた。

RGBビット拡張

まぁ、何だかんだ言っても300円だからね。

-----
あ、そうそう、LCDモジュールのLEDバックライト用のフレキは、正位置にそのまま繋ぐと、表裏が逆となってしまうので、1回転する。

現在までのソースコードなど

現在実装中のソースコードをココに置く。

SH-2A モーター・サイクル・コンピューター・ソースコード・アーカイブ

↑ここに最新版のソースコードを置いておくが、必ずしも十分なテストが行われている訳ではなく、いきなり動作しないかもしれないので注意する事。
また、テスト用のコードが含まれていたり色々です。

安定版が出来たら、別途アーカイブをアップする事とする。

C コンパイラは、「KPIT Commins GNUSHv10.01-ELF」を元にしている、標準ライブラリー「libc.a」に独自の改修を行っている為、インストール後に改修を行う必要がある。
※readme.txtを参照の事。

ファイル入出力は、まだ全然だ・・・

------

・test.raw は 480 × 272 ピクセル、RGB の生データ
※起動時に画面表示に使ってる。

・logger.bin は、御存じのように、実行バイナリー

↑の二つのファイルを SD カードに書き込み(logger.bin は app.bin にリネームする)「SPIwriterUser」を使って、「ff_loader」をフラッシュROM後半に書き込み、JPP をショートしてリセットすれば、起動するだろう~

gcc 標準ライブラリー libc.a の改造

SH-2A には USB が内臓なのだが、こいつと通信する為には、色々なスタックを実装する必要がある、ソースコードも公開されているのだが、色々ハマりそうと考えて、とりあえず、シリアルインターフェースを繋げる事にした。

最近のPCには、シリアルポートはまず無いので、USB-シリアルのブリッジを使う。
秋月電子で、FT232を使った格安なモジュールを売っている。
FT232 モジュール

とりあえず、これを繋いで、シリアルコンソールに文字を出す事が出来た。
でも、サンプルのコードはポーリングなので、割り込み処理にしないと実用性が無いな・・・

FT-232 USB シリアル

とりあえず、本格的なシリアルドライバーは後回しで、gcc の標準ライブラリーに細工する時が来た~

まず、重要なのは、記憶割り当てを行う「malloc」関数群、色々調べると、syscallsモジュールに、「_sbrk」という関数があり、「malloc」は、この低レベルメモリー割り当てを呼ぶ、通常は、シンボル「end」から、スタックの間のメモリー空間を使って、そこに記憶割り当て空間を作り、そこで記憶割り当てを行うのだが、それは、多少まずい、そこで、以下のように改修した。

caddr_t _sbrk (int incr)
{
extern char alloc_top;
extern char alloc_end;
static char *heap_end;
char *prev_heap_end;

if(heap_end == 0) {
heap_end = &alloc_top;
}

prev_heap_end = heap_end;
if((heap_end + incr) >= &alloc_end) {

CPU_UartPuts("Heap and Stack Collision occured...\n");
// abort();
return (caddr_t)NULL;
}
heap_end += incr;
return (caddr_t)prev_heap_end;
}

「alloc_top」、「alloc_end」は、独自のセクションで領域を割り当てていて、この空間内で、メモリーのアロケーションを行う。

※startup.s
.section .MEMALLOC, "w"
.align
.global _alloc_top
_alloc_top:
.space 65536
.global _alloc_end
_alloc_end:

現在は仮に65536バイト確保してある。

※リンク情報
.bss (NOLOAD) :
{
__bss_start__ = . ;
*(.bss)
*(.bss.*)
*(COMMON)
*(.got.*)
. = ALIGN(4);
__bss_end__ = . ;
_end = . ;
} > TRAM

.memalloc (NOLOAD) :
{
. = ALIGN(4);
__alloc_start__ = . ;
*(.MEMALLOC)
__alloc_end__ = . ;
} > TRAM

.stack (NOLOAD) :
{
__stack_start__ = . ;
*(.STACK)
*(.stack)
. = ALIGN(4);
__stack_end__ = . ;
} > TRAM

syscalls のモジュールは、通常、libc.a にアーカイブされているので、sh-elf-arコマンドを使い、オリジナルのlibc.aから、syscallsモジュールを削除しておいた。

リンクする場合、元のsyscalls内の関数全てを実装する必要があるので、とりあえず、ダミー関数を入れておいた。

次は、stdout、stdin、stderrなどファイル関係のサポートだな。

LCD 接続

SD カードからのブートが出来るようになると、早速 LCD を繋いでみたい!
組み込み機器用の小型の液晶を、個人で買うのは、実は、意外とハードルが高い!
正規ルートだと、もう、値段が尋常ではない。

そんな時に見つけたのが、「ストロベリーリナックス」で売ってる PSP の液晶ユニット、
ストロベリー・リナックス - PSP 液晶
まぁ、8800円は多少高いけど・・・

でもでも、さらに見つけたのが、「aitendo」
※最近は売り切れている。
※自分はココで買いました確か5000円くらいだったと思う。

PSP の液晶は、480 X 272 ピクセルでフルカラー、発色も凄く良い。
また、aitendo ではキャリーボードも売っていた(300円だった)これは、液晶のバックライト用 DC-DC も載っていて、フレキケーブルコネクターを普通の40Pコネクターに変換できる、自作にはピッタシの基板。

次はソフトなのだが、ネットを探すと、既に、繋げている人がいるようで、LCD デバイスの初期化コードがアップされているとこを発見!
早速、ソースコードを利用させてもらい、多少苦労したものの画面を出す事ができた。
※「SE組込人」さんありがとう御座います~

PSP 液晶 キャリーボード裏面

LCD にサンプル画像を表示

手始めに、SDカード・インターフェース

まず、考えなければならないのは開発環境。

雑誌の記事等では、ルネサス純正のHEWを使ったものが主流なようで、USBでPCと接続して、トレース、なども行える本格的なものなのだが、自分は、そこまでの環境は必要無いと考えている。
※GUIの統合環境は、裏で勝手に色々やられて好きではない。

むしろ、枯れた環境で開発出来て、全体が見通せる環境の方が良い。
まぁ、バグに悩まされて、トレースが必要な場合もあるだろうが、それはそれとして・・

そこで、昔からの「慣れ」と、emacs と make の CUI 環境の方が好きなので、cygwin 上で gcc を使う事としたのだが・・・
自分でソースコードからコンパイルする事もできるけど、既にコンパイル済みな「KPIT Cummins」のGNU Tools を使う事にした、登録が必要だけど、バグ修正なども比較的良く行われており、シンプルな構成で、インストーラー付き、この新しいSH-2Aにも対応している。
KPIT GNU TOOLS

開発環境に目処がついたとこで、開発スパンをどうするか・・・
この SH-2A には大容量RAMが内臓の為か、フラッシュ ROM を内蔵していない、代りに、外部にシリアル EEPROM があり、そこから BOOT できるようになっており、ローダーに、HEW とデバッグ通信する為のモニターも内臓している。

gcc で生成したバイナリーをどうやって送るか・・・
そんな事を考えているうちに、SDカードを接続して、SD カードに置いた実行バイナリーを読み込んで起動するローダーが発表された。

SD カードのインターフェースは、簡単なので、さっくり作った、SH-2A 基板の 3.3V ラインの容量が微妙なので、5V->3.3Vのレギュレーターを別途載せておいた。

SD カード・インタフェース

それで、自分起動用ソースコードを準備して、簡単なテストが動くようになった。

はじめに

バイクに積むコンピューター(と言っても、速度や、エンジン回転などの情報を表示したり、ウインカーやライトの制御などを行うもの)の構想は前からあり、実験用に何回か組んだ事もあった・・

いつもネックになるのは表示装置、以前は128×64の白黒液晶を使う方向で作業していたが、チープだし、カラーフォトフレームが3000円も出すと買える時代にそぐわないと感じていた・・

それで、カラー液晶なんだけど、制御回路や、フレームバッファのメモリーなど回路の規模が大きくなる事が問題だった。
液晶が接続できる、ARM ベースの Linux 基板なども買って、色々やったが、これはこれで良いし、パフォーマンスも申し分無いのだが、コストが高いのが問題となっていた、自分で使う分にはあまり問題では無いけど、複数台作って、欲しい人に提供する事を考えると、あまり高価になる事は避けるべきと感じてた。

そんな時、インターフェース2010年、6月号にSH-2A基板付録とゆーのを見つけた、まぁいつもの事で、あんまし期待していなかったのだが、内容を観て、興味が沸いた~
・144MHz駆動
・1MB RAM 内臓(ワンチップでこの容量は珍しい)
・64KB高速RAM内臓
・LCDインターフェース(RGB565の16ビットカラー)
・FPU 内臓
・USB インターフェース
などなど

そこで、コレをベースに使って、もう一度作り直してみる事にした。

SH-2A ベース基板

Just another WordPress site