Upload
dinhdieu
View
266
Download
7
Embed Size (px)
Citation preview
Arduino 原始碼讀書會
(II) : Bootloader 解析
講者介紹
郭宏澤
瞻營全 RD
◦ 等級1
◦ 打怪練級中
技能: 86Duino 未來 軟體維護與擴展
講者介紹
林恩州
瞻營全 RD
◦ 等級3
◦ 目前與郭宏澤一起 組隊打怪
技能: 86Duino 基礎 軟體開發
7:00 ~ 7:40 讀書會分享 I
7:40 ~ 8:00 問題討論&休息
8:00 ~ 8:40 讀書會分享 II
8:40 ~ 9:00 問題討論&結束
進行流程
找出 bootloader 原始碼
Arduino 原始碼根目錄
改過的 Processing IDE 原始碼 (Arduino 相關)
Processing IDE 原始碼
存放編譯結果的目錄
Arduino Bootloader, Standard API 原始碼
Arduino Library 原始碼
hardware → arduino
各種版本 bootloader 原始碼
Standard API 原始碼(共用部分)
各種周邊配套的處理器韌體
Standard API 不共用部分
定義 Board 選單及編譯參數
定義 Programmers 選單及燒錄參數
hardware → arduino → bootloaders
Duemilanove , Diecimila , Nano , Fio .......
Arduino NG or older w/ ATmega8
BT ATmega328 , BT ATmega168
Arduino Robot
LilyPad Arduino USB
Leonardo , Micro , Esplora
LilyPad Arduino ATmega168
Uno , Mini ATmega328 , Ethernet
Mega 2560 , Mega ADK
本次原始碼解析目標 (其它bootloaders可以此類推)
UNO Bootloader
optiboot source
code
已編譯好的各種版本 16 進位檔
Leonardo Bootloader
caterina source
code
已編譯好的各種版本 16 進位檔
各種版本
bootloader 說明
Serial Bootloader 解析
--- 以 UNO 為例
Arduino UNO Bootloader
Arduino UNO 使用了 optiboot,優點:
◦ 佔用空間只有1.5kB
◦ 鮑率115200,上傳程序速度較舊版 ATmega
bootloader 快
◦ 程式碼進行了優化,運行效率較舊版提高,並且無看門狗問題
◦ 支持較多的 ATmega 晶片
與 Bootloader 有關的電路
USB to Serial bridge Arduino 主晶片
USB 接頭
PC USB Serial
與 Bootloader 有關的電路
Serial TX/RX 資料傳輸線
Serial DTR (用於 reset
Arduino)
Arduino
主晶片
USB to Serial
bridge
UNO Bootloader 程式流程
UART init
Watchdog init
是否由 RESET
Pin 引起
執行 Arduino F/W
否
是
依命令把 Arduino
F/W寫入 Flash
把 watchdog 設定成 16ms,
並等待系統自行 reset
reset
每接收一個字元都會重設 watchdog
Watchdog 預設 1s
(timeout 自行 reset)
TX, RX 燈號是由
Atmega16U2(USB to
Serial bridge) 控制
由 serial port 接收
Host 命令
是
否 收到
exit bootloader
命令
Bootloader 原始碼重要細節
判斷 reset 來源, 如果不是
reset button 或 serial DTR
reset, 就呼叫 appStart() 直接執行 Arduino F/W
初始化 watchdog timer = 1s, (如果一秒內 bootloader
沒有從 serial 收到任何資料, 將會自動跳出並執行
Arduino F/W)
Bootloader 原始碼重要細節
從 serial port 讀取字元
Bootloader
main loop
進行 STK500 通訊協定的命令處理
(STK500協定規範請自行參考 Atmel 文件:
http://www.atmel.com/Images/doc2591.pdf)
如果收到 exit 命令, 則設定
watchdog timer = 16ms, 並呼叫 verifySpace() 等待系統自行 reset
Bootloader 重要函式註解
getch ( )
◦ 從 serial port 讀取一字元
putch ( )
◦ 由 serial port 送出一字元
verifySpace ( )
◦ 接受並回應 STK500 命令結尾 token
Bootloader 重要函式註解
watchdogReset ( )
◦ Reset watchdog timer
watchdogConfig ( )
◦ 設定 watchdog timer
appStart ( )
◦ 執行使用者燒錄的 Arduino 韌體程式
Arduino IDE 對 Bootloader 的操作
IDE 將編譯程式, 並透過
bootloader 將編譯結果
上傳到
Arduino
板子上
Arduino IDE 對 Bootloader 的操作
IDE 上傳程式的流程
取得要燒錄的檔案所在路徑和檔案名稱
由板子版本決定燒錄參數
取得燒錄程式路徑與檔名
執行燒錄程式 avrdude.exe
是否燒錄成功?
回傳失敗
是 (由 avrdude.exe 的回傳值決定)
否
(IDE 這部分的原始碼等之後的讀書會再進行詳細解析)
回傳成功
Avrdude 會自行透過 DTR
重啟 Arduino, 以進入
bootlaoder
USB Bootloader 解析
--- 以 Leonardo 為例
Arduino Leonardo Bootloader
Arduino Leonardo 使用 caterina
bootloader
◦ 透過 USB 直接與 PC 通訊, 省掉 USB to
Serial bridge, 降低成本
◦ 使用 LUFA library 來進行 USB 通訊
LUFA 是一套 AVR 系列微處理機專用的通訊程式庫, 支援各種 USB Class
caterina 只用到 CDC Class 的功能
與 Bootloader 有關的電路
USB 通訊線
Arduino 主晶片
與 Bootloader 有關的電路
USB 通訊線
USB 電源輸入
USB 接頭
Leonardo Bootloader 程式流程
HW init
Timer
LUFA init
是否有
POWER-ON
reset
Detach USB 並執行
Arduino F/W
否
是
Timer 中斷設定成每 1ms 觸發一次, 裡面處理 TX/RX LED 與
bootloader timeout
依命令把 Arduino F/W 寫入
flash, 並重置 timeout count
(timeout count
> 8000)
把 timeout count 設定為 7500 等待 timeout
timeout count
不累加
Arduino
F/W 是否存在?
timeout count ++
是 否
點滅 TX/RX LED 是否
timerout
是
否
Timer 中斷副程式
Bootloader 主程式
由 USB 接收 Host 命令,
點亮 TX/RX LED
收到 exit
bootloader
命令
是
否
Bootloader 原始碼重要細節
如果是由 reset button 引起的 reset, 則進入
bootloader
如果不是軟體 reset, 則直接執行 Arduino F/W
如果是 POWER-ON reset, 則直接執行 Arduino F/W
Bootloader 原始碼重要細節
Bootloader
main loop
執行 AVR910 通訊協定命令
LUFA library 的 USB 通訊處理
超過 8 秒沒從 host 收到資
料, 則跳出 bootloader 執行
Arduino F/W
執行 Arduino F/W
切斷 USB 連結 (Arduino F/W 會自己再一次進行 USB 連接行為)
Bootloader 原始碼重要細節
Bootloader timer 中斷副程式,
每隔 1ms觸發執行一次
Bootloader 使用的 timerout count 變數
Bootloader 原始碼重要細節 AVR910 通訊協定處理函式
指定 USB 資料讀取通道
從 USB 讀取字元
判斷 USB 通道是否有資料存在
如果收到 exit 命令, 則等待 0.5
秒再跳出執行 Arduino F/W
進行 AVR910 通訊協定的命令處理
(AVR910協定請自行參考 Atmel 文件:
http://www.atmel.com/im
ages/doc0943.pdf)
Bootloader 重要函式註解
FetchNextCommandByte ( )
◦ 從 USB port 讀取一字元
WriteNextResponseByte ( )
◦ 由 USB port 送出一字元
SetupHardware ( )
◦ 硬體初始化函式
Bootloader 重要函式註解
StartSketch ( )
◦ 執行使用者的 Arduino 韌體程式
EVENT_USB_Device_ConfigurationChanged ( )
◦ USB 事件處理 callback
EVENT_USB_Device_ControlRequest ( )
◦ USB 事件處理 callback
Arduino IDE 對 Bootloader 的操作
IDE 上傳程式的流程 取得要燒錄的檔案所在路徑
和檔案名稱
由板子版本決定燒錄參數
取得燒錄程式路徑與檔名
執行燒錄程式 avrdude.exe
是否燒錄成功?
對目前的 USB serial port 設定1200 bps baudrate 後再關閉
等待 bootloader USB serial
port 出現
Timeout?(5s)
等待 Arduino sketch USB
serial port 出現 將 Arduino sketch USB
serial port baudrate 改成正常值, 並回傳燒錄
成功 Timeout?(2s) 回傳燒錄成功
回傳失敗
回傳失敗
是 否
是 (由 avrdude.exe 的回傳值決定) 否
是 否
Arduino 自行切斷 USB 再重新連線
(IDE 這部分的原始碼等之後的讀書會再進行詳細解析)
(對 Arduino 做軟體 reset)
Leonardo 軟體 RESET 機制的實作
在 IDE 上傳 Arduino F/W 之前, 會先將 USB serial port 設定成 1200bps baudrate, 然後再關閉 serial port
上述行為會讓 Leonardo 上的 F/W 對一個指定記憶體空間填入 bootkey, 然後再自己 reset
reset 後進入 bootloader, 會去判斷是否為軟體 reset (檢查 bootkey), 如果是, 則進入 bootloader main loop 開始接收資料
輕鬆小品, 休息一下~~
複習 Arduino Bootloader 燒錄
接線路(Arduino to Arduino)
接線路(Arduino to MCU)
開啟 ArduinoISP程式檔
將程式上傳到Arduino板子上
選擇板子種類
開始燒錄bootloader
86Duino 的 Bootloader 實作
86Duino Bootloader 行為
86Duino Bootloader 只是開機第一個執行的 DOS 執行檔
行為大部分與 Arduino Leonardo 相同
只有軟體 reset 可以啟動 Arduino 韌體燒錄機制
◦ Arduino Leonardo 則是軟體 reset 和 reset
button 皆會啟動 Adruino 韌體燒錄機制
86Duino Bootloader 行為
86Duino F/W 先整個被接收到記憶體內,
再一次寫入 flash
◦ 當傳輸過程出錯, 不會破壞原有韌體程式
86Duino F/W 會先燒錄至暫存空間, 成功後再映射至韌體存放空間
◦ 當寫入過程出錯, 不會破壞原有韌體程式
Bootloader 原始碼重要細節
86Duinio F/W 最大 SIZE
Bootloader timeout 時間
可燒錄的程式類型
Bootloader 原始碼重要細節
初始化 I/O port
決定 bootloader 的運作模式
判斷是否有軟體 reset
Bootloader 原始碼重要細節
初始化 USB device port
配置存放 86Duino F/W 的記憶體陣列
Bootloader 原始碼重要細節
Bootloader main
loop 開始
Bootloader 原始碼重要細節
讀取要燒錄的 86Duino
F/W 大小
Bootloader 原始碼重要細節
從 USB 接收 86Duino F/W 檔案
Bootloader 原始碼重要細節
86Duino F/W 燒錄
Bootloader 原始碼重要細節
若是執行 Bootloader 燒錄則 reboot, 反之則執行 86Duino F/W
初版程式燒錄的 protocol
沒有使用 protocol (未來會新增)
初版是直接傳送特定格式的資料
TYPE Data length Data
1 Byte 4 Bytes N Bytes
1: 檔案是 bootloader
2: 檔案是 user program
86Duino 軟體 RESET 機制的實作
由 IDE 把 USB serial port 開啟為
1200bps baudrate 後再關閉 (與 Arduino
Leonardo 相同)
86Duino 收到上述行為後, 會對一個 I/O
空間寫入特定值, 然後自己 reset
reset 後進入 bootloader, 判斷上次是否為軟體 reset, 如果是, 則開始接收新的
F/W
Thank You 感謝大家來參與 Arduino 原始碼讀書會
接下來問題討論時間