mirror of
https://github.com/espressif/esp-modbus.git
synced 2025-07-30 10:27:16 +02:00
esp-modbus: make modbus files idf independent
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <stdint.h> // for standard int types definition
|
#include <stdint.h> // for standard int types definition
|
||||||
#include <stddef.h> // for NULL and std defines
|
#include <stddef.h> // for NULL and std defines
|
||||||
|
#include "soc/soc.h" // for BITN definitions
|
||||||
#include "esp_modbus_common.h" // for common types
|
#include "esp_modbus_common.h" // for common types
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
// Public interface header for slave
|
// Public interface header for slave
|
||||||
#include <stdint.h> // for standard int types definition
|
#include <stdint.h> // for standard int types definition
|
||||||
#include <stddef.h> // for NULL and std defines
|
#include <stddef.h> // for NULL and std defines
|
||||||
|
#include "soc/soc.h" // for BITN definitions
|
||||||
#include "freertos/FreeRTOS.h" // for task creation and queues access
|
#include "freertos/FreeRTOS.h" // for task creation and queues access
|
||||||
#include "freertos/event_groups.h" // for event groups
|
#include "freertos/event_groups.h" // for event groups
|
||||||
#include "esp_modbus_common.h" // for common types
|
#include "esp_modbus_common.h" // for common types
|
||||||
|
@ -151,26 +151,33 @@ eMBErrorCode
|
|||||||
eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
||||||
{
|
{
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
|
UCHAR *pucMBASCIIFrame = ( UCHAR* ) ucASCIIBuf;
|
||||||
|
USHORT usFrameLength = usRcvBufferPos;
|
||||||
|
|
||||||
|
if( xMBSerialPortGetRequest( &pucMBASCIIFrame, &usFrameLength ) == FALSE )
|
||||||
|
{
|
||||||
|
return MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
|
||||||
|
|
||||||
/* Length and CRC check */
|
/* Length and CRC check */
|
||||||
if( ( usRcvBufferPos >= MB_ASCII_SER_PDU_SIZE_MIN )
|
if( ( usFrameLength >= MB_ASCII_SER_PDU_SIZE_MIN )
|
||||||
&& ( prvucMBLRC( ( UCHAR * ) ucASCIIBuf, usRcvBufferPos ) == 0 ) )
|
&& ( prvucMBLRC( ( UCHAR * ) pucMBASCIIFrame, usFrameLength ) == 0 ) )
|
||||||
{
|
{
|
||||||
/* Save the address field. All frames are passed to the upper layed
|
/* Save the address field. All frames are passed to the upper layed
|
||||||
* and the decision if a frame is used is done there.
|
* and the decision if a frame is used is done there.
|
||||||
*/
|
*/
|
||||||
*pucRcvAddress = ucASCIIBuf[MB_SER_PDU_ADDR_OFF];
|
*pucRcvAddress = pucMBASCIIFrame[MB_SER_PDU_ADDR_OFF];
|
||||||
|
|
||||||
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
||||||
* size of address field and CRC checksum.
|
* size of address field and CRC checksum.
|
||||||
*/
|
*/
|
||||||
*pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
|
*pusLength = ( USHORT )( usFrameLength - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
|
||||||
|
|
||||||
/* Return the start of the Modbus PDU to the caller. */
|
/* Return the start of the Modbus PDU to the caller. */
|
||||||
*pucFrame = ( UCHAR * ) & ucASCIIBuf[MB_SER_PDU_PDU_OFF];
|
*pucFrame = ( UCHAR * ) & pucMBASCIIFrame[MB_SER_PDU_PDU_OFF];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -186,13 +193,14 @@ eMBASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
|||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
UCHAR usLRC;
|
UCHAR usLRC;
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
|
||||||
/* Check if the receiver is still in idle state. If not we where too
|
/* Check if the receiver is still in idle state. If not we where too
|
||||||
* slow with processing the received frame and the master sent another
|
* slow with processing the received frame and the master sent another
|
||||||
* frame on the network. We have to abort sending the frame.
|
* frame on the network. We have to abort sending the frame.
|
||||||
*/
|
*/
|
||||||
if( eRcvState == STATE_RX_IDLE )
|
if( eRcvState == STATE_RX_IDLE )
|
||||||
{
|
{
|
||||||
|
ENTER_CRITICAL_SECTION( );
|
||||||
/* First byte before the Modbus-PDU is the slave address. */
|
/* First byte before the Modbus-PDU is the slave address. */
|
||||||
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
||||||
usSndBufferCount = 1;
|
usSndBufferCount = 1;
|
||||||
@ -207,6 +215,13 @@ eMBASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
|||||||
|
|
||||||
/* Activate the transmitter. */
|
/* Activate the transmitter. */
|
||||||
eSndState = STATE_TX_START;
|
eSndState = STATE_TX_START;
|
||||||
|
EXIT_CRITICAL_SECTION( );
|
||||||
|
|
||||||
|
if ( xMBSerialPortSendResponse( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ) == FALSE )
|
||||||
|
{
|
||||||
|
eStatus = MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
vMBPortSerialEnable( FALSE, TRUE );
|
vMBPortSerialEnable( FALSE, TRUE );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -154,29 +154,34 @@ eMBErrorCode
|
|||||||
eMBMasterASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
eMBMasterASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
||||||
{
|
{
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
|
UCHAR *pucMBASCIIFrame = ( UCHAR* ) ucMasterASCIIRcvBuf;
|
||||||
|
USHORT usFrameLength = usMasterRcvBufferPos;
|
||||||
|
|
||||||
|
if( xMBMasterSerialPortGetResponse( &pucMBASCIIFrame, &usFrameLength ) == FALSE )
|
||||||
|
{
|
||||||
|
return MB_EIO;
|
||||||
|
}
|
||||||
ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
assert( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
|
||||||
|
|
||||||
|
assert( pucMBASCIIFrame );
|
||||||
/* Length and CRC check */
|
/* Length and CRC check */
|
||||||
if( ( usMasterRcvBufferPos >= MB_ASCII_SER_PDU_SIZE_MIN )
|
if( ( usFrameLength >= MB_ASCII_SER_PDU_SIZE_MIN )
|
||||||
&& ( prvucMBLRC( ( UCHAR * ) ucMasterASCIIRcvBuf, usMasterRcvBufferPos ) == 0 ) )
|
&& ( prvucMBLRC( ( UCHAR * ) pucMBASCIIFrame, usFrameLength ) == 0 ) )
|
||||||
{
|
{
|
||||||
/* Save the address field. All frames are passed to the upper layed
|
/* Save the address field. All frames are passed to the upper layed
|
||||||
* and the decision if a frame is used is done there.
|
* and the decision if a frame is used is done there.
|
||||||
*/
|
*/
|
||||||
*pucRcvAddress = ucMasterASCIIRcvBuf[MB_SER_PDU_ADDR_OFF];
|
*pucRcvAddress = pucMBASCIIFrame[MB_SER_PDU_ADDR_OFF];
|
||||||
|
|
||||||
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
||||||
* size of address field and CRC checksum.
|
* size of address field and CRC checksum.
|
||||||
*/
|
*/
|
||||||
*pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
|
*pusLength = ( USHORT )( usFrameLength - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
|
||||||
|
|
||||||
/* Return the start of the Modbus PDU to the caller. */
|
/* Return the start of the Modbus PDU to the caller. */
|
||||||
*pucFrame = ( UCHAR * ) & ucMasterASCIIRcvBuf[MB_SER_PDU_PDU_OFF];
|
*pucFrame = ( UCHAR * ) & pucMBASCIIFrame[MB_SER_PDU_PDU_OFF];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
}
|
}
|
||||||
EXIT_CRITICAL_SECTION( );
|
EXIT_CRITICAL_SECTION( );
|
||||||
@ -191,13 +196,13 @@ eMBMasterASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLengt
|
|||||||
|
|
||||||
if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
|
if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
|
||||||
/* Check if the receiver is still in idle state. If not we where too
|
/* Check if the receiver is still in idle state. If not we where too
|
||||||
* slow with processing the received frame and the master sent another
|
* slow with processing the received frame and the master sent another
|
||||||
* frame on the network. We have to abort sending the frame.
|
* frame on the network. We have to abort sending the frame.
|
||||||
*/
|
*/
|
||||||
if(eRcvState == STATE_M_RX_IDLE)
|
if(eRcvState == STATE_M_RX_IDLE)
|
||||||
{
|
{
|
||||||
|
ENTER_CRITICAL_SECTION( );
|
||||||
/* First byte before the Modbus-PDU is the slave address. */
|
/* First byte before the Modbus-PDU is the slave address. */
|
||||||
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
||||||
usMasterSndBufferCount = 1;
|
usMasterSndBufferCount = 1;
|
||||||
@ -208,17 +213,22 @@ eMBMasterASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLengt
|
|||||||
|
|
||||||
/* Calculate LRC checksum for Modbus-Serial-Line-PDU. */
|
/* Calculate LRC checksum for Modbus-Serial-Line-PDU. */
|
||||||
usLRC = prvucMBLRC( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
|
usLRC = prvucMBLRC( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
|
||||||
ucMasterASCIISndBuf[usMasterSndBufferCount++] = usLRC;
|
pucMasterSndBufferCur[usMasterSndBufferCount++] = usLRC;
|
||||||
|
|
||||||
/* Activate the transmitter. */
|
/* Activate the transmitter. */
|
||||||
eSndState = STATE_M_TX_START;
|
eSndState = STATE_M_TX_START;
|
||||||
|
EXIT_CRITICAL_SECTION( );
|
||||||
|
|
||||||
|
if ( xMBMasterSerialPortSendRequest( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount ) == FALSE )
|
||||||
|
{
|
||||||
|
eStatus = MB_EIO;
|
||||||
|
}
|
||||||
vMBMasterPortSerialEnable( FALSE, TRUE );
|
vMBMasterPortSerialEnable( FALSE, TRUE );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
}
|
}
|
||||||
EXIT_CRITICAL_SECTION( );
|
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +457,7 @@ xMBMasterASCIITransmitFSM( void )
|
|||||||
return xNeedPoll;
|
return xNeedPoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL MB_PORT_ISR_ATTR
|
||||||
xMBMasterASCIITimerT1SExpired( void )
|
xMBMasterASCIITimerT1SExpired( void )
|
||||||
{
|
{
|
||||||
BOOL xNeedPoll = FALSE;
|
BOOL xNeedPoll = FALSE;
|
||||||
@ -457,7 +467,6 @@ xMBMasterASCIITimerT1SExpired( void )
|
|||||||
/* Timer t35 expired. Startup phase is finished. */
|
/* Timer t35 expired. Startup phase is finished. */
|
||||||
case STATE_M_RX_INIT:
|
case STATE_M_RX_INIT:
|
||||||
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
|
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
|
||||||
ESP_EARLY_LOGI("xMBMasterASCIITimerT1SExpired", "RX_INIT_EXPIRED");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Start of message is not received during respond timeout.
|
/* Start of message is not received during respond timeout.
|
||||||
|
@ -41,6 +41,10 @@
|
|||||||
|
|
||||||
#include "sdkconfig.h" // for KConfig options
|
#include "sdkconfig.h" // for KConfig options
|
||||||
|
|
||||||
|
#if __has_include("esp_idf_version.h")
|
||||||
|
#include "esp_idf_version.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
@ -73,6 +77,15 @@ PR_BEGIN_EXTERN_C
|
|||||||
#error "None of Modbus communication mode is enabled. Please enable one of (ASCII, RTU, TCP) mode in Kconfig."
|
#error "None of Modbus communication mode is enabled. Please enable one of (ASCII, RTU, TCP) mode in Kconfig."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ESP_IDF_VERSION
|
||||||
|
|
||||||
|
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0))
|
||||||
|
// Features supported from 4.4
|
||||||
|
#define MB_TIMER_SUPPORTS_ISR_DISPATCH_METHOD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \brief This option defines the number of data bits per ASCII character.
|
/*! \brief This option defines the number of data bits per ASCII character.
|
||||||
*
|
*
|
||||||
* A parity bit is added before the stop bit which keeps the actual byte size at 10 bits.
|
* A parity bit is added before the stop bit which keeps the actual byte size at 10 bits.
|
||||||
|
@ -145,6 +145,10 @@ BOOL xMBPortSerialGetByte( CHAR * pucByte );
|
|||||||
|
|
||||||
BOOL xMBPortSerialPutByte( CHAR ucByte );
|
BOOL xMBPortSerialPutByte( CHAR ucByte );
|
||||||
|
|
||||||
|
BOOL xMBSerialPortGetRequest( UCHAR **ppucMBSerialFrame, USHORT * pusSerialLength ) __attribute__ ((weak));
|
||||||
|
|
||||||
|
BOOL xMBSerialPortSendResponse( UCHAR *pucMBSerialFrame, USHORT usSerialLength ) __attribute__ ((weak));
|
||||||
|
|
||||||
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED
|
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED
|
||||||
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
||||||
UCHAR ucDataBits, eMBParity eParity );
|
UCHAR ucDataBits, eMBParity eParity );
|
||||||
@ -158,6 +162,11 @@ void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
|
|||||||
BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
|
BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
|
||||||
|
|
||||||
BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
|
BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
|
||||||
|
|
||||||
|
BOOL xMBMasterSerialPortGetResponse( UCHAR **ppucMBSerialFrame, USHORT * usSerialLength );
|
||||||
|
|
||||||
|
BOOL xMBMasterSerialPortSendRequest( UCHAR *pucMBSerialFrame, USHORT usSerialLength );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------------- Timers functions ---------------------------------*/
|
/* ----------------------- Timers functions ---------------------------------*/
|
||||||
|
@ -70,18 +70,18 @@
|
|||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
|
|
||||||
static UCHAR ucMBMasterDestAddress;
|
static UCHAR ucMBMasterDestAddress;
|
||||||
static BOOL xMBRunInMasterMode = FALSE;
|
static BOOL xMBRunInMasterMode = FALSE;
|
||||||
static volatile eMBMasterErrorEventType eMBMasterCurErrorType;
|
static volatile eMBMasterErrorEventType eMBMasterCurErrorType;
|
||||||
static volatile USHORT usMasterSendPDULength;
|
static volatile USHORT usMasterSendPDULength;
|
||||||
static volatile eMBMode eMBMasterCurrentMode;
|
static volatile eMBMode eMBMasterCurrentMode;
|
||||||
|
|
||||||
/*------------------------ Shared variables ---------------------------------*/
|
/*------------------------ Shared variables ---------------------------------*/
|
||||||
|
|
||||||
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
||||||
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
|
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
|
||||||
volatile eMBMasterTimerMode eMasterCurTimerMode;
|
volatile eMBMasterTimerMode eMasterCurTimerMode;
|
||||||
volatile BOOL xFrameIsBroadcast = FALSE;
|
volatile BOOL xFrameIsBroadcast = FALSE;
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
@ -152,7 +152,7 @@ static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
#if MB_MASTER_TCP_ENABLED > 0
|
#if MB_MASTER_TCP_ENABLED
|
||||||
eMBErrorCode
|
eMBErrorCode
|
||||||
eMBMasterTCPInit( USHORT ucTCPPort )
|
eMBMasterTCPInit( USHORT ucTCPPort )
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "mbconfig.h"
|
#include "mbconfig.h"
|
||||||
|
|
||||||
#if MB_MASTER_RTU_ENABLED || MB_SLAVE_RTU_ENABLED
|
#if (MB_MASTER_RTU_ENABLED || MB_SLAVE_RTU_ENABLED || CONFIG_MB_UTEST)
|
||||||
|
|
||||||
static const UCHAR aucCRCHi[] = {
|
static const UCHAR aucCRCHi[] = {
|
||||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||||
|
@ -155,26 +155,33 @@ eMBErrorCode
|
|||||||
eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
||||||
{
|
{
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
|
UCHAR *pucMBRTUFrame = ( UCHAR* ) ucRTUBuf;
|
||||||
|
USHORT usFrameLength = usRcvBufferPos;
|
||||||
|
|
||||||
|
if( xMBSerialPortGetRequest( &pucMBRTUFrame, &usFrameLength ) == FALSE )
|
||||||
|
{
|
||||||
|
return MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
|
||||||
|
|
||||||
/* Length and CRC check */
|
/* Length and CRC check */
|
||||||
if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
|
if( ( usFrameLength >= MB_SER_PDU_SIZE_MIN )
|
||||||
&& ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
|
&& ( usMBCRC16( ( UCHAR * ) pucMBRTUFrame, usFrameLength ) == 0 ) )
|
||||||
{
|
{
|
||||||
/* Save the address field. All frames are passed to the upper layed
|
/* Save the address field. All frames are passed to the upper layed
|
||||||
* and the decision if a frame is used is done there.
|
* and the decision if a frame is used is done there.
|
||||||
*/
|
*/
|
||||||
*pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];
|
*pucRcvAddress = pucMBRTUFrame[MB_SER_PDU_ADDR_OFF];
|
||||||
|
|
||||||
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
||||||
* size of address field and CRC checksum.
|
* size of address field and CRC checksum.
|
||||||
*/
|
*/
|
||||||
*pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
*pusLength = ( USHORT )( usFrameLength - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
||||||
|
|
||||||
/* Return the start of the Modbus PDU to the caller. */
|
/* Return the start of the Modbus PDU to the caller. */
|
||||||
*pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
|
*pucFrame = ( UCHAR * ) & pucMBRTUFrame[MB_SER_PDU_PDU_OFF];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -191,14 +198,13 @@ eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
|||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
USHORT usCRC16;
|
USHORT usCRC16;
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
|
||||||
|
|
||||||
/* Check if the receiver is still in idle state. If not we where to
|
/* Check if the receiver is still in idle state. If not we where to
|
||||||
* slow with processing the received frame and the master sent another
|
* slow with processing the received frame and the master sent another
|
||||||
* frame on the network. We have to abort sending the frame.
|
* frame on the network. We have to abort sending the frame.
|
||||||
*/
|
*/
|
||||||
if( eRcvState == STATE_RX_IDLE )
|
if( eRcvState == STATE_RX_IDLE )
|
||||||
{
|
{
|
||||||
|
ENTER_CRITICAL_SECTION( );
|
||||||
/* First byte before the Modbus-PDU is the slave address. */
|
/* First byte before the Modbus-PDU is the slave address. */
|
||||||
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
||||||
usSndBufferCount = 1;
|
usSndBufferCount = 1;
|
||||||
@ -214,13 +220,19 @@ eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
|||||||
|
|
||||||
/* Activate the transmitter. */
|
/* Activate the transmitter. */
|
||||||
eSndState = STATE_TX_XMIT;
|
eSndState = STATE_TX_XMIT;
|
||||||
|
EXIT_CRITICAL_SECTION( );
|
||||||
|
|
||||||
|
if( xMBSerialPortSendResponse( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ) == FALSE )
|
||||||
|
{
|
||||||
|
eStatus = MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
vMBPortSerialEnable( FALSE, TRUE );
|
vMBPortSerialEnable( FALSE, TRUE );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
}
|
}
|
||||||
EXIT_CRITICAL_SECTION( );
|
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +284,7 @@ xMBRTUReceiveFSM( void )
|
|||||||
case STATE_RX_RCV:
|
case STATE_RX_RCV:
|
||||||
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
||||||
{
|
{
|
||||||
if ( xStatus ) {
|
if( xStatus ) {
|
||||||
ucRTUBuf[usRcvBufferPos++] = ucByte;
|
ucRTUBuf[usRcvBufferPos++] = ucByte;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,26 +161,34 @@ eMBErrorCode
|
|||||||
eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
||||||
{
|
{
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
|
UCHAR *pucMBRTUFrame = ( UCHAR* ) ucMasterRTURcvBuf;
|
||||||
|
USHORT usFrameLength = usMasterRcvBufferPos;
|
||||||
|
|
||||||
|
if( xMBMasterSerialPortGetResponse( &pucMBRTUFrame, &usFrameLength ) == FALSE )
|
||||||
|
{
|
||||||
|
return MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
assert( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
|
||||||
|
assert( pucMBRTUFrame );
|
||||||
|
|
||||||
/* Length and CRC check */
|
/* Length and CRC check */
|
||||||
if( ( usMasterRcvBufferPos >= MB_RTU_SER_PDU_SIZE_MIN )
|
if( ( usFrameLength >= MB_RTU_SER_PDU_SIZE_MIN )
|
||||||
&& ( usMBCRC16( ( UCHAR * ) ucMasterRTURcvBuf, usMasterRcvBufferPos ) == 0 ) )
|
&& ( usMBCRC16( ( UCHAR * ) pucMBRTUFrame, usFrameLength ) == 0 ) )
|
||||||
{
|
{
|
||||||
/* Save the address field. All frames are passed to the upper layed
|
/* Save the address field. All frames are passed to the upper layer
|
||||||
* and the decision if a frame is used is done there.
|
* and the decision if a frame is used is done there.
|
||||||
*/
|
*/
|
||||||
*pucRcvAddress = ucMasterRTURcvBuf[MB_SER_PDU_ADDR_OFF];
|
*pucRcvAddress = pucMBRTUFrame[MB_SER_PDU_ADDR_OFF];
|
||||||
|
|
||||||
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
||||||
* size of address field and CRC checksum.
|
* size of address field and CRC checksum.
|
||||||
*/
|
*/
|
||||||
*pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
*pusLength = ( USHORT )( usFrameLength - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
||||||
|
|
||||||
/* Return the start of the Modbus PDU to the caller. */
|
/* Return the start of the Modbus PDU to the caller. */
|
||||||
*pucFrame = ( UCHAR * ) & ucMasterRTURcvBuf[MB_SER_PDU_PDU_OFF];
|
*pucFrame = ( UCHAR * ) & pucMBRTUFrame[MB_SER_PDU_PDU_OFF];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -199,14 +207,13 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
|
|||||||
|
|
||||||
if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
|
if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
|
||||||
|
|
||||||
ENTER_CRITICAL_SECTION( );
|
|
||||||
|
|
||||||
/* Check if the receiver is still in idle state. If not we where to
|
/* Check if the receiver is still in idle state. If not we where to
|
||||||
* slow with processing the received frame and the master sent another
|
* slow with processing the received frame and the master sent another
|
||||||
* frame on the network. We have to abort sending the frame.
|
* frame on the network. We have to abort sending the frame.
|
||||||
*/
|
*/
|
||||||
if( eRcvState == STATE_M_RX_IDLE )
|
if( eRcvState == STATE_M_RX_IDLE )
|
||||||
{
|
{
|
||||||
|
ENTER_CRITICAL_SECTION( );
|
||||||
/* First byte before the Modbus-PDU is the slave address. */
|
/* First byte before the Modbus-PDU is the slave address. */
|
||||||
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
||||||
usMasterSndBufferCount = 1;
|
usMasterSndBufferCount = 1;
|
||||||
@ -217,11 +224,18 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
|
|||||||
|
|
||||||
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
|
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
|
||||||
usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
|
usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
|
||||||
ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
|
pucMasterSndBufferCur[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
|
||||||
ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
|
pucMasterSndBufferCur[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
|
||||||
|
EXIT_CRITICAL_SECTION( );
|
||||||
|
|
||||||
/* Activate the transmitter. */
|
/* Activate the transmitter. */
|
||||||
eSndState = STATE_M_TX_XMIT;
|
eSndState = STATE_M_TX_XMIT;
|
||||||
|
|
||||||
|
if ( xMBMasterSerialPortSendRequest( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount ) == FALSE )
|
||||||
|
{
|
||||||
|
eStatus = MB_EIO;
|
||||||
|
}
|
||||||
|
|
||||||
// The place to enable RS485 driver
|
// The place to enable RS485 driver
|
||||||
vMBMasterPortSerialEnable( FALSE, TRUE );
|
vMBMasterPortSerialEnable( FALSE, TRUE );
|
||||||
}
|
}
|
||||||
@ -229,7 +243,6 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
|
|||||||
{
|
{
|
||||||
eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
}
|
}
|
||||||
EXIT_CRITICAL_SECTION( );
|
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,11 +286,15 @@ xMBMasterRTUReceiveFSM( void )
|
|||||||
eSndState = STATE_M_TX_IDLE;
|
eSndState = STATE_M_TX_IDLE;
|
||||||
|
|
||||||
usMasterRcvBufferPos = 0;
|
usMasterRcvBufferPos = 0;
|
||||||
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
|
if( xStatus && ucByte ) {
|
||||||
eRcvState = STATE_M_RX_RCV;
|
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
|
||||||
|
eRcvState = STATE_M_RX_RCV;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable t3.5 timers. */
|
/* Enable t3.5 timers. */
|
||||||
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
vMBMasterPortTimersT35Enable( );
|
vMBMasterPortTimersT35Enable( );
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* We are currently receiving a frame. Reset the timer after
|
/* We are currently receiving a frame. Reset the timer after
|
||||||
@ -296,7 +313,9 @@ xMBMasterRTUReceiveFSM( void )
|
|||||||
{
|
{
|
||||||
eRcvState = STATE_M_RX_ERROR;
|
eRcvState = STATE_M_RX_ERROR;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
vMBMasterPortTimersT35Enable( );
|
vMBMasterPortTimersT35Enable( );
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return xStatus;
|
return xStatus;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
#include "sys/lock.h"
|
#include "sys/lock.h"
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
@ -72,6 +73,13 @@ vMBPortSetMode( UCHAR ucMode )
|
|||||||
EXIT_CRITICAL_SECTION();
|
EXIT_CRITICAL_SECTION();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL xMBPortSerialWaitEvent(QueueHandle_t xMbUartQueue, uart_event_t* pxEvent, ULONG xTimeout)
|
||||||
|
{
|
||||||
|
BOOL xResult = (BaseType_t)xQueueReceive(xMbUartQueue, (void*)pxEvent, (TickType_t) xTimeout);
|
||||||
|
ESP_LOGD(__func__, "UART event: %d ", pxEvent->type);
|
||||||
|
return xResult;
|
||||||
|
}
|
||||||
|
|
||||||
#if MB_TCP_DEBUG
|
#if MB_TCP_DEBUG
|
||||||
|
|
||||||
// This function is kept to realize legacy freemodbus frame logging functionality
|
// This function is kept to realize legacy freemodbus frame logging functionality
|
||||||
|
@ -38,8 +38,18 @@
|
|||||||
#define PORT_COMMON_H_
|
#define PORT_COMMON_H_
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h" // for queue
|
||||||
|
|
||||||
#include "esp_log.h" // for ESP_LOGE macro
|
#include "esp_log.h" // for ESP_LOGE macro
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
|
#include "driver/uart.h" // for uart_event_t
|
||||||
|
|
||||||
|
#if __has_include("driver/gptimer.h")
|
||||||
|
#include "driver/gptimer.h"
|
||||||
|
#else
|
||||||
|
#include "driver/timer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mbconfig.h"
|
#include "mbconfig.h"
|
||||||
|
|
||||||
#define INLINE inline
|
#define INLINE inline
|
||||||
@ -174,6 +184,8 @@ void prvvMBTCPLogFrame( const CHAR * pucMsg, UCHAR * pucFrame, USHORT usFrameLen
|
|||||||
void vMBPortSetMode( UCHAR ucMode );
|
void vMBPortSetMode( UCHAR ucMode );
|
||||||
UCHAR ucMBPortGetMode( void );
|
UCHAR ucMBPortGetMode( void );
|
||||||
|
|
||||||
|
BOOL xMBPortSerialWaitEvent(QueueHandle_t xMbUartQueue, uart_event_t* pxEvent, ULONG xTimeout);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
*
|
*
|
||||||
* File: $Id: portother.c,v 1.1 2010/06/06 13:07:20 wolti Exp $
|
* File: $Id: portother.c,v 1.1 2010/06/06 13:07:20 wolti Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "driver/uart.h"
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "freertos/queue.h" // for queue support
|
#include "freertos/queue.h" // for queue support
|
||||||
@ -85,15 +87,14 @@ static USHORT usMBPortSerialRxPoll(size_t xEventSize)
|
|||||||
|
|
||||||
if (bRxStateEnabled) {
|
if (bRxStateEnabled) {
|
||||||
// Get received packet into Rx buffer
|
// Get received packet into Rx buffer
|
||||||
while(xReadStatus && (usCnt++ <= MB_SERIAL_BUF_SIZE)) {
|
while(xReadStatus && (usCnt++ <= xEventSize)) {
|
||||||
// Call the Modbus stack callback function and let it fill the buffers.
|
// Call the Modbus stack callback function and let it fill the buffers.
|
||||||
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM
|
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM
|
||||||
}
|
}
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(ucUartNumber);
|
||||||
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
||||||
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
// Let the stack know that T3.5 time is expired and data is received
|
pxMBPortCBTimerExpired();
|
||||||
(void)pxMBPortCBTimerExpired(); // calls callback xMBRTUTimerT35Expired();
|
|
||||||
#endif
|
#endif
|
||||||
ESP_LOGD(TAG, "RX: %d bytes\n", usCnt);
|
ESP_LOGD(TAG, "RX: %d bytes\n", usCnt);
|
||||||
}
|
}
|
||||||
@ -126,7 +127,7 @@ static void vUartTask(void *pvParameters)
|
|||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
USHORT usResult = 0;
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receving data
|
//Event of UART receving data
|
||||||
@ -135,6 +136,8 @@ static void vUartTask(void *pvParameters)
|
|||||||
// This flag set in the event means that no more
|
// This flag set in the event means that no more
|
||||||
// data received during configured timeout and UART TOUT feature is triggered
|
// data received during configured timeout and UART TOUT feature is triggered
|
||||||
if (xEvent.timeout_flag) {
|
if (xEvent.timeout_flag) {
|
||||||
|
// Get buffered data length
|
||||||
|
ESP_ERROR_CHECK(uart_get_buffered_data_len(ucUartNumber, &xEvent.size));
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
usResult = usMBPortSerialRxPoll(xEvent.size);
|
usResult = usMBPortSerialRxPoll(xEvent.size);
|
||||||
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
@ -219,7 +222,7 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
|
|||||||
.stop_bits = UART_STOP_BITS_1,
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||||
.rx_flow_ctrl_thresh = 2,
|
.rx_flow_ctrl_thresh = 2,
|
||||||
.source_clk = UART_SCLK_APB,
|
.source_clk = UART_SCLK_APB
|
||||||
};
|
};
|
||||||
// Set UART config
|
// Set UART config
|
||||||
xErr = uart_param_config(ucUartNumber, &xUartConfig);
|
xErr = uart_param_config(ucUartNumber, &xUartConfig);
|
||||||
@ -257,6 +260,17 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL xMBSerialPortGetRequest( UCHAR **ppucMBSerialFrame, USHORT * usSerialLength )
|
||||||
|
{
|
||||||
|
BOOL eStatus = TRUE;
|
||||||
|
return eStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL xMBSerialPortSendResponse( UCHAR *pucMBSerialFrame, USHORT usSerialLength )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void vMBPortSerialClose(void)
|
void vMBPortSerialClose(void)
|
||||||
{
|
{
|
||||||
(void)vTaskSuspend(xMbTaskHandle);
|
(void)vTaskSuspend(xMbTaskHandle);
|
||||||
|
@ -89,7 +89,7 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
|
|||||||
USHORT usCnt = 0;
|
USHORT usCnt = 0;
|
||||||
|
|
||||||
if (bRxStateEnabled) {
|
if (bRxStateEnabled) {
|
||||||
while(xReadStatus && (usCnt++ <= MB_SERIAL_BUF_SIZE)) {
|
while(xReadStatus && (usCnt++ <= xEventSize)) {
|
||||||
// Call the Modbus stack callback function and let it fill the stack buffers.
|
// Call the Modbus stack callback function and let it fill the stack buffers.
|
||||||
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
|
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ static void vUartTask(void* pvParameters)
|
|||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
USHORT usResult = 0;
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receiving data
|
//Event of UART receiving data
|
||||||
@ -143,6 +143,8 @@ static void vUartTask(void* pvParameters)
|
|||||||
// This flag set in the event means that no more
|
// This flag set in the event means that no more
|
||||||
// data received during configured timeout and UART TOUT feature is triggered
|
// data received during configured timeout and UART TOUT feature is triggered
|
||||||
if (xEvent.timeout_flag) {
|
if (xEvent.timeout_flag) {
|
||||||
|
// Get buffered data length
|
||||||
|
ESP_ERROR_CHECK(uart_get_buffered_data_len(ucUartNumber, &xEvent.size));
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
|
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
|
||||||
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
@ -266,6 +268,24 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The function is called from ASCII/RTU module to get processed data buffer. Sets the
|
||||||
|
* received buffer and its length using parameters.
|
||||||
|
*/
|
||||||
|
BOOL xMBMasterSerialPortGetResponse( UCHAR **ppucMBSerialFrame, USHORT * usSerialLength )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The function is called from ASCII/RTU module to set processed data buffer
|
||||||
|
* to be sent in transmitter state machine.
|
||||||
|
*/
|
||||||
|
BOOL xMBMasterSerialPortSendRequest( UCHAR *pucMBSerialFrame, USHORT usSerialLength )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void vMBMasterPortSerialClose(void)
|
void vMBMasterPortSerialClose(void)
|
||||||
{
|
{
|
||||||
(void)vTaskDelete(xMbTaskHandle);
|
(void)vTaskDelete(xMbTaskHandle);
|
||||||
|
@ -74,7 +74,7 @@ BOOL xMBPortTimersInit(USHORT usTimeOut50us)
|
|||||||
esp_timer_create_args_t xTimerConf = {
|
esp_timer_create_args_t xTimerConf = {
|
||||||
.callback = vTimerAlarmCBHandler,
|
.callback = vTimerAlarmCBHandler,
|
||||||
.arg = NULL,
|
.arg = NULL,
|
||||||
#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
|
#if (MB_TIMER_SUPPORTS_ISR_DISPATCH_METHOD && CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD)
|
||||||
.dispatch_method = ESP_TIMER_ISR,
|
.dispatch_method = ESP_TIMER_ISR,
|
||||||
#else
|
#else
|
||||||
.dispatch_method = ESP_TIMER_TASK,
|
.dispatch_method = ESP_TIMER_TASK,
|
||||||
|
@ -71,7 +71,7 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
|
|||||||
esp_timer_create_args_t xTimerConf = {
|
esp_timer_create_args_t xTimerConf = {
|
||||||
.callback = vTimerAlarmCBHandler,
|
.callback = vTimerAlarmCBHandler,
|
||||||
.arg = NULL,
|
.arg = NULL,
|
||||||
#if CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD
|
#if (MB_TIMER_SUPPORTS_ISR_DISPATCH_METHOD && CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD)
|
||||||
.dispatch_method = ESP_TIMER_ISR,
|
.dispatch_method = ESP_TIMER_ISR,
|
||||||
#else
|
#else
|
||||||
.dispatch_method = ESP_TIMER_TASK,
|
.dispatch_method = ESP_TIMER_TASK,
|
||||||
|
@ -30,7 +30,7 @@ extern BOOL xMBMasterPortSerialTxPoll(void);
|
|||||||
#define MB_RESPONSE_TICS pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND + 10)
|
#define MB_RESPONSE_TICS pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND + 10)
|
||||||
|
|
||||||
|
|
||||||
static mb_master_interface_t* mbm_interface_ptr = NULL; //&default_interface_inst;
|
static mb_master_interface_t* mbm_interface_ptr = NULL;
|
||||||
static const char *TAG = "MB_CONTROLLER_MASTER";
|
static const char *TAG = "MB_CONTROLLER_MASTER";
|
||||||
|
|
||||||
// Modbus event processing task
|
// Modbus event processing task
|
||||||
@ -101,7 +101,7 @@ static esp_err_t mbc_serial_master_start(void)
|
|||||||
"mb stack initialization failure, eMBInit() returns (0x%x).", status);
|
"mb stack initialization failure, eMBInit() returns (0x%x).", status);
|
||||||
status = eMBMasterEnable();
|
status = eMBMasterEnable();
|
||||||
MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
|
MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
|
||||||
"mb stack set slave ID failure, eMBEnable() returned (0x%x).", (uint32_t)status);
|
"mb stack set slave ID failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status);
|
||||||
// Set the mbcontroller start flag
|
// Set the mbcontroller start flag
|
||||||
EventBits_t flag = xEventGroupSetBits(mbm_opts->mbm_event_group,
|
EventBits_t flag = xEventGroupSetBits(mbm_opts->mbm_event_group,
|
||||||
(EventBits_t)MB_EVENT_STACK_STARTED);
|
(EventBits_t)MB_EVENT_STACK_STARTED);
|
||||||
|
@ -159,7 +159,7 @@ static esp_err_t mbc_tcp_master_start(void)
|
|||||||
|
|
||||||
status = eMBMasterEnable();
|
status = eMBMasterEnable();
|
||||||
MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
|
MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
|
||||||
"mb stack set slave ID failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status);
|
"mb stack enable failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status);
|
||||||
|
|
||||||
// Add slave IP address for each slave to initialize connection
|
// Add slave IP address for each slave to initialize connection
|
||||||
mb_slave_addr_entry_t *p_slave_info;
|
mb_slave_addr_entry_t *p_slave_info;
|
||||||
@ -172,13 +172,12 @@ static esp_err_t mbc_tcp_master_start(void)
|
|||||||
// Add end of list condition
|
// Add end of list condition
|
||||||
(void)xMBTCPPortMasterAddSlaveIp(0xFF, NULL, 0xFF);
|
(void)xMBTCPPortMasterAddSlaveIp(0xFF, NULL, 0xFF);
|
||||||
|
|
||||||
|
|
||||||
// Wait for connection done event
|
// Wait for connection done event
|
||||||
bool start = (bool)xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group,
|
bool start = (bool)xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group,
|
||||||
(EventBits_t)MB_EVENT_STACK_STARTED, MB_TCP_CONNECTION_TOUT);
|
(EventBits_t)MB_EVENT_STACK_STARTED, MB_TCP_CONNECTION_TOUT);
|
||||||
MB_MASTER_CHECK((start), ESP_ERR_INVALID_STATE,
|
MB_MASTER_CHECK((start), ESP_ERR_INVALID_STATE,
|
||||||
"mb stack could not connect to slaves for %d seconds.",
|
"mb stack could not connect to slaves for %d seconds.",
|
||||||
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC);
|
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,6 +560,12 @@ static void vMBTCPPortServerTask(void *pvParameters)
|
|||||||
pxClientInfo->xSockId, pxClientInfo->pcIpAddr, xErr);
|
pxClientInfo->xSockId, pxClientInfo->pcIpAddr, xErr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xShutdownSemaphore) {
|
||||||
|
xSemaphoreGive(xShutdownSemaphore);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Close client connection
|
// Close client connection
|
||||||
xMBTCPPortCloseConnection(pxClientInfo);
|
xMBTCPPortCloseConnection(pxClientInfo);
|
||||||
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
version: "0.1.0"
|
version: "0.0.2"
|
||||||
description: ESP-MODBUS is the official Modbus library for Espressif SoCs.
|
description: ESP-MODBUS is the official Modbus library for Espressif SoCs.
|
||||||
dependencies:
|
dependencies:
|
||||||
idf: ">=4.1"
|
idf: ">=4.1"
|
||||||
|
files:
|
||||||
|
exclude:
|
||||||
|
- "docs/_build/**/*"
|
||||||
|
- "docs/_build"
|
||||||
|
- "test/**/build/**/*"
|
||||||
|
- "test/**/build"
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
# Test Apps
|
# Test implementation
|
||||||
|
|
||||||
This directory contains a set of ESP-IDF projects to be used as tests only, which aim to exercise various
|
This directory contains a set of ESP-IDF projects to be used as tests only, which aim to exercise various
|
||||||
configuration of components to check completely arbitrary functionality should it be building only, executing under
|
configuration of components to check completely arbitrary functionality should it be building only, executing under
|
||||||
various conditions or combination with other components, including custom test frameworks.
|
various conditions or combination with other components, including custom test frameworks.
|
||||||
|
|
||||||
The test apps are not intended to demonstrate the ESP-IDF functionality in any way.
|
The tests in this folder are not intended to demonstrate the ESP-IDF functionality in any way.
|
||||||
|
|
||||||
|
The examples can be found here: https://github.com/espressif/esp-idf/tree/master/examples/protocols/modbus
|
||||||
|
@ -2,5 +2,4 @@
|
|||||||
# CMakeLists in this exact order for cmake to work correctly
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
idf_component_register(SRCS "modbus_params.c"
|
idf_component_register(SRCS "modbus_params.c"
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include")
|
||||||
PRIV_REQUIRES esp-modbus)
|
|
||||||
|
@ -3,10 +3,8 @@
|
|||||||
#
|
#
|
||||||
CONFIG_MB_COMM_MODE_ASCII=y
|
CONFIG_MB_COMM_MODE_ASCII=y
|
||||||
CONFIG_MB_UART_BAUD_RATE=115200
|
CONFIG_MB_UART_BAUD_RATE=115200
|
||||||
CONFIG_FMB_TIMER_PORT_ENABLED=y
|
CONFIG_FMB_TIMER_PORT_ENABLED=n
|
||||||
CONFIG_FMB_TIMER_GROUP=0
|
|
||||||
CONFIG_FMB_TIMER_INDEX=0
|
|
||||||
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
||||||
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
|
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
|
||||||
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
|
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=400
|
||||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
idf:
|
|
||||||
component_hash: null
|
|
||||||
source:
|
|
||||||
type: idf
|
|
||||||
version: 5.0.0
|
|
||||||
manifest_hash: ef92ef397dcb09fa7a851b483306296fee18dfca839e1a68e8190dad2ed66a64
|
|
||||||
target: esp32
|
|
||||||
version: 1.0.0
|
|
@ -4,8 +4,6 @@
|
|||||||
CONFIG_MB_COMM_MODE_ASCII=y
|
CONFIG_MB_COMM_MODE_ASCII=y
|
||||||
CONFIG_MB_SLAVE_ADDR=1
|
CONFIG_MB_SLAVE_ADDR=1
|
||||||
CONFIG_MB_UART_BAUD_RATE=115200
|
CONFIG_MB_UART_BAUD_RATE=115200
|
||||||
CONFIG_FMB_TIMER_PORT_ENABLED=y
|
CONFIG_FMB_TIMER_PORT_ENABLED=n
|
||||||
CONFIG_FMB_TIMER_GROUP=0
|
|
||||||
CONFIG_FMB_TIMER_INDEX=0
|
|
||||||
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
|
||||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||||
|
Reference in New Issue
Block a user