当前版本存在偶然性失败——电压到了之后没电流

1.  apps/chrg/applications/thread/chrg_north.h: 更新版本号到V1.1.22
2.  apps/chrg/applications/utils/chrg_eload.c: 清理冗余注释和调试打印代码
3.  apps/chrg/applications/thread/chrg_comm.c: 更新版本号到V1.1.24,重构测试模式切换逻辑,新增优先级命令处理
4.  apps/chrg/applications/thread/chrg_roll_sou.c: 新增优先级命令调度逻辑,优先处理测试停止/切换命令
5.  apps/chrg/applications/utils/chrg_sink.c: 更新版本号到V1.1.24,重构初始化命令构建流程,新增初始化状态跟踪,增加调试打印开关
6.  docs/Allegro.jrl和docs/allegro.jrl,1: 更新Allegro设计日志文件
This commit is contained in:
wrh
2026-09-15 20:51:50 +08:00
parent 05309dfb41
commit 8327cb3500
7 changed files with 286 additions and 1102 deletions
+27 -8
View File
@@ -1,7 +1,7 @@
/****************************************************************************
文件名称 : chrg_comm.c
完成日期 :
当前版本号 : V1.1.23
当前版本号 : V1.1.24
主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。
版本历史 : 创建原始版本
说明 :
@@ -2571,6 +2571,7 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
rt_uint16_t old_loadc = pReal->sink.loadc;
rt_uint8_t old_on_work = pReal->sink.On_work;
rt_uint8_t old_work_mode = pReal->sink.work_mode;
rt_bool_t old_test_or_load_active;
rt_uint16_t sink_work = pShadow->sink.Now_State;
chrg_param_diff_t diff_info;
@@ -2610,9 +2611,31 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
if (sink_work == 0x01) {
curr_test = pReal->sink.test.test_mode;
curr_test_old = pReal->sink.test.test_mode_old;
if (((curr_test_old == 0) && (curr_test != 0)) ||
((curr_test == 0) && (curr_test_old != 0))) {
if (curr_test_old == 0) {
old_test_or_load_active = (old_on_work == 1U) &&
((old_work_mode == SINK_WORK_RUNING) ||
(old_work_mode == SINK_WORK_LOAD_STANDBY) ||
(old_work_mode == SINK_WORK_ON_TEST_SHORT) ||
(old_work_mode == SINK_WORK_ON_TEST_DYNA) ||
(old_work_mode == SINK_WORK_ON_TEST_OCP));
if (curr_test != curr_test_old) {
/* 测试模式切换优先清理旧批次,防止旧WORK_START插入新测试。 */
if (chrg_sou_com_batch_cancel((eIDX_SOU_CH)ch) != 0) {
return MB_EX_SLAVE_BUSY;
}
if (curr_test == 0) {
/* Protocol-before-CC test flow is disabled in this version. */
pReal->sub = IDX_SET_SINK_CC_BEFORE_PD;
pReal->sink.work_mode = SINK_WORK_INIT;
} else {
/* 普通负载或旧测试运行时,先停止电子负载再启动新测试。 */
if (old_test_or_load_active) {
rt_uint16_t stop_reg = REG_WORK;
rt_uint16_t stop_val = WORK_STOP;
if (chrg_sou_com_batch_submit((eIDX_SOU_CH)ch,
&stop_reg, &stop_val, 1U) != 0) {
return MB_EX_SLAVE_BUSY;
}
}
if (curr_test == SINK_TEST_DYNA) {
pReal->sink.work_mode = SINK_WORK_ON_TEST_DYNA;
} else if (curr_test == SINK_TEST_OCP) {
@@ -2621,10 +2644,6 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
pReal->sink.work_mode = SINK_WORK_ON_TEST_SHORT;
}
pReal->sink.test.test_mode_old = curr_test;
} else {
/* Protocol-before-CC test flow is disabled in this version. */
pReal->sub = IDX_SET_SINK_CC_BEFORE_PD;
pReal->sink.work_mode = SINK_WORK_INIT;
}
} else if (pReal->sink.On_work == 0) {
pReal->sink.On_work = 1;
+1 -1
View File
@@ -1,7 +1,7 @@
/****************************************************************************
文件名称 : chrg_north.h
完成日期 :
当前版本号 : V1.1.21
当前版本号 : V1.1.22
主要功能 : 实现北向通信交互,包括接收命令解析,发送请求命令,切换通路。以独立线程处理。
版本历史 : 创建原始版本
说明 :
+53 -1
View File
@@ -1,7 +1,7 @@
/****************************************************************************
文件名称 : chrg_roll_sou.c
完成日期 :
当前版本号 : V1.1.22
当前版本号 : V1.1.23
主要功能 : 实现南向通信轮巡请求命令。以独立线程处理。
版本历史 : 创建原始版本
说明 :
@@ -49,6 +49,37 @@ 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;
static rt_bool_t sou_com_batch_is_priority(rt_uint8_t ch,
sou_com_batch_ch_t *pBatch)
{
rt_uint16_t reg;
rt_uint16_t value;
if ((ch >= TOTAL_SOU_CHS) || (pBatch == RT_NULL) ||
(pBatch->cur_idx >= pBatch->reg_cnt)) {
return RT_FALSE;
}
reg = pBatch->reg_list[pBatch->cur_idx];
value = pBatch->val_list[pBatch->cur_idx];
if ((reg == REG_WORK) && (value == WORK_STOP)) {
return RT_TRUE;
}
if ((reg == ModbusRTU_ShortTest_CMD_MODE_FLAG) &&
(value == ModbusRTU_DYNA_CMD_MODE_STOP)) {
return RT_TRUE;
}
if ((reg == REG_REL_ON) && (value == ALL_REL_OFF)) {
return RT_TRUE;
}
if ((reg == REG_WORK) && (value == WORK_START) &&
(chrgnorth.sw[ch].sink.work_mode == SINK_WORK_ON_TEST_SHORT ||
chrgnorth.sw[ch].sink.work_mode == SINK_WORK_ON_TEST_DYNA ||
chrgnorth.sw[ch].sink.work_mode == SINK_WORK_ON_TEST_OCP)) {
return RT_TRUE;
}
return RT_FALSE;
}
struct chrg_rollsou_t chrgrollsou = {
.run = RUN_AUTO,
.ch = IDX_SOU_CH1,
@@ -538,6 +569,25 @@ static int sou_com_batch_next(rt_uint8_t *ch, rt_uint16_t *reg, rt_uint16_t *val
}
now = rt_tick_get();
/* 测试切换和停止命令先执行,避免被其它通道的长测试批次拖延。 */
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) ||
!sou_com_batch_is_priority(idx, pBatch) ||
((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;
}
/* 短路保活的WORK_START达到周期后优先下发,避免长批次挤占30ms保活窗口。 */
for (offset = 0; offset < TOTAL_SOU_CHS; offset++) {
idx = (rt_uint8_t)((g_sou_com_batch_rr_next_ch + offset) %
@@ -927,7 +977,9 @@ void chrg_roll_sou_thread_entry (void *data)
batch_ch = command_ch;
command_valid = RT_TRUE;
chrg_south_switch((eIDX_SOU_CH)command_ch);
#if SOUTH_COMMAND_DEBUG
rt_kprintf("ch=%d",command_ch);
#endif
chrg_eload_write_reg(ID_ELOAD, command_reg, command_value);
}
break;
+4 -14
View File
@@ -407,7 +407,6 @@ int chrg_eload_parse_version (rt_uint8_t idx, rt_uint8_t *data, rt_uint16_t len)
{
rt_uint16_t version;
/* A one-register Modbus 0x03 response is 7 bytes including CRC16. */
if ((idx >= TOTAL_SOU_CHS) || (data == RT_NULL) ||
(len != (MODBUSRTU_SW_VERSION_LEN * 2U + 5U)) ||
(data[0] != ID_ELOAD) || (data[1] != MB_REGISTER_RD) ||
@@ -416,7 +415,7 @@ int chrg_eload_parse_version (rt_uint8_t idx, rt_uint8_t *data, rt_uint16_t len)
}
version = u8v_to_u16(&data[3]);
/* HOLD_REG_CH0_VERSION is the per-channel south board version register. */
usRegHoldBuf[HOLD_REG_CH0_VERSION + idx * TOTAL_HOLD_CH_REGS] = version;
return 0;
}
@@ -443,9 +442,7 @@ int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16
return -1;
}
struct eload_p1_t *pP1 = (struct eload_p1_t *)&data[3];
// for(int i = 0;i<36;i++){
// rt_kprintf("%02x ",data[i+3]);
// }
pLOAD->status1 = pP1->status1;
pLOAD->status2 = pP1->status2;
pLOAD->fault1 = pP1->fault1;
@@ -465,6 +462,8 @@ int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16
pLOAD->vpp = swap_u16(pP1->Vpp);
pLOAD->Ripple = chrg_eload_ripple_filter_update(idx,
swap_u16(pP1->Ripple));
// if(idx == IDX_CH3)
// rt_kprintf("-----Ripple = %d-------\n",pLOAD->Ripple);
/* 保留功率板返回的真实电流,供卸载保护判断使用。 */
pSW->Now_current = pLOAD->current;
/*
@@ -486,14 +485,6 @@ int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16
/* 电压、电流均更新完成后再发布序号,避免状态机读取到半更新数据。 */
g_eload_sample_seq[idx]++;
#if LCD_OPEN
// for(int i = 0;i<4;i++){
// if(pNOR->sw[i].change_flag == 0x01){
// pNOR->free_flag = 0x00;
// }else {
// pNOR->free_flag = 0x01;
// }
// }
// rt_kprintf("ch=%d,free_flag=%d,",idx,pNOR->free_flag);
if(pNOR->free_flag==0x01){
LCD_SHOW(idx, pP1, pLOAD, pSW, pSOU->online[idx]);
}
@@ -525,7 +516,6 @@ int chrg_eload_parse (rt_uint8_t idx, rt_uint8_t pt, rt_uint8_t *data, rt_uint16
chrg_eload_dpdm_host_value(pSW->VZ);
usRegHoldBuf[HOLD_REG_CH0_VF+idx*TOTAL_HOLD_CH_REGS] =
chrg_eload_dpdm_host_value(pSW->VF);
// rt_kprintf("---------NOW VOLT END = %d\n----------",pSW->Now_voltage);
return 0;
}
+56 -29
View File
@@ -1,7 +1,7 @@
/****************************************************************************
文件名称 : chrg_sink.c
完成日期 :
当前版本号 : V1.1.21
当前版本号 : V1.1.24
主要功能 : 北向数据sink请求数据填充及发送。
版本历史 : 创建原始版本
说明 :
@@ -33,6 +33,7 @@
static rt_uint8_t g_sink_init_stage[TOTAL_SOU_CHS] = {0};
static rt_tick_t g_sink_init_north_relay_tick[TOTAL_SOU_CHS] = {0};
static rt_bool_t g_sink_init_in_progress[TOTAL_SOU_CHS] = {RT_FALSE};
/* 主继电器闭合跟踪:1=已提交ALL_REL_ON(主继电器应已闭合) 0=未闭合/已断开。
* 用于0V硬保护区分"首次开载/握手恢复"(主继电器未闭合,Now_voltage=0属正常)
@@ -255,22 +256,22 @@ static rt_uint8_t chrg_sink_init_build_commands(struct chrg_switch_t *pSW,
{
rt_uint8_t count;
regs[0] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[0] = ModbusRTU_DYNA_CMD_MODE_STOP;
if (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) {
regs[0] = REG_REL_ON; vals[0] = ALL_REL_OFF;
regs[1] = REG_REL_ON; vals[1] = FU_REL_ON;
regs[2] = REG_CURRENT_OUT + 1; vals[2] = 0;
regs[3] = REG_MODE; vals[3] = pSW->CV_mode;
regs[4] = Eload_Start_V_ON; vals[4] = (pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
regs[5] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[5] = ModbusRTU_DYNA_CMD_MODE_STOP;
regs[1] = REG_REL_ON; vals[1] = ALL_REL_OFF;
regs[2] = REG_REL_ON; vals[2] = FU_REL_ON;
regs[3] = REG_CURRENT_OUT + 1; vals[3] = 0;
regs[4] = REG_MODE; vals[4] = pSW->CV_mode;
regs[5] = Eload_Start_V_ON; vals[5] = (pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
count = 6U;
} else {
regs[0] = REG_REL_ON; vals[0] = FU_REL_ON;
regs[1] = REG_CURRENT_OUT + 1; vals[1] = 0;
regs[2] = REG_MODE; vals[2] = pSW->CV_mode;
regs[3] = Eload_Start_V_ON; vals[3] =
regs[1] = REG_REL_ON; vals[1] = FU_REL_ON;
regs[2] = REG_CURRENT_OUT + 1; vals[2] = 0;
regs[3] = REG_MODE; vals[3] = pSW->CV_mode;
regs[4] = Eload_Start_V_ON; vals[4] =
(pSW->sink.volt_on <= 500) ? 500 : pSW->sink.volt_on;
count = 4U;
count = 5U;
if (pSW->sink.test.test_mode_old == SINK_TEST_OCP) {
regs[count] = ModbusRTU_OCPTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
@@ -290,14 +291,11 @@ static int chrg_sink_init_submit_stage(eIDX_SOU_CH idx,
rt_uint8_t total;
rt_uint8_t start;
rt_uint8_t count;
rt_bool_t short_exit;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
total = chrg_sink_init_build_commands(pSW, regs, vals);
short_exit = (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) ?
RT_TRUE : RT_FALSE;
switch (g_sink_init_stage[idx]) {
case SINK_INIT_STAGE_CLEAR_RELAY:
@@ -305,12 +303,12 @@ static int chrg_sink_init_submit_stage(eIDX_SOU_CH idx,
count = 1U;
break;
case SINK_INIT_STAGE_AUX_RELAY:
start = short_exit ? 1U : 0U;
start = 1U;
count = 1U;
break;
case SINK_INIT_STAGE_REST:
start = short_exit ? 2U : 1U;
count = (rt_uint8_t)(total - start);
start = 2U;
count = (rt_uint8_t)(total - 2U);
break;
default:
return -1;
@@ -320,23 +318,23 @@ static int chrg_sink_init_submit_stage(eIDX_SOU_CH idx,
/*****************************************************************
函数名称: chrg_sink_work_init
函数描述: 执行负载INIT入口,先提交辅助继电器命令
函数描述: 执行负载INIT入口,首帧先退出短路测试
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 进入INIT_AUX_WAIT后台等待辅助继电器回码
输出参数: 进入INIT_AUX_WAIT后台等待南向回码
返回说明: 0:初始化命令提交成功 <0:参数或命令提交失败
其它说明: 收到01 02有效回码后等待30ms,再打开北向Sink继电器
*****************************************************************/
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_bool_t short_exit;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
short_exit = (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) ?
RT_TRUE : RT_FALSE;
g_sink_init_stage[idx] = short_exit ? SINK_INIT_STAGE_CLEAR_RELAY :
SINK_INIT_STAGE_AUX_RELAY;
/* 初始化必须优先于本通道尚未发送的旧命令,避免旧WORK_START插入初始化流程。 */
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
g_sink_init_in_progress[idx] = RT_TRUE;
g_sink_init_stage[idx] = SINK_INIT_STAGE_CLEAR_RELAY;
g_sink_init_north_relay_tick[idx] = 0U;
if (chrg_sink_init_submit_stage(idx, pSW) != 0) {
return -1;
@@ -374,7 +372,9 @@ static int chrg_sink_work_init_aux_wait(eIDX_SOU_CH idx,
return 0;
}
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK);
#if SOUTH_COMMAND_DEBUG
rt_kprintf("-------D+D- OPEN------\n");
#endif
pNOR->enable[idx] = 1;
pSW->sub = IDX_SET_SINK_CC_BEFORE_PD;
g_sink_init_stage[idx] = SINK_INIT_STAGE_REST;
@@ -399,6 +399,7 @@ static int chrg_sink_work_init_aux_wait(eIDX_SOU_CH idx,
}
/* 北向可能已推进到CC或电压查询,此处只更新南向完成状态。 */
g_sink_init_in_progress[idx] = RT_FALSE;
pSOU->online[idx] = 1;
pSW->sink.test.test_mode_old = 0;
pSW->sink.work_mode = SINK_WORK_WAIT;
@@ -492,6 +493,9 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW
}
/* RUNING批次必须完整发送:ALL_REL_ON、目标负载值、WORK_START。 */
ret = chrg_sou_com_batch_submit(idx, regs, vals, 3U);
#if SOUTH_COMMAND_DEBUG
rt_kprintf("------ALL_REL_ON-------\n");
#endif
if (ret == 0) {
g_sink_rel_main_closed[idx] = 1;
}
@@ -517,6 +521,7 @@ static int chrg_sink_work_load_stop(eIDX_SOU_CH idx,
return -1;
}
/* 自动停止优先于同通道残留启动批次,禁止STOP后继续发送WORK_START。 */
g_sink_init_in_progress[idx] = RT_FALSE;
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
@@ -568,6 +573,7 @@ static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return -1;
}
/* 低压保护优先级最高,先丢弃该通道残留的启动或设定命令。 */
g_sink_init_in_progress[idx] = RT_FALSE;
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
@@ -629,6 +635,7 @@ static int chrg_sink_work_stop_prepare(eIDX_SOU_CH idx,
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
g_sink_init_in_progress[idx] = RT_FALSE;
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
@@ -918,8 +925,9 @@ static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
*****************************************************************/
static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[4] = {Eload_Start_V_ON, ModbusRTU_ShortTest_Hold_Time,
ModbusRTU_ShortTest_CMD_MODE_FLAG, REG_WORK};
rt_uint16_t regs[4] = {Eload_Start_V_ON,
ModbusRTU_ShortTest_Hold_Time, ModbusRTU_ShortTest_CMD_MODE_FLAG,
REG_WORK};
rt_uint16_t vals[4] = {SINK_SHORT_TEST_VON_MV, 0, 0, 0};
/* 外部工程固定短路测试保持60秒且不带载。 */
vals[1] = 60000;
@@ -995,6 +1003,18 @@ int chrg_sink_volt_judge(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
/* 初始化及短路退出批次完成前,禁止电压判定提前启动普通负载。 */
if (g_sink_init_in_progress[idx] ||
(pSW->sink.work_mode == SINK_WORK_INIT) ||
(pSW->sink.work_mode == SINK_WORK_INIT_AUX_WAIT)) {
if (g_sink_init_in_progress[idx] &&
(pSW->sink.work_mode != SINK_WORK_INIT) &&
(pSW->sink.work_mode != SINK_WORK_INIT_AUX_WAIT)) {
pSW->sink.work_mode = SINK_WORK_INIT_AUX_WAIT;
}
return chrg_sink_work(idx, pSW);
}
#if SINK_VON_VOLTAGE_SOURCE == SINK_VON_VOLTAGE_FROM_PROTOCOL
voltage_seq = pSW->Sink_voltage_seq;
#else
@@ -1171,6 +1191,13 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
}
work_mode = pSW->sink.work_mode;
workmode = work_mode;
/* 初始化事务独占该通道,防止其它路径改成RUNING后追加普通启动命令。 */
if (g_sink_init_in_progress[idx] &&
(work_mode != SINK_WORK_INIT) &&
(work_mode != SINK_WORK_INIT_AUX_WAIT)) {
pSW->sink.work_mode = SINK_WORK_INIT_AUX_WAIT;
work_mode = SINK_WORK_INIT_AUX_WAIT;
}
if (work_mode != SINK_WORK_ON_TEST_SHORT) {
g_sink_short_start_tick[idx] = 0;
}