2014年10月31日金曜日

ロジックアナライザを使ってジッタ計測を行ない、システムの安定性を検証する

■概要

昨年2013年の組込み総合技術展におけるプレゼンテーションの内容について「ET2013のTOPPERSパビリオンでショートプレゼンテーションをさせて頂きました」で簡単に触れました。今日は、この中でお話させて頂いたロジックアナライザを使ってジッタ計測を行ない、システムの安定性を検証する方法について述べたいと思います。

現代の組み込みシステムでは、ソフトウェアがシステム制御の一部を担う事が非常に多くなりました。ソフトウェアで発生するジッタというのは、リアルタイムシステムを構築する上で必ず評価しなければならない項目です。現場でお仕事をしていると、意外にも「どうやって評価して良いのかわからない」、「機材がない」といった内容の話をよく聞きますが、ちょっとした工夫と道具で指標となるデータを簡単に得る事ができます。

■題材

題材として用意したのは、7セグメントLEDが複数付いたデジタル時計です。


このデジタル時計は、6桁の数値表示をソフトウェアで制御する設計になっています。シンクドライバは各桁共通になっており、ソースドライバを選択的に駆動しながら各桁の数値を順次表示する仕組みです。


各桁の表示時間は、そのまま表示輝度に影響を与えますから、バラツキが大きすぎるのは問題です。それでは、このシステムをリアルタイム制御する場合について考えてみましょう。

■計測

システムの安定性を検証するにはデータが必要です。
先ほどのシステムで、各桁の駆動時間間隔を調べることにします。


チャネル毎の計測結果をファイルとして吐き出せるツールならば何でも構わないのですが、私はWindows、Linux、Mac OS Xと三つのプラットフォームで使用可能な上、GUIもサクサク軽快に動作するSaleae Logicを愛用しています。

先に述べたように、ソースドライバの駆動時間によって輝度にばらつきが出ることがわかっていますから、今回はソースドライバの各チャネルのタイミングを計測してリアルタイム性について確認を行います。

以下に示すのが計測した結果です。


と言ってもこれではわかりませんよね。
少し拡大してみましょう。


一見良さそうに見えますが、これで「良し」というわけにはいきません。
先に示した膨大な量の計測結果に、処理遅延が発生していない事をこれらのデータで判別する事は出来ません。

この計測結果からデータを整理抽出して欲しいデータを得るのがこれからの作業です。

■整理

それでは先ほど得た計測結果を整理して欲しい情報を抽出してみます。
Saleae Logicのアプリケーションは、データをCSVにエクスポートする機能が付いています。


この機能を使って計測データをCSVに変換します。
何故変換するのかというと、後でシェルで自分の都合に合わせて加工するためです。
エクスポートしたデータは、イベントが発生した時間と、その時の各チャネルの信号状態が記述された形式になっています。


このまとまったデータから各チャネルのOnの状態だけを抽出してみましょう。
以下のようなスクリプトを書けば、簡単にチャネル毎のデータに分割できます。


先のデータを使ってチャネル0のOnの状態だけを抽出したファイルは以下のようになります。
このデータは、まさにOnになった瞬間のリストで、後から述べる方法を使うことで、処理のバラツキを知ることができます。


■工夫

ここまでの作業で、各桁のピンの状態がOnになる瞬間の時刻の羅列を得ることができました。しかし、今回の題材では基準となるクロックが外部に存在しません。そこで、今回は処理のバラツキについて、前後のイベントの間隔で見ることにしました。

計測したデータの分析にはScilabを用いると便利です。基本となる操作は、ファイルになったデータを読み込む事と、前後のイベントの間隔を抽出する事で、以下に示すたった二つの記述で実行できます。


一行目でデータを読み込み、二行目で各値の差分を抽出します。この操作を行ったデータを可視化すると、以下のようなグラフが得られます。


