SNSへはこちら

AVRマイコンでブートローダーを自作(2) - シリアル通信を実現する

続いて、ブートローダーの基本となるシリアル通信を実装します。
各種コマンドの実装は次回です。焦らず進んでいこうね。

ブートローダーの核となるUART

ブートローダーの役割を簡単に確認します。

そもそもブートローダーは主に以下の役割を担うと認識しています(多分正式ななにかは存在しない):

  • プログラム領域へのデータ読み書き
  • EEPROM など、不揮発性メモリへのデータアクセス
  • メインプログラムへのジャンプ(実行)

多分これに尽きると思います。他にも独自プロトコルのデバッグプローブ接続とかあると思いますが、細かいところは除外します。

プログラム

こんな感じよ。既存のコードを一部コピペしただけですが、HFUSE を 0xD8 (ブートローダー起動) にするか 0xD9 (ユーザープログラムコード実行) にするだけで挙動が変わるプログラムを作成したという点で目新しいと思います。

.include "../m328pdef.inc"
.device atmega328p

.def tmp = r16

.cseg
.org 0x0000
jmp main

main:
    sbi DDRB, 1
    sbi PORTB, 1
    jmp main

.org 0x3800
jmp bootloader_main

uart_init:
    ldi tmp, 0
    sts UBRR0H, tmp
    ldi tmp, 51
    sts UBRR0L, tmp ; set baud rate to 9600 bps

    ldi tmp, (1<<RXEN0) + (1<<TXEN0)
    sts UCSR0B, tmp ; enable tx and rx

    ldi tmp, (0b11<<UCSZ00)
    sts UCSR0C, tmp ; Set frame format: 8data, 1stop bit
    ret

.def data = r18
USART_Transmit:
    ; Wait for empty transmit buffer
    lds tmp, UCSR0A
    sbrs tmp, UDRE0
    rjmp USART_Transmit
    ; Put data into buffer, sends the data
    sts UDR0, data
    ret

USART_Receive:
    lds tmp, UCSR0A
    sbrs tmp, RXC0
    rjmp USART_Receive
    lds data, UDR0
    ret

bootloader_main:
    rcall uart_init
blmain_loop:
    rcall USART_Receive
    rcall USART_Transmit
    rjmp blmain_loop

これを書き込んでブートローダーから起動するように Fuse を設定してあげると、PB1 に取り付けた LED は消灯したままシリアル通信データがエコーバックされると思います。念の為、以下に UART のピン配置を示しておきます。書き込み用の FT232RL を使っている場合、UART 用の FT232RL も必要となるということですね。金を積んで買おう!!

マイコンピン番号 マイコン側ピン名
2 RXD
3 TXD

動作

HFUSE を 0xD9 にするとユーザープログラムが実行され、LEDが点灯します。

$ avrdude -c ft232r -p m328p -U hfuse:w:0xD9:m # ユーザープログラム実行。PB1のLEDが点灯。

一方、HFUSE を 0xD8 にすると BOOTRST ビットがセットされ、ブートローダー起動の後に、UART でエコーバックされます。

$ avrdude -c ft232r -p m328p -U hfuse:w:0xD8:m # ブートローダー起動。9600bpsで送信されたデータをそのまま返す。

以下が実行風景の再現です。

1234ABC AVR # こちらが入力データ

1234ABC AVR # このようにそのまま文字列が返ってくる

進捗は多くはないですが、これにてブートローダー経由で UART 通信をすることが可能と確認できました!
あとはこれを利用してフラッシュ読み出し、フラッシュ書き込みコマンドを実装すればとりあえずオレオレブートローダーを設計できますね!

次回はこのオレオレブートローダーを実装して AVR アーキテクチャの機械語手打ちという変態行為を行うことを目標とします。