support freemodbus RTU master and slave mode

This commit is contained in:
Liu_Weichao 2023-11-16 16:12:29 +08:00
parent b2ab878a33
commit 98232123e4
15 changed files with 167 additions and 298 deletions

View File

@ -1,11 +1,11 @@
SRC_DIR := freemodbus-latest
ifeq ($(CONFIG_CONNECTION_MODBUS_USING_RTU),y)
SRC_FILES := adapter_modbus_rtu.c
SRC_FILES :=
endif
ifeq ($(CONFIG_CONNECTION_MODBUS_USING_TCP),y)
SRC_FILES := adapter_modbus_tcp.c
SRC_FILES :=
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file adapter_Modbus_rtu.c
* @brief Implement the connection 4G adapter function
* @version 1.1
* @author AIIT XIUOS Lab
* @date 2021.06.25
*/
#include <adapter.h>
static int AdapterModbusRtuRegister(struct Adapter *adapter)
{
int ret = 0;
strncpy(adapter->name, ADAPTER_MODBUS_RTU_NAME, NAME_NUM_MAX);
adapter->net_protocol = PROTOCOL_NONE;//IP层协议类型串口没有此层
adapter->net_role = SLAVE;
adapter->adapter_status = UNREGISTERED;
ret = AdapterDeviceRegister(adapter);
if (ret < 0) {
printf("AdapterModbusRtu register error\n");
return -1;
}
return ret;
}
int AdapterModbusRtuInit(void)
{
int ret = 0;
struct Adapter *adapter = PrivMalloc(sizeof(struct Adapter));
if (!adapter) {
PrivFree(adapter);
return -1;
}
memset(adapter, 0, sizeof(struct Adapter));
ret = AdapterModbusRtuRegister(adapter);
if (ret < 0) {
printf("AdapterModbusRtuInit register ModbusRtu adapter error\n");
PrivFree(adapter);
return -1;
}
return ret;
}

View File

@ -176,13 +176,19 @@ void vMBMasterCBRequestScuuess( void );
* a new byte was received. The port implementation should wake up the
* tasks which are currently blocked on the eventqueue.
*/
extern BOOL( *pxMBFrameCBByteReceived ) ( void );
extern BOOL( *pxMBFrameCBTransmitterEmpty ) ( void );
extern BOOL( *pxMBPortCBTimerExpired ) ( void );
#ifdef ADD_RTTHREAD_FEATURES
extern BOOL( *pxMBFrameCBByteReceived ) ( void );
extern BOOL( *pxMBMasterFrameCBByteReceived ) ( void );
#endif
#ifdef ADD_XIZI_FEATURES
extern BOOL( *pxMBFrameCBByteReceived ) ( CHAR pucByte );
extern BOOL( *pxMBMasterFrameCBByteReceived ) ( CHAR pucByte );
#endif
extern BOOL( *pxMBMasterFrameCBTransmitterEmpty ) ( void );

View File

@ -85,7 +85,12 @@ static pvMBFrameClose pvMBFrameCloseCur;
* or transmission of a character.
* Using for Modbus Slave
*/
#ifdef ADD_RTTHREAD_FEATURES
BOOL( *pxMBFrameCBByteReceived ) ( void );
#endif
#ifdef ADD_XIZI_FEATURES
BOOL( *pxMBFrameCBByteReceived ) ( CHAR pucByte );
#endif
BOOL( *pxMBFrameCBTransmitterEmpty ) ( void );
BOOL( *pxMBPortCBTimerExpired ) ( void );

View File

@ -90,7 +90,12 @@ static pvMBFrameClose pvMBMasterFrameCloseCur;
* or transmission of a character.
* Using for Modbus Master,Add by Armink 20130813
*/
#ifdef ADD_RTTHREAD_FEATURES
BOOL( *pxMBMasterFrameCBByteReceived ) ( void );
#endif
#ifdef ADD_XIZI_FEATURES
BOOL( *pxMBMasterFrameCBByteReceived ) ( CHAR pucByte );
#endif
BOOL( *pxMBMasterFrameCBTransmitterEmpty ) ( void );
BOOL( *pxMBMasterPortCBTimerExpired ) ( void );

