ラベル h8write の投稿を表示しています。 すべての投稿を表示
ラベル h8write の投稿を表示しています。 すべての投稿を表示

2011年5月28日土曜日

野良管理していたソフトウェアをsourceforgeでホスティングする事にしました。

先日まで野良管理していたソフトウェアですが、sourceforgeで正式に(?)ホスティングすることにしました。バージョン管理はgitを採用しています。


Natural Tiny Shell (NT-Shell)

以下のウェブページからアクセス可能です。


H8/3069F writer for KOZOS (kz_h8write)

以下のウェブページからアクセス可能です。


ドキュメントなどもこれから充実させていく予定です。

2011年5月26日木曜日

H8/3069F writer for KOZOS - kz_h8write 「h8writeリベンジ解決編」

概要


先日の記事で勢いよく「改良しました!」と宣言したh8writeですが、やっぱり書き込みに失敗するという事がわかりました。
そもそも真の原因を掴めないまま改良したと言っても、何を改良したのか意味がわかりません。
自分でもそんな突っ込みを入れたくなるのですが、その日はグングン快調に書けていた上、オリジナルで実行するとやっぱり書けないという状態で、完全に勘違いモードに突入していました。


既に行く先の見えているH8/3069Fに肩入れするつもりはなかったのですが、KOZOS本(と著者!)が楽しくて仕方がないのと、宣言して出来なかった悔しさから本格的に問題を追及すべく、データーシートを片手にh8writeのソースコードを本格レビューしていくことにしました。

判明した事実


データーシートのプログラミングシーケンスを数分眺めていて、すぐに気付いたことがあります。

先日までは、プログラミングシーケンスなど気にも留めていなかったのです。
なぜなら10年もの間、皆さんが使い倒していて、正常に動いていたからです。
そこにあえて突っ込みを入れる必要はないだろうと思っていたのですが、ここが肝心な部分でした。

問題となっているのはホスト側のボーレートをマイコンが自動検出するメカニズムの部分です。

まずはデーターシートを見てみましょう。


このシーケンスで重要なのはホストからブートプログラムに送られる0x00です。

図にもあるように「MAX30回」です。
この意味が重要です。
決して、「いつも30回」ではありません。

それでは、h8write.cを見てみます。


関連する定義は以下のようになっています。


上記でお分かりのとおり、「最大30回」ではなく、「常に30回」送信しています。
これの何がいけないのでしょう?

答えはデーターシートに書いてあります。


要するにブートローダが合わせ込み完了を通知したら、次の状態に遷移しているのです。
では、遷移した先の問い合わせ選択コマンドとは何なのか?見てみましょう。


デバイスに関する様々な情報をホストが問い合わせするためのコマンドを受け付ける状態のようです。

要するに既にブートプログラム側は「ビットレート合わせ込みシーケンス完了」を宣言し、全く異なるシーケンスを持つ次の状態に遷移しようとているのに、ホスト側がだらだらとビットレート合わせ込み用データをまだまだ垂れ流しているというわけです。

これはいけません。

本来は、ブートプログラムから「ビットレート合わせ込み完了」が来た時点で、以下の図の赤で囲ったシーケンスを実行しなくてはならないからです。
だらだら0x00を送っているということは、本来確認用コード0x55を送るべきところで、0x00を送っている事を意味します。


オリジナルのh8writeの出力をもう一度確認してみます。


当然ながら実装の通り、ブートローダから「合わせ込み完了」が返ってきているにも関わらず、どんどん0x00を送出しています。


上記例は”たまたま”うまく動作している時の例です。
”たまたま”の根拠は先ほど挙げたデータシートの通りです。
明らかにデータシートで示唆されたシーケンスとは異なる事がわかります。

次に示すのは互いのシーケンスが一致していない事による失敗の例です。
失敗する時と明らかなタイミングの違いがあるかと思ったのですが、そのようには見えないのが不思議です。紙一重で動いていると言う事なのでしょうか?


ここで、ふと疑問に思われる事でしょう。
「なぜ皆はうまくいっているんだ?」
システムではよくある話ですが、おそらく偶然動いているだけです。

これにはいくつものタイミングが絡んでいます。
  • ソフトウェアが処理を行うまでの時間。
  • シリアルポートドライバが処理を開始するまでの時間。
  • カーネルが処理を開始するまでの時間。
  • H8側のブートプログラムが合わせ込みを完了するまでの時間。
  • H8側のブートプログラムが次の状態へ遷移するまでの時間。
特に、近年はレガシーポートが姿を消しています。
USBの先にシリアルポートデバイスが接続されるような場合には更にタイミングが従来より異なるでしょう。

まさに今回のh8writeの問題はここに原因がありました。
従来は偶然書けていたのです。

h8writer for KOZOS - kz_h8write


