pic serial bootloaderを試す 12F1822

ここ2~3週間ほどpicのbootloaderについて調べたり試したりしていて、実はうまく動作しなくて悩んでいましたがやっとうまく動作しました。
どれくらいpicのbootloaderに興味がある人がいるかわかりませんが、気づいた点など、纏めときます。
以下は全般的な話です。実際に試した内容は第6章から記載していますので、必要に応じて読み飛ばしてください。

1. 全般的なbootloaderの話

マイコンのbootloaderとは簡単に書きますと、ファームウェアを書き込むためのファームウェアと言った方が分かりやすいかと思ってます。
bootloaderがマイコンに書かれていれば、新しいファームウェアを書き込んで実行したいときにそのbootloaderがやってくれます。bootloaderを書いてしまえば、新しいファームウェア書き込みのために特別な装置(pickit3)などが必要なくなります。例えば、今のファームウエアをちょっと直したいところが見つかり、古いファームウェアが書かれたものを使っている人に新しいファームウェアのデータだけwebで渡せば、その人の環境でファームウェアのアップデートができる、といった具合です。そこで、pickit3などを別途購入して、、という風にはなりません。
私の場合のpicマイコンを使う用途では、ほとんどがmidi入力に対応していますので、midiデータを使ってpicのファームウェアを更新できるようにするのが最終的な目的です。その過程で、現状のUARTでのbootloaderを動作させ、理解する必要があったため、それを今回試しました。

2.bootloaderの種類

AN1310 high speed bootloader
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en546974

Tiny bootloader
http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm

そこで、bootloaderについて調べてみると上記2つがよさそうというところに落ち着きました。(他にもありますが、試していません)
AN1310は、microchip本家のbootloaderでファームウェアの書き込み以外にも、VerifyやFlash Erase、Readにも対応しています。
Tiny Bootloaderはその名のとおり、”小さい”ということから機能が厳選されています。そのためAN1310よりもbootloader自体のファイルが小さいというメリットがありますが、Flashの書き込みのみの対応になります。

実は上記二つのうちtiny bootladerで最終的には無事動作を確認しましたが、最初は勉強の意味を兼ねて、AN1310を試しました。私が今使っているpicには、12F1822以外に16F690もあり、最初は16F690で実機動作を確認してみました。
結果的に失敗に終わりましたが、最後までとある一点に気付かず時間を消耗してしまいました。勉強にはなりましたが。。
bootloaderをみると対応種類が多いため、あれではうまくいったけど、これだとうまくいかないというコメントが非常に多いのに気がつきます。だからと言って全部のpicを試すってのも現実的な話ではないですよね。。なので、全般的な話では、使用しているpicにbootloaderを適用するためのポイントをまとめています。

今回16F690もネット上ではまったく情報がなかったため、あれやこれや確認している過程で一点根本的なことに気がついてしまいました。。。

flashのself writeができないpicじゃん。

どうりでネット上にない訳です。AN1310のデバイスリストには、16F690が載っていたので、てっきり対応しているものだと思っていたら落とし穴でした。デバイスリストは単純にMPLABのデバイスリストからひっぱってきているだけなので、すべてのPICが載っている状態でした。

まずここで、bootloaderを試そうと思っているpicなのかを確認する最低限の項目として、最初に確認するべきは以下です。

3. bootloaderの適応できるかの確認項目

flashをself writeできるか、つまりFLASHを通常状態でwriteできるpicなのか

データシートを見てもらうとわかるのですが、FLASH / EEPROMの項目の部分にFLASH WRITEという言葉が載っているか確認して下さい。できるpicのデータシートには、だいたいFLASH Writeというサンプルコードも載っているはずです。(eeprom writeのことではないので注意)
16F690はFlashについては、READしかないというコメントがしっかり載ってました。。。。とほほ。
ただ、16F1828と1829が16F690とピンコンパチでself write対応してるので、そちらに乗り換えを検討しています。

当たり前じゃんと思うかもしれませんが、私はこんなことに気づくまでに結構時間をかけてしまいました。(思いこみってだめですね)

しかし、これだけでbootloaderがうまく動作するかというと結果的には、うまくはいきませんでしたので、私がモディファイ、チェックする必要性があった項目を纏めました。

ポートの設定
UARTのボーレート設定
FLASHの書き込み、消去のサイズ

ボートの設定
次の2ポートが正しく設定されていれば、bootloaderは問題なく動作します。UART用のTX(送信)とRX(受信)です。RXSTAとTXSTAが正しく設定されていれば、自動でTXとRXピンが設定されます。またTRISxでRxピンを入力にします。注意として、使用するpicによっては、APFCONというレジスタがあり、RXやTXを他のピンに割り当てられる機能がありますので、このレジスタもチェックし、TXとRXピンがどのピンなのか確認してください。
また、analog用のピンと共有している場合もあります。ADSELxレジスタも確認してください。

UARTのボーレート設定
ボーレートを設定するためには、コアクロック(Fosc)も正しく設定しないといけません。コアクロックはconfigとOSCCONで設定できると思います。内部オシレータを使用するのか、外部なのかを決めます。またPLLを内蔵しているものもあるようですので、その設定も確認する必要があります。

