- UART binary mode switch mechanism: enter handshake marker '[ota] binary mode ON', explicit exit via OTA_ABORT (immediate), 10s idle fallback (was 3s, must exceed the host retry window); host resync by CR probe - fix: otaIdleMs not re-armed on mode entry - every second 'ota' entry was kicked out by an instant idle timeout (leftover count from prior session) - lossy-link tolerance: device drops partial frames after a 100ms byte gap so host resends re-align; OTA session is now single-owner (second BEGIN on another channel gets BAD_STATE) - ble_ota_update.py: wait for the enter marker instead of blind sleeps, per-frame resend (2s x3), BAD_STATE+expected-offset treated as implicit ack for duplicate DATA/BEGIN (resync after ack loss), stage-labeled timeouts with raw-rx dump - verified on hardware: UART OTA full pass (55.7KB/41s, 4-5 lost frames auto-recovered) + BLE OTA regression pass; docs: dev log 44, ble_protocol.md 6.6 rework, AGENTS.md sync
73 lines
2.5 KiB
C
73 lines
2.5 KiB
C
/**
|
|
* @file app_ota.h
|
|
* @brief BLE OTA receiver: writes an incoming image into the opposite flash
|
|
* bank directly (lazy per-sector erase, only a 4-byte word staging
|
|
* buffer), verifies CRC32 and updates the bootloader's bootsetting
|
|
* record, then resets.
|
|
*
|
|
* Runs in the BLE schedule task context (invoked from app_ble_proto.c).
|
|
*/
|
|
#ifndef __APP_OTA_H__
|
|
#define __APP_OTA_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
|
|
/**
|
|
* @brief Handle one OTA frame (BLE_FRAME_OTA_BEGIN / OTA_DATA / OTA_END /
|
|
* OTA_ABORT). Sends OTA_RSP frames through the channel sink
|
|
* (app_ota_chan_rx) or, without a sink, app_ble_proto_send_frame().
|
|
*/
|
|
void app_ota_handle_frame(uint8_t type, uint8_t seq, const uint8_t* payload, uint16_t len);
|
|
|
|
/**
|
|
* @brief Abort any on-going OTA session (on BLE disconnect or fatal error).
|
|
*/
|
|
void app_ota_abort(void);
|
|
|
|
/**
|
|
* @brief Flash base of the bank this firmware is running from
|
|
* (CAIIC_APP1_BASE / CAIIC_APP2_BASE), or 0 when unknown.
|
|
*/
|
|
uint32_t app_ota_current_bank_base(void);
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
/* Transport channels (ble_protocol.md §6.6): the engine is fed via */
|
|
/* app_ota_chan_rx(); RSP frames go to the channel's sink. */
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
/** Response sink: receives one complete 0xCA-framed OTA_RSP. */
|
|
typedef void (*app_ota_rsp_sink_fn)(const uint8_t* frame, uint16_t len);
|
|
|
|
/** Generic channel byte input with an explicit sink. */
|
|
void app_ota_chan_rx(const uint8_t* data, uint16_t len, app_ota_rsp_sink_fn sink);
|
|
|
|
/** BLE OTA characteristic (...e0005): write = frame in, read = RSP out. */
|
|
void app_ota_chan_rx_ble(const uint8_t* data, uint16_t len);
|
|
const uint8_t* app_ota_chan_rsp_ble(uint16_t* out_len);
|
|
|
|
/** UART binary mode (CLI "ota"): one received byte in; RSP frames on TX.
|
|
* @return non-zero when the host sent OTA_ABORT - the frontend should
|
|
* leave binary mode and return to the text CLI immediately. */
|
|
uint8_t app_ota_chan_rx_uart(uint8_t ch);
|
|
|
|
/** Drop the reassembler state (channel idle timeout / link loss). */
|
|
void app_ota_chan_idle(void);
|
|
|
|
/**
|
|
* @brief Poll the deferred post-OTA_END reset: after a successful OTA_END
|
|
* the device resets only once the END response has been consumed by
|
|
* the host (plus a short grace), with a timeout fallback. Call from
|
|
* the BLE schedule task loop.
|
|
*/
|
|
void app_ota_reset_poll(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __APP_OTA_H__ */
|