- 新增混流解析函数 `parse_mixed_stream()`,支持标准包与光泵包交替出现的二进制文件 - 新增光泵磁力仪模拟器 `OpticMagSimulatorThread`,以可配置频率发送BCD帧 - 新增光泵磁场显示标签页,支持文件模式与实时模式下的磁场曲线绘制 - 新增 `flash_counter` 模块,用于NOFX模式下文件序号持久化 ♻️ refactor(data_storage): 重构数据存储目录与文件命名策略 - 会话目录改为按GPS日期命名(YYYYMMDD),无GPS时使用NOFX目录 - 文件命名改为基于GPS时间(HHMMSS)或Flash计数器(C开头),消除序号文件依赖 - 移除 `config_manager` 依赖和 `PARAM.TXT` 序号文件读写逻辑 - 新增 `GPS_ParseGPRMC()` 解析函数,提取日期字段用于目录命名 🐛 fix(ltc2508_driver): 修复DMA启动失败时资源泄漏问题 - SPI2/SPI3 DMA启动失败时主动停止已启动的DMA,防止资源泄漏 - 将SPI1的dummy发送缓冲区改为static,确保DMA传输期间数据有效 🐛 fix(rs485_driver): 修复DMA发送缓冲区可能被覆盖的问题 - 引入静态发送缓冲区 `s_tx_buf`,隔离调用方数据与DMA传输,防止TIM2 ISR覆盖 ♻️ refactor(ATEMParse): 重构数据结构定义与解析逻辑 - 移除硬编码的V1/V2 dtype,改为动态构建 `make_dtype()` 函数 - 新增数据格式选项(GPS经纬度/光泵),支持灵活配置 - 新增文件模式下的分页浏览功能(滑块/上一页/下一页) - 优化实时模式下的光泵数据显示与表格列过滤
60 lines
1.5 KiB
C
60 lines
1.5 KiB
C
#include "flash_counter.h"
|
||
|
||
typedef struct __attribute__((packed)) {
|
||
uint32_t magic;
|
||
uint32_t counter;
|
||
uint32_t checksum; // magic ^ counter,用于检测 Flash 损坏
|
||
} FlashCounterData_t;
|
||
|
||
HAL_StatusTypeDef FlashCounter_Init(uint32_t *counter)
|
||
{
|
||
const FlashCounterData_t *p = (const FlashCounterData_t *)FLASH_COUNTER_ADDR;
|
||
|
||
if (p->magic == FLASH_COUNTER_MAGIC &&
|
||
(p->magic ^ p->counter) == p->checksum) {
|
||
*counter = p->counter;
|
||
} else {
|
||
// 未初始化或校验失败,视为 0
|
||
*counter = 0;
|
||
}
|
||
return HAL_OK;
|
||
}
|
||
|
||
HAL_StatusTypeDef FlashCounter_Write(uint32_t counter)
|
||
{
|
||
FLASH_EraseInitTypeDef erase = {
|
||
.TypeErase = FLASH_TYPEERASE_SECTORS,
|
||
.Sector = FLASH_COUNTER_SECTOR,
|
||
.NbSectors = 1,
|
||
.VoltageRange = FLASH_VOLTAGE_RANGE_3, // 2.7 ~ 3.6 V
|
||
};
|
||
uint32_t sector_error = 0;
|
||
|
||
HAL_FLASH_Unlock();
|
||
|
||
if (HAL_FLASHEx_Erase(&erase, §or_error) != HAL_OK) {
|
||
HAL_FLASH_Lock();
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
FlashCounterData_t data = {
|
||
.magic = FLASH_COUNTER_MAGIC,
|
||
.counter = counter,
|
||
.checksum = FLASH_COUNTER_MAGIC ^ counter,
|
||
};
|
||
|
||
uint32_t addr = FLASH_COUNTER_ADDR;
|
||
uint32_t *word = (uint32_t *)&data;
|
||
|
||
for (uint8_t i = 0; i < sizeof(FlashCounterData_t) / 4; i++) {
|
||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, word[i]) != HAL_OK) {
|
||
HAL_FLASH_Lock();
|
||
return HAL_ERROR;
|
||
}
|
||
addr += 4;
|
||
}
|
||
|
||
HAL_FLASH_Lock();
|
||
return HAL_OK;
|
||
}
|