Files
templates/c/rs485-boot/include/rs485_boot.h

80 lines
2.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Потоковый загрузчик по RS-485 с кадрированием, CRC32 и продолжением передачи. Автомат
* принимает части входного потока и вызывает операции Flash через порт; неполный кадр не
* является готовой командой.
*/
#ifndef RS485_BOOT_H
#define RS485_BOOT_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RS485_BOOT_VERSION 1U
#define RS485_BOOT_MAX_PAYLOAD 512U
#define RS485_BOOT_MAX_FRAME (8U + RS485_BOOT_MAX_PAYLOAD + 4U)
#define RS485_BOOT_DATA_HEADER_SIZE 8U
#define RS485_BOOT_MAX_BLOCK (RS485_BOOT_MAX_PAYLOAD - RS485_BOOT_DATA_HEADER_SIZE)
typedef enum {
RS485_BOOT_IDLE = 0U,
RS485_BOOT_RECEIVING = 1U,
RS485_BOOT_READY = 2U,
RS485_BOOT_FAILED = 3U
} rs485_boot_state_t;
typedef enum {
RS485_BOOT_OK = 0U,
RS485_BOOT_INVALID_ARGUMENT = 1U,
RS485_BOOT_INVALID_LENGTH = 2U,
RS485_BOOT_BUSY = 5U,
RS485_BOOT_INTERNAL = 7U,
RS485_BOOT_UNSUPPORTED = 0x11U
} rs485_boot_result_t;
typedef struct {
uint32_t app_address;
uint32_t app_size;
uint16_t max_block_size;
} rs485_boot_config_t;
typedef struct {
bool (*transmit)(void *user, const uint8_t *data, uint16_t length);
bool (*erase)(void *user, uint32_t image_size);
bool (*write)(void *user, uint32_t offset, const uint8_t *data, uint16_t length);
bool (*read)(void *user, uint32_t offset, uint8_t *data, uint16_t length);
bool (*image_valid)(void *user, uint32_t image_size, uint32_t image_crc32);
void (*reboot)(void *user);
} rs485_boot_port_t;
typedef struct {
rs485_boot_config_t config;
rs485_boot_port_t port;
void *port_user;
uint8_t parser[RS485_BOOT_MAX_FRAME];
uint16_t parser_length;
uint8_t tx[RS485_BOOT_MAX_FRAME];
uint8_t scratch[32];
uint32_t image_size;
uint32_t image_crc32;
uint32_t next_offset;
uint32_t crc_errors;
rs485_boot_state_t state;
} rs485_boot_t;
bool rs485_boot_init(rs485_boot_t *boot, const rs485_boot_config_t *config,
const rs485_boot_port_t *port, void *port_user);
void rs485_boot_feed(rs485_boot_t *boot, const uint8_t *data, size_t length);
void rs485_boot_abort(rs485_boot_t *boot);
uint32_t rs485_boot_crc32(const uint8_t *data, size_t length);
#ifdef __cplusplus
}
#endif
#endif