Files
chrg/apps/chrg/applications/thread/chrg_comm.h
T
yhf c820aad809 feat: 完成项目多模块功能迭代与配置更新
1. 新增sqlite文件、协议文档、调试截图、配置ini等各类辅助文件
2. 更新Keil开发包版本与工程配置,调整编译优化等级
3. 重构继电器控制逻辑、串口收发逻辑与线程优先级
4. 新增Modbus寄存器映射、校准结构体与Ymodem升级相关代码
5. 完善南北向协议解析、快充挡位配置与调试日志
6. 修复注释格式、数组越界与线程邮箱溢出问题
7. 新增屏幕控制、功率板调试与协议格式说明文档
2026-07-18 15:32:54 +08:00

236 lines
8.9 KiB
C

/****************************************************************************
文件名称 : chrg_comm.h
完成日期 :
当前版本号 : V1.0
主要功能 : 实现对外通讯协议 MODBUS 服务端,以独立线程等待处理响应请求数据。
版本历史 : 创建原始版本
说明 :
******************************************************************************/
#ifndef __CHRG_COMM_H__
#define __CHRG_COMM_H__
#include <rtthread.h>
#include "chrg_tty.h"
#include "chrg_regs.h"
#define MODBUS_ADDRESS_DEFAULT 0x01
#define MB_HANDLERS_MAX (16)
typedef struct
{
//北向协议设置
rt_uint8_t proto_changed;
rt_uint8_t group_changed;
rt_uint16_t pro_volt_changed;
rt_uint16_t pro_curr_changed;
//南向功率设置
rt_uint8_t volt_changed;
rt_uint8_t curr_changed;
rt_uint8_t ccset_changed;
rt_uint8_t cvmode_changed;
} sink_proto_diff_t;
static void chrg_sink_get_proto_diff(struct chrg_switch_t *pReal,
struct chrg_switch_t *pShadow,
sink_proto_diff_t *pDiff,
rt_uint8_t *pNoChange);
typedef enum {
MB_REG_READ, /*!< Read register values and pass to protocol stack. */
MB_REG_WRITE /*!< Update register values. */
} eMBRegisterMode;
typedef enum {
MB_ENOERR, /*!< no error. */
MB_ENOREG, /*!< illegal register address. */
MB_EINVAL, /*!< illegal argument. */
MB_EPORTERR, /*!< porting layer error. */
MB_ENORES, /*!< insufficient resources. */
MB_EIO, /*!< I/O error. */
MB_EILLSTATE, /*!< protocol stack in illegal state. */
MB_ETIMEDOUT /*!< timeout error occurred. */
} eMBErrorCode;
// ========== 新寄存器地址映射 (使用0x06/0x10标准Modbus功能码) ==========
// 详细寄存器偏移定义见 chrg_regs.h
// 判断寄存器地址属于哪个区块的宏
#define REG_IS_SINK(addr) (((addr / 4) < TOTAL_SINK_CH_REGS))
#define REG_IS_SRC(addr) (((addr / 4) < TOTAL_SRC_CH_REGS))
#define REG_IS_SYS(addr) (((addr / 4) < TOTAL_SYS_CH_REGS))
// 根据地址提取通道号和区块内偏移
#define REG_GET_SINK_CH(addr) ((addr) / TOTAL_SINK_CH_REGS)
#define REG_GET_SINK_OFFSET(addr) ((addr) % TOTAL_SINK_CH_REGS)
#define REG_GET_SRC_CH(addr) ((addr) / TOTAL_SRC_CH_REGS)
#define REG_GET_SRC_OFFSET(addr) ((addr) % TOTAL_SRC_CH_REGS)
#define REG_GET_SYS_CH(addr) ((addr) / TOTAL_SYS_CH_REGS)
#define REG_GET_SYS_OFFSET(addr) ((addr) % TOTAL_SYS_CH_REGS)
//继电器偏移量
// 继电器寄存器偏移量
#define MODBUS_COIL_PWR_SRC 0x00 // 功率板-主电源继电器(每通道第0个)
#define MODBUS_COIL_PWR_SINK 0x01 // 功率板-主负载继电器(每通道第1个)
#define MODBUS_COIL_SINK_CC 0x02 // 协议板-负载CC继电器(每通道第2个)
#define MODBUS_COIL_SRC_CC 0x03 // 协议板-电源CC继电器(每通道第3个)
// 预留偏移量(对应每通道第4,可后续扩展)
#define MODBUS_COIL_PWR_ALL 0x04 // 功率板-俩个继电器
#define MODBUS_COIL_RESERVE2 0x05 // 预留继电器2(每通道第5个)
////复位相关
//#define RESET_NORTH_ADDR 0x0F00
//#define RESET_NORTH_VALUE 0x5A5A
//#define RESET_SOUTH_ADDR 0x0F01
#define MB_ADDRESS_BROADCAST (0) // 广播地址
#define MB_ADDRESS_MIN (1) // 地址最小值
#define MB_ADDRESS_MAX (247) // 地址最大值
// Modbus 标准功能码
#define MB_READ_COILS (0x01) // 读线圈
#define MB_READ_DISCRETE_INPUTS (0x02) // 读离散输入
#define MB_READ_HOLDING_REGISTER (0x03) // 读保持寄存器
#define MB_READ_INPUT_REGISTER (0x04) // 读输入寄存器
#define MB_WRITE_SINGLE_COIL (0x05) // 写单个线圈
#define MB_WRITE_REGISTER (0x06) // 写单个寄存器
#define MB_WRITE_MULTIPLE_COILS (0x0F) // 写多个线圈
#define MB_WRITE_MULTIPLE_REGISTERS (0x10) // 写多个寄存器
// 扩展功能码 (保留,非标准Modbus)
#define MB_YMODEM_UPDATAE (0x20) // Ymodem升级指令
#define MB_TRIM_ELOAD (0x21) // 校准源载指令
#define MB_FUNC_ERROR (0x80)
typedef enum {
MB_EX_NONE = 0x00,
MB_EX_ILLEGAL_FUNCTION = 0x01,
MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
MB_EX_ILLEGAL_DATA_VALUE = 0x03,
MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
MB_EX_ACKNOWLEDGE = 0x05,
MB_EX_SLAVE_BUSY = 0x06,
MB_EX_MEMORY_PARITY_ERROR = 0x08,
MB_EX_GATEWAY_PATH_FAILED = 0x0A,
MB_EX_GATEWAY_TGT_FAILED = 0x0B
} eMBException;
#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */
#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */
#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */
#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
typedef eMBException(*pFunctionHandler) (rt_uint8_t *reqFrame, rt_uint16_t reqLen,
rt_uint8_t *resFrame, rt_uint16_t *resLen);
struct code_func_t {
rt_uint8_t code;
pFunctionHandler func;
};
/*!
* Constants which defines the format of a modbus frame. The example is
* shown for a Modbus RTU/ASCII frame. Note that the Modbus PDU is not
* dependent on the underlying transport.
*
* <code>
* <------------------------ MODBUS SERIAL LINE PDU (1) ------------------->
* <----------- MODBUS PDU (1') ---------------->
* +-----------+---------------+----------------------------+-------------+
* | Address | Function Code | Data | CRC/LRC |
* +-----------+---------------+----------------------------+-------------+
* | | | |
* (2) (3/2') (3') (4)
*
* (1) ... MB_SER_PDU_SIZE_MAX = 256
* (2) ... MB_SER_PDU_ADDR_OFF = 0
* (3) ... MB_SER_PDU_PDU_OFF = 1
* (4) ... MB_SER_PDU_SIZE_CRC = 2
*
* (1') ... MB_PDU_SIZE_MAX = 253
* (2') ... MB_PDU_FUNC_OFF = 0
* (3') ... MB_PDU_DATA_OFF = 1
* </code>
*/
#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */
#define MB_PDU_SIZE_MIN 1 /*!< Function Code */
#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */
#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */
#define MB_PDU_FUNC_READ_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_WRITE_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_READWRITE_READ_ADDR_OFF (MB_PDU_DATA_OFF)
#define MB_PDU_FUNC_READ_DISCCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_READ_REGCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_READ_COILCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_VALUE_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF (MB_PDU_DATA_OFF + 2)
#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF (MB_PDU_DATA_OFF + 4)
#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF (MB_PDU_DATA_OFF + 5)
#define MB_PDU_FUNC_READ_SIZE (4)
#define MB_PDU_FUNC_WRITE_SIZE (4)
#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN (5)
#define MB_PDU_FUNC_READ_DISCCNT_MAX (0x07D0)
#define MB_PDU_FUNC_READ_COILCNT_MAX (0x07D0)
#define MB_PDU_FUNC_READ_REGCNT_MAX (0x007D)
#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX (0x0078)
#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX (0x07B0)
#define MB_YMODEM_DATA_SIZE (1029)
////升级协议状态
//typedef enum {
// Ymodem_No = 0,
// Ymodem_Wait,
// Ymodem_Rec_Start,
// Ymodem_Rec_1024,
// Ymodem_Rec_End,
// Ymodem_Rec_Finish
//} Ymodem_state;
#define THR_NAME_COMM "thr.comm"
#define DEV_NAME_COMM "uart1"
struct chrg_comm_t {
const char *devname;
struct chrg_tty_t *tty;
rt_uint16_t rx_len;
rt_uint8_t rx_buf[SIZE_BUF_TTY];
rt_uint16_t tx_len;
rt_uint8_t tx_buf[SIZE_BUF_TTY];
rt_uint8_t addr; // slave address
};
extern struct chrg_comm_t chrgcomm;
/*****************************************************************
函数名称: chrg_comm_thread_entry
函数描述: 对外RS485通信线程体
输入参数: *data: 本线程信息
输出参数: -
返回说明: -
其它说明: -
*****************************************************************/
extern void chrg_comm_thread_entry (void *data);
extern rt_uint8_t chrg_com_sink_on(rt_uint8_t ch, struct chrg_switch_t *pSW, rt_uint8_t *enable);
extern rt_uint8_t chrg_com_source_on(rt_uint8_t ch, rt_uint8_t protoCmd, struct chrg_switch_t *pSW, rt_uint8_t *enable);
extern void chrg_sink_diff_send_reg(eIDX_SOU_CH ch, sink_proto_diff_t *pDiff, struct chrg_switch_t *pReal);
#endif