コンテンツにスキップ

G474 Main アプリケーションブートローダー

目的

CM4からのFW更新に先立ち、User Flash先頭へ基板専用ブートローダーを置き、通常アプリをSlot Aへ再配置する。M1実装ではUART/CANによる更新はまだ行わず、安全IO、metadata、CRC32C、Slot A jumpだけを提供する。

STM32 System Memory bootloader、BOOT0によるROM boot、hardware bank swapのBFB2は使用しない。

Flash配置

領域 アドレス サイズ M1での用途
Bootloader 0x08000000~0x08007FFF 32 KB 安全IO、CRC、Slot A検証・jump
Slot A 0x08008000~0x0803FFFF 224 KB 現在の通常アプリ
Slot B 0x08040000~0x08077FFF 224 KB M3以降。M1では未使用
Metadata 0x08078000~0x0807FFFF 32 KB M1では先頭36 byteを使用

通常アプリのリンカSTM32G474RETX_FLASH.ldはSlot Aを指し、system_stm32g4xx.cのVECT_TAB_OFFSETは0x8000である。

起動判定

metadataの次の項目を全て検証した場合だけSlot Aへjumpする。

  • magic OFW1、format version、record size
  • state=CONFIRMED、slot=A、base=0x08008000
  • image sizeが8 byte以上224 KB以下
  • metadata CRC32C
  • 初期MSPがSRAM1またはCCMRAM内で8 byte alignment
  • Reset_HandlerがThumb addressかつimage範囲内
  • Slot A image全体のCRC32C

失敗時はPC14のerror LEDをHighにして安全状態で停止する。検証中はPC13をHighにし、成功時は消灯してSlot Aへjumpする。

M1安全IO表

SystemInit()からboard_io_init_safe()を呼び、C runtime/HALより前に設定する。各portのbonding済みGPIOは出力、入力、analog、SWD保持のいずれかに全分類し、maskの重複と未分類を_Static_assertで検出する。

GPIO M1 bootloader状態 理由
PA4 Output High IMU CS非選択
PA15 Output Low 既存未命名出力の安全初期値
PB2/PB10/PB14 Output Low 既存未命名出力の安全初期値
PB7 Output Low status LED初期消灯
PC0/PC5 Output Low 既存出力、IMU FSYNC
PC12 Output Low buzzer PWMを停止状態へ固定
PC13/PC14 Output Low後にstatus表示 boot validating/error LED
PA10/PB5/PB6/PC4/PD2 Input no-pull DIP、IMU INT。外部回路のlevelを維持
PB8 Input pull-down BOOT0兼用pinを実行開始後Low側へ固定
PA13/PA14 reset状態を保持 SWDIO/SWCLK
その他のbonding済みGPIO Analog no-pull M1で不使用。floating digital inputを残さない

PA11/PA12、PB12/PB13のFDCANとPB3/PB4のUSART2はM1ではanalogであり、M2以降で安全IO設定後にalternate functionへ切り替える。

更新開始から通常アプリへjumpするまで、TIM5は強制reset後にclock disableし、PC12はGPIO Output Lowを維持する。G474自身の更新中だけでなく、G474がF303更新を中継している間もブザーPWMを開始してはならない。

2026-08-24 実機導入結果

  • bootloader、Slot A、metadataの書込み・verifyに成功
  • 実Flash readbackは3成果物すべてSHA-256一致
  • VTOR=0x08008000、10回連続reset後もSlot A内でrunning
  • TIM5明示停止版ではmetadata消去時にPC=0x08000260でbootloader待機
  • 同待機中、PC12=GPIO Output Low、TIM5 CR1.CEN=0
  • metadata復元後、Slot Aへ正常復帰

Sub高速更新ゲートウェイ

