|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Phase-5 OTA firmware-update orchestration – implementation. More...
#include "ra8_ota.h"#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_ota_internal.h"#include "ra8_secure.h"Go to the source code of this file.
Functions | |
| void | priv_ota_set_state (ra8_ota_state_t new_state, ra8_err_t err) |
| Implementation of priv_ota_set_state() – latch state + progress fan-out. | |
| static ra8_err_t | internal_drain (uint8_t *dst, uint32_t cap, uint32_t *out_n) |
| Drain the network stream and accumulate up to cap bytes. | |
| ra8_err_t | ra8_ota_init (const ra8_ota_cfg_t *cfg) |
| Initialise the OTA module from a caller-supplied configuration. | |
| ra8_err_t | ra8_ota_deinit (void) |
| Reset the OTA module to its un-initialized state. | |
| ra8_ota_state_t | ra8_ota_get_state (void) |
| Return the current OTA state-machine value. | |
| static ra8_err_t | internal_fetch_manifest_payload (uint32_t *out_got) |
| Open the manifest URL and drain its payload into g_ra8_ota_buf. | |
| ra8_err_t | ra8_ota_check_for_update (ra8_ota_manifest_t *out_manifest) |
| Fetch and decode the upstream manifest, leaving it cached. | |
| static ra8_err_t | internal_download_chunk (uint32_t addr_base, uint32_t *in_out_done, uint32_t total) |
| Stream one chunk: drain network -> hash -> flash program. | |
| static ra8_err_t | internal_prepare_bank (const ra8_ota_manifest_t *manifest) |
| Erase the inactive bank and prime the SHA accumulator. | |
| static ra8_err_t | internal_download_loop (const ra8_ota_manifest_t *manifest) |
| Drain chunks until the entire image is downloaded or an error fires. | |
| ra8_err_t | ra8_ota_download_to_inactive_bank (const ra8_ota_manifest_t *manifest) |
| Download an image into the inactive bank, hashing as it goes. | |
| ra8_err_t | ra8_ota_commit_and_reboot (void) |
| Latch the inactive bank as the next boot bank and reboot. | |
| static ra8_err_t | internal_step_dispatch (void) |
| Drive one transition based on the current state. | |
| ra8_err_t | ra8_ota_run_step (void) |
| Drive the OTA state machine one step forward. | |
| ra8_err_t | ra8_ota_run_full_update (void) |
| Drive the OTA state machine through an end-to-end update. | |
| void | ra8_ota_system_reset_hook (void) |
| Weak system-reset hook overridden by the target build. | |
Variables | |
| static const char *const | s_tag = "ra8_ota" |
| Module log tag. | |
| ra8_ota_state_t | g_ra8_ota_state = k_ra8_ota_state_idle |
| Current state-machine value (shared; contract in ra8_ota_internal.h). | |
| ra8_ota_cfg_t | g_ra8_ota_cfg |
| Configuration captured at init time (shared; contract in ra8_ota_internal.h). | |
| bool | g_ra8_ota_initialized = false |
| True once ra8_ota_init succeeded (shared; contract in ra8_ota_internal.h). | |
| static ra8_ota_manifest_t | s_manifest |
| Cached decoded manifest from the most recent check. | |
| static bool | s_manifest_valid = false |
| Whether s_manifest holds a valid payload. | |
| static uint32_t | s_bytes_done = 0U |
| Bytes already programmed into the inactive bank. | |
| static ra8_err_t | s_last_err = k_ra8_ok |
| Last error observed by the state machine. | |
| uint8_t | g_ra8_ota_buf [k_ra8_ota_chunk_bytes] |
| Streaming buffer (shared; contract in ra8_ota_internal.h). | |
Phase-5 OTA firmware-update orchestration – implementation.
Plain-C implementation of the state machine declared in ra8_ota.h. The module owns three statics:
No malloc anywhere (NASA Rule 3). Every loop has a static upper bound (NASA Rule 2). Every public entry point has at least two preconditions (NASA Rule 5).
The ThreadX worker thread is wired in through weakly-bound functions ra8_ota_threadx_spawn / ra8_ota_threadx_join – the host test build provides empty stubs in this same TU so the module links cleanly on Linux x86_64. A target-side adapter lives outside this module.
Definition in file ra8_ota.c.
|
static |
Stream one chunk: drain network -> hash -> flash program.
Computes a chunk size capped at k_ra8_ota_chunk_bytes, drains it via internal_drain, updates the SHA-256 accumulator, programs it into flash at addr_base + *in_out_done and bumps the running counter.
| [in] | addr_base | Bank base address inside flash. |
| [in,out] | in_out_done | Bytes already programmed; bumped on success. |
| [in] | total | Image size in bytes. |
| k_ra8_ok | Chunk programmed and accumulator updated. |
| k_ra8_err_hw_error | Backend EOF before image complete. |
| other | Network / crypto / flash error. |
Definition at line 394 of file ra8_ota.c.
References g_ra8_ota_buf, g_ra8_ota_cfg, internal_drain(), k_ra8_err_hw_error, k_ra8_ok, k_ra8_ota_chunk_bytes, k_ra8_ota_state_downloading, and priv_ota_set_state().
Referenced by internal_download_loop().
|
static |
Drain chunks until the entire image is downloaded or an error fires.
Loops calling internal_download_chunk until s_bytes_done reaches manifest->image_size_bytes. Bounded by (k_ra8_ota_max_image_bytes / k_ra8_ota_chunk_bytes) + 1 iterations (NASA Rule 2).
| [in] | manifest | Manifest describing the in-flight image. |
| k_ra8_ok | Download completed. |
| k_ra8_err_hw_error | Chunk count exceeded the static cap. |
| other | Whatever internal_download_chunk returned. |
Definition at line 482 of file ra8_ota.c.
References g_ra8_ota_cfg, ra8_ota_manifest_t::image_size_bytes, internal_download_chunk(), k_ra8_err_hw_error, k_ra8_ok, k_ra8_ota_chunk_bytes, k_ra8_ota_max_image_bytes, and s_bytes_done.
Referenced by ra8_ota_download_to_inactive_bank().
|
static |
Drain the network stream and accumulate up to cap bytes.
Loops calling the user-supplied g_ra8_ota_cfg.net.read callback until either cap bytes have been collected or the backend reports EOF (got == 0). The loop is bounded by cap + 1 iterations (NASA Rule 2). Returns the byte count via out_n.
| [in,out] | dst | Destination buffer. |
| [in] | cap | Capacity in bytes. |
| [out] | out_n | Bytes actually received. |
| k_ra8_ok | Drain completed (possibly short on EOF). |
| other | Whatever the network backend returned. |
Definition at line 121 of file ra8_ota.c.
References g_ra8_ota_cfg, and k_ra8_ok.
Referenced by internal_download_chunk(), and internal_fetch_manifest_payload().
|
static |
Open the manifest URL and drain its payload into g_ra8_ota_buf.
Calls g_ra8_ota_cfg.net.open on the configured manifest URL, validates the advertised content length is below k_ra8_ota_manifest_max_bytes, then drains via internal_drain and appends a NUL byte so the JSON helpers may use strstr.
| [out] | out_got | Bytes received (NUL terminator added at g_ra8_ota_buf[got]). |
| k_ra8_ok | Payload fetched into g_ra8_ota_buf. |
| k_ra8_err_invalid_size | Server advertised too large a body. |
| other | Whatever the network backend returned. |
Definition at line 287 of file ra8_ota.c.
References g_ra8_ota_buf, g_ra8_ota_cfg, internal_drain(), k_ra8_err_invalid_size, k_ra8_ok, and k_ra8_ota_manifest_max_bytes.
Referenced by ra8_ota_check_for_update().
|
static |
Erase the inactive bank and prime the SHA accumulator.
Only invoked on a fresh download start (s_bytes_done == 0). Erases manifest->image_size_bytes worth of inactive-bank flash then re-initialises the SHA-256 accumulator so the new download is hashed from byte 0.
| [in] | manifest | Currently active manifest. |
| k_ra8_ok | Bank erased and SHA primed. |
| other | Whatever the flash erase / sha init returned. |
Definition at line 446 of file ra8_ota.c.
References g_ra8_ota_cfg, ra8_ota_manifest_t::image_size_bytes, and k_ra8_ok.
Referenced by ra8_ota_download_to_inactive_bank().
|
static |
Drive one transition based on the current state.
Switches on g_ra8_ota_state and dispatches to the matching public-API function (check_for_update, download_to_inactive_bank, verify_signature or commit_and_reboot). Terminal states (done / error) return k_ra8_ok so the caller may stop polling.
| k_ra8_ok | Step completed (or terminal state reached). |
| other | Whatever the dispatched function returned. |
Definition at line 649 of file ra8_ota.c.
References g_ra8_ota_state, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_ota_state_checking, k_ra8_ota_state_committing, k_ra8_ota_state_count, k_ra8_ota_state_done, k_ra8_ota_state_downloading, k_ra8_ota_state_error, k_ra8_ota_state_idle, k_ra8_ota_state_verifying, ra8_ota_check_for_update(), ra8_ota_commit_and_reboot(), ra8_ota_download_to_inactive_bank(), ra8_ota_verify_signature(), s_manifest, and s_manifest_valid.
Referenced by ra8_ota_run_step().
| void priv_ota_set_state | ( | ra8_ota_state_t | new_state, |
| ra8_err_t | err ) |
Implementation of priv_ota_set_state() – latch state + progress fan-out.
Set the OTA state-machine value and fire the progress callback.
Definition at line 80 of file ra8_ota.c.
References g_ra8_ota_cfg, g_ra8_ota_state, s_bytes_done, s_last_err, s_manifest, and s_manifest_valid.
Referenced by internal_download_chunk(), ra8_ota_check_for_update(), ra8_ota_commit_and_reboot(), ra8_ota_download_to_inactive_bank(), and ra8_ota_verify_signature().
|
nodiscard |
Fetch and decode the upstream manifest, leaving it cached.
Fetch and decode the manifest JSON over HTTPS.
Transitions the state machine idle -> checking -> idle (success) or idle -> checking -> error (failure). On success the manifest is mirrored both into *out_manifest and into the module-private s_manifest so subsequent steps can refer to it.
| [out] | out_manifest | Caller-owned manifest buffer. |
| k_ra8_ok | Manifest cached and returned. |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_null_ptr | out_manifest was NULL. |
| k_ra8_err_invalid_state | Module not in idle. |
| other | Network or decode error. |
Definition at line 338 of file ra8_ota.c.
References g_ra8_ota_buf, g_ra8_ota_initialized, g_ra8_ota_state, internal_fetch_manifest_payload(), k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_checking, k_ra8_ota_state_error, k_ra8_ota_state_idle, memcpy(), priv_ota_manifest_decode(), priv_ota_set_state(), RA8_CHECK_NULL_PTR, s_manifest, s_manifest_valid, and s_tag.
Referenced by internal_step_dispatch().
|
nodiscard |
Latch the inactive bank as the next boot bank and reboot.
Persist the bank swap and reboot.
Calls g_ra8_ota_cfg.flash.set_startup to mark the inactive bank as the boot bank, then invokes ra8_ota_system_reset_hook (which on hardware overrides to NVIC_SystemReset and on host is a no-op for testability).
| k_ra8_ok | Bank latched (the call normally doesn't return on hardware). |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_invalid_state | Module not in committing. |
| other | Backend error from set_startup. |
Definition at line 603 of file ra8_ota.c.
References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_committing, k_ra8_ota_state_done, k_ra8_ota_state_error, priv_ota_set_state(), and ra8_ota_system_reset_hook().
Referenced by app_run_attempt(), and internal_step_dispatch().
|
nodiscard |
Reset the OTA module to its un-initialized state.
Tear the OTA module down (mostly for tests / re-init).
Clears the cached configuration, manifest, byte-counter and last error so a future ra8_ota_init starts from a clean slate.
| k_ra8_ok | Always succeeds. |
Definition at line 224 of file ra8_ota.c.
References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_ok, k_ra8_ota_state_idle, memset(), s_bytes_done, s_last_err, and s_manifest_valid.
Referenced by app_run_attempt().
|
nodiscard |
Download an image into the inactive bank, hashing as it goes.
Stream the firmware blob into the inactive MRAM bank.
On a fresh start (s_bytes_done == 0) erases the bank and primes the SHA accumulator via internal_prepare_bank. Then opens the image URL and runs internal_download_loop. On success the state machine lands in verifying; on failure it lands in error.
| [in] | manifest | Manifest describing the image to fetch. |
| k_ra8_ok | Download complete; ready to verify. |
| k_ra8_err_not_initialized | Module not initialized. |
| k_ra8_err_null_ptr | manifest was NULL. |
| k_ra8_err_invalid_state | Module not in idle or downloading. |
| k_ra8_err_invalid_size | Image larger than the configured bank. |
| other | Network / crypto / flash error. |
Definition at line 534 of file ra8_ota.c.
References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, ra8_ota_manifest_t::image_size_bytes, ra8_ota_manifest_t::image_url, internal_download_loop(), internal_prepare_bank(), k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_downloading, k_ra8_ota_state_error, k_ra8_ota_state_idle, k_ra8_ota_state_verifying, priv_ota_download_state_invalid(), priv_ota_set_state(), RA8_CHECK_NULL_PTR, s_bytes_done, and s_tag.
Referenced by app_run_attempt(), and internal_step_dispatch().
| ra8_ota_state_t ra8_ota_get_state | ( | void | ) |
Return the current OTA state-machine value.
Return the current state-machine value.
Reads the latched g_ra8_ota_state directly. g_ra8_ota_state is a single byte, so a torn read is impossible on the target.
| k_ra8_ota_state_idle | Module not initialized, or genuinely idle. |
| other | Whatever state the worker last latched. |
Definition at line 257 of file ra8_ota.c.
References g_ra8_ota_state.
Referenced by app_run_attempt().
|
nodiscard |
Initialise the OTA module from a caller-supplied configuration.
Initialise the OTA module.
Verifies the module is in the un-initialized state, runs the full priv_ota_validate_cfg check on cfg, then captures the descriptor by-value into g_ra8_ota_cfg and resets the state machine to k_ra8_ota_state_idle.
| [in] | cfg | Configuration descriptor (function pointers + URLs). |
| k_ra8_ok | Module initialized. |
| k_ra8_err_invalid_state | Module already initialized. |
| k_ra8_err_null_ptr | cfg (or sub-pointer) was NULL. |
| k_ra8_err_invalid_arg | Configuration field out of range. |
Definition at line 182 of file ra8_ota.c.
References g_ra8_ota_cfg, g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_ota_state_idle, memcpy(), priv_ota_validate_cfg(), s_bytes_done, s_last_err, and s_manifest_valid.
Referenced by app_run_attempt().
|
nodiscard |
Drive the OTA state machine through an end-to-end update.
Kick off an end-to-end update from idle.
Loops calling ra8_ota_run_step for at most k_ra8_ota_state_count iterations (NASA Rule 2 bound: idle -> checking -> downloading -> verifying -> committing -> done). Stops early on done or error.
| k_ra8_ok | Update completed (or already done). |
| k_ra8_err_not_initialized | Module not initialized. |
| other | Whatever the failing step returned. |
Definition at line 740 of file ra8_ota.c.
References g_ra8_ota_initialized, g_ra8_ota_state, k_ra8_err_not_initialized, k_ra8_ok, k_ra8_ota_state_count, k_ra8_ota_state_done, k_ra8_ota_state_error, ra8_ota_run_step(), and s_last_err.
|
nodiscard |
Drive the OTA state machine one step forward.
Thin wrapper over internal_step_dispatch that gates on g_ra8_ota_initialized. Intended for callers that opted out of running the OTA worker as a background thread.
| k_ra8_ok | Step completed. |
| k_ra8_err_not_initialized | Module not initialized. |
| other | Step-specific error. |
Definition at line 707 of file ra8_ota.c.
References g_ra8_ota_initialized, internal_step_dispatch(), and k_ra8_err_not_initialized.
Referenced by ra8_ota_run_full_update().
| void ra8_ota_system_reset_hook | ( | void | ) |
Weak system-reset hook overridden by the target build.
Test/host hook for commit_and_reboot.
Called from ra8_ota_commit_and_reboot after the bank-swap is latched. The hardware build overrides this with a definition that calls NVIC_SystemReset. The host (unit-test) build keeps the weak no-op default so tests can observe post-commit state without actually exiting the process.
Definition at line 791 of file ra8_ota.c.
Referenced by ra8_ota_commit_and_reboot().
| uint8_t g_ra8_ota_buf[k_ra8_ota_chunk_bytes] |
Streaming buffer (shared; contract in ra8_ota_internal.h).
Streaming chunk buffer reused by the manifest, download and re-hash paths; defined in ra8_ota.c.
k_ra8_ota_chunk_bytes of static scratch shared with ra8_ota_verify.c so the re-hash pass reads the inactive bank back through it.
Definition at line 72 of file ra8_ota.c.
Referenced by internal_download_chunk(), internal_fetch_manifest_payload(), internal_rehash_bank(), and ra8_ota_check_for_update().
| ra8_ota_cfg_t g_ra8_ota_cfg |
Configuration captured at init time (shared; contract in ra8_ota_internal.h).
Module configuration captured by ra8_ota_init; defined in ra8_ota.c.
Function-pointer interfaces (net / crypto / flash) plus URLs and bank metadata. Shared read-only with ra8_ota_verify.c so the verify cluster can reach the crypto interface and the public-key handle.
Definition at line 54 of file ra8_ota.c.
Referenced by internal_bind_manifest_material(), internal_download_chunk(), internal_download_loop(), internal_drain(), internal_fetch_manifest_payload(), internal_prepare_bank(), internal_rehash_bank(), priv_ota_set_state(), ra8_ota_commit_and_reboot(), ra8_ota_deinit(), ra8_ota_download_to_inactive_bank(), ra8_ota_init(), and ra8_ota_verify_signature().
| bool g_ra8_ota_initialized = false |
True once ra8_ota_init succeeded (shared; contract in ra8_ota_internal.h).
True once ra8_ota_init has succeeded; defined in ra8_ota.c.
Shared with ra8_ota_verify.c so the verify entry point can reject calls issued before the module is initialized.
Definition at line 57 of file ra8_ota.c.
Referenced by ra8_ota_check_for_update(), ra8_ota_commit_and_reboot(), ra8_ota_deinit(), ra8_ota_download_to_inactive_bank(), ra8_ota_init(), ra8_ota_run_full_update(), ra8_ota_run_step(), and ra8_ota_verify_signature().
| ra8_ota_state_t g_ra8_ota_state = k_ra8_ota_state_idle |
Current state-machine value (shared; contract in ra8_ota_internal.h).
Current OTA state-machine value; defined in ra8_ota.c.
Single-byte cooperative state shared with ra8_ota_verify.c so the verify entry point can gate on k_ra8_ota_state_verifying.
Definition at line 51 of file ra8_ota.c.
Referenced by internal_step_dispatch(), priv_ota_set_state(), ra8_ota_check_for_update(), ra8_ota_commit_and_reboot(), ra8_ota_deinit(), ra8_ota_download_to_inactive_bank(), ra8_ota_get_state(), ra8_ota_init(), ra8_ota_run_full_update(), and ra8_ota_verify_signature().
|
static |
Bytes already programmed into the inactive bank.
Definition at line 66 of file ra8_ota.c.
Referenced by internal_download_loop(), priv_ota_set_state(), ra8_ota_deinit(), ra8_ota_download_to_inactive_bank(), and ra8_ota_init().
Last error observed by the state machine.
Definition at line 69 of file ra8_ota.c.
Referenced by priv_ota_set_state(), ra8_ota_deinit(), ra8_ota_init(), and ra8_ota_run_full_update().
|
static |
Cached decoded manifest from the most recent check.
Definition at line 60 of file ra8_ota.c.
Referenced by internal_step_dispatch(), priv_ota_set_state(), and ra8_ota_check_for_update().
|
static |
Whether s_manifest holds a valid payload.
Definition at line 63 of file ra8_ota.c.
Referenced by internal_step_dispatch(), priv_ota_set_state(), ra8_ota_check_for_update(), ra8_ota_deinit(), and ra8_ota_init().