bs_bcu_app/bsp/bsp_modbus.h

252 lines
7.3 KiB
C
Raw Permalink Normal View History

2024-11-07 17:24:19 +08:00
#ifndef BSP_MODBUS_MB_
#define BSP_MODBUS_MB_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "bsp_gate.h"
#define MODBUS_MAX_TASK (300u)
#define MODBUS_MAX_DEV (32u)
#define MODBUS_GATE_FREE_ADDR (0xFFFF)
/******************************************
* Helper Macros
******************************************/
#define READ_REGISTER_MAP_BEGIN() \
switch(index) \
{
#define READ_REGISTER_MAP_END() \
default: \
data = 0x00; \
break; \
}
#define READ_REGISTER_MAP_ITEM(INDEX, VARIABLE) \
case INDEX: \
data = VARIABLE; \
break;
#define WRITE_REGISTER_MAP_BEGIN() \
switch(index) \
{
#define WRITE_REGISTER_MAP_END() \
default: \
break; \
}
#define WRITE_REGISTER_MAP_ITEM(INDEX, VARIABLE) WRITE_REGISTER_MAP_ITEM_EX(INDEX, VARIABLE, value)
#define WRITE_REGISTER_MAP_ITEM_EX(INDEX, VARIABLE, VALUE) \
case INDEX: \
VARIABLE = VALUE; \
break;
#define WRITE_REGISTER_MAP_STATEMENT(INDEX, STATEMENT) \
case INDEX: \
STATEMENT; \
break;
#define WRITE_REGISTER_MAP_ITEM_CONFIG(INDEX, CONFIG) WRITE_REGISTER_MAP_ITEM_CONFIG_EX(INDEX, CONFIG, value)
#define WRITE_REGISTER_MAP_ITEM_CONFIG_EX(INDEX, CONFIG, VALUE) \
case INDEX: \
config_save(CONFIG, VALUE); \
break;
typedef enum
{
kModbusType_RTU,
kModbusType_TCP,
kModbusType_End
}ModbusType;
typedef enum
{
kModbusFun_0x01 = 0x01,
kModbusFun_0x02 = 0x02,
kModbusFun_0x03 = 0x03,
kModbusFun_0x04 = 0x04,
kModbusFun_0x05 = 0x05,
kModbusFun_0x06 = 0x06,
kModbusFun_0x0F = 0x0F,
kModbusFun_0x10 = 0x10,
kModbusFun_End,
}ModbusFun;
typedef enum
{
kBspMdEx_None = 0,
kBspMdEx_InvalidFunc,
kBspMdEx_InvalidAddr,
kBspMdEx_InvalidRegNum,
kBspMdEx_SlaveFault,
kBspMdEx_Acknowledge, //从机确认命令但需要较长时间,需要上位机等待
kBspMdEx_SlaveBusy,
}BspMdExCode;
struct _ModbusItem;
struct _ModbusTask;
typedef BspMdExCode (*ModbusFunCall)(uint16_t start_addr, uint16_t reg_num, uint8_t *buf, uint16_t *len);
typedef bool (*ModbusSendCall)(uint8_t comm_dev, uint8_t *buf, int32_t len);
typedef void (*MB_FUNC_CALL)(struct _ModbusItem * mb_item, uint8_t cmd, uint16_t start_addr, uint8_t *buf, uint16_t len);
typedef void (*HmiRxIntCtrlCall)(uint8_t comm_dev, bool is_en);
typedef void (*MasterCall)(struct _ModbusItem * mb_item, uint32_t base_time);
#define MODBUS_BUF_SIZE (280u)
typedef struct
{
uint8_t slave_addr;
uint8_t fun_code;
uint16_t reg_addr;
uint16_t reg_num;
uint16_t time_out;
}ModbusHead;
typedef struct _ModbusTask
{
uint16_t tick;
uint16_t buf_addr;
ModbusHead *head;
}ModbusTask;
typedef struct _ModbusItem
{
uint8_t addr;
uint8_t comm_dev;
ModbusType type;
bool is_master;
uint16_t tcp_transaction; //事务元标识符
uint16_t buf_pos;
uint16_t buf_size;
uint16_t start_addr;
uint16_t gate_write_data_absolute_addr;
uint32_t tick;
ModbusSendCall send_call;
GateItem *gate;
HmiRxIntCtrlCall ctrl_rx_int_call;
MB_FUNC_CALL func_call;
ModbusFunCall fun_call_array[kModbusFun_End];
MasterCall master_call;
uint8_t buf[MODBUS_BUF_SIZE];
uint8_t task_cashe;
uint8_t cur_task_idx;
uint8_t task_num;
bool is_read_write_data;
uint8_t gate_write_dev_addr;
uint8_t gate_write_try_cnt;
int16_t gate_write_data_addr;
uint16_t gate_write_data_value;
uint16_t gate_write_data_start_addr;
uint16_t gate_write_data_end_addr;
uint16_t time_out[MODBUS_MAX_DEV];
ModbusHead *gate_write_data_head;
ModbusTask *modbus_task;
struct _ModbusItem *next_item;
} ModbusItem;
typedef struct
{
uint8_t call_idx;
uint16_t max_task_num;
uint16_t gate_write_data_cnt;
ModbusItem *head_item;
ModbusItem *lastest_item;
MasterCall master_call_array[20];
ModbusTask modbus_task_buf[MODBUS_MAX_TASK];
}ModbusCommData;
//#define MODBUS_STATIC_TASK(_name, _slave_addr, _reg_num, _start_addr, _rcv_buf) \
// ModbusTask _name = \
// { \
// (NULL), \
// (_slave_addr), \
// (_reg_num), \
// (_start_addr), \
// (_rcv_buf), \
// }
#define MODBUS_STATIC_INIT(_name, _modbus_type, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _func_call) \
ModbusItem _name = \
{ \
(_slave_addr), \
(_comm_dev), \
(_modbus_type),\
(false),\
0, \
0, \
MODBUS_BUF_SIZE, \
0xFFFF, \
MODBUS_GATE_FREE_ADDR, \
0, \
_send_call, \
_func_call, \
_ctrl_rx_int_call, \
}
#define MODBUS_RTU_STATIC_INIT(_name, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate) MODBUS_STATIC_INIT(_name, kModbusType_RTU, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate)
#define MODBUS_TCP_STATIC_INIT(_name, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate) MODBUS_STATIC_INIT(_name, kModbusType_TCP, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate)
#define MODBUS_STATIC_INIT_CCM(_name, _modbus_type, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate) \
ModbusItem _name __attribute__((section (".CCM_RAM"))) = \
{ \
(_slave_addr), \
(_comm_dev), \
(_modbus_type),\
(false),\
0, \
0, \
MODBUS_BUF_SIZE, \
0xFFFF, \
MODBUS_GATE_FREE_ADDR, \
0, \
_send_call, \
_gate, \
_ctrl_rx_int_call, \
}
#define MODBUS_RTU_STATIC_INIT_CCM(_name, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate) MODBUS_STATIC_INIT_CCM(_name, kModbusType_RTU, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate)
#define MODBUS_TCP_STATIC_INIT_CCM(_name, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate) MODBUS_STATIC_INIT_CCM(_name, kModbusType_TCP, _slave_addr, _comm_dev, _send_call, _ctrl_rx_int_call, _gate)
void bsp_modbus_poll(ModbusItem * const item, bool is_enable_call);
void bsp_modbus_pos_send(ModbusItem * const mb_item, uint16_t len);
void bsp_modbus_neg_send(ModbusItem * const mb_item, BspMdExCode ex_code);
void bsp_modbus_register_master_fun(ModbusItem * const item, MasterCall master_call);
void bsp_modbus_register_fun(ModbusItem * const mb_item, ModbusFun fun_code, ModbusFunCall register_call);
void bsp_modbus_set_slaver_addr(ModbusItem * const item, uint8_t addr);
void bsp_modbus_push_data(ModbusItem * const mb_item, uint8_t *buf, uint16_t len);
void bsp_modbus_slaver_send_read(ModbusItem * const item, uint8_t dev_addr, uint8_t fun_code, uint8_t *buf, uint16_t len);
void bsp_modbus_master_read(ModbusItem * const item, uint8_t dev_addr, uint8_t fun_code, uint16_t start_addr, uint16_t reg_num);
void bsp_modbus_master_single_write(ModbusItem * const item, uint8_t dev_addr, uint8_t fun_code, uint16_t start_addr, uint16_t value);
void bsp_modbus_master_series_write(ModbusItem * const item, uint8_t dev_addr, uint8_t fun_code, uint16_t start_addr, uint16_t reg_num, uint8_t *buf);
bool bsp_modbus_register_task(ModbusItem * const item, ModbusHead *head);
uint16_t bsp_modbus_get_time_out(ModbusItem * const item, uint8_t addr);
void bsp_modbus_poll_all(uint32_t base_time);
void bsp_modbus_poll_call(uint32_t base_time);
#ifdef __cplusplus
}
#endif
#endif