GPS/GNSSモジュールを試用する11 -GtopFlashToolの謎に迫る-

今回の記事はSTM32の内容にもがっちり絡んでくるのでカテゴリどうしようか
と悩みましたが結局GNSS関連としました。



前回、Gms-g9のファーム更新
の際にGtopFlashToolなるものを使用して
UART経由でファームウエアのアップデートを行っております。
その時にGPSロガーとして使用しているSTM32Primer2に仕込んだUSB-CDCから
ではうまくアップデートを行うことが出来なかったことを述べておりました。
今回時間が出来てようやく重い腰を上げて調べることになったのですが
そこには意外な結果が待ち受けていたのでした。


●COMポートが開かない??

Lチカから先になかなか進むことができないねむいさんが唯一実用レベルで作った
STM32Primer2ベースのGPSロガーはSTM32のUSBデバイス機能を利用して
GPS/GNSSモジュールのNMEAセンテンスの記録の他にUSB-CDCとUSB-MSCを
実現しております。

USB-CDC機能は主にGNSSモジュールのAGPS等の機能設定を仮想COMポートを
開いてシリアル通信の形で、USB-MSC機能はSDカードに記録したデータをPC上
から簡単にTXTファイル形式で参照できるように出来ております。


で、GlobalTop GPS Viewer(v1.8)からでは上記のとおり問題なくUSB-CDCの
仮想COMポートを開きバリバリ通信できるのですが…

なぜか同じGtopが提供しているGtopFlashToolからはCOMポートが開けません
みたいなエラーを吐いてアップデート作業ができません。

一方はちゃんとCOM開けてもう一方は開けないとかイミフだったのですが
検索しているとそれっぽい質問が見つかりました。
Windows環境下ではUSB-CDCをなし得るためにusbser.sysを利用するのですが
infファイルは自前で作らないといけません。MSDNの情報を基にinfファイルを
いじってインストールしてみましたが…やっぱりダメorz

>http://support.microsoft.com/kb/837637/ja
↑ja版のサイトは機械翻訳文
> ユニバーサル シリアル バス (USB) モデムの .inf ファイルは Usbser.sys
> ドライバーを使用して両方および Usbser.sys ドライバー .inf ファイルからを
> 直接参照できます。ただし、お勧めしませんこの。

人間の言葉しゃべれこの。


もしかしてGtopFlashToolが何らかのUSBの通信レベルで何かがコケて仮想
COMポートが見えて無いのかと思い埃をかぶっていた秋月ロジアナを用いてUSBの
プロトコルを解析してみたのですがUSBの通信上ではSTALLした箇所が
見つけられませんでした。
↑USBの解析できるまでのロジアナの設定で苦労しましたorz

ちょっと困り果ててしまいましたが鴨川を散歩してる最中にGPS Viewerから
仮想COM開けてたのを思い出してひょっとして何らかの固有の文字列をやり
取りしてCOM開いた判定してるのかと思ってUARTの通信を見たらなんと仮想COM
開けてて信号のやり取りまで出来ているようでした!ちゃんと開けてる
じゃないですかーヤダー!
しかも制御文字もちゃんと送信されてるのでUART周りは全く問題なしと
判断しました。
そもそも糞詰まり対策もやってダブルバッファリングまでしてるので
STM32のUARTレベルに関する点は問題はないです。
となるとやっぱりもっと上の階層の問題ですか…。


●別の仮想COMではどうなのか
依然述べたとおりFT232Rに代表される出来合いのFTDIのUSBシリアル変換IC
なら全く問題はなし、自作のUSB-CDCが怪しいと思い別の物を試してみました。

1.STマイクロ謹製のSTM32F1のUSB-CDCのサンプル(STM32F103/107共)
  ->できない
  ※私のSTM32Primer2のUSB-CDCはこれがベースです。
2. LPC2388のLPCUSBのUSB-CDC
  ->できない
3. STマイクロ謹製のSTM32F1/F2/F4用のUSB-CDCサンプル
  ->できるじゃない!
4. MBED CMSIS-DAPのVCOM(FRDM-KL25Zを使用)
  ->できるじゃない!

…ん?それじゃSTM32F1系のUSB機能がやばいのかしら???

