程序流程与函数说明
1. 文档范围
本文按当前源码(2026-07-19)说明 apps/chrg/applications/ 的自研函数、运行流程和函数级调用关系,并补充 apps/boot/ 的启动主链。rt-thread/、libs/、CubeMX 生成代码、HAL 中断模板以及调试 shell 命令的内部库调用不展开。调用关系由源码静态分析得到;通过 INIT_*_EXPORT、线程入口、回调和函数指针发生的调用会单独标明。
2. 上电与初始化流程
main() 不是业务入口。GPIO、FAL、定时器、串口、继电器和看门狗由 RT-Thread 自动初始化段调用;chrg_thread_init() 再创建六个常驻线程。初始化失败目前不会阻止后续线程继续创建,排障时必须查看启动日志。
3. 运行期线程与数据流
| 线程入口 |
职责 |
主要输入 |
主要输出 |
chrg_north_thread_entry |
接收协议板/Sink/Source 北向帧 |
北向 UART ringbuffer |
更新 chrgnorth.sw[],投递帧 |
chrg_south_thread_entry |
接收功率板 Modbus 响应 |
南向 UART ringbuffer |
投递响应到轮询/通信模块 |
chrg_comm_thread_entry |
上位机 Modbus、寄存器映射和业务命令 |
mailbox、Modbus 回调 |
修改目标状态,生成南北向命令 |
chrg_lcd_thread_entry |
HMI 报文解析和状态显示 |
LCD 串口 |
修改配置、刷新页面 |
chrg_roll_nor_thread_entry |
分时驱动四路 Sink/Source 协议板 |
event、通道状态 |
查询/设置协议板,运行 Sink 状态机 |
chrg_roll_sou_thread_entry |
串行执行功率板寄存器读写 |
event、批命令队列 |
Modbus RTU 请求与完成状态 |
4. Sink 工作状态机
函数级主链:chrg_roll_nor_thread_entry() → chrg_roll_nor_set() → sink_get_vc() → 北向响应 → chrg_north_frame_dispatch() → chrg_sink_parse() → chrg_sink_work() → chrg_sink_work_init() / chrg_sink_work_volt_runing() / chrg_sink_nor_work_low() / chrg_sink_nor_work_off()。继电器动作由 chrg_sink_change_ON()、chrg_sink_SHOUT_ON()、chrg_nor_sw_rel() 完成,功率板命令最终经 chrg_set_sou_reg() 交给南向轮询线程。
5. 函数说明:入口与线程基础设施
main.c
| 函数 |
说明 |
show_app_version() |
打印 RT-Thread 版本和固件编译时间,无输入和返回值。 |
main() |
设置 shell 提示符后进入 1 秒延时循环;业务线程由自动初始化段提前创建。 |
thread/chrg_thread.c
| 函数 |
说明 |
chrg_thread_evt_send() |
向指定线程发送事件位;线程或事件对象无效时返回错误。 |
chrg_thread_mb_free() |
释放邮箱消息及其 payload,仅供本文件失败路径使用。 |
chrg_thread_mb_send() |
向指定线程邮箱转移消息所有权;发送失败时自动释放消息。 |
chrg_thread_mq_send() |
向指定线程消息队列复制定长消息。 |
chrg_thread_create() |
按 chrgthr[] 配置创建 IPC 对象、线程并启动线程。 |
chrg_thread_init() |
遍历六个线程配置并创建;由 INIT_APP_EXPORT 隐式调用。 |
6. 函数说明:通信线程
thread/chrg_north.c
| 函数 |
说明 |
chrg_compare() |
计算两个有符号量的绝对差值。 |
chrg_source_stop() |
按步骤停止 Source 输出并处理继电器/状态复位。 |
chrg_source_standard_output() |
执行 Source 标准输出控制流程。 |
chrg_source_fast_output() |
执行 Source 快充协议输出流程。 |
chrg_source_setting() |
根据 Source 当前配置选择和推进设置过程。 |
chrg_sink_parse() |
解析 Sink 电压、电流及状态,做低压/无流判定并调用 chrg_sink_work()。 |
chrg_north_handle_Seting_Volt() |
解析北向设置电压类响应并更新通道状态。 |
chrg_north_switch() |
选择当前北向物理通道。 |
chrg_north_send() |
通过北向 TTY 发送一帧数据。 |
chrg_north_frame_head() |
从 ringbuffer 搜索合法帧头。 |
chrg_north_frame_reset() |
重置组帧上下文,并按参数决定是否释放缓存。 |
chrg_north_frame_append() |
将接收字节追加到当前帧缓存。 |
chrg_north_frame_dispatch() |
校验完整帧并分派到 Source/Sink 业务解析。 |
chrg_north_pickup_frame() |
驱动“找帧头—收帧体—分派”状态机。 |
chrg_north_thread_entry() |
北向接收线程主循环,从 UART ringbuffer 持续提取帧。 |
north_ch() / north_diag() |
FinSH 调试命令:切换通道、查看诊断计数。 |
thread/chrg_south.c
| 函数 |
说明 |
chrg_south_switch_lv1() / chrg_south_switch_lv2_1() / chrg_south_switch_lv2_2() |
控制级联选择线,完成南向通道硬件选通。 |
chrg_south_switch() |
校验通道并组合调用三级选择函数。 |
chrg_south_send() |
通过南向 TTY 发送 Modbus RTU 帧。 |
chrg_south_frame_head() |
从 ringbuffer 识别目标地址和功能码。 |
chrg_south_frame_reset() |
清理南向组帧状态和动态缓存。 |
chrg_south_frame_append() |
追加南向接收字节。 |
chrg_south_frame_dispatch() |
校验 CRC 后将响应投递给消费者。 |
chrg_south_pickup_frame() |
推进南向组帧状态机。 |
chrg_south_thread_entry() |
南向接收线程主循环。 |
south_ch() |
FinSH 南向通道调试命令。 |
thread/chrg_roll_nor.c
| 函数 |
说明 |
sink_fill_pd_buf() |
按协议类型把组号、电压、电流编码为 Sink 参数字节。 |
chrg_nor_source_stop() |
分步骤停止 Source,关闭继电器并清理切换标志。 |
chrg_roll_nor_sw_uart() |
在指定通道选择 Sink 或 Source UART。 |
chrg_roll_nor_sink_pro_set() |
组装并发送 Sink 快充协议设置。 |
chrg_roll_nor_source_pro_set() |
按设置来源选择 Source 协议下发函数。 |
chrg_roll_nor_parse() |
根据角色和子命令生成一次北向查询/设置动作。 |
chrg_roll_nor_cmd() |
北向命令参数检查接口;当前仅做空指针检查。 |
chrg_roll_nor_set() |
北向轮询核心状态机,推进每通道 Source/Sink 子步骤。 |
chrg_roll_nor_thread_entry() |
轮询四个北向通道,等待响应并控制超时/重试。 |
sink() / source() |
FinSH 手工配置 Sink/Source 的调试入口。 |
chrg_trim_crc() |
计算校准数据 CRC。 |
chrg_trim_set_volt() / chrg_trim_set_curr() / chrg_trim_set_source_curr() |
写入电压、电流及 Source 电流校准值。 |
chrg_trim_set_zero() |
执行零点校准设置。 |
chrg_roll_trim_set() |
按校准类型分派具体校准函数。 |
thread/chrg_roll_sou.c
| 函数 |
说明 |
chrg_sou_com_batch_submit() |
提交一批南向连续写寄存器命令。 |
chrg_sou_com_batch_add_reg() |
向当前批次追加通道、寄存器和值。 |
chrg_set_sou_reg() |
提交单个异步寄存器写命令。 |
chrg_set_sou_reg_com() |
将寄存器写入合并批次。 |
sou_com_batch_next() |
在锁保护下取下一条批命令。 |
sou_com_batch_complete() |
标记批命令完成并推进队列。 |
sou_com_batch_cancel() |
取消指定通道批命令。 |
sou_com_batch_pending_locked() |
判断锁内是否还有待处理批命令。 |
sou_single_command_finish() |
结束单命令,恢复期望运行状态。 |
sou_com_response_matches() |
判断响应是否匹配当前请求。 |
sou_msg_free() |
释放南向邮箱消息。 |
sou_com_command_failed() |
统一处理超时/协议错误和批次回滚。 |
chrg_roll_sou_thread_entry() |
串行发送南向命令、等待响应并处理重试。 |
south_send() / south_run() |
FinSH 发送寄存器和启停调试命令。 |
7. 函数说明:业务与协议
utils/chrg_sink.c
| 函数 |
说明 |
sink_get_vc() / sink_get_pd() |
生成 Sink 电压电流/协议查询帧。 |
sink_set_cc_line() / sink_set_cc_lvl() |
设置 CC 线选择和电平。 |
sink_set_pd() |
编码并发送 Sink 快充协议参数。 |
chrg_sink_work_init() |
初始化工作步骤并下发停止/安全继电器命令。 |
chrg_sink_work_volt_runing() |
在电压满足条件时推进 RUNING 动作。 |
chrg_sink_nor_work_low() |
处理持续低压状态并复位运行条件。 |
chrg_sink_nor_work_off() |
执行 Sink 停机收尾。 |
chrg_sink_change_ON() / chrg_sink_SHOUT_ON() |
控制换向和短接相关继电器步骤。 |
chrg_sink_work() |
根据 work_mode 分派 Sink 工作状态。 |
utils/chrg_source.c
| 函数组 |
说明 |
source_get_vc() / source_get_pd() |
生成 Source 电参/协议查询帧。 |
source_set_cc_lvl() / source_set_cc_choose() |
配置 Source CC 电平和选择方式。 |
parse_mulit_gear_One() / parse_power_single_gear() |
解析单组固定档快充能力。 |
parse_pd_11group_pdo() / parse_power_pdo_gear() |
解析 PDO/PPS 多档能力。 |
parse_mulit_gear_more() / parse_multi_gear_more() |
解析多组多档协议能力。 |
parse_ufcs_gear_more() / parse_power_ufcs() |
解析 UFCS 档位。 |
pd_fill_single_group() |
通用单组协议参数编码。 |
source_set_pd() |
按协议、电压和电流生成 Source 设置帧。 |
pd_fill_single_group_com() |
按通信寄存器档位编码单组参数。 |
pd_fill_single_group_need_src_com() / pd_fill_single_group_no_src_com() |
分别编码需要/不需要 Source 参数的协议。 |
pd_fill_single_group_FCP_AFC() / pd_fill_single_group_UFCS() |
编码 FCP/AFC 和 UFCS 专用参数。 |
source_set_pd_com() / source_set_pd_new_com() |
根据寄存器配置或完整通道状态下发 Source 协议。 |
utils/chrg_eload.c
| 函数组 |
说明 |
chrg_eload_set_ymodem_resp() / chrg_eload_get_ymodem_resp() / chrg_eload_clear_ymodem_resp() |
设置、读取和清除电子负载升级响应标志。 |
memcmp_8bytes() |
比较固定 8 字节标识。 |
chrg_eload_read_regs() / chrg_eload_write_reg() / chrg_eload_write_More_reg() |
生成电子负载 Modbus 读、单写和多写请求。 |
chrg_eload_send_ymodem_data() |
转发 YModem 升级数据。 |
chrg_write_cv() |
写入电子负载 CV 参数。 |
chrg_eload_send_relay() |
下发电子负载继电器动作。 |
chrg_eload_refresh() |
刷新电子负载测量状态。 |
chrg_eload_parse() |
解析电子负载响应并更新通道数据。 |
snp_ch() |
选择电子负载通道。 |
Show_Volt() / Show_Curr() / Show_Ripple() / Show_DZF() |
计算或刷新对应测量显示项。 |
Sta_compute() |
汇总测量状态。 |
LCD_SHOW() |
将电子负载测量结果推送到 LCD。 |
utils/chrg_north_pkg.c 与 utils/chrg_utils.c
| 函数 |
说明 |
chrg_north_pkg_encode() / chrg_north_pkg_decode() |
编码和解码北向协议包,并校验长度/校验值。 |
mb_crc16() |
计算 Modbus CRC16。 |
_crc8() / calc_crc8() |
单字节推进及整段 CRC8 计算。 |
u16_to_u8v() / u16_to_u8v_com() / u8v_to_u16() |
16 位整数与字节序列互转。 |
u32_to_u8v() / u8v_to_u32() |
32 位整数与字节序列互转。 |
swap_u16() / swap_u32() |
交换 16/32 位整数端序。 |
8. 函数说明:上位机、LCD 与板级封装
thread/chrg_comm.c
| 函数组 |
说明 |
chrg_shadow_sync() / chrg_shadow_init() |
同步/初始化 Modbus 寄存器影子数据。 |
mb_set_bits() / mb_get_bits() |
在 Modbus 位缓冲区写入/读取指定位段。 |
mb_reg_input_cb() / mb_reg_holding_cb() / mb_reg_test_cb() |
输入、保持和测试寄存器回调。 |
mb_ymodem_updata_cb() |
处理升级寄存器数据。 |
mb_reg_coils_cb() / mb_reg_discrete_cb() |
线圈与离散输入回调。 |
funcReadCoils() / funcReadDiscreteInputs() / funcReadHoldingRegister() / funcReadInputRegister() |
实现对应 Modbus 读功能。 |
funcWriteCoil() / funcWriteHoldingRegister() / funcWriteMultipleCoils() / funcWriteMultipleHoldingRegister() |
校验并执行对应写功能。 |
sink_proto_lookup() / src_proto_lookup() / src_type_lookup() |
将寄存器枚举映射为内部协议/Source 类型。 |
parse_load_no_group() / parse_load_with_group() |
解析无组号/带组号的负载协议参数。 |
chrg_com_source_on() |
根据通信配置启动 Source 流程。 |
funcWriteProtoCal() / funcSinkTest() / funcTrimELoad() |
处理协议校准、Sink 测试和电子负载校准命令。 |
funYmodemUpadata() |
推进固件升级命令。 |
chrg_comm_parse_msg() |
解析通信线程邮箱消息并分派功能码。 |
chrg_comm_updata_north() |
将实时北向状态同步到寄存器区。 |
chrg_comm_thread_entry() |
初始化 Modbus 从站并循环处理消息/状态同步。 |
chrg_mb_write_sink() / chrg_mb_write_src() / chrg_mb_write_sys() |
将保持寄存器变化写入 Sink、Source 和系统状态。 |
chrg_sink_get_proto_diff() |
比较目标与实际 Sink 协议参数。 |
chrg_sink_diff_send_reg() |
仅发送存在差异的 Sink 寄存器。 |
set_ymodem_update_channel() / mb_error() / rs485snd() |
分别设置升级通道、转换错误码和提供 RS485 调试命令。 |
thread/chrg_lcd.c
| 函数组 |
说明 |
chrg_sou_work() / chrg_sou_stop() |
启动/停止指定功率通道。 |
chrg_pro_set() |
应用 LCD 输入的快充协议配置。 |
chrg_set_eload_sink() / chrg_set_eload_source() |
配置电子负载的 Sink/Source 角色。 |
chrg_set_CV() / chrg_set_CC() / chrg_roll_set_cv() |
设置 CV、CC 及轮询相关目标值。 |
chrg_lcd_parse() |
解析 HMI 命令并修改对应通道配置。 |
chrg_lcd_send() |
向 HMI 发送数据。 |
chrg_lcd_thread_entry() |
LCD 串口收发与周期刷新主循环。 |
lcdsend() |
FinSH LCD 原始发送调试命令。 |
bsp/
| 模块 |
函数说明 |
chrg_fal.c |
chrg_fal_read()、chrg_fal_write()、chrg_fal_erase()、chrg_fal_erase_all() 封装分区访问;chrg_fal_init() 初始化 FAL。 |
chrg_gpio.c |
chrg_gpio_mode_set()、chrg_gpio_get()、chrg_gpio_set() 封装 GPIO;chrg_gpios_init() 初始化引脚。 |
chrg_rel.c |
chrg_nor_sw_rel() 控制北向继电器;chrg_nor_rel_init() 初始化;rel_test() 用于 shell 测试。 |
chrg_switch.c |
chrg_switch_ch() 驱动通道译码选择线。 |
chrg_vcom.c |
chrg_vcom_init() 初始化 USB 虚拟串口;chrg_vcom_console_init() 注册控制台。 |
chrg_wdt.c |
chrg_wdt_feed() 喂狗;chrg_wdt_init() 初始化并启动看门狗。 |
chrg_tmr.c |
chrg_tmr_get_count()、chrg_tmr_start()、chrg_tmr_stop()、chrg_tmr_release()、chrg_tmr_open() 管理软件秒定时器;chrg_tmr_1s_callback() 计时;chrg_tmrs_init() 初始化;uptime()、sec_tmr() 为 shell 命令。 |
chrg_led.c |
chrg_led_get()、chrg_led_set()、chrg_led_toggle()、chrg_led_pulsing()、chrg_led_flashing() 控制 LED;chrg_led_timer_set_on()、chrg_led_timer_set_off()、chrg_led_timer_start()、chrg_led_timer_delete()、chrg_led_timer_timeout_callback()、chrg_led_show() 管理闪烁时序;chrg_leds_init() 初始化。 |
chrg_tty.c |
chrg_tty_send_comp_hook()、chrg_tty_recv_ind_hook() 为驱动回调;chrg_tty_cal_byte_tmo()、chrg_tty_mode_set()、chrg_tty_dev_open()、chrg_tty_config() 配置串口;chrg_tty_connect()、chrg_tty_disconn()、chrg_tty_destory() 管理连接;chrg_tty_set_recv_tmo()、chrg_tty_set_byte_tmo() 设置超时;chrg_tty_recv()、chrg_tty_send()、chrg_tty_break_recv()、chrg_tty_send_then_recv() 完成阻塞式收发。 |
9. Bootloader 函数级主链
Boot 辅助模块职责:firmware.c 的 FM_* 函数负责分区头、擦写、CRC 校验、版本和搬运;ymodem.c 的 ymodemHandler()、ymodemConfig() 负责升级协议状态机;transfer.c 的 DT_Init()、DT_Send()、DT_PollingReceive() 负责串口帧传输;drv_timer.c 提供启动、重启、暂停、注销、处理和用户数据绑定;bsp_uart.c/bsp_uart_port.c 提供 UART、DMA、中断及接收完成回调。
10. 阅读与调试顺序
- 启动异常先看
chrg_thread_init() 和各 INIT_*_EXPORT 初始化返回值。
- 北向无数据依次跟踪
chrg_north_thread_entry()、chrg_north_frame_head()、chrg_north_pickup_frame()、chrg_north_frame_dispatch()。
- Sink 不启动依次检查
chrg_sink_parse() 的电压/电流判定、work_mode、chrg_sink_work() 和 chrg_set_sou_reg()。
- 功率板命令未生效依次检查
chrg_set_sou_reg()、chrg_roll_sou_thread_entry()、chrg_south_send() 和南向响应匹配。
- 上位机写入未生效依次检查 Modbus
funcWrite*()、chrg_mb_write_*()、共享状态和两个轮询线程。