/**
* @file fml_modbus_comm.c
* @brief fml层文件
* @author
* @note
* @version v0.1 版本
* @date 2023年7月24日
*/
#include "app_modbus_comm.h"
#include "fml_modbus_comm.h"
// 定义指向modbus功能0x03、0x06、0x10功能成员表指针
mb_reg_handle_t *gp_mb_x03_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x06_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x10_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x2B_regs_handle = NULL; //读设备识别码
mb_reg_handle_t *gp_mb_x41_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x42_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x50_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x51_regs_handle = NULL;
mb_reg_handle_t *gp_mb_x52_regs_handle = NULL;
int32_t fml_sci_modbus_x03request_handle(comm_context_t *p_comm_context);
int32_t fml_sci_modbus_x06_handle(comm_context_t *p_comm_context);
int32_t fml_sci_modbus_x10request_handle(comm_context_t *p_comm_context);
int32_t fml_sci_modbus_x2Brequest_handle(comm_context_t *p_comm_context);
int32_t fml_sci_modbus_x41request_handle(comm_context_t* p_comm_context);
int32_t fml_sci_modbus_x42request_handle(comm_context_t* p_comm_context);
int32_t fml_sci_modbus_x50request_handle(comm_context_t* p_comm_context);
int32_t fml_sci_modbus_x51request_handle(comm_context_t* p_comm_context);
int32_t fml_sci_modbus_x52request_handle(comm_context_t* p_comm_context);
// modbus 从机模式报文解析、处理实现功能码表
const mb_frame_handle_t g_sci_mb_slave_func_table[] = {
{MB_X03_READ_REGS, NULL, fml_sci_modbus_x03request_handle},
{MB_X06_WRITE_REG, NULL, fml_sci_modbus_x06_handle},
{MB_X10_WRITE_REGS, NULL, fml_sci_modbus_x10request_handle},
{MB_X2B_READ_REGS, NULL, fml_sci_modbus_x2Brequest_handle},
{MB_X41_RIRMWARE_TRANSFER, NULL, fml_sci_modbus_x41request_handle},
{MB_X42_RIRMWARE_UPGRADE, NULL, fml_sci_modbus_x42request_handle},
{MB_X50_RIRMWARE_TRANSFER, NULL, fml_sci_modbus_x50request_handle},
{MB_X51_RIRMWARE_UPGRADE, NULL, fml_sci_modbus_x51request_handle},
{MB_X52_BROAD_SPECIAL_CMD, NULL, fml_sci_modbus_x52request_handle},
};
/**
* @brief modbus协议 获取应答报文长度
* @param [in] p_comm_context上下文对象指针
* @retval <0 失败,以及失败原因
* @retval >=0 成功, 帧长度
*/
uint8_t get_response_length(comm_context_t* p_comm_context)
{
uint8_t len = 0;
uint8_t cmd = 0;
uint8_t byte_len = 0;
cmd = (uint8_t)(p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + p_comm_context->head_length]);
switch (cmd)
{
case MB_X03_READ_REGS:
byte_len = (uint16_t)((p_comm_context->recv_buf[MB_X03_LEN_INDEXH] << 8) | (p_comm_context->recv_buf[MB_X03_LEN_INDEXL]));
byte_len = byte_len * 2;
/* slave(1) func(1) byte(1) data(byte) crc(2) */
len = 1 + 1 + 1 + byte_len;
break;
case MB_X06_WRITE_REG:
/* slave(1) func(1) addr(2) count(2) crc(2) */
len = 1 + 1 + 2 + 2;
break;
case MB_X10_WRITE_REGS:
/* slave(1)+ func(1)+addr(2)+ count(2)+ crc(2) */
len = 1 + 1 + 2 + 2;
break;
case MB_X2B_READ_REGS:
len = X2B_requst_ack_len() + 8;
break;
case MB_X80_ABNORMAL_REGS:
/* slave(1) func(1) Error(1) crc(2) */
len = 1 + 1 + 1;
break;
}
return len;
}
/**
* @brief modbus协议 应答报文制作函数
* @param [in] p_comm_context上下文对象指针
* @param [in] err_type modbus请求执行结果
* @note sdk的发送函数会将tcp和rtu自适应增加偏移,故发送时不需要增加偏移
* @note sdk的接收函数接收的是裸数据,需要加偏移
* @retval <0 失败,以及失败原因
* @retval =0 成功
*/
int32_t modbus_request_ack(comm_context_t* p_comm_context, int32_t err_type)
{
int32_t err = MB_APP_SUCC;
uint16_t byte_len = 0;
uint16_t object_lift = 0;
uint16_t offset = p_comm_context->head_length;
if (MB_APP_SUCC == err_type)
{
//广播指令直接退出,没有应答报文
if (MODBUS_BROAD_ADDR == p_comm_context->recv_buf[MB_SLAVE_INDEX + offset])
{
return MB_APP_SUCC;
}
switch (p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + offset])
{
case MB_X03_READ_REGS:
// modbus 设备地址
p_comm_context->send_buf[MB_SLAVE_INDEX] = p_comm_context->recv_buf[MB_SLAVE_INDEX + offset];
// 功能码
p_comm_context->send_buf[MB_FUNC_CODE_INDEX] = p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + offset];
byte_len = (uint16_t)((p_comm_context->recv_buf[MB_X03_LEN_INDEXH + offset] << 8) | (p_comm_context->recv_buf[MB_X03_LEN_INDEXL + offset]));
byte_len = byte_len * 2;
// slave(1) + func(1) + byte_len(1) + data(n) + crc(2) 不能超过发送缓存区长度
if ((byte_len + 5) > SCI_RECV_BUFF_MAX_LEN)
{
return MB_ILLEGAL_DATA_ERR;
}
// 回复字节个数
p_comm_context->send_buf[MB_X03_ACK_BYTE_INDEX] = (uint8_t)(byte_len);
break;
case MB_X06_WRITE_REG:
// modbus 设备地址
p_comm_context->send_buf[MB_SLAVE_INDEX] = p_comm_context->recv_buf[MB_SLAVE_INDEX + offset];
// 功能码
p_comm_context->send_buf[MB_FUNC_CODE_INDEX] = p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + offset];
// modbus 寄存器地址
p_comm_context->send_buf[MB_X06_ADDR_INDEXH] = p_comm_context->recv_buf[MB_X06_ADDR_INDEXH + offset];
p_comm_context->send_buf[MB_X06_ADDR_INDEXL] = p_comm_context->recv_buf[MB_X06_ADDR_INDEXL + offset];
// modbus 寄存器数据
p_comm_context->send_buf[MB_X06_DATA_INDEXH] = p_comm_context->recv_buf[MB_X06_DATA_INDEXH + offset];
p_comm_context->send_buf[MB_X06_DATA_INDEXL] = p_comm_context->recv_buf[MB_X06_DATA_INDEXL + offset];
break;
case MB_X10_WRITE_REGS:
// modbus 设备地址
p_comm_context->send_buf[MB_SLAVE_INDEX] = p_comm_context->recv_buf[MB_SLAVE_INDEX + offset];
// 功能码
p_comm_context->send_buf[MB_FUNC_CODE_INDEX] = p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + offset];
// modbus 寄存器地址
p_comm_context->send_buf[MB_X10_ADDR_INDEXH] = p_comm_context->recv_buf[MB_X10_ADDR_INDEXH + offset];
p_comm_context->send_buf[MB_X10_ADDR_INDEXL] = p_comm_context->recv_buf[MB_X10_ADDR_INDEXL + offset];
// modbus 寄存器长度
p_comm_context->send_buf[MB_X10_LEN_INDEXH] = p_comm_context->recv_buf[MB_X10_LEN_INDEXH + offset];
p_comm_context->send_buf[MB_X10_LEN_INDEXL] = p_comm_context->recv_buf[MB_X10_LEN_INDEXL + offset];
break;
case MB_X2B_READ_REGS:
// modbus 设备地址
p_comm_context->send_buf[MB_SLAVE_INDEX] = p_comm_context->recv_buf[MB_SLAVE_INDEX + offset];
// 功能码
p_comm_context->send_buf[MB_FUNC_CODE_INDEX] = p_comm_context->recv_buf[MB_FUNC_CODE_INDEX + offset];
//MEI类型
p_comm_context->send_buf[MB_X2B_MEI_TYPE] = p_comm_context->recv_buf[MB_X2B1_MEI_TYPE + offset];
//Raed_Device_ID码索引
p_comm_context->send_buf[MB_X2B_R