h8writeは長年沢山の方々がお使いになっていて実績という意味では申し分ないのですが、実装が美しくありません。
車輪の再開発をするつもりはないのですが、頭の整理も兼ねて綺麗に実装しなおすことにしました。

プログラムは「KOZOS本と一緒に使う」という意味でkz_h8writeと名付けました。

kz_h8writeは以下の要素から構成されています。
  • motモジュール(motファイルを読み込むモジュールです。)
  • serialモジュール(シリアルポートを制御するモジュールです。)
  • kz_h8write(全体の制御を行うモジュールです。)
オリジナルh8writeの実装は各機能が癒着気味で修正の影響が見えにくくなっていました。
また、失敗した時に何の処理で失敗したのか見当がつきにくかった問題もあります。

問題のビットレート合わせ込みは以下のように実装しました。
データーシートにあるように計測用マーカーを送信して、ブートプログラムからの返答を確認した時点でこちらも応答を返すという手順にしてあります。


実際のやりとりもロジックアナライザで観察してみました。
ホストからのビットレート合わせ込み用コード(0x00)に対して3回目には応答が返ってきています。


kz_h8writeは応答があった時点でデータシート通り、確認用のコード(0x55)を送出しH8から返答(0xE6)を受けています。


これでホストとH8は合わせ込まれたビットレートで正しく通信できるわけです。

kz_h8writeコマンドツールにはmotファイル名、クロック周波数[MHz]、シリアルポート名を与えて使用します。

kz_h8write kzload.mot 20 /dev/ttyUSB0

各シーケンスが実行されていく様子を確認する事ができます。

=======================================
 KOZOS H8/3069F Flash Writer.          
 Copyright(C) 2011 Shinichiro Nakamura 
=======================================
Bitrate sequence: Done.
Inquiry device: Done.
Select device: Done.
Inquiry clock mode: Done.
Select clock mode: Done.
Select bitrate: Done.
Write erase: Done.
Complete.

全ての作業が完了した時には「Complete.」と表示が行われます。

今回の実装で複数の環境で昨日今日と試していますが、期待通りに動いています。
※まれに電源投入後1回目は失敗するのですが、もう一度実行するとうまくいきます。

前回と異なるのは明らかにおかしい箇所を修正したバージョンだということです。
原因(の1つ)を解明して修正していますので、先日の「何だかわからないけど動くようになりました!」とは意味が違います。

このkz_h8writeを暫く使ってみようと思っています。

ソースコード


LinuxとWindows上で動作させることができます。
ソースコード:ここからダウンロードして下さい。

(2011/05/28追記)
http://sourceforge.jp/projects/kz-h8write/で管理することにしました。
最新版は上記サイトからダウンロードして下さい。

ライセンス


MITライセンスを適用します。
商用、非商用を問わず自由にお使い頂けます。

関連リンク


2011年5月23日月曜日

Linux上でH8/3069の書き込みに失敗する件 (h8write for KOZOSを実装しました)

(2011/05/25追記)
この記事で取り上げられているh8write for KOZOSの対策は本質的な解決策を示していません。
後日取り上げる別の記事で「リベンジ解決編」をお届けする予定です。
暫くお待ち下さい。

(2011/05/26追記)
この投稿記事で取り上げられている内容は本質的な解決策を示しているとは言えませんでした。
そこでH8/3069F writer for KOZOS - kz_h8write 「h8writeリベンジ解決編」を公開しました。

h8write for KOZOSって何?
h8writeはMitsuiwa Yukioさんが実装したH8書き込み用ツールです。
(ウェブ:Open SH/H8 writer)
このh8write for KOZOSは三岩さんが実装したオリジナルのh8writeの実装修正バージョンです。

主にKOZOSをLinux上で体験したい方に向けて公開します。

KOZOSとは坂井弘亮さんがフルスクラッチで設計実装されたOSで「組み込みOS自作入門」という書籍の題材にもなっているOSです。


これがかなり面白い内容で、坂井さんのオリジナリティ溢れる視点で最後まで楽しく読む事ができます。ちなみにこんな勢いで読み進める事ができます。

KOZOSについては以下のページもご覧下さい。
http://kozos.jp/kozos/

さて、本題です。

この書籍ではプラットフォームに秋月電子通商H8/3069Fネット対応マイコンLANボードが使われています。

実は、H8がプラットフォームとして選択されていたので、敬遠していたのですが、「これはやっぱり面白い」と書籍の内容を一目見て衝動買いしてしまいました。それも、随分と前・・・。

随分と前に購入しておきながら、なぜ触れなかったかと言うと、書き込みツールであるh8writeで書き込みができなかったからなのです。

私は個人的に開発環境にUbuntuを好きで利用しています。Windowsの端末環境では開発がスムーズに進まないからです。実際にh8writeをコンパイルして動作させてみると、稀に書き込みに成功するものの、殆ど失敗します。