5.Versaloon(STM32Primer2と同じSTM32F1系)のVCOM
  ->できるじゃない! orz
  ※VersaloonのUSBのソフトウエア側は独自実装


つまりSTM32のファームウエアの問題ですかorz
でもいろいろ試しててGtopFlashToolのエラーの出方の違いに気づきました!

先にGNSSモジュールをなにも繋がずにフラッシュ書き込みを実行しようと
すると駄目な方は繋いでも繋いでなくても"Fail to open the COM Port"
になってて行ける方はとりあえずCOMポートは開き何か読みに行ってるようで
"DL_HANDLE error code"になっていました。


●SEND_BREAK
というわけでSTM32Primer2のRlinkはOpenOCDでデバッグできないのでそれと
ソフト的に等価なSTM32F107VCTのUSB-CDCを用いて上の
"Fail to open the COM Port"になる瞬間をinsightで捉えました…
ら一瞬で原因が分かったorz


"Fail to open the COM Port"になる直前にVirtual_Com_Port_NoData_Setup()
という関数を通過していて引数に0x23が来てエラーを返していたことが判明。
この関数はホストから送られてくるUSB-CDC固有のリクエストを扱う関数の
ようで…

このページによれば0x23はSEND_BREAKに相当するものであるとのこと。
STM32F1USB-CDCのサンプルでは未サポートとしてエラーを返していたため
Gtop ToolはSEND_BREAKを実行できないCOMポートと判断して"COMポート
開けません"とエラーを返していたことが判明。

ってわけでSEND_BREAKのハンドルを追加してSEND_BREAKのリクエストが
送られてきたらとにかく"USB_SUCCESS"を返すようにしました。


おおっ!

GPSTr@ckerのUSB-CDCでもGms-g9のファーム書き換えできたじゃない♥

GPSViewerではSEND_BREAKは一切送信されていたなかったのでエラーに
ならなかった(=COMポートを開くことができた)ことが理解できました。

ところでSEND_BREAKって何か?ともっと調べてみるとUSB-CDC-ACMの規格
定められたものだようで文字通り"BREAK信号を送信せよ"という意味です。
そしてBREAKって何というとRS-232Cの規格で定められたものでTxDをスペース
(論理L)に固定する行為を指すとのこと。RS-232Cの電圧レベルでいうと
論理が逆転するので、一定時間+15Vに固定することになります。

そしてGTopFlashToolはなぜわざわざSEND_BREAKを送信していたかという
ことですが、それはMTK系のGNSSモジュールのファームウエアアップデートの
方法にあります。
MTK系モジュールはUART経由で特定のコマンドを受け取るとセルフアップ
デートモードに推移しますがその過程で現在通信しているボーレートから
セルフアップデート通信用に自動的にボーレートが上がります。
具体的には115200bpsに推移します。このときGtopFlashToolからCOMポート
経由でBREAK信号が送られているようです。
9600bpsから急にレートの高い115200bpsに上がって間違ったデータとして
受け取られないように一定期間データの送信を止める措置を行っている
わけです。



というところでいろんなマイコンのUSB-CDCの実装を見ているとSEND_BREAKに
対する取り扱いは現在ではごくまれにしか使われないためかまともにBREAK状態
になる実装はめったになく、適当にOKで返してるのが殆どです。逆に言うと
STM32F1系のUSB-CDCのサンプルはちゃんと"unsupported"で返してたから
マシだったのかも!?

そしてGitHubのGPSTr@ckerは既にGtopFlashToolでもちゃんとファームの
書き換えが出来るように修正済です。さらにFatFs0.10aに更新し今更ですが
USBライブラリもF1系最終のV4.0.0準拠にして益々最強に強めております!


●あのお方

今回いろいろ調べて最終的に気付いたのですがUSBのファームウエアがらみで
困っている人のもとに颯爽と現れ強力な解決策を提示して爽やかに去っていく
tsuneo氏がSEND_BREAKにもやはり言及されていました
私の中ではFatファイルシステムにChaN氏が居ればUSBにはtsuneo氏が
居るといった感じです。

そういう私は2014年の今でもUSBアレルギーが全く克服してないので
これを機会に今年はUSBを自分の物にすることをテーマに進めていきたいと
思います!

Go to top of page