- Add ota.h / ota.c: ota_enter_dfu() (armed guard, writes BKP15R, resets), ota_fw_crc32() using STM32F7 hardware CRC peripheral (CRC-32/MPEG-2, 512 KB) - Add JLINK_CMD_DFU_ENTER (0x06) and dfu_req flag to jlink.h / jlink.c - Handle dfu_req in main loop: calls ota_enter_dfu(is_armed) — no-op if armed - Update usbd_cdc_if.c: move DFU magic from BKP0R to BKP15R (OTA_DFU_BKP_IDX) resolving BKP register conflict with BNO055 calibration (BKP0R–6R, PR #150) - Add scripts/flash_firmware.py: CRC-32/MPEG-2 + ISO-HDLC verification, dfu-util flash, host-side backup/rollback, --trigger-dfu JLink serial path - Add test/test_ota.py: 42 tests passing (CRC-32/MPEG-2, CRC-16/XMODEM, DFU_ENTER frame structure, BKP register safety, flash constants) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.1 KiB
C
64 lines
2.1 KiB
C
#ifndef OTA_H
|
||
#define OTA_H
|
||
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
|
||
/*
|
||
* OTA firmware update — Issue #124
|
||
*
|
||
* DFU entry triggered by JLINK_CMD_DFU_ENTER (0x06) or USB CDC 'R' command.
|
||
* Uses RTC backup register OTA_DFU_BKP_IDX to pass magic across the soft reset.
|
||
*
|
||
* RTC BKP register map:
|
||
* BKP0R–BKP5R : BNO055 calibration offsets (PR #150)
|
||
* BKP6R : BNO055 magic (0xB055CA10, PR #150)
|
||
* BKP7R–BKP14R : Reserved
|
||
* BKP15R : OTA DFU magic (this module)
|
||
*
|
||
* Using BKP15R avoids collision with BNO055 (BKP0–6) and the old BKP0R
|
||
* that the original request_bootloader() used before this module.
|
||
*
|
||
* Dual-bank note: STM32F722 has single-bank flash (512 KB). Hardware A/B
|
||
* rollback is not supported without a custom bootloader. DFU via the ST
|
||
* system bootloader at 0x1FF00000 is the supported update path. Rollback
|
||
* is handled by the host-side flash_firmware.py script, which keeps a
|
||
* backup of the previous binary.
|
||
*/
|
||
|
||
/* RTC backup register index used for DFU magic — avoids BNO055 BKP0–6 */
|
||
#define OTA_DFU_BKP_IDX 15u
|
||
|
||
/* Magic value written before reset to trigger DFU entry on next boot */
|
||
#define OTA_DFU_MAGIC 0xDEADBEEFu
|
||
|
||
/* STM32F722 internal flash: 512 KB starting at 0x08000000 */
|
||
#define OTA_FLASH_BASE 0x08000000u
|
||
#define OTA_FLASH_SIZE 0x00080000u /* 512 KB */
|
||
|
||
/*
|
||
* ota_enter_dfu(is_armed)
|
||
*
|
||
* Request entry to USB DFU mode (ST system bootloader at 0x1FF00000).
|
||
* Returns false without side effects if is_armed is true.
|
||
* Otherwise: enables backup domain, writes OTA_DFU_MAGIC to BKP15R,
|
||
* disables IRQs, calls NVIC_SystemReset(). Never returns on success.
|
||
*
|
||
* Call from the main loop only (not from ISR context).
|
||
*/
|
||
bool ota_enter_dfu(bool is_armed);
|
||
|
||
/*
|
||
* ota_fw_crc32()
|
||
*
|
||
* Compute a CRC-32/MPEG-2 checksum of the full flash region using the
|
||
* STM32 hardware CRC peripheral (poly 0x04C11DB7, init 0xFFFFFFFF,
|
||
* 32-bit words, no reflection). Covers OTA_FLASH_SIZE bytes from
|
||
* OTA_FLASH_BASE including erased padding.
|
||
*
|
||
* Takes ~0.5 ms at 216 MHz. Call only while disarmed.
|
||
*/
|
||
uint32_t ota_fw_crc32(void);
|
||
|
||
#endif /* OTA_H */
|