この可視化されたデータは、ドライバの特定ピンがOnになった瞬間のイベント間隔のバラツキを時間軸方向に見たものです。しかし、これでは望んでいるリアルタイム性が確保できているのか判断しづらいので、異なる表現のデータも得てみましょう。


上記で示したScilab用の記述は、時間軸方向に並べられたイベント差分データを、単にヒストグラムに展開するものです。何か特別な加工をしているわけではありませんが、データの表現方法を変えるだけで、ずいぶんとわかりやすくなりました。


このバラツキのデータから中心値、最悪値、標準偏差を求め、システムが十分に安定したリアルタイム性を有しているのかどうかを判定します。

■まとめ

今回使用したのは、安価なロジックアナライザとLinux環境のみです。高価な専用機器を購入しなくても、工夫次第で今まで見ることの出来なかったシステムの性能を計測し把握できます。
こういったちょっとした工夫で今までと違う結果を得られるのが、組み込みシステムの面白いところなのかもしれません。

■玩具

ちょっと楽しくしたい場合、いろんなシチュエーションのデータを使ってアニメーションgifなどにすると面白いです。組込み総合技術展のプレゼンテーションでお見せしたアニメーションは、まさに上記で示した作業を経て作りました。結構手間が・・・かかってないか。



■ダウンロード

今回の「ロジックアナライザを使ってジッタ計測を行ない、システムの安定性を検証する」を実際に体験してみたい方のために、データ一式をダウンロードできるようにしました。

こちらからダウンロード


  • 無保証です。
  • 上記内容に関しての無断転載は御遠慮下さい。

2014年9月30日火曜日

割と地味なlcdtoolの地味な改良を考える(だけ)

lcdtoolとは、テキストLCDの表示内容を模擬してBMPファイルを生成してくれるツールです。
LCDプロファイルとLCDフォントファイルを作れば、様々なタイプのテキストLCDを模擬できます。





「リアルな操作画面のキャプチャが欲しい! ~ドキュメント制作時に便利なLCD画像生成ツールを作ってみた~」で述べたように、取り扱い説明書やらで便利に使えるツールなのですが、割と色々なところに使い始めて、スクリプトのような機能を内包したくなってきました。

というのも、世の中には文字列だけの表示器だけではなく、記号や図形を組み合わせた表示器が存在します。このような場合、従来のlcdtoolではうまく対応できません。

そこでアレコレ考えた結果、lcdtoolNT-Basicを組み込んでBasicで描画処理を記述できるようにしようと思い立ちました。(なんでBasicなんですか?とか聞かないで下さい・・・)

NT-Basicを使った描画処理は、従来から存在するLCDプロファイルにスクリプトファイル指定を追加し、外部のNT-Basicスクリプトを実行する形式で実現する予定です。この機能追加が実現すれば、lcdtoolを使って更に柔軟な表現が可能になります。

この機能追加を行なったlcdtoolは、遅くとも年内にリリースする予定。
現在、GUI化も検討しており、楽しみな改良計画です。

2014年8月31日日曜日

Blackfin BlueBoot Version 0.5.0のリリース (地味に改良しました)

■概要

今年に入って地味にアップデートを続けているBlackfin BlueBootですが、前回のVersion 0.4.0に引き続き、これまた地味にVersion 0.5.0へアップデートしました。

きっかけとなったのは「KOZOS for Blackfin "BlacKOZOS"の設計方針」で始めたBlacKOZOSの作業です。この中で、コールドスタート時の動作確認用にターゲットにイメージを書き込むためにBlackfin BlueBootを使っていたのですが、稀に書き込みに失敗する事がわかりました。

■どんな失敗?

Blackfin BlueBootの場合、書き込み後に読み込みを実施して比較検証まで実施しているのですが、比較検証段階でターゲットから応答が無い(ような)状態に陥るというのが発生現象でした。現象発生時、表出現象には幾つか種類があるものの、書き込み直後の操作である事は共通した表出現象・・・。

「なんだろうな?」と思って設計を見返したところ、手を抜いて気にしていた部分を見つけました。

