support freemodbus RTU master and slave mode
This commit is contained in:
parent
b2ab878a33
commit
98232123e4
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
Loading…
Reference in New Issue