refactor(chrg): 重构北向轮询与状态机代码,补充注释与函数文档

1.  apps/chrg/applications/thread/chrg_roll_nor.c: 新增chrg_roll_nor_cmd、chrg_roll_nor_set函数注释,补充线程判断逻辑注释
2.  apps/chrg/applications/thread/chrg_comm.c: 完善modbus写入寄存器的注释,补充角色切换逻辑说明
3.  apps/chrg/applications/utils/chrg_source.c: 为所有电源状态机函数补充详细中文注释与函数说明
4.  apps/chrg/applications/thread/chrg_north.c: 删除冗余全局变量与函数,补充帧处理、解析函数注释,修正初始化注释
5.  apps/chrg/applications/utils/chrg_sink.c: 删除大量废弃测试代码,为所有负载状态机函数补充详细中文注释与函数说明
This commit is contained in:
wrh
2026-07-22 10:14:48 +08:00
parent 684ad2e20e
commit 587e03b65f
5 changed files with 238 additions and 343 deletions
+16 -2
View File
@@ -1867,7 +1867,11 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
struct chrg_thread_t *pTHR_NOR = &chrgthr[IDX_THR_ROLL_NOR];
rt_mutex_take(pTHR_NOR->mutex, RT_WAITING_FOREVER);
/* 保存复制前的真实角色,复制后据此判断是否需要先停后切。 */
/*
* pReal保存当前正在运行的真实状态,pSW指向COM影子配置。
* 必须在rt_memcpy之前保存old_id,否则复制后会丢失旧角色,
* 无法判断本次生效是普通参数更新还是Source/Sink角色切换。
*/
eIDX_ID old_id = pReal->id;
g_shadow_dirty[ch] = 0;
@@ -1878,6 +1882,7 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
rt_uint16_t old_loadv = pReal->sink.loadv;
rt_uint16_t old_loadc = pReal->sink.loadc;
//rt_uint8_t old_sink_test = pReal->sink.test.test_mode;
/* COM参数统一生效;复制完成后的id就是本次请求的目标角色。 */
rt_memcpy(pReal, &g_shadow_sw[ch], sizeof(struct chrg_switch_t));
eIDX_ID new_id = pReal->id;
@@ -1885,7 +1890,11 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
{
int switch_ret;
/* 复制后按新角色选择状态机,保证id与work_mode归属一致。 */
/*
* SWITCH表示“切换进入new_id对应角色”,因此必须按new_id
* 选择状态机,保证ID_SOURCE只使用Source状态机,ID_SINK
* 只使用Sink状态机。SWITCH内部先停止旧角色,再转入INIT。
*/
if (new_id == ID_SOURCE) {
pReal->source.work_mode = SOURCE_WORK_SWITCH;
switch_ret = chrg_source_work_state(ch, pReal);
@@ -1894,12 +1903,17 @@ static eMBException chrg_mb_write_sys(rt_uint8_t ch, rt_uint16_t reg_offset, rt_
switch_ret = chrg_sink_work((eIDX_SOU_CH)ch, pReal);
}
/* 入队失败时保留影子待生效标志,让COM返回忙并允许重试。 */
if (switch_ret != 0) {
g_shadow_dirty[ch] = 1;
rt_mutex_release(pTHR_NOR->mutex);
return MB_EX_SLAVE_BUSY;
}
/*
* 角色切换路径已经完成状态安排,必须直接返回,避免继续执行
* 下方同角色启动/停止逻辑并再次覆盖INIT状态。
*/
rt_mutex_release(pTHR_NOR->mutex);
return MB_EX_NONE;
}
+63 -16
View File
@@ -23,12 +23,6 @@
//#define LOG_TAG "chrg.nor"
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>
rt_uint16_t volt;
uint16_t chrg_compare(rt_int16_t a, rt_int16_t b)
{
if(a>b) return a - b;
else return b - a;
}
/*****************************************************************
函数名称: chrg_source_standard_output
@@ -53,7 +47,16 @@ void chrg_source_standard_output(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
}
}
//电源快充
/*****************************************************************
函数名称: chrg_source_parse
函数描述: 解析北向电源板电压电流回码并驱动Source状态机
输入参数: frame_data:完整北向回码 idx:当前通道 pSW:通道控制结构体
pNOR:北向总控结构体
输出参数: 更新协商电压、电流、source.work_mode及上次下发电压缓存
返回说明: -
其它说明: frame_data[4~7]为实测值,[8~11]为协议协商目标值;
目标电压变化时进入RUNING,相同时进入WAIT
*****************************************************************/
void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
@@ -61,7 +64,6 @@ void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
rt_uint16_t Curr_mA = (frame_data[10] << 8) | frame_data[11];
rt_uint16_t volt_mv_Now = (frame_data[4] << 8) | frame_data[5];
rt_uint16_t Curr_mA_Now = (frame_data[6] << 8) | frame_data[7];
rt_uint16_t volt_compare = chrg_compare(volt_mv, volt_mv_Now);
static rt_uint16_t last_volt_mv[TOTAL_SOU_CHS] = {0};
static rt_uint8_t number = 0;
int ret;
@@ -84,7 +86,15 @@ void chrg_source_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
}
}
//电源设置
/*****************************************************************
函数名称: chrg_source_setting
函数描述: 根据电源协议类型和启停标志选择标准输出或快充解析流程
输入参数: frame_data:北向回码 idx:当前通道 pSW:通道控制结构体
pNOR:北向总控结构体
输出参数: 可能更新功率板设定值或北向子状态sub
返回说明: -
其它说明: 标准协议直接设置输出,快充协议使用协商结果驱动状态机
*****************************************************************/
void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
@@ -103,7 +113,16 @@ void chrg_source_setting(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
}
}
//解析负载返回数据
/*****************************************************************
函数名称: chrg_sink_parse
函数描述: 解析北向负载板回码并根据电压、电流反馈驱动Sink状态机
输入参数: frame_data:完整北向回码 idx:当前通道 pSW:通道控制结构体
pNOR:北向总控结构体
输出参数: 更新VZ、VF、低压计数、无电流计数及sink.work_mode
返回说明: -
其它说明: 电压连续低于门槛进入LOW;电压达到目标附近进入RUNING;
运行电流连续过低时退回WAIT重新判断
*****************************************************************/
void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
@@ -163,8 +182,12 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
/*****************************************************************
函数名称: chrg_north_handle_Seting_Volt
功能描述: 处理设置电压/电流命令,解析命令数据并执行相应操作
****************************************************/
函数描述: 根据当前通道角色分发21字节电压电流回码
输入参数: frame_data:完整北向回码 frame_len:回码长度
输出参数: 调用Source或Sink解析函数更新当前通道状态
返回说明: -
其它说明: 当前通道由chrgnorth.idx确定,角色由pSW->id确定
*****************************************************************/
rt_uint8_t change_number = 0;
static void chrg_north_handle_Seting_Volt(rt_uint8_t *frame_data, rt_uint16_t frame_len)
{
@@ -198,7 +221,7 @@ struct chrg_north_t chrgnorth = {
.source = { // 电源侧参数初始化
.On_Flag = 0, // 启动标志初始关闭
.Set_CV_Flag = 1, // 启停控制初始置1
.work_mode = SOURCE_WORK_WAIT,
.work_mode = SOURCE_WORK_WAIT, // 上电保持等待,禁止自动执行Source INIT
}, // 关键:补充逗号分隔source和sink
.sink = {
.protocol = 0xFE,
@@ -216,7 +239,7 @@ struct chrg_north_t chrgnorth = {
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.work_mode = SOURCE_WORK_WAIT,
.work_mode = SOURCE_WORK_WAIT, // 上电保持等待,禁止自动执行Source INIT
},
.sink = {
.protocol = 0xFE,
@@ -233,7 +256,7 @@ struct chrg_north_t chrgnorth = {
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.work_mode = SOURCE_WORK_WAIT,
.work_mode = SOURCE_WORK_WAIT, // 上电保持等待,禁止自动执行Source INIT
},
.sink = {
.protocol = 0xFE,
@@ -250,7 +273,7 @@ struct chrg_north_t chrgnorth = {
.source = {
.On_Flag = 0,
.Set_CV_Flag = 1,
.work_mode = SOURCE_WORK_WAIT,
.work_mode = SOURCE_WORK_WAIT, // 上电保持等待,禁止自动执行Source INIT
},
.sink = {
.protocol = 0xFE,
@@ -393,6 +416,14 @@ int a_number;
#define NORTH_FRAME_TIMEOUT_MS 100
/*****************************************************************
函数名称: chrg_north_frame_reset
函数描述: 复位北向帧接收状态并按需释放未完成帧内存
输入参数: pFrame:帧接收上下文 release:是否释放pMB及payload
输出参数: 清零接收长度、帧头标志、超时计时和消息指针
返回说明: -
其它说明: 完整帧已移交邮箱时release应为RT_FALSE,异常中止时为RT_TRUE
*****************************************************************/
static void chrg_north_frame_reset(struct pickup_info_t *pFrame, rt_bool_t release)
{
if (RT_NULL == pFrame) {
@@ -413,6 +444,14 @@ static void chrg_north_frame_reset(struct pickup_info_t *pFrame, rt_bool_t relea
pFrame->pMB = RT_NULL;
}
/*****************************************************************
函数名称: chrg_north_frame_append
函数描述: 从北向环形缓冲区追加数据到当前未完成帧
输入参数: rb:北向接收环形缓冲区 pFrame:帧接收上下文
输出参数: 更新已接收长度和最后接收时间
返回说明: 1:完整帧接收完成 0:仍需等待数据 <0:参数或状态异常
其它说明: 单次仅复制当前帧剩余长度,避免读取下一帧数据
*****************************************************************/
static int chrg_north_frame_append(struct rt_ringbuffer *rb,
struct pickup_info_t *pFrame)
{
@@ -444,6 +483,14 @@ static int chrg_north_frame_append(struct rt_ringbuffer *rb,
return (pFrame->length == (rt_size_t)pFrame->len_msg) ? 1 : 0;
}
/*****************************************************************
函数名称: chrg_north_frame_dispatch
函数描述: 分发已经组装完成的北向数据帧
输入参数: pFrame:包含完整pMB消息的帧接收上下文
输出参数: 21字节回码进入电压解析,同时完整消息发送到北向轮询邮箱
返回说明: -
其它说明: 消息所有权移交邮箱后只复位上下文,不在此处释放pMB
*****************************************************************/
static void chrg_north_frame_dispatch(struct pickup_info_t *pFrame)
{
struct mb_msg_t *pMB = pFrame->pMB;
+23 -1
View File
@@ -272,6 +272,14 @@ static int chrg_roll_nor_parse (struct chrg_rollnor_t *pROLL, rt_uint8_t *data)
return 0;
}
/*****************************************************************
函数名称: chrg_roll_nor_cmd
函数描述: 执行北向手动插入命令的入口检查
输入参数: pROLL:北向轮询控制结构体
输出参数: -
返回说明: 0:参数有效 <0:参数为空
其它说明: 当前仅保留入口,具体手动命令由后续功能扩展
*****************************************************************/
static int chrg_roll_nor_cmd (struct chrg_rollnor_t *pROLL)
{
if (RT_NULL == pROLL) {
@@ -279,6 +287,15 @@ static int chrg_roll_nor_cmd (struct chrg_rollnor_t *pROLL)
}
return 0;
}
/*****************************************************************
函数名称: chrg_roll_nor_set
函数描述: 按当前角色和sub状态发送一条北向协议命令
输入参数: ch:北向通道编号 pSW:通道控制结构体 enable:通道使能指针
输出参数: 某些发送步骤成功发起后推进pSW->sub
返回说明: -
其它说明: Source依次执行CC选择、协议设置、VC查询;
Sink依次执行CC线选择、协议设置、VC查询
*****************************************************************/
void chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW,rt_uint8_t *enable)
{
if(pSW->id==ID_SOURCE){ //电源
@@ -358,7 +375,12 @@ void chrg_roll_nor_thread_entry (void *data)
idx = index%TOTAL_NOR_CHS;
pSW = &pNOR->sw[idx];
rt_mutex_take(pTHR->mutex, RT_WAITING_FOREVER);
/* INIT/STOP必须在enable过滤前执行,否则停机通道无法重新启动。 */
/*
* INIT/STOP必须在enable过滤前执行:STOP会把enable清零,而COM
* 启动时只改变work_mode。若先判断enable,停机通道会直接continue
* INIT永远没有机会把enable重新置1,也就无法恢复北向轮询。
* Source->Sink切换后的SINK_WORK_INIT同样从这里首次执行。
*/
if ((pSW->id == ID_SOURCE) &&
((pSW->source.work_mode == SOURCE_WORK_INIT) ||
(pSW->source.work_mode == SOURCE_WORK_STOP))) {
+68 -323
View File
@@ -128,322 +128,14 @@ int sink_set_pd (rt_uint8_t pd, rt_uint8_t *buf)
return chrg_north_send(frame, len);
}
//// 短路测试参数解析 指令码:0x01
//void sink_test_short_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_short *pTest = &pSW->sink.test.short_test;
// // 解析报文:高字节pData[1]、低字节pData[2] → 测试保持时间
// pTest->hold_time = (pData[1] << 8) | pData[2];
// pTest->set_mode = pData[3]; // 模式选择:0=测试后一直保持;1=保持指定时长后恢复原有电流
// rt_kprintf("[SINK] Short Test: time=%d, mode=%d\n",
// pTest->hold_time, pTest->set_mode);
//}
////=============================================================================
//// OCP过流保护测试参数解析 指令码:0x02
////=============================================================================
//void sink_test_ocp_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_OCP *pTest = &pSW->sink.test.OCP_test;
// pTest->start_curr = (pData[1] << 8) | pData[2]; // 解析:OCP测试起始电流
// pTest->end_curr = (pData[3] << 8) | pData[4]; // 解析:OCP测试终止电流
// pTest->change_curr = (pData[5] << 8) | pData[6]; // 解析:电流步进值
// pTest->change_keep_time = (pData[7] << 8) | pData[8]; // 解析:单步电流保持时间
// pTest->hold_time = (pData[9] << 8) | pData[10]; // 解析:OCP触发后保持时间
// pTest->stop_volt = (pData[11]<< 8) | pData[12]; // 解析:停止判定电压
// pTest->set_mode = pData[13]; // 测试结束模式:0=保持设定时间后恢复;1=一直保持
// pTest->hold_curr = pData[14]; // OCP触发后是否带载,0=带载,1=不带载
// // pTest->change_mode = pData[11]; // 电流变化模式(预留):0=置0;1=达标立即置0;2=保持当前电流
// // pTest->interval_time = pData[12]; // 指令保护间隔时间(预留)
// pSW->sink.loadc = pTest->start_curr; // 负载电流初始化为OCP起始电流
//#if SINK_TEST_DEBUG
// rt_kprintf("[SINK] OCP Test: start=%d, end=%d\n",
// pTest->start_curr, pTest->end_curr);
//#endif
//}
////=============================================================================
//// 动态负载测试参数解析 指令码:0x03
////=============================================================================
//void sink_test_dynamic_set(struct chrg_switch_t *pSW, rt_uint8_t *pData, rt_uint8_t run_flag)
//{
// struct test_change *pTest = &pSW->sink.test.change_test;
//// rt_uint16_t change_curr = 0;
// pTest->curr1_set = (pData[1] << 8) | pData[2]; // 解析:第一阶段设定电流
// pTest->time1_set = (pData[3] << 8) | pData[4]; // 解析:第一阶段保持时长
// pTest->curr2_set = (pData[5] << 8) | pData[6]; // 解析:第二阶段设定电流
// pTest->time2_set = (pData[7]<< 8) | pData[8]; // 解析:第二阶段保持时长
// pTest->k_Rise = (pData[9] << 8) | pData[10]; // 电流上升斜率
// pTest->k_Fall = (pData[11]<< 8) | pData[12]; // 电流下降斜率
// // pTest->start_time = (pData[14]<< 8) | pData[13]; // 产品稳定时长(预留)
// // pSW->sink.loadc = pTest->curr1_set;
//#if SINK_TEST_DEBUG
// rt_kprintf("[SINK] Dynamic Test: curr1=%d, curr2=%d\n",
// pTest->curr1_set, pTest->curr2_set);
//#endif
//}
////=============================================================================
//// 短路测试状态机执行函数
//// 依据 work_step 分步配置寄存器,启动短路测试
////=============================================================================
//void chrg_nor_sink_short_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
//
// switch (pTest->work_step)
// {
// case 0:
// // 第一步:切换为电子负载模式,吸合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
//// rt_kprintf("first\r\n");
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = 1;
// break;
// case 1:
// // 根据模式分支配置参数
// if(pTest->short_test.set_mode == 0x00) { //直接释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
// pTest->work_step = 2;
// }
// else{ //按设定的时间后释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
// pTest->work_step = 4;
// }
//
// rt_kprintf("set_mode = %d",pTest->short_test.set_mode);
// break;
// case 2:
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_ShortTest_Hold_Time , pTest->short_test.hold_time);
// pTest->work_step = 4;
// break;
// case 4:
// // 启动整机工作,清零状态标志
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pTest->work_step = 5;
// pSW->change_flag = 0;
// break;
// case 5:
// break;
// default:
// pTest->work_step = 0;
// break;
// }
//}
////=============================================================================
//// OCP过流保护测试状态机执行函数
//// 分步配置电流、时长、模式寄存器,最终启动OCP测试
////=============================================================================
//// OCP测试执行
//void chrg_nor_sink_OCP_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->work_step)
// {
// case 0: // 初始化:切负载模式、闭合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
//// rt_kprintf("first\r\n");
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = SET_OCP_STARTCURR;
// break;
// case SET_OCP_STARTCURR: // 设置OCP起始电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StartCurrent, pTest->OCP_test.start_curr);
// pTest->work_step = SET_OCP_ENDCURR;
// break;
// case SET_OCP_ENDCURR: // 设置OCP终止电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_StopCurrent , pTest->OCP_test.end_curr);
// pTest->work_step = SET_OCP_STEP;
// break;
// case SET_OCP_STEP: // 设置电流步进值
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_CURR , pTest->OCP_test.change_curr);
// pTest->work_step = SET_OCP_STEP_HOLD_TIME;
// break;
// case SET_OCP_STEP_HOLD_TIME: // 设置单步保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Step_Hold_Time , pTest->OCP_test.change_keep_time);
// pTest->work_step = SINK_OCP_STOP_VOLT;
// break;
// case SINK_OCP_STOP_VOLT: //设置截止电压
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Vtrig_Stop , pTest->OCP_test.stop_volt);
// pTest->work_step = SET_OCP_CMD_MODE_RUN;
// break;
// case SET_OCP_CMD_MODE_RUN: // 标记测试运行模式
// if(pTest->OCP_test.set_mode == 0x00) { //释放
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_NO_CURR); //直接为0
// pTest->work_step = SET_OCP_HOLD_TIME;
// }
// else{ //保持
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN_ALWAYS_KEPP); //保持
// pTest->work_step = SET_OCP_RUNNING;
// }
// break;
// case SET_OCP_HOLD_TIME: // 设置OCP触发后保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_OCPTest_Hold_Time , pTest->OCP_test.hold_time);
// pTest->work_step = SET_OCP_RUNNING;
// break;
// case SET_OCP_RUNNING: // 启动OCP测试
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pSW->change_flag = 0;
// pTest->work_step = 0x10;
// break;
// case 0x10:
// break;
// default:
// break;
// }
//}
////=============================================================================
//// 动态负载测试状态机执行函数
//// 依次配置两段电流、时长、升降斜率,启动动态负载测试
////=============================================================================
//void chrg_nor_sink_change_test(rt_uint8_t ch, struct chrg_switch_t *pSW)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->work_step)
// {
// case 0: // 初始步骤:切换电子负载模式、闭合负载开关
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_ELOAD, ELOAD_LOAD);
// chrg_nor_sw_rel((eIDX_NOR_CH)ch,ID_SINK);
// pTest->work_step = SET_DYNA_CURR1;
// break;
// case SET_DYNA_CURR1: // 设置第一路输出电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L1, pTest->change_test.curr1_set);
// pTest->work_step = SET_DYNA_TIME1;
// #if SINK_TEST_DEBUG
// rt_kprintf("Curr1: %d\n", pTest->change_test.curr1_set);
// #endif
// break;
// case SET_DYNA_TIME1: // 设置第一阶段保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T1 , pTest->change_test.time1_set);
// pTest->work_step = SET_DYNA_CURR2;
// #if SINK_TEST_DEBUG
// rt_kprintf("Time1: %d\n", pTest->change_test.time1_set);
// #endif
// break;
// case SET_DYNA_CURR2: // 设置第二路输出电流
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_L2 , pTest->change_test.curr2_set);
// pTest->work_step = SET_DYNA_TIME2;
// #if SINK_TEST_DEBUG
// rt_kprintf("Curr2: %d\n", pTest->change_test.curr2_set);
// #endif
// break;
// case SET_DYNA_TIME2: // 设置第二阶段保持时间
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_T2 , pTest->change_test.time2_set);
// pTest->work_step = SET_DYNA_RISE_SLEW_RATE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Time2: %d\n", pTest->change_test.time2_set);
// #endif
// break;
// case SET_DYNA_RISE_SLEW_RATE: // 设置电流上升斜率
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Rise_Slew_Rate , pTest->change_test.k_Rise);
// pTest->work_step = SET_DYNA_FALL_SLEW_RATE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Rise Slew Rate: %d\n", pTest->change_test.k_Rise);
// #endif
// break;
// case SET_DYNA_FALL_SLEW_RATE: // 设置电流下降斜率
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_Fall_Slew_Rate , pTest->change_test.k_Fall);
// pTest->work_step = SET_DYNA_CND_MODE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
// #endif
// break;
// case SET_DYNA_CND_MODE: // 标记动态测试为运行状态
// chrg_set_sou_reg((eIDX_SOU_CH)ch, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_RUN);
// pTest->work_step = SET_DYNA_RUNNING;
// pTest->work_step = SET_DYNA_CND_MODE;
// #if SINK_TEST_DEBUG
// rt_kprintf("Fall Slew Rate: %d\n", pTest->change_test.k_Fall);
// #endif
// break;
// case SET_DYNA_RUNNING: // 启动整机工作,锁定当前运行步骤、清空标志位
// chrg_set_sou_reg((eIDX_SOU_CH)ch, REG_WORK, WORK_START);
// pTest->work_step = SET_DYNA_RUNNING;
// pTest->work_step = 0x11;
// pSW->change_flag = 0;
// break;
// case 0x11:
// break;
// default:
// #if SINK_TEST_DEBUG
// rt_kprintf("Invalid work step: %d\n", pTest->work_step);
// #endif
// break;
// }
//}
////=============================================================================
//// 短路测试停止处理函数
//// 依据 stop_step 分步执行停止流程,清除测试标记并跳转状态
////=============================================================================
//void chrg_nor_sink_short_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭短路测试运行模式
// chrg_set_sou_reg(idx, ModbusRTU_ShortTest_CMD_MODE_FLAG, ModbusRTU_DYNA_CMD_MODE_STOP);
// // pTest->stop_step = TEST_STOP_RUN;
// // break;
// // case TEST_STOP_RUN: // 清除测试标志,切换至负载状态管理流程
// //chrg_set_sou_reg(idx, REG_WORK, WORK_STOP);
// //pTest->stop_step = TEST_STOP_REL;
// //chrg_nor_sw_rel((eIDX_NOR_CH)idx,0);
// //*enable = 0;
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空短路测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE; 跳转至负载工作状态处理
// break;
// default:
// break;
// }
//}
////=============================================================================
//// OCP过流保护测试停止处理函数
////=============================================================================
//void chrg_nor_sink_OCP_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭OCP测试运行模式
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_OCPTest_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空OCP测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
// break;
// default:
// break;
// }
//}
////=============================================================================
//// 动态负载测试停止处理函数
////=============================================================================
//void chrg_nor_sink_change_test_stop(rt_uint8_t idx, struct chrg_switch_t *pSW,rt_uint8_t *enable)
//{
// struct test *pTest = &pSW->sink.test;
// switch (pTest->stop_step)
// {
// case TEST_STOP_CMD_MODE: // 下发停止指令,关闭动态测试运行模式
// chrg_set_sou_reg((eIDX_SOU_CH)idx, ModbusRTU_DYNA_CMD_MODE_FLAG , ModbusRTU_DYNA_CMD_MODE_STOP);
// pSW->change_flag = 0;
// pSW->sink.test.test_mode = 0; // 清空动态测试标记
// pSW->sub = 21; // IDX_SET_SINK_WORK_STATE;
// break;
// default:
// break;
// }
//}
//sink开机初始化
/*****************************************************************
函数名称: chrg_sink_work_init
函数描述: 执行负载INIT状态,复位测试配置并初始化功率板
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 设置运行、使能、在线标志并更新work_mode
返回说明: 0:初始化成功 <0:命令提交失败
其它说明: 成功后打开负载北向继电器并进入SINK_WORK_WAIT
*****************************************************************/
static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
@@ -477,7 +169,14 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return 0;
}
//sink进入运行状态
/*****************************************************************
函数名称: chrg_sink_work_volt_runing
函数描述: 执行负载RUNING状态,闭合功率继电器并启动负载
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:命令提交成功 非0:命令提交失败
其它说明: CV模式下写负载电压,其他模式下写负载电流
*****************************************************************/
static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[4] = {0x01, 0x01, 0, REG_WORK};
@@ -493,7 +192,14 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW
return chrg_sou_com_batch_submit(idx, regs, vals, 4);
}
//sink进入低电压状态
/*****************************************************************
函数名称: chrg_sink_nor_work_low
函数描述: 执行负载低电压状态,断开功率继电器并停止负载
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:命令提交成功 非0:命令提交失败
其它说明: 由北向负载解析连续检测到低电压后触发
*****************************************************************/
static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[2] = {0x01, REG_WORK};
@@ -502,7 +208,14 @@ static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return chrg_sou_com_batch_submit(idx, regs, vals, 2);
}
//com端关机流程
/*****************************************************************
函数名称: chrg_sink_nor_work_off
函数描述: 执行负载主动关机流程
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 清除运行、使能和在线标志,关闭北向继电器
返回说明: 0:关机成功 <0:停止命令提交失败
其它说明: 先断开功率继电器并发送WORK_STOP,再关闭软件通道
*****************************************************************/
static int chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
@@ -523,7 +236,15 @@ static int chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return 0;
}
// 切换进入负载:停止旧电源后,从负载初始化状态开始运行
/*****************************************************************
函数名称: chrg_sink_work_switch
函数描述: 处理“电源切换到负载”的过渡状态
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 清除旧电源运行标志,设置负载北向入口和INIT状态
返回说明: 0:停止命令成功加入队列 非0:命令入队失败
其它说明: pSW->id已由COM更新为ID_SINK;先提交旧电源WORK_STOP
后续负载INIT使用同一通道队列,保证停止命令先执行
*****************************************************************/
static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t reg = REG_WORK;
@@ -535,13 +256,23 @@ static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return ret;
}
/* 停止成功入队后,清除旧Source运行标志。 */
pSW->source.On_Flag = 0;
/* 首次进入Sink时必须从CC线配置开始,不能沿用Source的sub状态。 */
pSW->sub = IDX_SET_SINK_CCLINE;
/* SWITCH只负责旧角色退出,后续启动统一交给Sink INIT状态。 */
pSW->sink.work_mode = SINK_WORK_INIT;
return 0;
}
//动态测试启动
/*****************************************************************
函数名称: chrg_sink_TEST_DYNA_ON
函数描述: 配置并启动动态负载测试
输入参数: ch:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:命令提交成功 非0:命令提交失败
其它说明: 一次提交两组负载、保持时间、斜率、测试命令和WORK_START
*****************************************************************/
static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
{
struct test *pTest = &pSW->sink.test;
@@ -561,7 +292,14 @@ static int chrg_sink_TEST_DYNA_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
return chrg_sou_com_batch_submit((eIDX_SOU_CH)ch, regs, vals, 8);
}
//短路测试启动
/*****************************************************************
函数名称: chrg_sink_TEST_SHORT_ON
函数描述: 配置并启动负载短路测试
输入参数: ch:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:命令提交成功 非0:命令提交失败
其它说明: 根据set_mode选择定时无载或持续保持模式
*****************************************************************/
static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[3] = {ModbusRTU_ShortTest_Hold_Time,ModbusRTU_ShortTest_CMD_MODE_FLAG, REG_WORK};
@@ -579,7 +317,14 @@ static int chrg_sink_TEST_SHORT_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
}
//负载工作
/*****************************************************************
函数名称: chrg_sink_work
函数描述: 负载工作状态机统一入口
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 根据sink.work_mode执行对应状态动作
返回说明: 0:状态处理成功 <0:参数、状态或命令提交失败
其它说明: 每通道记录上次成功状态,相同状态不重复下发寄存器
*****************************************************************/
int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
static uint8_t last_state[TOTAL_SOU_CHS] ={100,100,100,100};
+68 -1
View File
@@ -17,6 +17,14 @@
#include "chrg_roll_sou.h"
#include "chrg_rel.h"
/*****************************************************************
函数名称: chrg_source_init_submit
函数描述: 将电源模式初始化参数批量提交到南向功率板命令队列
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:提交成功 <0:参数错误或队列提交失败
其它说明: 命令顺序为源载模式、CV/CC模式、继电器、初始电压、保护电流、启动
*****************************************************************/
int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
{
/* Source启动参数一次入队,最后发送WORK_START使功率板开始输出。 */
@@ -43,6 +51,14 @@ int chrg_source_init_submit(rt_uint8_t idx, struct chrg_switch_t *pSW)
return chrg_sou_com_batch_submit(idx, regs, vals, 6);
}
/*****************************************************************
函数名称: chrg_source_work_init
函数描述: 执行电源INIT状态,初始化功率板并打开对应北向通道
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 更新电源运行标志、通道使能、在线状态及work_mode
返回说明: 0:初始化命令提交成功 非0:初始化失败
其它说明: 成功后状态切换为SOURCE_WORK_WAIT,等待北向返回协商电压
*****************************************************************/
static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
@@ -64,12 +80,28 @@ static int chrg_source_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return 0;
}
/*****************************************************************
函数名称: chrg_source_work_wait
函数描述: 执行电源WAIT状态
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:状态处理完成
其它说明: WAIT状态不下发命令,由北向解析函数判断目标电压是否变化
*****************************************************************/
static int chrg_source_work_wait(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
/* WAIT状态不产生南向命令,等待下一帧北向电压数据。 */
return 0;
}
/*****************************************************************
函数名称: chrg_source_work_running
函数描述: 执行电源RUNING状态,下发最新协商目标电压
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:命令提交成功 非0:命令提交失败
其它说明: 本状态只写电压寄存器,不重复发送WORK_START
*****************************************************************/
static int chrg_source_work_running(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
/* RUNING只下发协商后的目标电压,不重复发送启动命令。 */
@@ -79,6 +111,14 @@ static int chrg_source_work_running(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return chrg_sou_com_batch_submit(idx, &reg, &value, 1);
}
/*****************************************************************
函数名称: chrg_source_work_low
函数描述: 执行电源低电压异常状态,停止功率板输出
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: -
返回说明: 0:停止命令提交成功 非0:命令提交失败
其它说明: 本函数只发送WORK_STOP,不关闭通道使能和北向继电器
*****************************************************************/
static int chrg_source_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
/* 电压异常时先停止功率板输出,保留状态供上层判断。 */
@@ -88,6 +128,14 @@ static int chrg_source_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return chrg_sou_com_batch_submit(idx, &reg, &value, 1);
}
/*****************************************************************
函数名称: chrg_source_work_stop
函数描述: 执行电源主动关机流程
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 清除运行、使能和在线标志,关闭北向继电器
返回说明: 0:停止成功 非0:停止命令提交失败
其它说明: 成功后状态恢复为SOURCE_WORK_WAIT,等待下一次启动命令
*****************************************************************/
static int chrg_source_work_stop(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
@@ -112,7 +160,15 @@ static int chrg_source_work_stop(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return 0;
}
// 切换进入电源:关闭旧负载继电器并停止输出,然后进入电源初始化
/*****************************************************************
函数名称: chrg_source_work_switch
函数描述: 处理“负载切换到电源”的过渡状态
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 清除旧负载运行标志,设置电源北向入口和INIT状态
返回说明: 0:停止命令成功加入队列 非0:命令入队失败
其它说明: pSW->id已由COM更新为ID_SOURCE;先关闭旧负载继电器并提交
WORK_STOP,后续电源INIT使用同一通道队列,保证停止命令先执行
*****************************************************************/
static int chrg_source_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[2] = {REG_REL_ON, REG_WORK};
@@ -124,12 +180,23 @@ static int chrg_source_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return ret;
}
/* 停止成功入队后,清除旧Sink运行标志。 */
pSW->sink.On_work = 0;
/* 首次进入Source时必须从CC线配置开始,不能沿用Sink的sub状态。 */
pSW->sub = IDX_SET_SOURCE_CC_SET;
/* SWITCH只负责旧角色退出,后续启动统一交给Source INIT状态。 */
pSW->source.work_mode = SOURCE_WORK_INIT;
return 0;
}
/*****************************************************************
函数名称: chrg_source_work_state
函数描述: 电源工作状态机统一入口
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 根据source.work_mode执行对应状态动作
返回说明: 0:状态处理成功 <0:参数、状态或命令提交失败
其它说明: 支持INIT、WAIT、RUNING、LOW、STOP和SWITCH状态
*****************************************************************/
int chrg_source_work_state(rt_uint8_t idx, struct chrg_switch_t *pSW)
{
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {