文章總列表

STM32 Bootloader

要解決的問題

  • 升級韌體很麻煩,開機殼短路兩個點上電洗掉程式,最後再用JTAG寫程式
  • 但是裝置接在CAN bus,為什麼不能用CAN更新軟體,省掉上面步驟?
  • Atollic這份文件把bootloader講解得很詳細

Flash規劃

STM32F103C8T6的page size是1KB

  • Page[7:0] bootloader
  • Page[15:8] main program
  • Page[23:16] program to upgrade
  • Page[62] bootloader NVRAM
  • Page[63] main program NVRAM

我的程式不大,直接多放一份program to update也還好,程式運行中把軟體寫入此區域。重新開機,bootloader偵測到更新需求,把program to update覆蓋main memory完成更新後,再正常開機。所以bootloader邏輯很簡單

if bootloader_nvram_update == True
    copy program_to_upgrade to main_program
Jump to main program

修改main program

本來主程式放在Flash開頭,現在被放到8K開始,我們要告訴linker script搬家了





也要告訴軟體,中斷向量表搬家了

主程式的修改就這樣,很簡單吧!

產生bootloader

bootloader也許會精雕細琢壓code size;但是我很懶,stm32cubemx直接產生,畢竟最後我也要讀寫Flash,有現成driver用就是爽

打開main.c,照著Atollic的文件抄,記得加上__disable_irq()才不會噴出hard fault。我也懶得找原因了,推測是跳入主程式時,也許會摸到某些保護跑飛。反正多一行就搞定,別太折磨自己了



實際的PM開銷約3K左右,就可以跳轉入主程式了



燒錄和Debug

現在MCU有兩個子專案,有兩個ELF file,代表要分兩步讓一顆MCU正常使用

  • 我用Segger ozone,先載入bootloader.jdebug,燒寫bootloader到page[7:0],不碰其他地方
  • 原本專案就有一個stm32.jdebug,燒寫主程式到page[15:8]

Segger Ozone文件有描述怎麼做得聰明一點,一個jdebug file就可以同時處理兩個ELF;不過我偏好讓事情簡單一點,Tool背後不要做太多事

所以開發者的習慣變這樣,想debug哪裡就開哪區,就是人要明確地意識到自己在查哪裡

  • 修改主程式,編譯後用stm32.jdebug燒錄和debug
  • 修改bootloader,編譯後用bootloader.jdebug,在跳轉到main program之前都能debug

如果要量產,程式編譯完會產生兩個hex檔,他們可以合併起來

結論

  1. Bootloader的精隨是重新定義中斷向量表跳轉程式,Atollic的文件寫得比我好100倍,真的看不懂網路上也有中文資料可查,原理講解請找專業
  2. 這篇文章特別解釋,已經會動的專案,怎麼加上bootloader,還有toolchain怎麼調整。不敢說是best practice,起碼流程有稍微想一想,第一次下手可以參考
  3. 跳轉入主程式前,增加一層bootloader,確實能大幅增加軟體彈性

留言

這個網誌中的熱門文章

幼犬書桌椅選擇心得 升降桌 兒童桌椅

STM32 UART + DMA,使用HAL實作TX/RX,以及不定長度接收

CANON G3000 廢墨瓶改裝