というのも、Blackfin BlueBoot Version 0.4.0までは、ターゲット上でフラッシュロムへの書き込みがまさに終わったかどうかの確認は行なわず、ターゲット上に搭載されているフラッシュロムのデータシートに規定された書き込みにかかる最大時間をホスト側で待ってから、その次の動作に移行するという設計になっていました。

イメージ図にすること以下のようになります。
ホスト側の処理を台詞にすると、以下のように随分と乱暴な感じ。
これはいけません。


ざっくり言うと「データシートに書かれた最大時間は待ったんだから終わってんだろ?」という話ですが、これには幾つか問題があります。
  1. 常に最大時間待つので、必然的に書き込みが遅くなる。
  2. ソフトウェア上で待つという事は、必然的にバラツキを生む事になる。
  3. 待つ処理に対するバラツキは、実行環境によっても異なる上、それは予想し難い。
  4. その他。
一番目に挙げた「最大時間待つ」問題は、実はセクタ消去にも適用していたので、のっけから劇遅な状態を生んでいました。これは本来、フラッシュロムのステータスレジスタを参照して、次の処理に移行可能か確認するようにすれば高速ですし、そもそも次の処理が失敗する可能性もなくなります。

二番目に挙げた「待つ処理のバラツキ」問題は、根拠としているデータシート上の最大時間を保証できない可能性もあるという意味で大問題です。これも、先のフラッシュロムのステータスレジスタを参照してから次の処理に移行する事で解決できます。

問題の類としては、H8/3069F writer for KOZOS - kz_h8write 「h8writeリベンジ解決編」と同じとも言えなくないような・・・。

■改良版

Blackfin BlueBoot Version 0.5.0では、プロトコルバージョンを2に変更した上で、フラッシュロムのステータス取得コマンドを追加しました。これにより、ターゲット側のブートローダも更新が必要になりましたが、これによって安定動作が得られるならば何の問題もありません。新しくflash_busyというインターフェースがflash.hに追加され、各ターゲットはこの定義に対する実装を要求されるようになります。


さて、改良版のホスト側の動作をイメージ図にするとこんな感じでしょうか?


ホスト側のコントローラは、ターゲットからフラッシュロムのお仕事が完了したのか、逐次必要に応じて問い合わせるようにしました。

これにより、
  1. 余計な待ち時間が不要となり、従来よりも動作が高速になりました。
  2. 書き込み処理の安定性が向上しました。
  3. より環境に依存せずに書き込みができるようになりました。
  4. その他。
という結果を得ました。

昔のどこかのバージョンで、フラッシュロムのライトサイクルとかその類の情報をターゲットから貰うようにしたのですが、これも次のバージョンでは整理したいと考えています。

■ダウンロード

Blackfin BlueBootは以下のサイトからダウンロードできます。
趣味でもお仕事でも御自由にお使い下さい。
完全無保証です。
動作させた結果、起きた如何なる問題も当方は責任を持ちません。

2014年7月27日日曜日

KOZOS for Blackfin "BlacKOZOS"の設計方針

UOS-LPC800

UOS-LPC800を公開してから早くも一年が経ちました。
思いっきり遊びでしか使えない感じのOSが一部の方に好評で、ここでも述べたようにadafruitでも紹介されたりもしています。


本当は公開後に色々機能追加する事を考えていましたが、LPC-810と組み合わせて紹介されているので、彼に入りきらなくなるのは可哀想です。どうしようかな?と考えていたら1年が経過していました。あらら。

KOZOS

UOS-LPC800は、坂井さんがお作りになったKOZOSが制作のきっかけになっています。


KOZOSは、完全ホビー向けOSでありながらソフトウェア割り込みを使ったシステムコールによる操作を実現するなど、とても興味深い作り込みになっています。坂井さんによるユニークなキャラクタであるニジマス君も見逃せません。

坂井さんの書籍が販売されてから私も早速購入して色々な活動に取り組みました。

"BlacKOZOS" - KOZOS for Blackfin

