|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The IOmcu's half of the firmware update: the UPDATE_CTL and UPDATE_DATA pages (link_pages.h) and what they write. More...
#include <stdbool.h>#include <stdint.h>#include "link_pages.h"#include "link_sha256.h"#include "link_update_image.h"Go to the source code of this file.
Data Structures | |
| struct | link_update_io_t |
| The flash, gate, boot ROM and restart callbacks of the update. More... | |
| struct | link_update_dev_t |
| The state of the IOmcu's side of one update session. More... | |
Macros | |
| #define | LINK_UPD_HASH_STEP 1024u |
| Bytes a link_update_dev_poll() hashes, at most: 1KiB, about 0.4ms of SHA-256 at 150MHz (not measured). | |
| #define | LINK_UPD_SILENCE_MS 5000u |
| Time without a request to either update page that ends a session: longer than the panel's own 1000ms wait for an answer, so one lost frame costs a retry and not the session, and longer than the panel's LINK_UPH_LOST_MS, so the panel gives up first. | |
| #define | LINK_UPD_SWEEP_MS 1000u |
| Time between two tries of an owed erase of the other slot's first sector: each one parks the loop for about 19ms. | |
| #define | LINK_UPD_RESTART_MS 20u |
| Time from the ACTIVATE that wrote the first sector to the restart, so its acknowledgement is on the wire first. | |
Functions | |
| void | link_update_dev_init (link_update_dev_t *u, const link_update_io_t *io, const uint8_t *running, const uint8_t *target, uint32_t slot_bytes, uint16_t slot) |
Start idle. slot is LINK_UPD_SLOT as the boot ROM reports it: the running slot, LINK_UPD_SLOT_NONE without a partition table this build writes, and LINK_UPD_SLOT_TRIAL for an image that waits for its BUY. running and target may be NULL with LINK_UPD_SLOT_NONE. | |
| void | link_update_dev_read_ctl (link_update_dev_t *u, uint8_t offset, uint8_t count, uint16_t *out) |
| The two pages' handlers, for the caller's link_page_t table. | |
| uint8_t | link_update_dev_write_ctl (link_update_dev_t *u, uint8_t offset, uint8_t count, const uint16_t *in) |
| Write registers of the UPDATE_CTL page: one command and its arguments. | |
| void | link_update_dev_read_data (link_update_dev_t *u, uint8_t offset, uint8_t count, uint16_t *out) |
| Read registers of the UPDATE_DATA page. | |
| uint8_t | link_update_dev_write_data (link_update_dev_t *u, uint8_t offset, uint8_t count, const uint16_t *in) |
| Write registers of the UPDATE_DATA page: stage part of a block. | |
| void | link_update_dev_poll (link_update_dev_t *u, uint32_t now_ms) |
| The work that does not fit a reply: LINK_UPD_HASH_STEP bytes of a hash, the restart LINK_UPD_RESTART_MS after ACTIVATE, an owed erase of the other slot's first sector, and the end of a session that has had no request to either update page for LINK_UPD_SILENCE_MS. | |
| bool | link_update_dev_holds_arm (const link_update_dev_t *u) |
| True while ARM is refused: a session runs or an image waits for BUY. | |
| bool | link_update_dev_refuses_arm (const link_update_dev_t *u, uint8_t off, uint8_t n, const uint16_t *in) |
Whether a write of n CONTROL registers from off is refused for the update: it asks for a non-zero ARM while link_update_dev_holds_arm(). | |
The IOmcu's half of the firmware update: the UPDATE_CTL and UPDATE_DATA pages (link_pages.h) and what they write.
Pure C. The flash, the store's gate, the boot ROM's BUY and the restart are the caller's, handed in as callbacks, and both slots are read through plain pointers, so the host suite runs every path against a slot in RAM.
RAM: two 4KiB sector buffers – the slot's first sector, held until ACTIVATE writes it last, and the sector being filled.
SPDX-License-Identifier: MIT
| #define LINK_UPD_SILENCE_MS 5000u |
Time without a request to either update page that ends a session: longer than the panel's own 1000ms wait for an answer, so one lost frame costs a retry and not the session, and longer than the panel's LINK_UPH_LOST_MS, so the panel gives up first.
Requests to other pages do not count: a panel that polls and sends no update has left it.
| bool link_update_dev_holds_arm | ( | const link_update_dev_t * | u | ) |
True while ARM is refused: a session runs or an image waits for BUY.
| u | The update state; NULL gives false. |
| void link_update_dev_init | ( | link_update_dev_t * | u, |
| const link_update_io_t * | io, | ||
| const uint8_t * | running, | ||
| const uint8_t * | target, | ||
| uint32_t | slot_bytes, | ||
| uint16_t | slot ) |
Start idle. slot is LINK_UPD_SLOT as the boot ROM reports it: the running slot, LINK_UPD_SLOT_NONE without a partition table this build writes, and LINK_UPD_SLOT_TRIAL for an image that waits for its BUY. running and target may be NULL with LINK_UPD_SLOT_NONE.
A bought image that finds the other slot's first sector written owes its erase.
| u | The update state to set up. |
| io | The callbacks; kept, not copied. |
| running | The running slot's bytes. |
| target | The other slot's bytes. |
| slot_bytes | Bytes in one slot, a multiple of the 4KiB sector. |
| slot | LINK_UPD_SLOT as the boot ROM reports it. |
| void link_update_dev_poll | ( | link_update_dev_t * | u, |
| uint32_t | now_ms ) |
The work that does not fit a reply: LINK_UPD_HASH_STEP bytes of a hash, the restart LINK_UPD_RESTART_MS after ACTIVATE, an owed erase of the other slot's first sector, and the end of a session that has had no request to either update page for LINK_UPD_SILENCE_MS.
Once per pass of the caller's loop.
| u | The update state. |
| now_ms | The current time, in ms. |
| void link_update_dev_read_ctl | ( | link_update_dev_t * | u, |
| uint8_t | offset, | ||
| uint8_t | count, | ||
| uint16_t * | out ) |
The two pages' handlers, for the caller's link_page_t table.
| u | The update state. |
| offset | First register, 0 to LINK_UPD_COUNT - 1. |
| count | Number of registers to read. |
| out | Receives the registers. |
| void link_update_dev_read_data | ( | link_update_dev_t * | u, |
| uint8_t | offset, | ||
| uint8_t | count, | ||
| uint16_t * | out ) |
Read registers of the UPDATE_DATA page.
| u | The update state. |
| offset | First register of the staged block. |
| count | Number of registers to read. |
| out | Receives the registers. |
| bool link_update_dev_refuses_arm | ( | const link_update_dev_t * | u, |
| uint8_t | off, | ||
| uint8_t | n, | ||
| const uint16_t * | in ) |
Whether a write of n CONTROL registers from off is refused for the update: it asks for a non-zero ARM while link_update_dev_holds_arm().
The caller answers it with LINK_NACK_NOT_ARMED before the page's own rules run, so nothing of the frame is stored. A disarm is always taken.
| u | The update state. |
| off | First CONTROL register of the write. |
| n | Number of registers in the write. |
| in | The registers written. |
| uint8_t link_update_dev_write_ctl | ( | link_update_dev_t * | u, |
| uint8_t | offset, | ||
| uint8_t | count, | ||
| const uint16_t * | in ) |
Write registers of the UPDATE_CTL page: one command and its arguments.
| u | The update state. |
| offset | First register; must be LINK_UPD_CMD. |
| count | Number of registers, 1 to 4. |
| in | The registers written. |
| uint8_t link_update_dev_write_data | ( | link_update_dev_t * | u, |
| uint8_t | offset, | ||
| uint8_t | count, | ||
| const uint16_t * | in ) |
Write registers of the UPDATE_DATA page: stage part of a block.
| u | The update state. |
| offset | First register of the block, 0 to LINK_UPD_DATA_COUNT - 1. |
| count | Number of registers written. |
| in | The registers written. |