私は「OSを作りたかった」わけなので、「h8writeのデバッグがしたかった」わけではありません。
プライオリティの関係から少しずつ放置状態になっていました。
(皆さんの中にもこういう方はきっといるはず。)

ふと思い立ちh8writeのソースコードを調べてみたところ、実装があまり美しいとは言えません。

シリアルポート周辺の実装を見るとなんだかごちゃごちゃしています。
そして、今回問題となっているのはシリアルポート周辺処理です。

問題を後々整理できるようにと、第1段階としてシリアルポート周辺処理を整理することにしました。
また、この過程で気になる実装を修正して完成したのがserial.cとserial.hです。

このserial.cとserial.hにシリアルポートの処理を任せた実装が私の改良実装版です。
そして、「ダメ元」で試してみたところ、かなりの確率で書き込みに成功することがわかりました。

そこで、この実装をh8write for KOZOSと名付け、早々に公開することにしました。

どうしてオリジナルではいけないの?

オリジナルではいけないということはありません。
このh8write for KOZOSはオリジナルのh8writeで書き込みに失敗する方のためのツールです。

近年、レガシーポートがコンピュータから姿を消し、結果的に当該ボードにはUSB-シリアル変換ケーブルを使って書き込む事が多くなっているように思います。

KOZOSの書籍で扱っているH8は3069です。
実は、オリジナルのh8writeでは、USB-シリアル変換ケーブルを使うケースにおいて、一部の環境で書き込めない問題が発生しています。

実際に調べてみるとH8/3069の書き込み時には、ボーレート9600でCPU情報を確認した後、COMポートを一度クローズし、ボーレート19200で再オープンして書き込みを行っている事がわかりました。

オリジナルのコードではこのボーレートを指定しながらのオープン・クローズ処理周辺の実装に問題があるように見えました。

と言っても、ツールの実装当時から見ると、カーネル側の処理も随分変わりましたし、USB-シリアル変換ケーブルに搭載されたデバイスのドライバの実装の甘さも関連があるかもしれません。

そこでシリアルポートの処理を中心に実装を試験的に見直し、書き込みに失敗する幾つかの環境で試行してみたところ、うまく書き込めることがわかりました。

ダウンロード

こちらからソースコードをダウンロードして下さい。
簡単なMakefile付きです。

Ubuntu 10.10上でのみコンパイルと動作を確認しています。
その他の環境での動作確認等が出来ましたら、是非御報告頂ければ幸いです。

(2011/05/26追記)
この投稿記事で取り上げられている内容は本質的な解決策を示しているとは言えませんでした。
そこでH8/3069F writer for KOZOS - kz_h8write 「h8writeリベンジ解決編」を公開しました。

何が違うの?(実装面)

  • シリアルポートの実装を分離しました。
  • シリアルポートの実装を見直しました。
  • 関数名を一部変更しました。
  • Windowsに対する実装サポートはバッサリ削除してあります。

何が違うの?(実動作)

うまく動作することがわかったら、どんな風に実動作が異なるのか知りたくなります。


オリジナルのh8writeを使って書き込みに失敗する環境を用意し、観察してみます。
確認したのは「最初にH8にデータを送信する箇所」です。

NG: オリジナルのh8write


OK: 改良実装版h8write


最初に送信するデータはボーレート9600で送信されます。
なんだか、最後の方が異なります。
もう一度書いておきますが、シリアル周辺の実装を修正しただけです。


続くパケットではプロセッサの種別を確認するのですが、オリジナルの実装ではこの時点で動作していないことがわかりました。

まとめ

h8writeの実装には気になる点がいくつもあります。
今回は深追いをせずにシリアル周辺の実装のみを修正して効果を確かめました。

今のところノートパソコン、デスクトップに作った2つの環境で書き込みが出来ています。
実は、この2つの環境はオリジナルのh8writeでは書き込みに失敗します。

本来であれば、もう少し丁寧に追い込まなければならない点が残っています。
しかし、かなり多くの方が「書き込めない」で困っている様子(私自身がそう)でしたので、早めに公開することにしました。

皆さんのh8writeの問題が解決し、KOZOSを楽しんで頂ければ幸いです。

(検証に御協力頂ける方)Linuxディストリビューション名と使ったUSB-シリアル変換ケーブルなどもろもろの情報と共にhttp://groups.google.com/group/kozos_tomonokaiまで動作結果を御連絡下さい。

(2011/05/26追記)
この投稿記事で取り上げられている内容は本質的な解決策を示しているとは言えませんでした。
そこでH8/3069F writer for KOZOS - kz_h8write 「h8writeリベンジ解決編」を公開しました。

ライセンス等
  • ライセンスはオリジナルに従います。
  • 但し、serial.cとserial.hをh8write.cと切り離して用いる場合、MITライセンスを適用します。
  • 使用した如何なる結果についても、当方は責任を持ちません。