View File

@ -226,8 +226,14 @@ eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
return eStatus;
}
#ifdef ADD_RTTHREAD_FEATURES
BOOL
xMBRTUReceiveFSM( void )
#endif
#ifdef ADD_XIZI_FEATURES
BOOL
xMBRTUReceiveFSM( CHAR pucByte )
#endif
{
BOOL xTaskNeedSwitch = FALSE;
UCHAR ucByte;
@ -241,7 +247,8 @@ xMBRTUReceiveFSM( void )
#endif
/* Always read the character. */
( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
// ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
ucByte = pucByte;
switch ( eRcvState )
{
@ -264,6 +271,7 @@ xMBRTUReceiveFSM( void )
* receiver is in the state STATE_RX_RECEIVCE.
*/
case STATE_RX_IDLE:
vMBPortTimersDisable( );
usRcvBufferPos = 0;
ucRTUBuf[usRcvBufferPos++] = ucByte;
eRcvState = STATE_RX_RCV;
@ -286,7 +294,7 @@ xMBRTUReceiveFSM( void )
{
eRcvState = STATE_RX_ERROR;
}
vMBPortTimersEnable();
//vMBPortTimersEnable();
break;
}
return xTaskNeedSwitch;

View File

@ -42,7 +42,12 @@ void eMBRTUStart( void );
void eMBRTUStop( void );
eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength );
eMBErrorCode eMBRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength );
#ifdef ADD_RTTHREAD_FEATURES
BOOL xMBRTUReceiveFSM( void );
#endif
#ifdef ADD_XIZI_FEATURES
BOOL xMBRTUReceiveFSM( CHAR pucByte );
#endif
BOOL xMBRTUTransmitFSM( void );
BOOL xMBRTUTimerT15Expired( void );
BOOL xMBRTUTimerT35Expired( void );
@ -53,8 +58,13 @@ void eMBMasterRTUStart( void );
void eMBMasterRTUStop( void );
eMBErrorCode eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength );
eMBErrorCode eMBMasterRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength );
BOOL xMBMasterRTUReceiveFSM( void );
BOOL xMBMasterRTUTransmitFSM( void );
#ifdef ADD_RTTHREAD_FEATURES
BOOL xMBMasterRTUReceiveFSM( void );
#endif
#ifdef ADD_XIZI_FEATURES
BOOL xMBMasterRTUReceiveFSM( CHAR pucByte );
#endif
BOOL xMBMasterRTUTimerExpired( void );
#endif

View File

