feat: 完善Mesh继电器OTA与地址协议
- 增加STM8 Bootloader工程及出厂固件恢复流程\n- 增加W25Q64外部Flash驱动和OTA分包接收、CRC16校验、断点续传状态管理\n- 增加固件版本查询、升级结果上报与主机确认机制\n- 将业务帧从55 AA帧头调整为发送方Mesh短地址+CMD+LEN+DATA+CRC16\n- 修正JDY-28M外层地址与业务发送方地址的职责划分,支持广播请求定向应答\n- 同步更新硬件引脚、存储分区、OTA流程和主机通信协议文档\n- 已使用SDCC重新编译,应用代码大小为5512字节,链接地址为0x8800
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @file bootloader.h
|
||||
* @brief Bootloader 顶层流程接口。
|
||||
*/
|
||||
#ifndef STM8_BOOTLOADER_H
|
||||
#define STM8_BOOTLOADER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化 Bootloader 所需的最小硬件资源。 */
|
||||
void Bootloader_Init(void);
|
||||
/** 判断应用程序区域是否包含可执行程序。 */
|
||||
uint8_t Bootloader_IsApplicationValid(void);
|
||||
/** 跳转到应用程序入口地址,函数成功后不返回。 */
|
||||
void Bootloader_JumpToApplication(void);
|
||||
/** Bootloader 主任务,后续OTA接收和搬运流程在此扩展。 */
|
||||
void Bootloader_Task(void);
|
||||
/** 检查W25Q64中的升级请求并完成固件搬运。 */
|
||||
uint8_t Bootloader_ProcessUpgrade(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file bootloader_config.h
|
||||
* @brief Bootloader 的固定地址和安全策略配置。
|
||||
*/
|
||||
#ifndef STM8_BOOTLOADER_CONFIG_H
|
||||
#define STM8_BOOTLOADER_CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Bootloader 在 STM8 程序 Flash 中的起始地址。 */
|
||||
#define BOOTLOADER_START_ADDRESS 0x8000u
|
||||
/** Bootloader 预留空间,当前规划为 1KB。 */
|
||||
#define BOOTLOADER_SIZE_BYTES 0x0800u
|
||||
/** 应用程序固定入口地址,必须与应用工程链接地址一致。 */
|
||||
#define APPLICATION_START_ADDRESS 0x8800u
|
||||
/** STM8S003F3P6 程序 Flash 的最后一个地址。 */
|
||||
#define APPLICATION_END_ADDRESS 0x9FFFu
|
||||
/** 应用程序允许使用的最大空间。 */
|
||||
#define APPLICATION_MAX_SIZE_BYTES \
|
||||
(APPLICATION_END_ADDRESS - APPLICATION_START_ADDRESS + 1u)
|
||||
|
||||
/** W25Q64 中保存出厂固件镜像的固定地址,容量64KiB。 */
|
||||
#define FACTORY_IMAGE_ADDRESS 0x000000ul
|
||||
/** W25Q64 中保存出厂固件元数据的固定地址,独占4KiB扇区。 */
|
||||
#define FACTORY_METADATA_ADDRESS 0x010000ul
|
||||
/** W25Q64 中保存OTA升级固件的固定地址,容量64KiB。 */
|
||||
#define OTA_IMAGE_ADDRESS 0x020000ul
|
||||
/** W25Q64 中保存OTA元数据的固定地址,独占4KiB扇区。 */
|
||||
#define OTA_METADATA_ADDRESS 0x030000ul
|
||||
/** 升级元数据魔数,用于避免误把普通数据当成升级请求。 */
|
||||
#define OTA_METADATA_MAGIC 0x4F544131ul
|
||||
/** 出厂恢复镜像元数据魔数。 */
|
||||
#define FACTORY_METADATA_MAGIC 0x46414331ul
|
||||
|
||||
/* 元数据字段相对于各自元数据扇区起始地址的固定偏移。 */
|
||||
#define METADATA_MAGIC_OFFSET 0x00u
|
||||
#define METADATA_IMAGE_SIZE_OFFSET 0x04u
|
||||
#define METADATA_VERSION_OFFSET 0x08u
|
||||
#define METADATA_CRC16_OFFSET 0x0Au
|
||||
#define METADATA_IMAGE_VALID_OFFSET 0x0Eu
|
||||
#define METADATA_UPGRADE_REQUEST_OFFSET 0x0Fu
|
||||
#define METADATA_UPGRADE_RESULT_OFFSET 0x10u
|
||||
/** 镜像已经完整写入并通过校验时使用的有效标志。 */
|
||||
#define METADATA_IMAGE_VALID_VALUE 0xA5u
|
||||
|
||||
/** 应用程序有效标记,避免把空白 Flash 当作可执行程序。 */
|
||||
#define APPLICATION_FIRST_BYTE_INVALID 0x00u
|
||||
#define APPLICATION_FIRST_BYTE_ERASED 0xFFu
|
||||
|
||||
/** Bootloader 看门狗刷新周期,必须小于硬件看门狗超时时间。 */
|
||||
#define BOOTLOADER_WATCHDOG_REFRESH_LOOP 20000u
|
||||
/** 上电恢复按键判定时间,单位为毫秒。 */
|
||||
#define FACTORY_BUTTON_HOLD_TIME_MS 5000u
|
||||
/** Bootloader忙等待1ms的循环次数,需结合实际系统时钟校准。 */
|
||||
#define BOOTLOADER_DELAY_1MS_LOOPS 1200u
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file stm8_bootloader_registers.h
|
||||
* @brief Bootloader 使用的 STM8S003F3P6 最小寄存器定义。
|
||||
*/
|
||||
#ifndef STM8_BOOTLOADER_REGISTERS_H
|
||||
#define STM8_BOOTLOADER_REGISTERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define REG8(address) (*((volatile uint8_t *)(address)))
|
||||
|
||||
/* FLASH 外设寄存器地址,地址来自 STM8S003 数据手册。 */
|
||||
#define FLASH_CR1_ADDR 0x505Au
|
||||
#define FLASH_CR2_ADDR 0x505Bu
|
||||
#define FLASH_NCR2_ADDR 0x505Cu
|
||||
#define FLASH_IAPSR_ADDR 0x505Fu
|
||||
#define FLASH_PUKR_ADDR 0x5062u
|
||||
|
||||
#define FLASH_CR1 REG8(FLASH_CR1_ADDR)
|
||||
#define FLASH_CR2 REG8(FLASH_CR2_ADDR)
|
||||
#define FLASH_NCR2 REG8(FLASH_NCR2_ADDR)
|
||||
#define FLASH_IAPSR REG8(FLASH_IAPSR_ADDR)
|
||||
#define FLASH_PUKR REG8(FLASH_PUKR_ADDR)
|
||||
|
||||
/* Flash 控制位。 */
|
||||
#define FLASH_CR2_PRG 0x01u
|
||||
#define FLASH_CR2_WPRG 0x10u
|
||||
#define FLASH_IAPSR_HVOFF 0x08u
|
||||
|
||||
/* IWDG 寄存器。 */
|
||||
#define IWDG_KR_ADDR 0x50E0u
|
||||
#define IWDG_PR_ADDR 0x50E1u
|
||||
#define IWDG_RLR_ADDR 0x50E2u
|
||||
#define IWDG_KR REG8(IWDG_KR_ADDR)
|
||||
#define IWDG_PR REG8(IWDG_PR_ADDR)
|
||||
#define IWDG_RLR REG8(IWDG_RLR_ADDR)
|
||||
|
||||
/* SPI1 外设寄存器。 */
|
||||
#define SPI1_CR1_ADDR 0x5200u
|
||||
#define SPI1_CR2_ADDR 0x5201u
|
||||
#define SPI1_ICR_ADDR 0x5202u
|
||||
#define SPI1_SR_ADDR 0x5203u
|
||||
#define SPI1_DR_ADDR 0x5204u
|
||||
#define SPI1_CR1 REG8(SPI1_CR1_ADDR)
|
||||
#define SPI1_CR2 REG8(SPI1_CR2_ADDR)
|
||||
#define SPI1_SR REG8(SPI1_SR_ADDR)
|
||||
#define SPI1_DR REG8(SPI1_DR_ADDR)
|
||||
|
||||
#define GPIOA_ODR REG8(0x5000u)
|
||||
#define GPIOA_IDR REG8(0x5001u)
|
||||
#define GPIOA_DDR REG8(0x5002u)
|
||||
#define GPIOA_CR1 REG8(0x5003u)
|
||||
#define GPIOC_ODR REG8(0x500Au)
|
||||
#define GPIOC_DDR REG8(0x500Cu)
|
||||
#define GPIOC_CR1 REG8(0x500Du)
|
||||
|
||||
#define SPI_CR1_SPE 0x40u
|
||||
#define SPI_CR1_MSTR 0x04u
|
||||
#define SPI_CR1_BR0 0x08u
|
||||
#define SPI_CR1_BR1 0x10u
|
||||
#define SPI_CR1_BR2 0x20u
|
||||
#define SPI_CR2_SSI 0x01u
|
||||
#define SPI_CR2_SSM 0x02u
|
||||
#define SPI_SR_RXNE 0x01u
|
||||
#define SPI_SR_TXE 0x02u
|
||||
#define SPI_SR_BSY 0x80u
|
||||
|
||||
#define FLASH_IAPSR_EOP 0x04u
|
||||
#define FLASH_CR2_PRG 0x01u
|
||||
#define FLASH_CR2_ERASE 0x20u
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file w25q64.h
|
||||
* @brief W25Q64JV 硬件SPI访问接口。
|
||||
*/
|
||||
#ifndef STM8_BOOTLOADER_W25Q64_H
|
||||
#define STM8_BOOTLOADER_W25Q64_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** 初始化STM8硬件SPI和W25Q64片选。 */
|
||||
void W25Q64_Init(void);
|
||||
/** 读取W25Q64 JEDEC ID,便于启动时确认芯片存在。 */
|
||||
uint32_t W25Q64_ReadJedecId(void);
|
||||
/** 从W25Q64连续读取数据。 */
|
||||
void W25Q64_Read(uint32_t address, uint8_t *buffer, uint16_t length);
|
||||
/** 擦除包含指定地址的4KB扇区。 */
|
||||
uint8_t W25Q64_EraseSector(uint32_t address);
|
||||
/** 向W25Q64页内写入数据,长度不能跨越256字节页边界。 */
|
||||
uint8_t W25Q64_PageProgram(uint32_t address, const uint8_t *data,
|
||||
uint16_t length);
|
||||
/** 将升级元数据中的request字节清零,表示升级已处理。 */
|
||||
uint8_t W25Q64_ClearUpgradeRequest(void);
|
||||
/** 写入Bootloader升级结果码,供主程序启动后上报。 */
|
||||
uint8_t W25Q64_WriteUpgradeResult(uint8_t result);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user