FLASHの書き込み、消去のサイズ
picによって一度に書き込みできるFLASHのサイズと消去できるFlashのサイズが違います。
bootloaderのファームウェアをみると、このFlashサイズによって、場合分けをしていますが、それが正しく場合分けされているのか確認してください。また、PICのシリーズには書き込む前に一度FLASHを消去しないと動作しないものがあります(ここも私ははまりました)。上書きでは、動作しないってことです。面倒ですが、一度FLASHを消去して、書き込むという手順をアップデート毎にやる必要があります。

4. 必要なファイル

1. bootloader firmware (xxxxx.hex)
2. application firmware (yyyyy.hex)
3. PC software (zzzzz.exe)

bootloader全般的に最低限必要なファイルは上記です。

1. bootloader firmware
これは、マイコンに駐在し、2.のapplication firmwareをFlashにself writeするプログラムです。
(注意これを書き込むためにpickit3などが最初の一回のみ必要です。
一回これを書いてしまえば、後はこいつがその後のファームをコントロールしてくれます。)

2. application firmware
これは、ユーザーが書き込みたいfirmwareです。

3. PC software
これは、2.のファイルをマイコンに送るためのPC上で走るソフトウェアです。

5. bootloaderの流れ

すでに上記の三つのファイルがある場合の動作の流れです。

1. PCとマイコンをつなぐ(UARTで)
2. マイコンの電源を起動
3. PC applicationでapplication firmwareをマイコンに流し込む(UARTで)
4. マイコンのbootloaderがPCから送られてくるfirmwareを受信する
5. 受信したfirmwareをFlashに書き込む
6. firmwareの実行

最小限、ファームを書き込むときのみの流れです。

以上、全般的な話しで、本題の実機で試してみた話に入ります。

6. 実際に試してみた。

使用したpcのアプリケーションはtiny bootloaderで、マイコンは12F1822です。
tiny bootloaderは以下のURLからダウンロード可能です。
http://www.etc.ugal.ro/cchiculita/software/tinyblddownload.htm
tinybldver198を使用してください。最新のtinybld1106は、新しいデバイスリスト(.ini)を更新してもそれがうまく認識されませんでした。 (注意windowsオンリーのプログラムです)

マイコンのbootloaderのプログラムとアプリケーションプログラム一式はこちらです。
12F1822_bootloader_af.zip (150kB)

使用するのは、

マイコンに常駐させる 12F1822_bootloader_revA.hex

アプリケーションファイル 12F1822_RA0-4_1S.HEX

アプリケーションファイル  12F1822_FA0-4_10ms. HEX

MPLABのプロジェクトファイルもいれてあるので、勝手にいじいじしてください。

bootloaderのソースはこちらのサイトのプログラムをモディファイしました。
https://sites.google.com/site/molec12f1822/home

試したapplication firmwareは以下の二つです。(上記一式のapplication fwフォルダに入っています。)RA0~R5ピンをHigh,Lowにするだけのものですが、スピードが違います。(約1sと10ms) 抵抗を介してLEDを接続するとわかりやすいです。

12F1822_RA0-4_1S.hex

12F1822_RA0-4_10ms.hex

接続は以下を参考にしてください。TXピンとRXピンを間違えないようにしてください。RS232ポートが私のpcにはありませんので、USB to Serialのケーブルを使います。D sub 9Fのコネクタのところです。また電圧レベルが違うので、MAX232を間に挟みます。(私はADM2303を代用で使っていますが問題ありませんでした) 後は、マイコンの電源5VとGNDを接続します。

手順

最初に行わないといけないのは、12F1822_bootloader_revA.hexをマイコンに書き込みです。

pickit3を使用して、書き込みます。持ってない方はこの際に購入するか、だれかに借りて~。

書き込みが完了したら、tinybldwin.exeを開きます。

ここで、一度閉じます。これはpiccodes.iniを生成するためです。

できたiniファイルをテキストエディタでオープンして、以下を追加します。

$22, B, 12F 1822,           $1000, $100,

これは、tinybldwinに”0×22″という値がきたら、こいつは”12F1822″だなと判断するために必要になります。

次に、再度tinybldwin.exeを開き、commポートを正しく設定します。接続したポートを確認してください。

スピードは9600です。

次にアプリケーションファイルを選択するために、browseボタンを押し、上記一式の中の12F1822_RA0-4~.hexファイルを選択します。

Write Flashを押した後にマイコンの電源を投入します。

tinywin.exeをみると書き込みがされているのがわかります。WRITE OKと表示されたら書き込み完了です。

しばらくするとRA0-4がHigh,Lowを繰り返しているはずです。

7. 仕組み

モディファイした項目とキーになる命令のピックアップして説明していきます。

まず上記のソース(12F1822_bootloader_revA.asm)の流れを説明します。

pcからはどんなデータ(データパケット)が送られているのかですが、

まず、pcから”0xc1″というデータが送られてくるので、それを受信したら、マイコンのbootloaderは”k”という値をpcに返します。それをpcが受け取り以下のデータパケットの送信を開始します。