通常アプリにfw_update_gateway.cを追加し、CM4から受けた最大896 byteのchunkをFDCAN1へ展開する。更新中はTIM7周期処理を停止し、TIM5 buzzer PWM停止とactuator_buzzer_off()を維持する。

  • UART frame: magic OFW2、version、type、sequence、length、header CRC16、payload、CRC32C
  • payload最大907 byte、同一sequence再受信時は前回応答を返す
  • USART2 RXは通常モードを含めIRQでRX FIFOを全量drainし、72-byte FWUP要求と長い更新frameでのHAL 1-byte再登録による欠落を抑える
  • CAN dataは0x480~0x4FF、node commandは0x610、responseは0x650 + OTA node ID
  • ENTERでCAN1/CAN2のnodeを個別指定し、同一imageの左右BLDCは両バスへ並列送信する
  • FDCAN TX FIFOに空きができるまで待ち、更新frameを破棄しない
  • CAN応答timeout時はHELLOでcommit offsetを照会し、書込み済みchunkを二重programしない
  • 故障注入用にCAN frameの欠落、重複、逆順、payload破損を最初のchunkへ適用できる

2026-08-25、CM4→Main→Subの65,168 byte更新を実機確認した。正常時は8.287~10.437秒、全故障複合注入時は14.186秒で、全体CRC32C 0xF692FBA9まで一致した。

2026-08-27、CM4経由のMain A/B更新をB→A、A→Bの順で確認した。最終状態はSlot A generation 8、Slot B generation 9がともにCONFIRMED、preferred Slot B、boot attempts 0である。左右BLDC同時更新も10回連続で成功した。

Slot A jump時のCPU状態

bootloaderはjump準備中に全割り込みを禁止するが、その状態を通常アプリへ引き継いではならない。NVIC pending/enableとSysTickを消去した後、CONTROL、BASEPRI、FAULTMASK、PRIMASKを0へ戻し、Slot AのMSPとVTORを設定してReset_Handlerへ分岐する。

2026-08-24の初回実機導入では、当初PRIMASK=1を引き継いだためTIM7、USART2受信、UART DMA送信が動作しなかった。修正後は4レジスタがすべて0で、次を確認した。

  • CM4 USART2: 1 Mbps、128-byte frame、約124 Hz
  • 3秒取得の372 frameでAB EA同期、checksum、送信連番が全て正常
  • LPUART1: 2 Mbpsでorion main start、IMU初期化完了、CAN1/CAN2開始を確認

2026-08-25に導入後のSlot A更新を10回連続実行し、全10回でapplication/metadata verify、Slot A起動、例外mask 0、CM4 USART2のchecksum・送信連番を確認した。

回路図で用途未確認のPA15、PB2、PB10、PB14、PC0は、現行MX_GPIO_Init()と同じLowを暫定安全値としている。実機書込み前に回路図でactive levelを確定する。

ビルド

powershell -NoProfile -ExecutionPolicy Bypass -File .\Script\build_bootloader.ps1 -Rebuild
powershell -NoProfile -ExecutionPolicy Bypass -File .\Script\build_slot_a.ps1 -Configuration Debug -Rebuild

build_slot_a.ps1はSlot A vectorと領域を検査し、.binに対するCRC32C metadataを生成する。

初回導入

最初にdry-runし、Flash全体、CRC32C、Option Bytesを退避する。

powershell -NoProfile -ExecutionPolicy Bypass -File .\Script\install_main_bootloader.ps1 -Configuration Debug

出力されたbackupとIO表を確認した後だけ、明示的に-Executeを付ける。

powershell -NoProfile -ExecutionPolicy Bypass -File .\Script\install_main_bootloader.ps1 -Configuration Debug -Execute

-ExecuteなしではFlash書込みもresetも行わない。初回導入が完了するまでは既存flash.ps1を使用しない。

導入後にST-LinkでSlot Aを更新する場合は、先にbuild_slot_a.ps1を実行し、明示的に次を使用する。

powershell -NoProfile -ExecutionPolicy Bypass -File .\Script\flash.ps1 -Configuration Debug -BootloaderInstalled

WRPはM1では設定しない。UART更新、rollback、SWD復旧の実機試験完了後にbootloader領域だけを保護する。