2016年9月10日土曜日

STM32F1のブートローダのUSART

FreeRTOSとかJPEGカメラとかモータードライバとかやりたいんだけど、何を血迷ったかBootloaderのSerialインターフェースを叩いてる。

STBee使ってるなら大抵はDFUを使ってるだろうし、STM32F4ならマイコン自体にUSB DFUが標準搭載だし、JTAGを使ってる人ならJTAGで書くだろうけど、STM32にはチップ自体にFlashを書き換えるプログラムが搭載されている。

このプログラムを呼び出すにはBoot0を1に、Boot1を0にした状態でマイコンをリセットすれば起動し、その後に外から何らかの操作を行えばそれに合わせて更に分岐していく。
例えばリセット後にUSART1に0x7Fを叩けばUSART経由でROMを呼んだり書いたりいろいろできる。

一番最初のプログラムについてはAN2606 "STM32(TM) microcontroller system memory boot mode"という資料が参考になる。
USARTのブートローダについてはAN3155 "USART protocol used in the STM32 bootloader”という資料が参考になる。


さて、USARTを叩いた時にハマった点について。
ちゃんとANに書いてあるから「PDFをよく読め」で一応答えになるけど、もうちょっと詳しく。



まず通信の設定。
一番最初の0x7Fでボーレートを自動設定するので、ボーレートは結構自由に設定していいらしい。一応9600-115200が動作範囲だが、もっと早くしても動く場合もあるようだ。ただし3.3VレベルのRS232だから、配線等によっては高速動作は難しい場合も有ると思う。
あと、電子工作ではあまり使わないが、BootloaderではパリティをEvenに設定してやる必要がある。
その他は通常の設定と同じで、1bitスタート、1bitストップとなっている。


次にブートローダの起動。
前述のとおりシステムメモリを起動してUSARTに0x7Fを送ればUSART Bootloaderが起動する。この際ACK(0x79)を返して正常に起動したことが通知される。
USART BootloaderではACK(0x79)やNACK(0x1F)が使用されるが、これはASCIIコードのACK(0x06)やNAK(0x15)ではないので注意すること。

一旦ブートローダが起動してしまえば0x7Fを送ってもACKが帰ることはない。
自前でBootloaderを叩くプログラムを作る場合はBootloaderが起動済みに0x7Fを送ってもACKが返らない、という自体に対処する必要がある。
Bootloaderでコマンド待ちになっている場合は2バイトを受信し、そのバイト列が正常ならACKを返し、それ以外はNACKを返す、という動作をする。
つまり0x7Fを送ってACKが帰った場合は正常に起動、何も返らない場合はもう一度0x7Fを送信し、NACKが変えれば起動済み、2回目にも返答がない場合は異常状態として終了、という手順を踏むことになる。(2回目は0x7Fでなくてもいいが、一番無害なのは0x7Fだと思う。)


正常に起動した場合は次にコマンドを実行することになる。コマンドは何種類かあるが、AN3155に書いてあるので詳細はそちらを参照のこと。
Read Memoryコマンドを例に上げると、コマンドコードは0x11となる。コマンドを叩く場合はコマンドコード+その補数の2バイトを送信するので、0x11 0xEEの2バイトを送信する。
正常に受理された場合はACKが帰る。NACKが帰る場合は補数の計算結果が合わなかったりコマンドが存在しなかったりということが考えられる。
ACKもNACKも返らない場合は2バイト区切りのタイミングがずれている可能性がある。

コマンドが正常に認識されたら、次は開始アドレスを送信する。これは32bit(4バイト)で表し、上位バイトを先に送る。次に先の4バイトをxorした値をチェックサムとして送信する。マイコン内で計算したxorと一致した場合は正常と認識されACKが帰る。もちろん一致しない場合はNACKが帰る。

開始アドレスが決定されたら次はデータ長を送信する。データ長は1バイトで、つまり最大256バイトまでしか得られない。
データ長は(欲しいデータ数 - 1)を送信する。例えば0を送れば1バイトが読めるし、255を送れば256バイトを読むことができる。
データ長についてもビット反転等を考慮してチェックサムを送る。ここでのチェックサムというのは先に送ったバイトの補数となる。
ここで補数が正しい場合はACKが帰り、直後に要求したデータが帰ることになる。
ちなみにBootloaderから送られてくるデータにはチェックサムは付属しない。ということで読んだデータがビット反転等を起こしていないことは保証されない。


例えばデバイス署名の0x1FFFF7E0(Flash容量)を読んでみると、0x00 0x02が帰り、STM32F103VEの512kbyteに一致する。
ただし0x1FFFF7E2(RAM容量)を読むと0xFF 0xFFが帰り、不正な値となる。



まだイマイチ理解できていないが、おおよそ動くことはわかった。USARTでFlashを焼いたりできるようになれば、XBee経由で書き換えとかもできるようになる。ということでバッテリーで動きまわるようなものを作るときには便利なんじゃないかな。

本家の書き込みソフトもあるけど、最近STのダウンロードはユーザー登録が必要になり、面倒なのでまだ登録していない(会社名書けとか言われても困るし。。。)。
以前にユーザープログラムとしてUSARTでデータを受けてFlashを書き換えるヤツも作った気がするが、コレはこれでROMを圧迫するとか、一々先頭を変更しないとダメとか、いろいろ大変。
せっかくマイコン内にBootloaderが有るんだから使ってみるのも手だろうと思ってる。

0 件のコメント:

コメントを投稿