2011年5月14日土曜日

LPC1769の内蔵ブートローダを使って書き込みに失敗する環境がある(lpc21isp使用時)

概要

ARM Cortex-M3で遊ぼうということで設計したNXP LPC1769搭載基板
グダグダと色々なファームウェア部品を作ったりして楽しんでいるわけです。

このボードには「いつでもどこでもLPC1769」という裏コンセプトがあり、
  • 「だいたいパスポートサイズ」
  • 「USBバスパワーで動作する」
  • 「内蔵ブートローダで書き込みができる」
といった特徴があります。
ノートパソコンとこのボードとUSBケーブルさえあれば、開発を楽しむ事ができる仕組みです。
「ちょっとしたデモ」であれば十分対応できます。

この特徴を生かして今日の今までノートパソコンを使った開発で楽しんでいました。
ふと思い立って自宅の大画面環境で作業した方が効率も良いし・・・と思った時の事です。

なんと、LPC1769の内蔵ブートローダを使った書き込みに失敗します。
何度やっても再現性100%で。

どちらもVMware Player上に仕立てたUbuntu 10.10で行っています。
プロジェクトのリポジトリから書き込みスクリプトを含む全てのリソースをチェックアウトして作業しています。

異なる可能性があるとすれば、ローカル環境設定とツールのバージョンくらいでしょう。
これに依存する何かが書き込み時の起こっているとは考えにくかったのですが、「おかしい、おかしい」と言っているだけでは前に進みません。

そこで先日購入したロジックアナライザでちょっと見てみることにしました。

正しく動作する環境

まずは正しく動作する環境の方です。
lpc21ispのバージョンは1.79です。



正しく動作しない環境
次に正しく動作しない環境の方です。
lpc21ispのバージョンは1.64です。



さて、何か変ですね?
ちょっと見比べてみましょう。
上側は動作する時、下側は動作しない時の要求と応答です。


整理してみます。

lpc21ispのバージョン状況lpc21ispLPC1769Synchronized確認トークンの補足説明
1.79正しく動作するSynchronized\nSynchronized\nOK\r\nlpc21ispとLPC1769で一致している。
1.64正しく動作しないSynchronized\r\nSynchronized\rOK\r\nlpc21ispは\r\nをセパレータとして使用している。LPC1769はそれとは異なるセパレータを返す。(ように見える)

「ように見える」と書いたのは、ここがポイントだからなのですが、それは後述します。

この手の書き込みプロトコルは、ターゲット上の内蔵ブートローダとホスト側のアプリケーションの協調動作で成り立ちます。
例えばアプリケーション側から「XXXだぜ!」と要求を受けて、内蔵ブートローダが「おっけー!」という具合です。
例に漏れずLPCシリーズの内蔵ブートローダもそのようになっています。

上記2つの環境間で異なるのはトークンセパレータのようです。
では、どちらが本来の実装なのでしょうか?

データシートを見てみます。


「全てのISPコマンドは単一のASCII文字列で送られなければならない。」
「文字列はキャリッジリターン と/か ラインフィードによって終端されなければならない。」

原文の「and/or」を「と/か」と訳しました。
要するに正解は
  • CR
  • LF
  • CR + LF
と、どれでも良さそうに書いてあります。

何かこの辺りの問題がありそうなのはわかりました。
では、立ち返って現象を見てみます。

user@ubuntu:~/Projects/TOPPERS-ASP-for-BlackTank-LPC1769$ ./devwrite.sh 
lpc21isp version 1.64
File TOPPERS-ASP_BlackTank-LPC1769.hex:
loaded...
converted to binary format...
image size : 115032
Synchronizing (ESC to abort). OK
No answer on Oscillator-Command

「オシレータコマンドの返答がない。」と言っていますね。
これが最後のやり取りのようです。

応答がないため、アプリケーション(lpc21isp)がそれ以降の処理を中止して終了するわけです。
でも、実際にはLPC1769から応答が返ってきています。

先ほど見た「Synchronized」は非同期シリアル通信の通信速度を自動判別する部分です。
これは書き込み動作の前の最初の操作ですから、オシレータコマンドとは関連ありません。

オシレータコマンドのやりとりを探すために、トリガがかかってからのサンプル数を増やしてみます。
以下は正しく動作しない環境でのやりとりです。


やりとりは以下のようになります。
  • アプリケーション:「4000で頼む。」
  • 内蔵ブートローダ:「4000ね。おっけー!」
さて、正しく動作する環境で見てみましょう。


面白いのはアプリケーション側からやってくるセパレータによって、内蔵ブートローダ自身が用いるセパレータも変えてくるという点です。

但し、上記動作を見て下さい。
アプリケーション側が2つのセパレータを送った場合、内蔵ブートローダは先頭のキャラクタのみを採用するようです。
また、「OK\r\n」という固定的な返答も見られる事から、混在しているようにも見えます。

この動作は、アプリケーション側がデータシートに書いてある通り「CR」でも、「LF」でも、「CR + LF」でも正しく動作するよう実装してあれば問題ありません。

ですが、私の手元にあった古いlpc21isp (Version 1.64)ではそうなっていないということがわかりました。

本来であれば、このコマンドに続いてアプリケーション側から書き込み用のデータが送られてきます。
しかし、失敗する環境では「返答がない。」と判定されていました。
恐らくセパレータの解釈に問題があるのでしょう。
もしかしたら、受信側のセパレータの解釈に問題がありながら、送信側で対応したのかもしれません。その証拠に2つのバージョンでは送信するセパレータが異なる事がわかります。

この件に関して言えば、最近のバージョン (Version 1.79)では修正されているので心配ありません。
LPC1768やLPC1769を使う方の御参考までに。

おわりに

この手の問題は実際に色んな調査をしてみなければ原因がわからないことが多いので大変です。

今回のケースでは「あぁ、lpc21ispが古いのだなぁ」と片付ける事もできます。
ですが、「2つのバージョンでどのように異なり、その差異の何が問題となるのか?」を調べることで安心して使用できるようになります。

ウェブ上にある情報は断片的なものが多いのですが、「どのような問題があり」、「それをどのように解決したのか?」を自分のために整理すると意外に面白い発見になるのかもしれません。

0 件のコメント:

コメントを投稿