あれから二年ほど経ち、現在は主にBlackfinを使って色々遊んでいます。
私の場合、新しいプロセッサをいじる場合には、クラスの中で小さいものを選んで使う事にしています。現在はBF592というプロセッサで離散的に遊んでいるのですが、この小さなプロセッサでキビキビ動作するOSを書いてみたくなりました。

名前も決めてあって、BlackfinとKOZOSをかけて、BlacKOZOSです。
とてもブラックな感じ。「ブラッコゾス」です。「ブッコロス」ではありません。

本体OSは何もないのに、キャラクタはもうあります。
完全に順番を間違っています。


"BlacKOZOS"の設計方針

設計は以下のように進める事にしました。

①普通に動作するだけのプログラム

普通に動作するだけのプログラムが、どうしてOSに発展するのか理解できないかもしれませんが、最初のタスクしか実行できないところから"BlacKOZOS"の開発をスタートさせる事にしました。これは、まさにOSを使うことで解決したい問題を提示した形です。ざっくり言うと、複数の仕事を並行し、かつ効率的に処理させたい、複数の仕事を協調動作させたい、という課題。


②割り込み関数でレジスタの退避と復旧

次に、①で動作している仕事を一切阻害する事なく、割り込み処理の中で①で使っているレジスタを退避、復旧させます。ここでは、コンテキストスイッチ、つまりタスクの切り替えは行わず、退避したレジスタをそのまま復旧させます。レジスタ周辺の操作は少しでも間違えると動作しません。このコンテキストスイッチなしのレジスタ退避復旧処理は、正しく実装できた時点で、みかけ上①と同じ処理を提供する事になります。つまり、レジスタの退避と復旧を正しく行いながら、依然としてかなり単純な実行モデルを維持できます。


③コンテキストスイッチを追加する

レジスタの退避復旧が実現できたら、コンテキストスイッチを追加します。②を先行させる事にはもうひとつ別の理由があり、②が実現できた時点でコンテキストスイッチは基本的にC言語で記述できるようになっています。どういうことかと言うと、レジスタ退避作業によって実行中のコンテキストを復旧するためのレジスタは保存されているので、それらをかなり自由に使うC言語を使ってレジスタを汚しても、レジスタ復旧で必要な値へ復旧できるわけです。リンクリストを辿ったりする作業をアセンブラで書くのも面倒なのでうってつけというわけです。


まとめ

今回は大雑把な設計方針について明らかにし、作業の道筋を立てました。
Blackfinの場合、割り込みマスクの取り扱いが1つのポイントかもしれません。
その辺りも後々触れていければと思います。

2014年6月30日月曜日

Windows、Mac OS、Linuxで動作可能なChaNさんのFM音源モジュールの簡易シミュレーター

http://elm-chan.org/junk/32bit/nxpdip.html#fmに掲載されたFM音源の実験で掲載されたコードは、移植性が高く小規模なマイコンでも動作する上、極めて素直に実装されていて「これは凄い!」と驚くばかりです。あぁ、優秀な人はこうやって設計実装できるんだなぁと実装の各所を見て感じました。


さっそく私も、金子システムのTUNA-CANなどに移植してFM音源の動作を楽しんでいるのですが、ここで移植の過程で最初に作ったシミュレーターのコードを掲載する事にしました。


ここからダウンロード


このコードはWindows、Mac OS、Linux上でコンパイル可能。出来上がったバイナリに出力WAVファイル名を与えると、エレピが単音で発音されるWAVファイルが出来上がります。Audacityで開いた時の様子は以下。


シミュレーターというにはお粗末な感じですが、これにChaN氏が作ったようなフロントエンドを被せれば立派なFM音源ソフトになります。マイコンをベースにしていると、あちこちに持ち歩くのも面倒ですが、PCベースなら色々な実験も楽!というわけです。

あぁ、楽しいなぁ!

2014年5月11日日曜日

WIZnet W5300始めました

