1. 修改Flash保存偏移只需要备份修改的部分, 而不是全部备份

This commit is contained in:
coffee 2026-01-07 15:32:09 +08:00
parent 7b24684f06
commit 688e831d57
3 changed files with 128 additions and 16 deletions

View File

@ -32,12 +32,27 @@
#define HDPROTOCOL_OCCUPY_TIMEOUT (1000)
enum eHSProtocolPortType
{
kHSProtocolARM, ///< ARM通信端
kHSProtocolTV, ///< TV通信端
kHSProtocolRS232, ///< RS232中控端
kHSProtocolRS485, ///< RS485中控端
kHSProtocolSensor, ///< 传感器端
// 不需要缓存的放下面
kHSProtocolSelf, ///< 本端, 用于中转数据, 不参与协议发送端
kHSProtocolMAX, ///< 协议最大数量
};
enum eHDProtocolSupport
{
kHDProtocolNone = 0x00, ///< 无协议, 不阻塞等待
kHDProtocolFpga = 0x01, ///< fpga协议, 独占解析端
kHDProtocolVP = 0x02, ///< vp协议, 独占解析端
kHDProtocolTV = 0x04, ///< tv协议
kHDProtocolTV = 0x04, ///< tv协议, 独占解析端
};
/**
@ -50,15 +65,16 @@ typedef struct __attribute__((__packed__)) HDProtocolServerInfo
HRingBufferType *readBuff; ///< 读取环状缓冲区, 内存需要用户调用 HDProtocolInitInfo 提供, 最低需要 sizeof(_HRingBufferBase) + 1 的空间
uint8_t supportProtocol; ///< 支持的协议, 用于解析端选择, 避免多路口同时解析
uint8_t src; ///< 源数据口
uint8_t dst; ///< 目标数据口(如果需要始终转发可以修改该项目, 否则默认和src一样)
uint8_t tmpDst; ///< 临时回送目标数据口(用于该指令需要先请求某个数据后才能回复的情况)
uint8_t feedbackRoute; ///< 反馈后路由数据口(如果需要始终转发可以修改该项目, 否则默认和src一样)
uint8_t tmpfeedbackRoute; ///< 临时反馈后目标协议路由口(用于该指令需要先请求某个数据后才能回复的情况)
uint8_t tmpReadCount : 5; ///< 临时数据最大等待回复次数
uint8_t tmpEnable : 1; ///< 当前临时目标等待数据, 需要等待数据内部标记开启, 数据完成或者超时后自动关闭
uint8_t run : 1; ///< 内部标记当前正常读取, 如果再次触发解析, 则不等待
uint8_t checkAlarm : 1; ///< 启动缓存报警检查
uint8_t notifyAlarm : 1; ///< 通知缓存报警(内部管理)
uint8_t occupy : 1; ///< 内部标记当前正在占用
uint8_t delayCount : 6; ///< 延时等待次数(默认: 1), 每次等待时间为 HSCHEDULE_DELAY_TIMEOUT
uint8_t forward : 1; ///< 内部标记转发
uint8_t delayCount : 5; ///< 延时等待次数(默认: 1), 每次等待时间为 HSCHEDULE_DELAY_TIMEOUT
} HDProtocolServerInfo;
/**
@ -127,21 +143,44 @@ void HDProtocolSendPort(uint8_t dst, const void *data, int len);
/**
* @brief (, , HDProtocolGetDest )
* @param src
* @param dst
* @param feedbackRoute
* @param data
* @param len
* @param needReadCount
* @param waitCount
*/
void HDProtocolTmpSend(uint8_t src, uint8_t dst, const void *data, int len, uint8_t needReadCount, uint8_t waitCount);
void HDProtocolTmpSend(uint8_t src, uint8_t feedbackRoute, const void *data, int len, uint8_t needReadCount, uint8_t waitCount);
/**
* @brief
* @brief (, , HDProtocolGetDest )
* @param src
* @param dst
* @param data
* @param len
* @param needReadCount
* @param waitCount
*/
void HDProtocolTmpForward(uint8_t src, uint8_t dst, const void *data, int len, uint8_t needReadCount, uint8_t waitCount);
/**
* @brief /
* @param info
* @return
* @return , 0
*/
uint8_t HDProtocolGetDest(HDProtocolServerInfo *info);
/**
* @brief
* @return , 0
*/
uint8_t HDProtocolGetCurrDest();
/**
* @brief
* @return , 0
*/
uint8_t HDProtocolGetCurrSrc();
/**
* @brief
* @return

View File

@ -13,7 +13,7 @@
#endif
// 占用信息监测, 需要大于协议数量
#define OCCUPIED_MAX (10)
#define OCCUPIED_MAX (kHSProtocolMAX)
struct __attribute__((__packed__)) OccupiedInfo {
@ -77,6 +77,11 @@ static void SetOccupied(uint8_t currIndex, uint8_t protocol, uint8_t enable)
return ;
}
// 如果开启选项一样, 不需要在继续检查
if (sInfo.info[currIndex].occupy == enable) {
return ;
}
uint8_t index = OCCUPIED_MAX;
for (int i = 0; i < OCCUPIED_MAX; ++i) {
if (sOccupiedInfo[i].enbale == 0) {
@ -124,6 +129,7 @@ static void SetOccupied(uint8_t currIndex, uint8_t protocol, uint8_t enable)
static void WaitRead(HDProtocolServerInfo *info)
{
if (info->tmpEnable == 0) {
info->forward = 0;
return ;
}
@ -151,10 +157,11 @@ static void WaitRead(HDProtocolServerInfo *info)
}
if (info->tmpEnable) {
LogD("wait tmp read not recv[%d]", info->src);
LogD("wait tmp read not recv[%d], count[%d], forward[%d]", info->src, info->delayCount, info->forward);
}
info->tmpEnable = 0;
info->forward = 0;
}
static void ParseReadData(int index, int isTimeout)
@ -176,11 +183,13 @@ static void ParseReadData(int index, int isTimeout)
if (sInfo.info[index].tmpReadCount == 0) {
sInfo.info[index].tmpEnable = 0;
sInfo.info[index].forward = 0;
}
}
if (isTimeout) {
sInfo.info[index].tmpEnable = 0;
sInfo.info[index].forward = 0;
}
SetOccupied(index, sInfo.info[index].supportProtocol, len == 0 ? 0 : 1);
@ -208,7 +217,7 @@ void HDProtocolInitInfo(HDProtocolServerInfo *info, uint8_t src, void *data, int
HRingbufferInit8(info->readBuff, dataLen);
info->delayCount = 1;
info->src = src;
info->dst = src;
info->feedbackRoute = src;
}
void _HDProtocolSetSupportProtocol(HDProtocolServerInfo *info, int len, ...)
@ -267,10 +276,15 @@ void HDProtocolSendPort(uint8_t dst, const void *data, int len)
}
WaitRead(&sInfo.info[dst]);
if (len == 0) {
LogE("Send data len is zero, dst[%d]", dst);
return;
}
sInfo.writeCall(&sInfo.info[dst], (const uint8_t *)data, len);
}
void HDProtocolTmpSend(uint8_t src, uint8_t dst, const void *data, int len, uint8_t needReadCount, uint8_t waitCount)
void HDProtocolTmpSend(uint8_t src, uint8_t feedbackRoute, const void *data, int len, uint8_t needReadCount, uint8_t waitCount)
{
if (data == NULL || len == 0) {
return;
@ -287,7 +301,31 @@ void HDProtocolTmpSend(uint8_t src, uint8_t dst, const void *data, int len, uint
WaitRead(&sInfo.info[src]);
sInfo.info[src].tmpEnable = 1;
sInfo.info[src].tmpDst = dst;
sInfo.info[src].tmpfeedbackRoute = feedbackRoute;
sInfo.info[src].delayCount = waitCount;
sInfo.info[src].tmpReadCount = needReadCount;
sInfo.writeCall(&sInfo.info[src], (const uint8_t *)data, len);
}
void HDProtocolTmpForward(uint8_t src, uint8_t dst, const void *data, int len, uint8_t needReadCount, uint8_t waitCount)
{
if (data == NULL || len == 0) {
return;
}
if (sInfo.writeCall == NULL || sInfo.info == NULL) {
return;
}
if (src >= sInfo.infoLen) {
LogE("index[%d] is out of range[%d]", src, sInfo.infoLen);
return;
}
WaitRead(&sInfo.info[src]);
sInfo.info[src].tmpEnable = 1;
sInfo.info[src].tmpfeedbackRoute = dst;
sInfo.info[src].forward = 1;
sInfo.info[src].delayCount = waitCount;
sInfo.info[src].tmpReadCount = needReadCount;
sInfo.writeCall(&sInfo.info[src], (const uint8_t *)data, len);
@ -300,10 +338,30 @@ uint8_t HDProtocolGetDest(HDProtocolServerInfo *info)
}
if (info->tmpEnable && info == HDProtocolGetCurrInfo()) {
return info->tmpDst;
return info->tmpfeedbackRoute;
}
return info->dst;
return info->feedbackRoute;
}
uint8_t HDProtocolGetCurrDest()
{
HDProtocolServerInfo *info = HDProtocolGetCurrInfo();
if (info == NULL) {
return 0;
}
return info->feedbackRoute;
}
uint8_t HDProtocolGetCurrSrc()
{
HDProtocolServerInfo *info = HDProtocolGetCurrInfo();
if (info == NULL) {
return 0;
}
return info->src;
}
HDProtocolServerInfo *HDProtocolGetCurrInfo()
@ -317,6 +375,10 @@ HDProtocolServerInfo *HDProtocolGetCurrInfo()
void HDProtocolRead(uint8_t src, const void *data, int len)
{
if (data == NULL || len == 0) {
return;
}
if (sInfo.readCall == NULL || sInfo.info == NULL) {
return;
}
@ -411,6 +473,7 @@ void HDProtocolRun()
// 还有其他协议等待抢占, 检查时间
if (HDLogGetTime() - sOccupiedInfo[occupiedIndex].occupyTime > HDPROTOCOL_OCCUPY_TIMEOUT) {
waitTime = 1;
LogD("index[%d] occpyTime finish", occupiedIndex);
}
}

View File

@ -415,6 +415,15 @@ static void AddBackupAddr(uint32_t addr, uint32_t size)
}
}
static void AddBackupOffsetAddr(uint32_t addr, uint32_t offset, uint32_t size)
{
if (IsProtect(addr, size) == 0) {
return ;
}
AddBackupAddr(addr + offset, size);
}
static uint8_t _CalcCrc32(uint32_t addr, uint32_t offset, const uint8_t *data, uint16_t len, void *args)
{
uint32_t needLen = *(uint32_t *)args;
@ -1271,7 +1280,8 @@ static uint8_t WriteOffset(HFlashAddr_t addr, uint32_t offset, const void *data,
// 检查是否在保护区域, 需要的话需要写入等待备份
if (IsProtect(addr, size)) {
AddBackupAddr(addr, useSize);
// 仅备份修改的部分
AddBackupOffsetAddr(addr, offset, size);
}
return result;