diff --git a/apps/chrg/applications/thread/chrg_comm.c b/apps/chrg/applications/thread/chrg_comm.c index d020026..9d08969 100644 --- a/apps/chrg/applications/thread/chrg_comm.c +++ b/apps/chrg/applications/thread/chrg_comm.c @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_comm.c 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。 版本历史 : 创建原始版本 说明 : @@ -27,7 +27,7 @@ #include "stm32f4xx_hal.h" #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 ucCoilBuf[(TOTAL_COIL_REGS+BITS_UCHAR-1)/BITS_UCHAR]; @@ -618,7 +618,7 @@ eMBException funcReadHoldingRegister (rt_uint8_t *reqFrame, rt_uint16_t reqLen, /* * 协议板版本号使用独立的只读地址0x0300,不占用现有通道保持寄存器空间。 - * 当前版本V1.1.9编码为0x0119,Modbus响应按高字节在前返回01 19。 + * 当前版本V1.1.10编码为0x011A,Modbus响应按高字节在前返回01 1A。 * 该特殊地址只支持一次读取一个寄存器,避免与普通连续寄存器混用。 */ if (regAddress == HOLD_REG_FIRMWARE_VERSION) { diff --git a/apps/chrg/applications/thread/chrg_comm.h b/apps/chrg/applications/thread/chrg_comm.h index 9f294a6..1f3687d 100644 --- a/apps/chrg/applications/thread/chrg_comm.h +++ b/apps/chrg/applications/thread/chrg_comm.h @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_comm.h 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。 版本历史 : 创建原始版本 说明 : diff --git a/apps/chrg/applications/thread/chrg_north.c b/apps/chrg/applications/thread/chrg_north.c index 578b19f..16108f8 100644 --- a/apps/chrg/applications/thread/chrg_north.c +++ b/apps/chrg/applications/thread/chrg_north.c @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_north.c 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。 版本历史 : 创建原始版本 说明 : diff --git a/apps/chrg/applications/thread/chrg_roll_nor.c b/apps/chrg/applications/thread/chrg_roll_nor.c index 7843710..7b8a87a 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.c +++ b/apps/chrg/applications/thread/chrg_roll_nor.c @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_roll_nor.c 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 版本历史 : 创建原始版本 说明 : diff --git a/apps/chrg/applications/thread/chrg_roll_nor.h b/apps/chrg/applications/thread/chrg_roll_nor.h index 7a3ff22..74d3a7f 100644 --- a/apps/chrg/applications/thread/chrg_roll_nor.h +++ b/apps/chrg/applications/thread/chrg_roll_nor.h @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_roll_nor.h 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 实现北向通信轮巡请求命令。以独立线程处理。 版本历史 : 创建原始版本 说明 : diff --git a/apps/chrg/applications/thread/chrg_roll_sou.c b/apps/chrg/applications/thread/chrg_roll_sou.c index 3612cd7..cc0a46d 100644 --- a/apps/chrg/applications/thread/chrg_roll_sou.c +++ b/apps/chrg/applications/thread/chrg_roll_sou.c @@ -26,6 +26,8 @@ #define SOU_MUTEX_TIMEOUT_MS 100 #define SOU_RESPONSE_TIMEOUT_MS 20 #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_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_burst_ch = TOTAL_SOU_CHS; +static rt_uint8_t g_sou_com_batch_burst_count = 0U; struct chrg_rollsou_t chrgrollsou = { .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(); + /* 短路保活的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一条 -> ..." 交替执行,而不是低编号通道独占总线。 */ 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++; - /* 当前寄存器已收到匹配写回码。下一次调度从下一个通道开始; - * 当前通道的下一条命令会在其它就绪通道各执行一条后继续发送。 */ - g_sou_com_batch_rr_next_ch = (rt_uint8_t)((ch + 1U) % TOTAL_SOU_CHS); /* 暂时关闭副继电器与主继电器之间的固定延时;需要恢复时重新启用本段。 */ if ((reg == REG_REL_ON) && (value == ALL_REL_OFF) && (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->reg_cnt = 0; 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); return 0; @@ -636,6 +673,12 @@ int chrg_sou_com_batch_cancel(eIDX_SOU_CH ch) pBatch->cur_idx = 0; pBatch->reg_cnt = 0; 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量测同样失效,后续状态会重新申请新量测。 */ 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); @@ -735,6 +778,23 @@ static void sou_com_command_failed(rt_uint8_t ch, rt_uint16_t reg, rt_uint16_t v (*retry_count)++; 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; } @@ -766,7 +826,7 @@ void chrg_roll_sou_thread_entry (void *data) rt_uint8_t run = 0; rt_uint8_t index = 0, idx = 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 single_ch = 0; rt_uint8_t single_part = 0; @@ -796,7 +856,7 @@ void chrg_roll_sou_thread_entry (void *data) version_probe = RT_FALSE; response_part = MB_R_PART1; if ((run != RUN_COM) && (run != RUN_UPDATA)) { - retry_count = 0; + rt_memset(retry_count, 0, sizeof(retry_count)); } // rt_kprintf("------ROLL SOU START \n--------"); 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); if (next_ret <= 0) { - retry_count = 0; rt_thread_mdelay(1); continue; } @@ -919,10 +978,10 @@ void chrg_roll_sou_thread_entry (void *data) if (response_valid) { if (run == RUN_COM) { if (sou_com_batch_complete(batch_ch, command_reg, command_value) == 0) { - retry_count = 0; + retry_count[batch_ch] = 0; } else { 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) { sou_single_command_finish(run); @@ -940,7 +999,7 @@ void chrg_roll_sou_thread_entry (void *data) } } else if (run == RUN_COM) { sou_com_command_failed(batch_ch, command_reg, command_value, - "invalid response", &retry_count); + "invalid response", &retry_count[batch_ch]); } else { LOG_E("crc failed"); } @@ -956,7 +1015,7 @@ void chrg_roll_sou_thread_entry (void *data) } if ((run == RUN_COM) && command_valid) { sou_com_command_failed(batch_ch, command_reg, command_value, - "timeout", &retry_count); + "timeout", &retry_count[batch_ch]); } else if (run != RUN_AUTO) { sou_single_command_finish(run); } diff --git a/apps/chrg/applications/utils/chrg_source.c b/apps/chrg/applications/utils/chrg_source.c index 01626a3..51276f4 100644 --- a/apps/chrg/applications/utils/chrg_source.c +++ b/apps/chrg/applications/utils/chrg_source.c @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_source.c 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 北向数据source请求数据填充及发送。 版本历史 : 创建原始版本 说明 : diff --git a/apps/chrg/applications/utils/chrg_source.h b/apps/chrg/applications/utils/chrg_source.h index 3ddb1a8..d45f908 100644 --- a/apps/chrg/applications/utils/chrg_source.h +++ b/apps/chrg/applications/utils/chrg_source.h @@ -1,7 +1,7 @@ /**************************************************************************** 文件名称 : chrg_source.c 完成日期 : -当前版本号 : V1.1.9 +当前版本号 : V1.1.10 主要功能 : 北向数据source请求数据填充及发送,命令字定义。 版本历史 : 创建原始版本 说明 :