今年の初めに、私にとって神様のように色々できちゃう方から「それなら、これをあげるよ。」と頂いてしまったW5300の評価キット(WIZ200WEB-EVB)をようやく触り始めました。


最近興味がもくもく湧いているjQueryとかBootstrap等と組み合わせて、色々なオモチャが作れるのではないだろうかと考えているところです。Node.jsなんかも楽しそうですが、まずはチマチマやろうと考えています。

2014年4月30日水曜日

Graphviz dotを使ってプロジェクトの関係図を作る

ちょっと思うことがあって、ここ数年のプロジェクトの関係をGraphviz dotを使って整理してみました。
青がハードウェア、黄はミドルウェア、緑はソフトウェアです。

ざっくり言うとmbedがここ数年の活動の起源になっていたのかな?と思います。


NXPのプロセッサが搭載されたBlackTankなるものを設計し、ツールやミドルウェアを整備したくなって、ここから「車輪の再開発沼」に突入しました。そして、Blackfinで「高価なツールを買わないとフラッシュに書けないですって!」と、フラッシュライターの開発が始まりました。まさに「ツール開発大好き」な人の典型的な感じです。しまいには、取扱説明書の作成に便利なLCD Toolとか、「誰が使うんだ!」と思わずツッコミを入れたくなります。

こんな感じで振り返ったのも、そろそろ違うことをやりたくなってきたからなのですが、一体何をやるのかは・・・まだ考えていません。

この関係図は以下のコードから生成しました。

digraph projects {

graph [label = "Projects"];

// Hardware Platform
"mbed" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"LPCXpresso" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"LPCXpresso Clock" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"BlackTank" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"BlueTank" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"ACB-BF592" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"TUNA-CAN" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"KOZOS EXPBRD" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];
"LPC800 Mini Board" [shape=circle, style=filled, color="#feeeee", fillcolor=blue, fontcolor=white];

// Firmware Solution
"NT-Shell" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"NT-Monitor" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"NT-Logger" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"NT-Basic" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"tinybmpio" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"tinywavio" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];
"UOS-LPC800" [shape=hexagon, style=filled, color="#feeeee", fillcolor=yellow, fontcolor=black];

// Software Solution
"Blackfin BlueBoot" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];
"Blackfin FastFlash" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];
"Blackfin MiniConfig" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];
"LCD Tool" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];
"kz_h8write" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];
"kz_xmodem" [shape=box, style=filled, color="#feeeee", fillcolor=green, fontcolor=black];

// The relationship
"mbed" -> "LPCXpresso" -> "LPCXpresso Clock";
"mbed" -> "LPC800 Mini Board" -> "UOS-LPC800";
"BlackTank" -> "BlueTank";
"BlackTank" -> "NT-Shell";
"BlackTank" -> "tinybmpio";
"LPCXpresso" -> "BlackTank";
"tinybmpio" -> "tinywavio";
"NT-Shell" -> "NT-Monitor";
"NT-Shell" -> "NT-Logger";
"NT-Shell" -> "NT-Basic";
"NT-Shell" -> "Blackfin BlueBoot";
"NT-Shell" -> "KOZOS EXPBRD";
"NT-Shell" -> "BlueTank";
"BlueTank" -> "LCD Tool";
"ACB-BF592" -> "BlueTank";
"ACB-BF592" -> "Blackfin BlueBoot";
"Blackfin BlueBoot" -> "Blackfin MiniConfig";
"Blackfin BlueBoot" -> "BlueTank";
"Blackfin BlueBoot" -> "ACB-BF592";
"Blackfin BlueBoot" -> "TUNA-CAN";
"Blackfin MiniConfig" -> "Blackfin FastFlash";
"kz_h8write" -> "kz_xmodem";
"NT-Basic" -> "KOZOS EXPBRD";
"kz_h8write" -> "KOZOS EXPBRD";
"kz_xmodem" -> "KOZOS EXPBRD";
}

AltStyle によって変換されたページ (->オリジナル) /