@ -235,8 +235,14 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
return eStatus;
}
#ifdef ADD_RTTHREAD_FEATURES
BOOL
xMBMasterRTUReceiveFSM( void )
#endif
#ifdef ADD_XIZI_FEATURES
BOOL
xMBMasterRTUReceiveFSM( CHAR pucByte )
#endif
{
BOOL xTaskNeedSwitch = FALSE;
UCHAR ucByte;
@ -249,8 +255,9 @@ xMBMasterRTUReceiveFSM( void )
MB_CHECK(( eSndState == STATE_M_TX_IDLE ) || ( eSndState == STATE_M_TX_XFWR ));
#endif
/* Always read the character. */
( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
// /* Always read the character. */
// ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
ucByte = pucByte;
switch ( eRcvState )
{
@ -302,7 +309,7 @@ xMBMasterRTUReceiveFSM( void )
{
eRcvState = STATE_M_RX_ERROR;
}
vMBMasterPortTimersT35Enable();
//vMBMasterPortTimersT35Enable();
break;
}
return xTaskNeedSwitch;

View File

@ -112,9 +112,9 @@ xMBPortEventGet( eMBEventType * eEvent )
unsigned int recvedEvent;
/* waiting forever OS event */
while (0 != PrivEventProcess(xSlaveOsEvent,
EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent));
PrivEventProcess(xSlaveOsEvent,
EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent);
switch (recvedEvent)
{

View File

@ -286,13 +286,13 @@ xMBMasterPortEventPost( eMBMasterEventType eEvent )
BOOL
xMBMasterPortEventGet( eMBMasterEventType * eEvent )
{
unsigned int recvedEvent;
unsigned int recvedEvent = EV_MASTER_ERROR_PROCESS;
/* waiting forever OS event */
while (0 != PrivEventProcess(xMasterOsEvent,
EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent));
PrivEventProcess(xMasterOsEvent,
EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent);
/* the enum type couldn't convert to int type */
switch (recvedEvent)
@ -450,11 +450,11 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
unsigned int recvedEvent;
/* waiting forever OS event */
while (0 != PrivEventProcess(xMasterOsEvent,
EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
| EV_MASTER_ERROR_RECEIVE_DATA
| EV_MASTER_ERROR_EXECUTE_FUNCTION,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent));
PrivEventProcess(xMasterOsEvent,
EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
| EV_MASTER_ERROR_RECEIVE_DATA
| EV_MASTER_ERROR_EXECUTE_FUNCTION,
EVENT_OR | EVENT_AUTOCLEAN, 0, &recvedEvent);
switch (recvedEvent)
{

View File

@ -255,6 +255,7 @@ static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
/* ----------------------- Static variables ---------------------------------*/
/* software simulation serial transmit IRQ handler thread */
static pthread_t thread_serial_soft_trans_irq;
static pthread_t thread_serial_recv_irq;
/* serial event */
static int event_serial;
/* modbus slave serial device */
@ -264,35 +265,36 @@ static int uart_fd = 0;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
#define RTU_RECV_DATA_LENGTH 8
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
static int serial_rx_ind(void *dev, size_t size);
static void prvvUARTRxISR(CHAR pucByte);
static void *serial_soft_trans_irq(void* parameter);
static void *serial_recv_irq(void* parameter);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
eMBParity eParity)
{
int ret = 0;
uint8_t baud_rate, data_bits, parity;
uint32_t baud_rate;
uint8_t data_bits, parity;
baud_rate = ulBaudRate;
data_bits = ucDataBits;
/* set serial configure parameter */
switch(eParity){
case MB_PAR_NONE: {
data_bits = DATA_BITS_8;
parity = PARITY_NONE;
break;
}
case MB_PAR_ODD: {
data_bits = DATA_BITS_9;
parity = PARITY_ODD;
break;
}
case MB_PAR_EVEN: {
data_bits = DATA_BITS_9;
parity = PARITY_EVEN;
break;
}
@ -328,14 +330,14 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
cfg.serial_stop_bits = STOP_BITS_1;
cfg.serial_buffer_size = 128;
cfg.serial_parity_mode = parity;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
cfg.serial_bit_order = 1;
cfg.serial_invert_mode = 1;
#ifdef CONNECTION_MODBUS_RTU_EXTUART
cfg.ext_uart_no = CONNECTION_MODBUS_RTU_UART_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif
cfg.serial_timeout = -1;
cfg.dev_recv_callback = serial_rx_ind;
cfg.dev_recv_callback = NULL;
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
ioctl_cfg.args = &cfg;
@ -361,6 +363,15 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
PrivTaskCreate(&thread_serial_soft_trans_irq, &attr, &serial_soft_trans_irq, (void *)&args);
PrivTaskStartup(&thread_serial_soft_trans_irq);
attr.schedparam.sched_priority = 22;
attr.stacksize = 2048;
char task2_name[] = "slave_recv";
args.pthread_name = task2_name;
PrivTaskCreate(&thread_serial_recv_irq, &attr, &serial_recv_irq, (void *)&args);
PrivTaskStartup(&thread_serial_recv_irq);
return TRUE;
}
@ -449,9 +460,9 @@ void prvvUARTTxReadyISR(void)
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
void prvvUARTRxISR(void)
void prvvUARTRxISR(CHAR pucByte)
{
pxMBFrameCBByteReceived();
pxMBFrameCBByteReceived(pucByte);
}
/**
@ -463,23 +474,36 @@ static void *serial_soft_trans_irq(void* parameter) {
unsigned int recved_event;
while (1) {
/* waiting for serial transmit start */
PrivEventProcess(event_serial, EVENT_SERIAL_TRANS_START, EVENT_OR, 0, &recved_event);
/* execute modbus callback */
prvvUARTTxReadyISR();
if (0 == PrivEventProcess(event_serial, EVENT_SERIAL_TRANS_START, EVENT_OR, 0, &recved_event)) {
/* execute modbus callback */
prvvUARTTxReadyISR();
}
}
}
/**
* This function is serial receive callback function
* Software simulation serial receive data IRQ handler.
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return 0
* @param parameter parameter
*/
static int serial_rx_ind(void *dev, size_t size) {
while(size--)
prvvUARTRxISR();
return 0;
static void *serial_recv_irq(void* parameter) {
int i;
int data_size = 0;
int data_recv_size = 0;
char recv_data[RTU_RECV_DATA_LENGTH] = {0};
while (1) {
while (data_size < RTU_RECV_DATA_LENGTH) {
data_recv_size = PrivRead(uart_fd, recv_data + data_size, RTU_RECV_DATA_LENGTH - data_size);
data_size += data_recv_size;
}
/* execute modbus recv callback */
for (i = 0; i < RTU_RECV_DATA_LENGTH; i ++) {
prvvUARTRxISR(recv_data[i]);
}
data_size = 0;
data_recv_size = 0;
}
}
#endif

View File

@ -259,6 +259,7 @@ static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
/* ----------------------- Static variables ---------------------------------*/
/* software simulation serial transmit IRQ handler thread */
static pthread_t thread_serial_soft_trans_irq;
static pthread_t thread_serial_recv_irq;
/* serial event */
static int event_serial;
/* modbus master serial device */
@ -268,35 +269,36 @@ static int uart_fd = 0;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
#define RTU_RECV_DATA_LENGTH 8
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR(void);
static void prvvUARTRxISR(void);
static int serial_rx_ind(void *dev, size_t size);
static void prvvUARTRxISR(CHAR pucByte);
static void *serial_soft_trans_irq(void* parameter);
static void *serial_recv_irq(void* parameter);
/* ----------------------- Start implementation -----------------------------*/
BOOL xMBMasterPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
eMBParity eParity)
{
int ret = 0;
uint8_t baud_rate, data_bits, parity;
uint32_t baud_rate;
uint8_t data_bits, parity;
baud_rate = ulBaudRate;
data_bits = ucDataBits;
/* set serial configure parameter */
switch(eParity){
case MB_PAR_NONE: {
data_bits = DATA_BITS_8;
parity = PARITY_NONE;
break;
}
case MB_PAR_ODD: {
data_bits = DATA_BITS_9;
parity = PARITY_ODD;
break;
}
case MB_PAR_EVEN: {
data_bits = DATA_BITS_9;
parity = PARITY_EVEN;
break;
}
@ -332,14 +334,14 @@ BOOL xMBMasterPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
cfg.serial_stop_bits = STOP_BITS_1;
cfg.serial_buffer_size = 128;
cfg.serial_parity_mode = parity;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
cfg.serial_bit_order = 1;
cfg.serial_invert_mode = 1;
#ifdef CONNECTION_MODBUS_RTU_EXTUART
cfg.ext_uart_no = 0;
cfg.port_configure = PORT_CFG_INIT;
#endif
cfg.serial_timeout = -1;
cfg.dev_recv_callback = serial_rx_ind;
cfg.dev_recv_callback = NULL;
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
ioctl_cfg.args = &cfg;
@ -356,15 +358,24 @@ BOOL xMBMasterPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
pthread_attr_t attr;
attr.schedparam.sched_priority = 21;
attr.stacksize = 1024;
attr.stacksize = 2048;
char task_name[] = "master_trans";
char task1_name[] = "master_trans";
pthread_args_t args;
args.pthread_name = task_name;
args.pthread_name = task1_name;
PrivTaskCreate(&thread_serial_soft_trans_irq, &attr, &serial_soft_trans_irq, (void *)&args);
PrivTaskStartup(&thread_serial_soft_trans_irq);
attr.schedparam.sched_priority = 22;
attr.stacksize = 2048;
char task2_name[] = "master_recv";
args.pthread_name = task2_name;
PrivTaskCreate(&thread_serial_recv_irq, &attr, &serial_recv_irq, (void *)&args);
PrivTaskStartup(&thread_serial_recv_irq);
return TRUE;
}
@ -453,9 +464,9 @@ void prvvUARTTxReadyISR(void)
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
void prvvUARTRxISR(void)
void prvvUARTRxISR(CHAR pucByte)
{
pxMBMasterFrameCBByteReceived();
pxMBMasterFrameCBByteReceived(pucByte);
}
/**
@ -467,24 +478,38 @@ static void *serial_soft_trans_irq(void* parameter) {
unsigned int recved_event;
while (1) {
/* waiting for serial transmit start */
PrivEventProcess(event_serial, EVENT_SERIAL_TRANS_START, EVENT_OR, 0, &recved_event);
/* execute modbus callback */
prvvUARTTxReadyISR();
if (0 == PrivEventProcess(event_serial, EVENT_SERIAL_TRANS_START, EVENT_OR, 0, &recved_event)) {
/* execute modbus callback */
prvvUARTTxReadyISR();
}
}
}
/**
* This function is serial receive callback function
* Software simulation serial receive data IRQ handler.
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return 0
* @param parameter parameter
*/
static int serial_rx_ind(void *dev, size_t size) {
prvvUARTRxISR();
return 0;
static void *serial_recv_irq(void* parameter) {
int i;
int data_size = 0;
int data_recv_size = 0;
char recv_data[RTU_RECV_DATA_LENGTH] = {0};
while (1) {
while (data_size < RTU_RECV_DATA_LENGTH) {
data_recv_size = PrivRead(uart_fd, recv_data + data_size, RTU_RECV_DATA_LENGTH - data_size);
data_size += data_recv_size;
}
/* execute modbus recv callback */
for (i = 0; i < RTU_RECV_DATA_LENGTH; i ++) {
prvvUARTRxISR(recv_data[i]);
}
data_size = 0;
data_recv_size = 0;
}
}
#endif
#endif

View File

@ -142,7 +142,7 @@ MSH_CMD_EXPORT(mb_master_sample, run a modbus master sample);
#define SLAVE_ADDR 0x01
#define PORT_NUM 4
#define PORT_BAUDRATE 115200
#define PORT_PARITY MB_PAR_EVEN
#define PORT_PARITY MB_PAR_NONE
#define MB_POLL_THREAD_PRIORITY 22
#define MB_SEND_THREAD_PRIORITY 22
@ -189,7 +189,7 @@ static void *mb_master_poll(void *parameter)
}
}
static int mb_master_sample(int argc, char **argv)
static int mb_master_sample(void)
{
static uint8_t is_init = 0;

View File

@ -168,7 +168,7 @@ MSH_CMD_EXPORT(mb_slave_sample, run a modbus slave sample);
#define PORT_NUM 4
#define PORT_BAUDRATE 115200
#define PORT_PARITY MB_PAR_EVEN
#define PORT_PARITY MB_PAR_NONE
#define MB_POLL_THREAD_PRIORITY 22
#define MB_SEND_THREAD_PRIORITY 22
@ -199,14 +199,7 @@ static void *send_thread_entry(void *parameter)
static void *mb_slave_poll(void *parameter)
{
if (strstr(parameter, "RTU")) {
eMBInit(MB_RTU, SLAVE_ADDR, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
} else if (rt_strstr(parameter, "TCP")) {
eMBTCPInit(0);
} else {
rt_kprintf("Error: unknown parameter");
}
eMBInit(MB_RTU, SLAVE_ADDR, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
eMBEnable();
while (1) {
@ -215,7 +208,7 @@ static void *mb_slave_poll(void *parameter)
}
}
static int mb_slave_sample(int argc, char **argv)
static int mb_slave_sample(void)
{
static uint8_t is_init = 0;
@ -224,18 +217,13 @@ static int mb_slave_sample(int argc, char **argv)
return -1;
}
if (argc < 2) {
printf("Usage: mb_slave_sample RTU/TCP\n");
return -1;
}
pthread_attr_t attr;
attr.schedparam.sched_priority = MB_POLL_THREAD_PRIORITY;
attr.stacksize = 2048;
char task1_name[] = "md_s_poll";
pthread_args_t args;
args.arg = argv[1];
args.arg = NULL;
args.pthread_name = task1_name;
PrivTaskCreate(&tid1, &attr, &mb_slave_poll, (void *)&args);

View File

@ -1,144 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file modbus_rtu.c
* @brief Implement the connection Modbus RTU adapter function, using Modbus rtu device
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021.07.08
*/
#include <adapter.h>
#define PLC_DATA_LENGTH 1024
struct CircularAreaApp *g_circular_area;
static pthread_t recv_plc_data_task;
/**
* @description: Open modbus rtu function
* @param adapter - Modbus RTU device pointer
* @return success: 0, failure: -1
*/
static int ModbusRtuOpen(struct Adapter *adapter)
{
/* open serial port*/
adapter->fd = PrivOpen("/dev/tty3", 2);//2 read and write
if (adapter->fd < 0) {
printf("ModbusRtuOpen get serial %s fd error\n", "/dev/tty3");
return -1;
}
PrivTaskDelay(2500);
ADAPTER_DEBUG("Modbus rtu open done\n");
return 0;
}
/**
* @description: Close modbus rtu function
* @param adapter - Modbus RTu device pointer
* @return success: 0, failure: -1
*/
static int ModbusRtuClose(struct Adapter *adapter)
{
/*step1: close modbus serial port*/
int ret;
ret = PrivClose(adapter->fd);
if(ret < 0){
printf("ModbusRtuOpen close serial %s fd error\n", "/dev/tty3");
return -1;
}
ADAPTER_DEBUG("Modbus rtu Close done\n");
return 0;
}
static int ModbusRtuIoctl(struct Adapter *adapter, int cmd)
{
// uint32_t baud_rate = *((uint32_t *)args);
struct SerialDataCfg serial_cfg;
memset(&serial_cfg, 0 ,sizeof(struct SerialDataCfg));
serial_cfg.serial_baud_rate = BAUD_RATE_9600 ;
serial_cfg.serial_data_bits = DATA_BITS_8;
serial_cfg.serial_stop_bits = STOP_BITS_1;
serial_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
serial_cfg.serial_parity_mode = PARITY_EVEN;
serial_cfg.serial_bit_order = STOP_BITS_1;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
serial_cfg.is_ext_uart = 0;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
ioctl_cfg.args = &serial_cfg;
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
return 0;
}
static int ModbusRtuSend(struct Adapter *adapter, const void *buf, size_t len)
{
int ret;
ret = PrivWrite(adapter->fd, buf, len);
if(ret < 0){
printf("send failed %d!\n", ret);
}
return ret;
}
static int ModbusRtuRecv(struct Adapter *adapter, void *buf, size_t len)
{
int recv_len=0, recv_len_continue=0;
uint8 *recv_buf = PrivMalloc(len);
recv_len = PrivRead(adapter->fd, recv_buf, len);
if (recv_len) {
while (recv_len < len) {
recv_len_continue = PrivRead(adapter->fd, recv_buf + recv_len, len - recv_len);
if (recv_len_continue) {
recv_len += recv_len_continue;
} else {
recv_len = 0;
break;
}
}
memcpy(buf, recv_buf, len);
}
PrivFree(recv_buf);
return recv_len;
}
static const struct IpProtocolDone ec200t_done =
{
.open = ModbusRtuOpen,
.close = ModbusRtuClose,
.ioctl = ModbusRtuIoctl,
.setup = NULL,
.setdown = NULL,
.setaddr = NULL,
.setdns = NULL,
.setdhcp = NULL,
.ping = NULL,
.netstat = NULL,
.connect = NULL,
.send = ModbusRtuSend,
.recv = ModbusRtuRecv,
.disconnect = NULL,
};