chore: 版本升级至V1.1.10并优化批量通信逻辑

1. 更新所有文件的版本号注释从V1.1.9到V1.1.10
2. 修改chrg_comm.c中的固件版本宏定义为0x011A
3. 新增短路保活命令优先调度逻辑,避免挤占保活窗口
4. 优化批量通信的通道轮转和重试机制
5. 改为按通道维护重试计数,避免全局计数异常
6. 新增批量通信突发计数和通道状态管理
This commit is contained in:
wrh
2026-09-09 11:08:51 +08:00
parent 9a7892e105
commit e56830fc86
8 changed files with 78 additions and 19 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_comm.c 文件名称 : chrg_comm.c
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。 主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
@@ -27,7 +27,7 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#define HOLD_REG_FIRMWARE_VERSION 0x0300U /* 协议板固件版本,只读 */ #define HOLD_REG_FIRMWARE_VERSION 0x0300U /* 协议板固件版本,只读 */
#define CHRG_FIRMWARE_VERSION 0x0119U /* 当前协议板版本:V1.1.9 */ #define CHRG_FIRMWARE_VERSION 0x011AU /* 当前协议板版本:V1.1.10 */
rt_uint8_t ucDiscInBuf[(TOTAL_DISC_REGS+BITS_UCHAR-1)/BITS_UCHAR]; rt_uint8_t ucDiscInBuf[(TOTAL_DISC_REGS+BITS_UCHAR-1)/BITS_UCHAR];
rt_uint8_t ucCoilBuf[(TOTAL_COIL_REGS+BITS_UCHAR-1)/BITS_UCHAR]; rt_uint8_t ucCoilBuf[(TOTAL_COIL_REGS+BITS_UCHAR-1)/BITS_UCHAR];
@@ -618,7 +618,7 @@ eMBException funcReadHoldingRegister (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
/* /*
* 协议板版本号使用独立的只读地址0x0300,不占用现有通道保持寄存器空间。 * 协议板版本号使用独立的只读地址0x0300,不占用现有通道保持寄存器空间。
* 当前版本V1.1.9编码为0x0119,Modbus响应按高字节在前返回01 19。 * 当前版本V1.1.10编码为0x011A,Modbus响应按高字节在前返回01 1A。
* 该特殊地址只支持一次读取一个寄存器,避免与普通连续寄存器混用。 * 该特殊地址只支持一次读取一个寄存器,避免与普通连续寄存器混用。
*/ */
if (regAddress == HOLD_REG_FIRMWARE_VERSION) { if (regAddress == HOLD_REG_FIRMWARE_VERSION) {
+1 -1
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_comm.h 文件名称 : chrg_comm.h
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。 主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
+1 -1
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_north.c 文件名称 : chrg_north.c
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。 主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_roll_nor.c 文件名称 : chrg_roll_nor.c
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_roll_nor.h 文件名称 : chrg_roll_nor.h
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
+69 -10
View File
@@ -26,6 +26,8 @@
#define SOU_MUTEX_TIMEOUT_MS 100 #define SOU_MUTEX_TIMEOUT_MS 100
#define SOU_RESPONSE_TIMEOUT_MS 20 #define SOU_RESPONSE_TIMEOUT_MS 20
#define SOU_COM_MAX_ATTEMPTS 3 #define SOU_COM_MAX_ATTEMPTS 3
#define SOU_COM_BURST_MAX 10U
#define SOU_COM_RETRY_YIELD_MS 1U
#define SOU_REL_SWITCH_DELAY_MS 100U #define SOU_REL_SWITCH_DELAY_MS 100U
#define SOU_CHANNEL_BIT(ch) ((rt_uint8_t)(1U << (ch))) #define SOU_CHANNEL_BIT(ch) ((rt_uint8_t)(1U << (ch)))
@@ -45,6 +47,8 @@ static rt_uint8_t g_sou_version_ready[TOTAL_SOU_CHS] = {0U};
* 回码错误或超时时游标保持不变,使同一条命令优先完成重发,避免破坏 * 回码错误或超时时游标保持不变,使同一条命令优先完成重发,避免破坏
* 本通道批次内的寄存器执行顺序。 */ * 本通道批次内的寄存器执行顺序。 */
static rt_uint8_t g_sou_com_batch_rr_next_ch = 0U; static rt_uint8_t g_sou_com_batch_rr_next_ch = 0U;
static rt_uint8_t g_sou_com_batch_burst_ch = TOTAL_SOU_CHS;
static rt_uint8_t g_sou_com_batch_burst_count = 0U;
struct chrg_rollsou_t chrgrollsou = { struct chrg_rollsou_t chrgrollsou = {
.run = RUN_AUTO, .run = RUN_AUTO,
@@ -535,6 +539,29 @@ static int sou_com_batch_next(rt_uint8_t *ch, rt_uint16_t *reg, rt_uint16_t *val
} }
now = rt_tick_get(); now = rt_tick_get();
/* 短路保活的WORK_START达到周期后优先下发,避免长批次挤占30ms保活窗口。 */
for (offset = 0; offset < TOTAL_SOU_CHS; offset++) {
idx = (rt_uint8_t)((g_sou_com_batch_rr_next_ch + offset) %
TOTAL_SOU_CHS);
sou_com_batch_ch_t *pBatch = &g_sou_com_batch.ch[idx];
if ((pBatch->pending != RT_TRUE) ||
(pBatch->cur_idx >= pBatch->reg_cnt) ||
(pBatch->reg_list[pBatch->cur_idx] != REG_WORK) ||
(pBatch->val_list[pBatch->cur_idx] != WORK_START) ||
(chrgnorth.sw[idx].id != ID_SINK) ||
(chrgnorth.sw[idx].sink.work_mode != SINK_WORK_ON_TEST_SHORT) ||
(chrgnorth.sw[idx].sink.test.test_mode != SINK_TEST_SHORT) ||
((pBatch->next_send_tick != 0U) &&
((rt_int32_t)(now - pBatch->next_send_tick) < 0))) {
continue;
}
pBatch->next_send_tick = 0U;
*ch = idx;
*reg = pBatch->reg_list[pBatch->cur_idx];
*value = pBatch->val_list[pBatch->cur_idx];
rt_mutex_release(pTHR->mutex);
return 1;
}
/* 从上一次成功命令的下一个通道开始查找,使多通道批次按 /* 从上一次成功命令的下一个通道开始查找,使多通道批次按
* "CH1一条 -> CH2一条 -> ..." 交替执行,而不是低编号通道独占总线。 */ * "CH1一条 -> CH2一条 -> ..." 交替执行,而不是低编号通道独占总线。 */
for (offset = 0; offset < TOTAL_SOU_CHS; offset++) { for (offset = 0; offset < TOTAL_SOU_CHS; offset++) {
@@ -593,9 +620,6 @@ static int sou_com_batch_complete(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t va
} }
pBatch->cur_idx++; pBatch->cur_idx++;
/* 当前寄存器已收到匹配写回码。下一次调度从下一个通道开始;
* 当前通道的下一条命令会在其它就绪通道各执行一条后继续发送。 */
g_sou_com_batch_rr_next_ch = (rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS);
/* 暂时关闭副继电器与主继电器之间的固定延时;需要恢复时重新启用本段。 */ /* 暂时关闭副继电器与主继电器之间的固定延时;需要恢复时重新启用本段。 */
if ((reg == REG_REL_ON) && (value == ALL_REL_OFF) && if ((reg == REG_REL_ON) && (value == ALL_REL_OFF) &&
(pBatch->cur_idx < pBatch->reg_cnt) && (pBatch->cur_idx < pBatch->reg_cnt) &&
@@ -616,6 +640,19 @@ static int sou_com_batch_complete(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t va
pBatch->cur_idx = 0; pBatch->cur_idx = 0;
pBatch->reg_cnt = 0; pBatch->reg_cnt = 0;
pBatch->next_send_tick = 0U; pBatch->next_send_tick = 0U;
g_sou_com_batch_burst_ch = TOTAL_SOU_CHS;
g_sou_com_batch_burst_count = 0U;
g_sou_com_batch_rr_next_ch = (rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS);
} else if (g_sou_com_batch_burst_ch != ch) {
g_sou_com_batch_burst_ch = ch;
g_sou_com_batch_burst_count = 1U;
g_sou_com_batch_rr_next_ch = ch;
} else if (++g_sou_com_batch_burst_count >= SOU_COM_BURST_MAX) {
g_sou_com_batch_burst_ch = TOTAL_SOU_CHS;
g_sou_com_batch_burst_count = 0U;
g_sou_com_batch_rr_next_ch = (rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS);
} else {
g_sou_com_batch_rr_next_ch = ch;
} }
rt_mutex_release(pTHR->mutex); rt_mutex_release(pTHR->mutex);
return 0; return 0;
@@ -636,6 +673,12 @@ int chrg_sou_com_batch_cancel(eIDX_SOU_CH ch)
pBatch->cur_idx = 0; pBatch->cur_idx = 0;
pBatch->reg_cnt = 0; pBatch->reg_cnt = 0;
pBatch->next_send_tick = 0U; pBatch->next_send_tick = 0U;
if (g_sou_com_batch_burst_ch == ch) {
g_sou_com_batch_burst_ch = TOTAL_SOU_CHS;
g_sou_com_batch_burst_count = 0U;
g_sou_com_batch_rr_next_ch =
(rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS);
}
/* 已取消事务对应的优先P1量测同样失效,后续状态会重新申请新量测。 */ /* 已取消事务对应的优先P1量测同样失效,后续状态会重新申请新量测。 */
g_sou_measure_once_pending_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch); g_sou_measure_once_pending_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
g_sou_measure_once_active_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch); g_sou_measure_once_active_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
@@ -735,6 +778,23 @@ static void sou_com_command_failed(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t v
(*retry_count)++; (*retry_count)++;
if (*retry_count < SOU_COM_MAX_ATTEMPTS) { if (*retry_count < SOU_COM_MAX_ATTEMPTS) {
struct chrg_thread_t *pTHR = &chrgthr[IDX_THR_ROLL_SOU];
if (rt_mutex_take(pTHR->mutex,
rt_tick_from_millisecond(SOU_MUTEX_TIMEOUT_MS)) == RT_EOK) {
sou_com_batch_ch_t *pBatch = &g_sou_com_batch.ch[ch];
if ((pBatch->pending == RT_TRUE) &&
(pBatch->cur_idx < pBatch->reg_cnt) &&
(pBatch->reg_list[pBatch->cur_idx] == reg) &&
(pBatch->val_list[pBatch->cur_idx] == value)) {
pBatch->next_send_tick = rt_tick_get() +
rt_tick_from_millisecond(SOU_COM_RETRY_YIELD_MS);
g_sou_com_batch_rr_next_ch =
(rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS);
g_sou_com_batch_burst_ch = TOTAL_SOU_CHS;
g_sou_com_batch_burst_count = 0U;
}
rt_mutex_release(pTHR->mutex);
}
return; return;
} }
@@ -766,7 +826,7 @@ void chrg_roll_sou_thread_entry (void *data)
rt_uint8_t run = 0; rt_uint8_t run = 0;
rt_uint8_t index = 0, idx = 0; rt_uint8_t index = 0, idx = 0;
rt_uint8_t batch_ch = 0; rt_uint8_t batch_ch = 0;
rt_uint8_t retry_count = 0; rt_uint8_t retry_count[TOTAL_SOU_CHS] = {0};
rt_uint8_t command_ch = 0; rt_uint8_t command_ch = 0;
rt_uint8_t single_ch = 0; rt_uint8_t single_ch = 0;
rt_uint8_t single_part = 0; rt_uint8_t single_part = 0;
@@ -796,7 +856,7 @@ void chrg_roll_sou_thread_entry (void *data)
version_probe = RT_FALSE; version_probe = RT_FALSE;
response_part = MB_R_PART1; response_part = MB_R_PART1;
if ((run != RUN_COM) && (run != RUN_UPDATA)) { if ((run != RUN_COM) && (run != RUN_UPDATA)) {
retry_count = 0; rt_memset(retry_count, 0, sizeof(retry_count));
} }
// rt_kprintf("------ROLL SOU START \n--------"); // rt_kprintf("------ROLL SOU START \n--------");
switch (run) { switch (run) {
@@ -855,7 +915,6 @@ void chrg_roll_sou_thread_entry (void *data)
{ {
int next_ret = sou_com_batch_next(&command_ch, &command_reg, &command_value); int next_ret = sou_com_batch_next(&command_ch, &command_reg, &command_value);
if (next_ret <= 0) { if (next_ret <= 0) {
retry_count = 0;
rt_thread_mdelay(1); rt_thread_mdelay(1);
continue; continue;
} }
@@ -919,10 +978,10 @@ void chrg_roll_sou_thread_entry (void *data)
if (response_valid) { if (response_valid) {
if (run == RUN_COM) { if (run == RUN_COM) {
if (sou_com_batch_complete(batch_ch, command_reg, command_value) == 0) { if (sou_com_batch_complete(batch_ch, command_reg, command_value) == 0) {
retry_count = 0; retry_count[batch_ch] = 0;
} else { } else {
sou_com_command_failed(batch_ch, command_reg, command_value, sou_com_command_failed(batch_ch, command_reg, command_value,
"batch changed", &retry_count); "batch changed", &retry_count[batch_ch]);
} }
} else if (run != RUN_AUTO) { } else if (run != RUN_AUTO) {
sou_single_command_finish(run); sou_single_command_finish(run);
@@ -940,7 +999,7 @@ void chrg_roll_sou_thread_entry (void *data)
} }
} else if (run == RUN_COM) { } else if (run == RUN_COM) {
sou_com_command_failed(batch_ch, command_reg, command_value, sou_com_command_failed(batch_ch, command_reg, command_value,
"invalid response", &retry_count); "invalid response", &retry_count[batch_ch]);
} else { } else {
LOG_E("crc failed"); LOG_E("crc failed");
} }
@@ -956,7 +1015,7 @@ void chrg_roll_sou_thread_entry (void *data)
} }
if ((run == RUN_COM) && command_valid) { if ((run == RUN_COM) && command_valid) {
sou_com_command_failed(batch_ch, command_reg, command_value, sou_com_command_failed(batch_ch, command_reg, command_value,
"timeout", &retry_count); "timeout", &retry_count[batch_ch]);
} else if (run != RUN_AUTO) { } else if (run != RUN_AUTO) {
sou_single_command_finish(run); sou_single_command_finish(run);
} }
+1 -1
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_source.c 文件名称 : chrg_source.c
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 北向数据source请求数据填充及发送。 主要功能 : 北向数据source请求数据填充及发送。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :
+1 -1
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
文件名称 : chrg_source.c 文件名称 : chrg_source.c
完成日期 : 完成日期 :
当前版本号 : V1.1.9 当前版本号 : V1.1.10
主要功能 : 北向数据source请求数据填充及发送,命令字定义。 主要功能 : 北向数据source请求数据填充及发送,命令字定义。
版本历史 : 创建原始版本 版本历史 : 创建原始版本
说明 : 说明 :