AdrHighByte, AdrLowByte, #bytes, Pgm-memory bytes (DataLow, DataHigh)…, Checksum

AdrHighByteは、書き込みを行うFlashのアドレスの上位8bit(6bitしか使いません)
AdrLowByteは、書き込みを行うFlashのアドレスの下位8bit
#bytesは、固定のようで、64(0×40)がきます。つまり64bytesなので、32wordsです。
Datalowは、データの下位8bit
DataHighは、データの上位8bit
Checksumはエラー訂正用です。

picのFlashメモリのアドレスは14bit長でデータは16bitですので、このように上位8bit、下位8bitで分けてそれぞれデータが送られてくる訳です。

これをbootloaderが受信します。受け取ったデータは、まずはbuffer(RAM)にためていきます。NewPgmRcvBufferというのが0×20~0x6Fまで80個分用意してあります。

その後、buffer(RAM)をFlashに書き込んでいきます。
64byte分一気にやります。
しかし、12F1822のFlash write/erase blockは一度に16words=32bytesですので、2回に分けてやる訳です。

まとめると
pcからデータが0xc1かをチェックする
0xc1ならば、kを返す
pcがデータパケットを送信してくるので、書き込みアドレスを受信する
64bytesのデータを受信し、bufferにためる
bufferのうち32bytesをFlashに書き込む(書き込む前にFlashを消去する)
bufferのうち32bytesをFlashに書き込む(書き込む前にFlashを消去する)

となります。

上記を繰り返してapplication firmwareのデータがすべて受信したら、bootloaderはタイムアウトして、application firmwareを実行します。

また、bootloaderは電源起動時または、リセット解放時の特定の時間の間に0xC1を受け取らないとapplication firmwareを実行します。
一度application firmwareを実行したら、電源起動もしくはリセットをかけない限り、bootloaderモードには入りません。

特定の時間といったのは、コアクロックの設定によって変わります。

以上がbootloaderの一連の流れです。

コアクロックは、内部オシレータの16MHzに設定しました。
config設定を以下のようにし、MRSTをonにしてそれ以外を全てoffにしました。

__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF

uartのボーレートを9600bpsにするために固定値に設定しました。ソースファイル(.asm)を確認してください。

;====================================
Init_Bootloader:
;====================================
    BANKSEL ANSELA                      ; Switch ->Bank3
    clrf    ANSELA                      ; Port-A all pins are Digital I/O

    bcf     BAUDCON,BRG16               ; NOT Set BRG16 bit for low-speed baud generator
    clrf    SPBRGH                      ; Clear high-baud register
    ;movf    spbrg_value,w              ; Not used
	movlw	D'25'						; '25' is for 9600bps (at internal osc 16MHz)
    movwf   SPBRGL
    movlw   b'10010000'                 ; Enable Asyn-UART for SPEN=SerPort-enable & CREN=Continuous-Rcv
    movwf   RCSTA
    movlw   b'00100000'                 ; Enable Asyn-UART TXEN & BRGH=0/Low-speed
    movwf   TXSTA
    BANKSEL OSCCON                      ; Switch ->Bank1
    movlw   b'01111000'                 ; Internal oscillator = 16Mhz (FOSC determined by Internal-OSC block)
    movwf   OSCCON

txとrxのポートも設定します。

        BANKSEL TRISA
	movlw   B'00000010'                ; RA1 set as Input
        movwf   TRISA

元のファイルでは、flash blockの場合わけのルーティンで重要なコメントがコメントアウトされていたので、元に戻しました。
どうやら元のファイル試した方はpcのソフトが代わりにやってくれているのでコメントアウトしたようです。

    #ifdef      PgmBlockSize16              ; Use programming block size of 16 words (BlockCount should be 2)
    lsrf    BytesInBlock,F
    rlf     BlockCount,F
    #endif

2回目の32byteの処理のところで、flash eraseの処理が一回足りなかったので、もう一回やるようにしました。

RedoLoop:
    movlw   0x20			; This is the number of BYTES inside one write-block (16words = 32bytes for 12F1822)
    movwf   BytesInBlock
    incf	EEADRL, F
    ;goto	WriteLoop		; Should go to ErasePgmMem again ...to erase more 16 word(32byte) block.
    goto	ErasePgmMem

8.最後に

とてつもなく長い記事になってしまいましたが、これからserial bootloaderをpicで試す方の参考になれば、幸いです。

あ~、記事書くの疲れました。

実はこれはゴールではなく、”midi bootloader”を作るのが目標ですので、それを今検討してます。

また、他のpic 16F1828, 1829についても試してみたいと思います。

以上

2件のコメント »

  1. [...] 前回は、bootloaderの仕組みなどを12F1822ベースで記載しましたが、他にも使用したかった16F1828/9にもbootloaderを対応させたました。 [...]

    ピンバック by pic serial bootloaderを試す 16F182xにも対応 | Analogfeeder — 2014/04/05 @ 02:35

  2. [...] ブートローダーの仕組み等はこちらに詳細を記載していますので、参照ください。 [...]

    ピンバック by midi bootloader for pic 完成 | Analogfeeder — 2014/04/30 @ 00:10

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする