2012年9月30日日曜日
「茶室で楽しむKOZOS拡張基板」企画の開催報告 ~少し優しい気持ちになって、いつもと違うく組み込み開発を!~
「茶室で楽しむKOZOS拡張基板」企画の開催報告です。
2012年09月30日追記:
@kanpapaさんが別途レポートをまとめてくれました。
雰囲気がよく出ているのでそちらもお楽しみ下さい。
ウェブサイトきょうのかんぱぱの「茶室で楽しむKOZOS拡張基板に参加してきました」のページです。
茶室の横を流れる水の音を楽しみながらの開発は、今までに味わったことのない楽しさを提供してくれました。
2012年09月30日追記:
@kanpapaさんが別途レポートをまとめてくれました。
雰囲気がよく出ているのでそちらもお楽しみ下さい。
ウェブサイトきょうのかんぱぱの「茶室で楽しむKOZOS拡張基板に参加してきました」のページです。
まずは、なぜ会場に都筑民家園を選んだのか?について。
キーワードは「少し優しい気持ちになれる」です。
駅周辺は商業施設でごちゃごちゃしています。
しかし、少し離れるだけで田舎の雰囲気を味わえるという場所。
弥生時代の集落がそのまま復元されています。
都筑民家園は、約200年前の家を移築したもの。
私のお気に入りは屋根の構造です。
で、ここをぶらりと訪れた時に繋がったのがKOZOS拡張基板だったわけです。
皆様にいつもと違う環境で組み込み開発して頂ければという企画でした。
駅周辺は商業施設でごちゃごちゃしています。
しかし、少し離れるだけで田舎の雰囲気を味わえるという場所。
弥生時代の集落がそのまま復元されています。
都筑民家園は、約200年前の家を移築したもの。
私のお気に入りは屋根の構造です。
で、ここをぶらりと訪れた時に繋がったのがKOZOS拡張基板だったわけです。
皆様にいつもと違う環境で組み込み開発して頂ければという企画でした。
茶室を除けばそこは組み込み開発室。(プライバシーに配慮してぼかしてあります。)
茶室の横を流れる水の音を楽しみながらの開発は、今までに味わったことのない楽しさを提供してくれました。
こんな感じで、茶室と組み込み開発の不思議なコラボレーションとなりました。
ちなみに、KOZOS拡張基板は当然ながら全て無事に動作しました。
まぁこれが当たり前なのですが、主催者としては一安心というところ。
(KOZOSのブログ:オープンソースカンファレンスでの展示の様子も是非!)
(KOZOSのブログ:オープンソースカンファレンスでの展示の様子も是非!)
参加された皆様には、後からでも楽しめるようにちょっとした資料も一緒にお渡ししました。
組み込み開発は、どうしても世知辛い事になりがちです。
開発の性質上仕方のない事ですが、常に違う視点も取り入れる工夫を続けたいですね。
お忙しい中御参加頂いた皆様、ありがとうございました。
はるばる遠方(大阪府!福島県!)からお越しいただいた方、ありがとうございました。
ラベル:
KOZOS,
KOZOS EXPBRD #00
2012年9月23日日曜日
小規模組み込みシステムで使えるBASICインタプリタをKOZOSと同時に楽しむ! (NT-Basic on KOZOS)
先の記事「NT-Basic on KOZOSのために・・・ (NT-Basicの改良)」では、小規模組み込みシステムで使用可能なBASICインタプリタであるNT-Basicの改良を行ないました。
やっとこさ使えそうな物になってきたので、NT-Shellと組み合わせてKOZOS上で動作させてみました。
デモの中で流れている音楽は、KOZOS EXPBRD上に搭載されたマイクロSDカードから再生しています。
と同時に、シリアルコンソールからBASICインタプリタを楽しむ事ができるというのが今回のデモです。
何かオペレーティングシステムを使っているからこその動作が欲しかったので作ってみました。
何かオペレーティングシステムを使っているからこその動作が欲しかったので作ってみました。
端末の処理はNatural Tiny Shell (NT-Shell)の処理系を使用しています。
自然な入力が可能で、入力処理が破綻せずスムーズにプログラムの編集ができます。
自然な入力が可能で、入力処理が破綻せずスムーズにプログラムの編集ができます。
KOZOS EXPBRDには、グラフィックLCDや入力スイッチが搭載されています。
NT-Basicに命令を追加してグラフィック制御などもできるようにするとゲームも作れそう。
NT-Basicの拡張でKOZOSも使うからKZ-Basicなんていうのも洒落ています。
KZ-Basic (拡張NT-Basic)という名称で拡張していく事を考えています。
今回のソースコードは「茶室で楽しむKOZOS拡張基板」でもお渡しする予定です。
NT-Basicの拡張でKOZOSも使うからKZ-Basicなんていうのも洒落ています。
KZ-Basic (拡張NT-Basic)という名称で拡張していく事を考えています。
今回のソースコードは「茶室で楽しむKOZOS拡張基板」でもお渡しする予定です。
2012年9月22日土曜日
NT-Basic on KOZOSのために・・・ (NT-Basicの改良)
NT-Basic on KOZOS(NT-Basicの改良)
SWEST14での刺激を受けた結果、インタプリタの実装に興味が出てきてNT-Basicなるものを出力しました。それではという事でKOZOSと組み合わせて使おうと思ったのですが、実際にあまり使い勝手が良くなかったのでNT-Basicの改良から行うことにしました。
エディタが必要だ
KOZOS上で実際に動作させる場合、単にファイルシステムからコードを読み込んで動作させるだけでは面白くありません。ターミナルエミュレータから実際にコードを入力して実行するようなインタラクティブな動作を実現したいのです。この時に必要になるのが実用的なエディタです。入力を間違えても再編集できて、昔ながらのBasicシステムに似たような動作を提供できるのが理想です。viのように本格的なエディタを設計する気分にはなれなかったので、以下のような戦略をとることにしました。
- 行編集機能はNT-Shellを用いて機能提供する。
- プログラムは新たに作るtexteditモジュールが保持する。
- ターミナルにrunコマンドを与えた時点でイタンプリタを動作させる。
texteditモジュールのインターフェースは以下のようにしました。
int textedit_init(textedit_t *p);
int textedit_clear(textedit_t *p);
int textedit_insert(textedit_t *p, const int line_number, const char *text);
int textedit_delete(textedit_t *p, const int line_number);
int textedit_fetch(textedit_t *p, const int line_number, char *text, const int maxsize);
NT-Basicはプログラムを文字列として受け取ります。
エディタを設計するならば、内部データは双方向リンクリストで構成する行データの集合として表現したいのですが、NT-Basic側の都合に合わせて単純な一つの文字列で複数の行編集が可能なtexteditモジュールとして設計しました。
これでプログラムの編集は実現できます。
プログラムエラー発生時の挙動修正
初版のNT-Basicでは、プログラムエラーが発生した時に最終的にハードウェア抽象化層のhal_halt関数を呼び出していました。この関数は無限に処理を返さない関数として実装する事を想定しており、「プログラムエラー=処理を永遠に返さない」というあんまりな挙動を提供する結果を生んでいました。「それはないだろう」という事で、エラーを検出した時点で、そこから最終的にntbasic_executeまでエラーを伝搬させるようにしました。HAL層にhaltがあると意味がわからないので、hal_haltは削除しました。ちなみに、c89で上位にエラーを伝搬させるのは丁寧に実装するしかない、みたいな感じの実装になっています。
上位でエラー発生時の行番号の取得も可能です。
NT-Basicの実行方法
初版の実装でもう一つ致命的に使いにくいのが、実行方法でした。ntbasic_executeは、実行したらプログラム終了まで処理を返さないという仕様だったのです。が、これではベアメタルシステムで使いにくくて仕方ありません。NT-Basicでチョコチョコ処理をしながら、別の作業をさせたい事もあるわけです。実際に使ってみると、先ほどのエラー時の挙動と合わせて組み込みシステムで実質使えないような挙動になっていました。
そこで、改良したNT-Basicでは、ntbasic_executeを呼ぶ度に1ステートメントのみ処理するように仕様を変更しました。こうする事でベアメタルシステムでもNT-Basicを導入しやすくなります。
ntbasic_t ntbasic;
ntbasic_error_t error;
/*
* Setup and execute.
*/
error = ntbasic_setup(&ntbasic, program);
while (error == NoError) {
error = ntbasic_execute(&ntbasic);
}
/*
* Check the termination code.
*/
if (error != EndOfTheProgram) {
core_error_message(&ntbasic, error);
}
辛かった変数名の制限
最初の実装では変数名はAからZまでの26文字という小さなBasicではありがちの制限を持っていました。実際にプログラムを組んでみるとわかるのですが、これがかなり辛い制限です。
「あれ?この変数は何を入れてるんだっけ?」みたいにすぐに迷子になれます。
「えーと、Rはアレの略にしたから・・・、で、Aは・・・何だっけ?」みたいに脳内記号表を使う羽目になるわけです。本来、これは機械にやらせるべき作業内容です。
そこで、自由に変数名を付けられるような仕様変更を行いました。
内部設計と実装は至ってシンプルです。
小さな記号表モジュールを作って対応しました。
記号表の考え方は非常に面白いものです。
ここでハッシュ法を使った動作を簡単なモデルで紹介しましょう。
ハッシュ法を用いた記号表の実現
記号表は、変数名や型、長さやその他属性を管理するテーブルです。NT-Basicの場合、変数は内部的にintしか持たないので型や長さは存在しません。
記号表における一番シンプルな例という事になります。
で、与えられた変数名から実際の値を取りだす場合、テーブルを探索する事になります。
線形探索した場合、最悪の場合テーブルのサイズ分の文字列比較作業が必要になります。
上記の図でGHIという変数を探索した場合、先頭から3番目で探索完了になりますが、実際にテーブルの最後に存在した場合、テーブルサイズ分の探索作業を行なう事になります。
これでは変数にアクセスする度に膨大な時間が必要になるので効率的とは言えません。
そこで考えられたのがハッシュ法です。
基本的な考えは非常にシンプルです。
まず、与えられた文字列から導出可能なハッシュ値を得ます。
このハッシュ値は文字列から得られる値で、同じ文字列からは毎回同じ値が得られます。
次に、この得られたハッシュ値を元にテーブルの参照先インデックスを決定します。
例えば、参照先インデックスとして28という数値が得られたら、記号表のインデックス28を参照するという仕組みです。
有限長のテーブルの場合、「参照先インデックス % テーブルサイズ」などとして参照先インデックスを決定します。
整理すると「文字列からハッシュ値」、「ハッシュ値からテーブル参照先インデックス」という過程で、変数名を与えるだけで一意に決まる(ように見える)インデックス番号が求まりました。
さて、ここで疑問が沸いてきます。
仮にテーブルのサイズが16だったとして、ハッシュ値0と16の結果はどうなるでしょうか?
先ほどの例では「参照先インデックス % テーブルサイズ」なのでテーブルの参照先がどちらも0になってしまいます。
変数名として与えられた文字列が異なるものなので、理想的には得られたハッシュ値は異なる結果となります。それにも関わらずテーブルの参照先が同じになってしまいました。
安直な実装の場合、参照先インデックスに格納されている変数名と照合して、合致すれば期待する変数が格納されているものとして処理します。
そして、期待する変数名でなければ近い位置のテーブルを探します。
これにより、線形探索よりも遥に少ない処理で期待する変数値を得ることができます。
実際には、ハッシュ値自身の衝突も考える必要があります。
ハッシュ値自身の衝突の場合も、上記のように期待する変数でなければ近い位置のテーブルを探索するという方法を取ります。
ちなみに、流石に上限なしで対応させるとメモリが幾らあっても足りないので、デフォルトの定義では変数名8文字、変数32個までにしてあります。これはヘッダファイルを書き換えるだけで大きくする事ができます。組み込むシステムに合わせて定義を修正すれば良いでしょう。
この改良によって、以下のようなプログラムが見違えるように判りやすく書けるようになります。
以下はアリスとボブとキャロルの年齢を総計として出力する例です。(ちょっと無理矢理な例)
改良前
INPUT "A=",A
INPUT "B=",B
INPUT "C=",C
T = A + B + C
PRINT "T=",T
改良後
INPUT "Alice=",Alice
INPUT "Bob=",Bob
INPUT "Carol=",Carol
Total = Alice + Bob + Carol
PRINT "Total=",Total
まとめ
今回は小規模組み込みシステムで楽しむためのNT-Basicの改良として、実行方法、エラー時の挙動、変数名の制限について改良した内容について示しました。ちなみに、NT-Basicは総行数が約2000行とコンパクト。
1人で簡単に読み切れるサイズです。
--------------------
LinesFile
--------------------
438core.c
281expression.c
109hal.c
106main.c
157ntbasic.c
269ntlibc.c
443statement.c
111tinyrand.c
135variable.c
--------------------
2049Total
http://shinta.main.jp/firmware/ntbasic/ntbasic_ja.html
2012年9月19日水曜日
オーディオ信号処理で学ぶDSP
堀江誠一さんのお書きになったInterfaceの記事についてバックナンバーを調べました。
現在、BlueTank BF592を使ったごにょごにょ信号処理をしているのですが、知りたかったあれやこれやがこの連載に満載になっていました。
Jan. 2007 第1回:DSPでループバックとカラオケを作ろう
Feb. 2007 第2回:FIRフィルタを使ってみよう
Mar. 2007 第3回:高速なIIRフィルタの解説と実装
Apr. 2007 第4回:Blackfinの周辺機能制御と割り込み
July 2007 第5回:I2CポートでA-Dコンバータを制御する
Sept. 2007 第6回:エフェクタを作ってみる(あふれと飽和)
Oct. 2007 第7回:Sin波を作る(テーブル参照のテクニック)
Dec. 2007 第8回:複素信号処理
Feb. 2008 第9回:DSPでソフトウェア無線を実現する(複素信号処理に基づいたSDRの作成)
DSPを使った信号処理に興味のある人は必見です。
Interface誌のバックナンバーはこちらからどうぞ。
ラベル:
B073 : BlueTank,
DSP,
Interface
2012年9月17日月曜日
KOZOS拡張基板KOZOS EXPBRDを使ったミュージック・プレイヤー
いよいよ2012年9月29日に「茶室で楽しむKOZOS拡張基板」を開催します。
例えばどんな事ができる拡張基板なのかイメージが掴んで頂く為に、応用例としてミュージック・プレイヤーを仕立ててみました。
[フレーム]
アプリケーションはブートローダ経由でDRAM上に展開してブートしています。
SDカードからブートできるのでパソコンなしでKOZOSの実行が可能!
ブートローダもアプリケーションもソースコードを公開しますので御安心下さい。
どんどん改造して自分好みに仕立て上げる事ができます。
既に定員に達している本企画ですが、見学も大歓迎です。
http://atnd.org/events/30481で見学希望の旨を書いて登録して下さい。
例えばどんな事ができる拡張基板なのかイメージが掴んで頂く為に、応用例としてミュージック・プレイヤーを仕立ててみました。
[フレーム]
アプリケーションはブートローダ経由でDRAM上に展開してブートしています。
SDカードからブートできるのでパソコンなしでKOZOSの実行が可能!
ブートローダもアプリケーションもソースコードを公開しますので御安心下さい。
どんどん改造して自分好みに仕立て上げる事ができます。
既に定員に達している本企画ですが、見学も大歓迎です。
http://atnd.org/events/30481で見学希望の旨を書いて登録して下さい。
ラベル:
KOZOS,
KOZOS EXPBRD #00
2012年9月15日土曜日
テキストLCDをグラフィックLCDのように扱うギミック ~テキストLCDでもここまでできる!~
今回はちょっとお遊び休憩ネタです。
Analog Devices社Blackfin BF592搭載オーディオ・プラットフォームBlueTank BF592を使ったお遊び。
まずは動作をご覧下さい。
[フレーム]
上記で使用しているテキストLCDは2行8文字の表示が可能なLCDです。
殆どのテキストLCDにはHD44780互換のLCDコントローラが搭載されています。
ユーザ登録可能な文字は8つあります。
しかし、普通に考えるとユーザ登録文字を使って全画面を一度に表示する事はできません。
なぜなら2行x8文字で、16文字のユーザ登録文字が必要になるからです。
では「どうしているのか?」というと簡単で、時分割で細かく切り替えて表示を行なっています。
以下にステップ毎の動作の様子を示します。
1文字目は普通に考えてもいけます。
もちろん2文字目も。
3文字。
4文字。
5文字。
6文字。
7文字。
8文字。
ここで、ユーザ登録文字の8文字を使い切りました。
まだ画面の半分しか描画できていません。
で、どうするのかというと・・・。
新たに描画の必要がある領域のために一番最初に書いた文字を消します。
これなら使っているユーザ登録文字は依然として8文字です。
同様にして。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
これで下側の画面描画が完了しました。
上記を非常に細かい時間で繰り返すと以下のように見えるというのが今回のギミック。
まぁ、飛び越し走査とは違いますが、あえて言うならば「なんちゃってインターレース」でしょうか?
実はこのデモ、48KHzステレオオーディオの処理をしながらの動作です。
先日のFFTスペアナと合わせればもっと楽しい見た目を提供できそう。
動作を見ると実装は複雑なんじゃないか?と思うかもしれません。
でも、きちんと設計すればそんな事はありません。
以下のような定義でざざっと絵を作れるようにしました。
で、実際の描画は下層のglcdモジュールにお任せという具合です。
gcld_blitを呼ぶと、内部でうまい具合に1シーケンス分の処理をしてくれるという設計です。
上記の画像は「リアルなLCD画像ファイルが得られるLCD Toolの改良」で取り上げたlcdtoolを使って生成しました。
LCDプロファイルとLCDフォントに少し手を入れるだけで好みの出力が得られます。
BMP画像ファイルの生成はスクリプトで一発自動生成。
また、出力が間違っていても、スクリプトさえ残しておけば後で何度も修正する事ができます。
Analog Devices社Blackfin BF592搭載オーディオ・プラットフォームBlueTank BF592を使ったお遊び。
まずは動作をご覧下さい。
[フレーム]
上記で使用しているテキストLCDは2行8文字の表示が可能なLCDです。
殆どのテキストLCDにはHD44780互換のLCDコントローラが搭載されています。
ユーザ登録可能な文字は8つあります。
しかし、普通に考えるとユーザ登録文字を使って全画面を一度に表示する事はできません。
なぜなら2行x8文字で、16文字のユーザ登録文字が必要になるからです。
では「どうしているのか?」というと簡単で、時分割で細かく切り替えて表示を行なっています。
以下にステップ毎の動作の様子を示します。
1文字目は普通に考えてもいけます。
もちろん2文字目も。
3文字。
4文字。
5文字。
6文字。
7文字。
8文字。
ここで、ユーザ登録文字の8文字を使い切りました。
まだ画面の半分しか描画できていません。
で、どうするのかというと・・・。
新たに描画の必要がある領域のために一番最初に書いた文字を消します。
これなら使っているユーザ登録文字は依然として8文字です。
同様にして。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
どんどん上側を消して下側を書きます。
これで下側の画面描画が完了しました。
上記を非常に細かい時間で繰り返すと以下のように見えるというのが今回のギミック。
まぁ、飛び越し走査とは違いますが、あえて言うならば「なんちゃってインターレース」でしょうか?
実はこのデモ、48KHzステレオオーディオの処理をしながらの動作です。
先日のFFTスペアナと合わせればもっと楽しい見た目を提供できそう。
動作を見ると実装は複雑なんじゃないか?と思うかもしれません。
でも、きちんと設計すればそんな事はありません。
以下のような定義でざざっと絵を作れるようにしました。
で、実際の描画は下層のglcdモジュールにお任せという具合です。
glcd_clear(&(w->glcd)); for (px = 0; px < GLCD_PX; px++) { for (py = 0; py < GLCD_PY; py++) { glcd_set_pixel(&(w->glcd), px, py, (img1[py][px + (VOL_MAX - w->volume)] == 'o') ? 1 : 0); } }
gcld_blitを呼ぶと、内部でうまい具合に1シーケンス分の処理をしてくれるという設計です。
glcd_blit(&w->glcd);
上記の画像は「リアルなLCD画像ファイルが得られるLCD Toolの改良」で取り上げたlcdtoolを使って生成しました。
LCDプロファイルとLCDフォントに少し手を入れるだけで好みの出力が得られます。
BMP画像ファイルの生成はスクリプトで一発自動生成。
#!/bin/sh
LCDTOOL=lcdtool
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq01.bmp '\x00' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq02.bmp '\x00\x02' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq03.bmp '\x00\x02\x04' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq04.bmp '\x00\x02\x04\x06' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq05.bmp '\x00\x02\x04\x06\x08' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq06.bmp '\x00\x02\x04\x06\x08\x0A' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq07.bmp '\x00\x02\x04\x06\x08\x0A\x0C' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq08.bmp '\x00\x02\x04\x06\x08\x0A\x0C\x0E' ' '
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq09.bmp ' \x02\x04\x06\x08\x0A\x0C\x0E' '\x01'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq10.bmp ' \x04\x06\x08\x0A\x0C\x0E' '\x01\x03'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq11.bmp ' \x06\x08\x0A\x0C\x0E' '\x01\x03\x05'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq12.bmp ' \x08\x0A\x0C\x0E' '\x01\x03\x05\x07'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq13.bmp ' \x0A\x0C\x0E' '\x01\x03\x05\x07\x09'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq14.bmp ' \x0C\x0E' '\x01\x03\x05\x07\x09\x0B'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq15.bmp ' \x0E' '\x01\x03\x05\x07\x09\x0B\x0D'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont seq16.bmp ' ' '\x01\x03\x05\x07\x09\x0B\x0D\x0F'
$LCDTOOL bluetank.lcdprof glcd_demo.lcdfont view.bmp '\x00\x02\x04\x06\x08\x0A\x0C\x0E' '\x01\x03\x05\x07\x09\x0B\x0D\x0F'
自動化してあるので、画面数が多くても操作が苦になる事はありません。また、出力が間違っていても、スクリプトさえ残しておけば後で何度も修正する事ができます。
ラベル:
B073 : BlueTank,
Break time,
lcd,
lcdtool
2012年9月13日木曜日
BlueTank BF592 FFT Graphical Spectrum Analyzer
Analog Devices社Blackfin BF592搭載オーディオ・プラットフォームBlueTank BF592を使ったグラフィカル・スペクトラム・アナライザーです。
[フレーム]
2x8文字のLCDですが、都合の良い事に8文字のユーザ・フォントを登録する事ができます。
1文字1バンドで考えてしまうと8バンドしか表示できません。
でも、1ピクセル1バンドとして考えると5ドットx8文字で最大40バンドの表示が可能になります。
この基板設計時に考えた事をようやく実現する事ができました。
8文字表示のLCDを選択したのは、単に「コンパクトだから」というわけではなかったのです。
今回のサンプリング周波数は48,000[Hz]でFFT計算サイズは64です。
なので周波数軸での分解能は750[Hz]という事になります。
750[Hz]の分解能で40バンドまで表示できる事を考えると、ナイキスト周波数の範囲まで十分に表示できる事がわかります。
FFT計算サイズの内部定義を一行書きかえるだけで、表示側も連動するように実装しました。
折り返し成分を表示しないようなガードも入れてあります。
BlueTank BF592に対するオーディオ・フレームワークの実装もかなり進みました。
上記のコードはフレームワーク層のコードを除くとコメントを含んで約300行の実装で済みます。
(コメントが何行なんだ!)
アプリケーション共通の処理は全てオーディオ・フレームワーク側に隠ぺいしました。
main.cみたいな小さなアプリケーションの実装のみで上記のような処理を実現する事ができます。
ちなみに、上記のアプリケーションは天ノ岩戸のmayaさんが実装したFFTアナライザを改造して作りました。この場を借りてお礼申し上げます。
そして、オーディオ・フレームワークについてはDSP空挺団の酔漢さんの作られたUZUMEにかなり影響を受けています。最初はUZUMEのミニマム・プラットフォームとしてBlueTank BF592を仕立てる計画でしたが、似ても似つかない物になってしまったのでもじってUZURAというフレームワーク名を付けました。変なフレームワークで本家や市場に混乱や迷惑をかけない措置です。
ちょっと借り物競走みたいなプロジェクトになってきましたが、まだまだBlueTank BF592遊びは続けようと考えています。
[フレーム]
2x8文字のLCDですが、都合の良い事に8文字のユーザ・フォントを登録する事ができます。
1文字1バンドで考えてしまうと8バンドしか表示できません。
でも、1ピクセル1バンドとして考えると5ドットx8文字で最大40バンドの表示が可能になります。
この基板設計時に考えた事をようやく実現する事ができました。
8文字表示のLCDを選択したのは、単に「コンパクトだから」というわけではなかったのです。
今回のサンプリング周波数は48,000[Hz]でFFT計算サイズは64です。
なので周波数軸での分解能は750[Hz]という事になります。
750[Hz]の分解能で40バンドまで表示できる事を考えると、ナイキスト周波数の範囲まで十分に表示できる事がわかります。
FFT計算サイズの内部定義を一行書きかえるだけで、表示側も連動するように実装しました。
折り返し成分を表示しないようなガードも入れてあります。
BlueTank BF592に対するオーディオ・フレームワークの実装もかなり進みました。
上記のコードはフレームワーク層のコードを除くとコメントを含んで約300行の実装で済みます。
(コメントが何行なんだ!)
アプリケーション共通の処理は全てオーディオ・フレームワーク側に隠ぺいしました。
main.cみたいな小さなアプリケーションの実装のみで上記のような処理を実現する事ができます。
ちなみに、上記のアプリケーションは天ノ岩戸のmayaさんが実装したFFTアナライザを改造して作りました。この場を借りてお礼申し上げます。
そして、オーディオ・フレームワークについてはDSP空挺団の酔漢さんの作られたUZUMEにかなり影響を受けています。最初はUZUMEのミニマム・プラットフォームとしてBlueTank BF592を仕立てる計画でしたが、似ても似つかない物になってしまったのでもじってUZURAというフレームワーク名を付けました。変なフレームワークで本家や市場に混乱や迷惑をかけない措置です。
ちょっと借り物競走みたいなプロジェクトになってきましたが、まだまだBlueTank BF592遊びは続けようと考えています。
ラベル:
ACB-BF592,
B073 : BlueTank,
DSP,
FFT,
UMB-SSM2603,
UZUME,
UZURA
2012年9月8日土曜日
Natural Tiny Basic (NT-Basic) ~WindowsでもLinuxでもMac OSでも組み込み機器でも楽しめるBASICインタプリタ~
まつもとゆきひろさんから得た刺激
先日のSWEST14でまつもとゆきひろさんの講演を聞いてからというものの、言語処理系にとても興味が湧いてきました。何から手を付けて良いかわからなかったので、手始めに既存のBASICインタプリタに手を入れるところから始めました。
オーディオプラットフォームであるBlueTank BF592で動作させた時の様子が以下の動画です。
[フレーム]
NT-Basicのアプリケーションコード
NT-Basicを使用するアプリケーションコードは至ってシンプルです。ntbasic_ ntbasic; ntbasic_execute(&ntbasic, your_program);
上記のようにntbasicハンドラとプログラム文字列をntbasic_execute関数に渡してあげるだけです。
先ほどの動画の動作は以下のコードから実現しています。
#include "ntbasic.h"
#include "uart.h"
#include "lcd.h"
#include "bfin_util.h"
int main(void)
{
ntbasic_t ntbasic;
char *prog1 =
"100 FOR I = 1 TO 8\n" \
"110 C = 65 + I - 1\n" \
"120 WRITE 1, C\n" \
"130 NEXT\n" \
"140 END\n";
char *prog2 =
"100 FOR I = 1 TO 8\n" \
"110 C = 97 + I - 1\n" \
"120 WRITE 1, C\n" \
"130 NEXT\n" \
"140 END\n";
uart_init();
lcd_init();
while (1) {
/*
* プログラム1を実行する。
*/
lcd_goto(0, 0);
ntbasic_execute(&ntbasic, prog1);
bfin_util_usleep(1000000);
/*
* プログラム1で書いた表示を消去する。
*/
lcd_clear();
bfin_util_usleep(1000000);
/*
* プログラム2を実行する。
*/
lcd_goto(0, 1);
ntbasic_execute(&ntbasic, prog2);
bfin_util_usleep(1000000);
/*
* プログラム2で書いた表示を消去する。
*/
lcd_clear();
bfin_util_usleep(1000000);
}
return 0;
}
今回のターゲットは組み込み装置でしたが、実際にLinuxやWindowsやMac OSでもビルドできるようにしました。
なので、「パソコン上でインタプリタ側のプログラムを動作確認」して「実機で動作」という流れでインタプリタを楽しむ事ができます。
「いつでもどこでもインタプリタ」がキーワードです。
組み込み装置で使うためのHAL構造
この手のソフトウェアで重要なのは構造です。I/Oは最下層のHAL(Hardware Abstract Layer)が実行するようにしてあります。
インタプリタ上のプログラムは、ハードウェア抽象化層を介し、実際のデバイスを制御します。
ターゲット依存部は単に小さなハードウェア抽象化層に対する実装を加えるのみで済みます。
int hal_getc(void);
int hal_putc(int c);
int hal_read(const int port, int *data);
int hal_write(const int port, const int data);
int hal_halt(void);
hal_getc(void)とhal_putc(int c)は標準入出力系を担います。
ポート番号を指定してデータをI/Oするのが、hal_read(const int port, int *data)とhal_write(const int port, const int data)です。
先ほどお見せした動画は、このHALの層で「ポート番号1に対する出力はLCD」という実装を追加したわけです。
int hal_write(const int port, const int data)
{
switch (port) {
case 0:
/*
* Port 0 is UART in this port.
*/
hal_putc(data);
return 0;
case 1:
/*
* Port 1 is LCD in this port.
*/
lcd_putc((char)data);
return 0;
}
return -1;
}
実際に動作させてみると結構楽しいおもちゃです。
「茶室で楽しむKOZOS拡張基板」のように何か一つ企画をやりたいなぁと考えています。
リソース
ソースコードは以下からダウンロードできます。
ラベル:
BASIC,
Natural Tiny Basic
2012年9月1日土曜日
SWEST14参加報告
勢い余って参加申し込みしておいたSWESTですが、あっという間に過ぎ去っていきました。
下呂までは長い道のりでしたが、コードを書いていたらあっという間です。
参加者数は200名弱でしょうか。
水明館はなかなか素敵な宿でした。
初参加という事もあって意味もわからず出したので、ちょっと場違いな感じもします。
次回以降、参加するなら再考したいです。
ポスターはズームランドさんに印刷を頼みました。
これはなかなか良かったかも。印刷内容はともかく。
今回は金子システムさんのところのDSP基板を搭載したBlueTankでNT-Loggerを、LPCXpressoを使った基板でNT-Shellのデモでお届けしました。
今回のDSP基板、とても気に入ったのでちょこっと宣伝もさせて頂きました。
NT-Loggerのデモでは、リアルタイム性を維持しながらシステムのロギングを実行する様子を展示しました。48KHzステレオサンプリングの音声を処理しながらロギングしてシステムの挙動を観察できます。
NT-Shellのデモは、「適当に作ったシェル」と「NT-Shell」による動作の違いを示し、適当に作ると何が問題なのか、NT-Shellで何を解決したのかを提示しました。
お越しいただいた皆様ありがとうございました。
様々な方と色々な意見交換ができてとても有用でした。
下呂までは長い道のりでしたが、コードを書いていたらあっという間です。
参加者数は200名弱でしょうか。
水明館はなかなか素敵な宿でした。
初参加という事もあって意味もわからず出したので、ちょっと場違いな感じもします。
次回以降、参加するなら再考したいです。
ポスターはズームランドさんに印刷を頼みました。
これはなかなか良かったかも。印刷内容はともかく。
今回は金子システムさんのところのDSP基板を搭載したBlueTankでNT-Loggerを、LPCXpressoを使った基板でNT-Shellのデモでお届けしました。
今回のDSP基板、とても気に入ったのでちょこっと宣伝もさせて頂きました。
NT-Loggerのデモでは、リアルタイム性を維持しながらシステムのロギングを実行する様子を展示しました。48KHzステレオサンプリングの音声を処理しながらロギングしてシステムの挙動を観察できます。
NT-Shellのデモは、「適当に作ったシェル」と「NT-Shell」による動作の違いを示し、適当に作ると何が問題なのか、NT-Shellで何を解決したのかを提示しました。
お越しいただいた皆様ありがとうございました。
様々な方と色々な意見交換ができてとても有用でした。
ラベル:
B073 : BlueTank,
LPCXpresso,
SWEST
リアルなLCD画像ファイルが得られるLCD Toolの改良
先日からの改良点
先日適当に作ったLCD Toolですが、なかなか便利に使えそうなので本格的に便利になるように改良しました。以下に改良点を示します。
機能 改良前 改良後
LCD形状 プログラムにハードコーディング LCDプロファイルで指定可能
LCD描画色 プログラムにハードコーディング LCDプロファイルで指定可能
ドット形状等 プログラムにハードコーディング LCDプロファイルで指定可能
ユーザーフォント プログラムにハードコーディング フォントファイルで指定可能
出力画像サイズ プログラムにハードコーディング プログラム内部で自動計算
非文字コード指定 シェル機能に期待(Windowsでは困難) エスケープ文字による指定が可能
動作プラットフォーム Linuxを前提に実装 LinuxとWindowsで動作確認済み
適当にプログラムでハードコーディングしていた部分を外部から与えられるようにしました。
LCDプロファイルとフォントデータについては後述します。
入力と出力の関係
以下に入力と出力の関係を示します。LCDプロファイルとは、LCD形状、LCD描画色、ドットサイズ、キャラクタ間隔などを定義したテキストファイルです。
このテキストファイルを編集する事で手持ちのLCDとそっくりの出力を得ることができるようになります。
ファイルの中身は以下のようになっています。
幾つかのLCDに対するサンプルを完備しています。
#
# SC1602BBWB-XA-GB-G
#
CHCNT_X = 16 # Character Count (X)
CHCNT_Y = 2 # Character Count (Y)
CHOFS_X = 16 # Character Offset (X)
CHOFS_Y = 16 # Character Offset (Y)
CHGAP_X = 2 # Character Gap (X)
CHGAP_Y = 2 # Character Gap (Y)
PIXSIZ_X = 4 # Pixel Size (X)
PIXSIZ_Y = 4 # Pixel Size (Y)
PIXGAP_X = 1 # Pixel Gap (X)
PIXGAP_Y = 1 # Pixel Gap (Y)
FGCOL.R = 220 # Foreground Color (Red)
FGCOL.G = 220 # Foreground Color (Green)
FGCOL.B = 220 # Foreground Color (Blue)
BGCOL.R = 120 # Background Color (Red)
BGCOL.G = 120 # Background Color (Green)
BGCOL.B = 230 # Background Color (Blue)
CONTRAST = 96 # Contrast
初版では「ユーザフォントはプログラム中のデータを書き換えてね」という冷たい仕様でした。
実際にユーザフォントを定義しようとすると結構面倒でした。
新しいバージョンでは、フォントファイルを与えるだけで内部のフォントデータを書き換えてくれます。
###########
CODE = 0x00
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x01
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x08
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
###########
CODE = 0x09
###########
.....
.o.o.
ooooo
ooooo
ooooo
.ooo.
..o..
.....
プログラム内部のフォントデータは16進数で記述されています。
点灯させたいドットをイメージしながら16進数を操作させるのは不親切です。
上記のように人間がイメージできる形式で記述すれば済むようにしました。
実行例
以下に実行例を示します。lcdtool ACM0802C-NLW-BBH.lcdprof UserFontSample.lcdfont test1.bmp "ABCDEFGH" "abcdefgh"
lcdtool SC1602BBWB-XA-GB-G.lcdprof UserFontSample.lcdfont test2.bmp "ABCDEFGHIJKLMNOP" "abcdefghijklmnop"
lcdtool SC2004CSLB-XA-LB-G.lcdprof UserFontSample.lcdfont test3.bmp "Line 1: LCD Tool" "Line 2: Sample" "Line 3: LCD Tool" "Line 4: Sample"
上記の実行例を見てわかるように、LCDプロファイルとユーザフォント、出力画像ファイル名、メッセージを与えさえすればBMP画像ファイルが得られます。
LCDプロファイルをどんどんカスタマイズしてVFD版を作ったりしても面白そうです。
ユーザフォントを使った出力の指定方法
ユーザフォントを使った出力の指定は、バックスラッシュを使って指定する事ができます。例えば、上記のCGRAM(3)を表示させたい場合、「\x02」とコマンドラインに与えます。
「\」を表示させたい場合、 「\\」と入力して下さい。
Linuxの端末で与える場合、シェルに解釈させないためにシングルクォートで囲ってから指定する必要があります。
リソースのダウンロード
本記事執筆段階でのスナップショットをこちらからダウンロードできます。ドキュメントはこちらからダウンロードできます。
Visual C++ 2010 Expressのプロジェクトファイルも同梱してあります。
Windowsでビルドして使用する事もできます。
追記
2012年09月04日追記:v0.0.2にはバグがありました。上記から最新のv0.0.3をダウンロードして下さい。2012年09月15日追記:http://shinta.main.jp/software/lcdtool/lcdtool_ja.htmlに最新版があります。
登録:
コメント (Atom)