esp-modbus: make modbus files idf independent

This commit is contained in:
aleks
2022-03-11 11:42:19 +01:00
parent 811f251496
commit 6b5430a18f
25 changed files with 228 additions and 97 deletions

View File

@ -9,6 +9,7 @@
#include <stdint.h> // for standard int types definition
#include <stddef.h> // for NULL and std defines
#include "soc/soc.h" // for BITN definitions
#include "esp_modbus_common.h" // for common types
#ifdef __cplusplus

View File

@ -10,6 +10,7 @@
// Public interface header for slave
#include <stdint.h> // for standard int types definition
#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/event_groups.h" // for event groups
#include "esp_modbus_common.h" // for common types

View File

@ -151,26 +151,33 @@ eMBErrorCode
eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
{
eMBErrorCode eStatus = MB_ENOERR;
UCHAR *pucMBASCIIFrame = ( UCHAR* ) ucASCIIBuf;
USHORT usFrameLength = usRcvBufferPos;
if( xMBSerialPortGetRequest( &pucMBASCIIFrame, &usFrameLength ) == FALSE )
{
return MB_EIO;
}
ENTER_CRITICAL_SECTION( );
assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
/* Length and CRC check */
if( ( usRcvBufferPos >= MB_ASCII_SER_PDU_SIZE_MIN )
&& ( prvucMBLRC( ( UCHAR * ) ucASCIIBuf, usRcvBufferPos ) == 0 ) )
if( ( usFrameLength >= MB_ASCII_SER_PDU_SIZE_MIN )
&& ( prvucMBLRC( ( UCHAR * ) pucMBASCIIFrame, usFrameLength ) == 0 ) )
{
/* Save the address field. All frames are passed to the upper layed
* 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
* 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. */
*pucFrame = ( UCHAR * ) & ucASCIIBuf[MB_SER_PDU_PDU_OFF];
*pucFrame = ( UCHAR * ) & pucMBASCIIFrame[MB_SER_PDU_PDU_OFF];
}
else
{
@ -186,13 +193,14 @@ eMBASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
eMBErrorCode eStatus = MB_ENOERR;
UCHAR usLRC;
ENTER_CRITICAL_SECTION( );
/* 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
* frame on the network. We have to abort sending the frame.
*/
if( eRcvState == STATE_RX_IDLE )
{
ENTER_CRITICAL_SECTION( );
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
usSndBufferCount = 1;
@ -207,6 +215,13 @@ eMBASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
/* Activate the transmitter. */
eSndState = STATE_TX_START;
EXIT_CRITICAL_SECTION( );
if ( xMBSerialPortSendResponse( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ) == FALSE )
{
eStatus = MB_EIO;
}
vMBPortSerialEnable( FALSE, TRUE );
}
else

View File

@ -154,29 +154,34 @@ eMBErrorCode
eMBMasterASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
{
eMBErrorCode eStatus = MB_ENOERR;
UCHAR *pucMBASCIIFrame = ( UCHAR* ) ucMasterASCIIRcvBuf;
USHORT usFrameLength = usMasterRcvBufferPos;
if( xMBMasterSerialPortGetResponse( &pucMBASCIIFrame, &usFrameLength ) == FALSE )
{
return MB_EIO;
}
ENTER_CRITICAL_SECTION( );
assert( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX );
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
assert( pucMBASCIIFrame );
/* Length and CRC check */
if( ( usMasterRcvBufferPos >= MB_ASCII_SER_PDU_SIZE_MIN )
&& ( prvucMBLRC( ( UCHAR * ) ucMasterASCIIRcvBuf, usMasterRcvBufferPos ) == 0 ) )
if( ( usFrameLength >= MB_ASCII_SER_PDU_SIZE_MIN )
&& ( prvucMBLRC( ( UCHAR * ) pucMBASCIIFrame, usFrameLength ) == 0 ) )
{
/* Save the address field. All frames are passed to the upper layed
* and the decision if a frame is used is done there.
*/
*pucRcvAddress = ucMasterASCIIRcvBuf[MB_SER_PDU_ADDR_OFF];
* and the decision if a frame is used is done there.
*/
*pucRcvAddress = pucMBASCIIFrame[MB_SER_PDU_ADDR_OFF];
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
* size of address field and CRC checksum.
*/
*pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
* size of address field and CRC checksum.
*/
*pusLength = ( USHORT )( usFrameLength - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
/* Return the start of the Modbus PDU to the caller. */
*pucFrame = ( UCHAR * ) & ucMasterASCIIRcvBuf[MB_SER_PDU_PDU_OFF];
}
else
{
/* Return the start of the Modbus PDU to the caller. */
*pucFrame = ( UCHAR * ) & pucMBASCIIFrame[MB_SER_PDU_PDU_OFF];
} else {
eStatus = MB_EIO;
}
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;
ENTER_CRITICAL_SECTION( );
/* 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
* frame on the network. We have to abort sending the frame.
*/
if(eRcvState == STATE_M_RX_IDLE)
{
ENTER_CRITICAL_SECTION( );
/* First byte before the Modbus-PDU is the slave address. */
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
usMasterSndBufferCount = 1;
@ -208,17 +213,22 @@ eMBMasterASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLengt
/* Calculate LRC checksum for Modbus-Serial-Line-PDU. */
usLRC = prvucMBLRC( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
ucMasterASCIISndBuf[usMasterSndBufferCount++] = usLRC;
pucMasterSndBufferCur[usMasterSndBufferCount++] = usLRC;
/* Activate the transmitter. */
eSndState = STATE_M_TX_START;
EXIT_CRITICAL_SECTION( );
if ( xMBMasterSerialPortSendRequest( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount ) == FALSE )
{
eStatus = MB_EIO;
}
vMBMasterPortSerialEnable( FALSE, TRUE );
}
else
{
eStatus = MB_EIO;
}
EXIT_CRITICAL_SECTION( );
return eStatus;
}
@ -447,7 +457,7 @@ xMBMasterASCIITransmitFSM( void )
return xNeedPoll;
}
BOOL
BOOL MB_PORT_ISR_ATTR
xMBMasterASCIITimerT1SExpired( void )
{
BOOL xNeedPoll = FALSE;
@ -457,7 +467,6 @@ xMBMasterASCIITimerT1SExpired( void )
/* Timer t35 expired. Startup phase is finished. */
case STATE_M_RX_INIT:
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
ESP_EARLY_LOGI("xMBMasterASCIITimerT1SExpired", "RX_INIT_EXPIRED");
break;
/* Start of message is not received during respond timeout.

View File

@ -41,6 +41,10 @@
#include "sdkconfig.h" // for KConfig options
#if __has_include("esp_idf_version.h")
#include "esp_idf_version.h"
#endif
#ifdef __cplusplus
PR_BEGIN_EXTERN_C
#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."
#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.
*
* A parity bit is added before the stop bit which keeps the actual byte size at 10 bits.

View File

@ -145,6 +145,10 @@ BOOL xMBPortSerialGetByte( CHAR * pucByte );
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
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
UCHAR ucDataBits, eMBParity eParity );
@ -158,6 +162,11 @@ void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
BOOL xMBMasterSerialPortGetResponse( UCHAR **ppucMBSerialFrame, USHORT * usSerialLength );
BOOL xMBMasterSerialPortSendRequest( UCHAR *pucMBSerialFrame, USHORT usSerialLength );
#endif
/* ----------------------- Timers functions ---------------------------------*/

View File

@ -70,18 +70,18 @@
/* ----------------------- Static variables ---------------------------------*/
static UCHAR ucMBMasterDestAddress;
static BOOL xMBRunInMasterMode = FALSE;
static UCHAR ucMBMasterDestAddress;
static BOOL xMBRunInMasterMode = FALSE;
static volatile eMBMasterErrorEventType eMBMasterCurErrorType;
static volatile USHORT usMasterSendPDULength;
static volatile USHORT usMasterSendPDULength;
static volatile eMBMode eMBMasterCurrentMode;
/*------------------------ Shared variables ---------------------------------*/
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
volatile eMBMasterTimerMode eMasterCurTimerMode;
volatile BOOL xFrameIsBroadcast = FALSE;
volatile BOOL xFrameIsBroadcast = FALSE;
static enum
{
@ -152,7 +152,7 @@ static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
};
/* ----------------------- Start implementation -----------------------------*/
#if MB_MASTER_TCP_ENABLED > 0
#if MB_MASTER_TCP_ENABLED
eMBErrorCode
eMBMasterTCPInit( USHORT ucTCPPort )
{

View File

@ -39,7 +39,7 @@
#include "port.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[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

View File

@ -155,26 +155,33 @@ eMBErrorCode
eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
{
eMBErrorCode eStatus = MB_ENOERR;
UCHAR *pucMBRTUFrame = ( UCHAR* ) ucRTUBuf;
USHORT usFrameLength = usRcvBufferPos;
if( xMBSerialPortGetRequest( &pucMBRTUFrame, &usFrameLength ) == FALSE )
{
return MB_EIO;
}
ENTER_CRITICAL_SECTION( );
assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
/* Length and CRC check */
if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
&& ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
if( ( usFrameLength >= MB_SER_PDU_SIZE_MIN )
&& ( usMBCRC16( ( UCHAR * ) pucMBRTUFrame, usFrameLength ) == 0 ) )
{
/* Save the address field. All frames are passed to the upper layed
* 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
* 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. */
*pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
*pucFrame = ( UCHAR * ) & pucMBRTUFrame[MB_SER_PDU_PDU_OFF];
}
else
{
@ -191,14 +198,13 @@ eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
eMBErrorCode eStatus = MB_ENOERR;
USHORT usCRC16;
ENTER_CRITICAL_SECTION( );
/* 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
* frame on the network. We have to abort sending the frame.
*/
if( eRcvState == STATE_RX_IDLE )
{
ENTER_CRITICAL_SECTION( );
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
usSndBufferCount = 1;
@ -214,13 +220,19 @@ eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
/* Activate the transmitter. */
eSndState = STATE_TX_XMIT;
EXIT_CRITICAL_SECTION( );
if( xMBSerialPortSendResponse( ( UCHAR * ) pucSndBufferCur, usSndBufferCount ) == FALSE )
{
eStatus = MB_EIO;
}
vMBPortSerialEnable( FALSE, TRUE );
}
else
{
eStatus = MB_EIO;
}
EXIT_CRITICAL_SECTION( );
return eStatus;
}
@ -272,7 +284,7 @@ xMBRTUReceiveFSM( void )
case STATE_RX_RCV:
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
{
if ( xStatus ) {
if( xStatus ) {
ucRTUBuf[usRcvBufferPos++] = ucByte;
}
}

View File

@ -161,26 +161,34 @@ eMBErrorCode
eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
{
eMBErrorCode eStatus = MB_ENOERR;
UCHAR *pucMBRTUFrame = ( UCHAR* ) ucMasterRTURcvBuf;
USHORT usFrameLength = usMasterRcvBufferPos;
if( xMBMasterSerialPortGetResponse( &pucMBRTUFrame, &usFrameLength ) == FALSE )
{
return MB_EIO;
}
ENTER_CRITICAL_SECTION( );
assert( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX );
assert( usFrameLength < MB_SER_PDU_SIZE_MAX );
assert( pucMBRTUFrame );
/* Length and CRC check */
if( ( usMasterRcvBufferPos >= MB_RTU_SER_PDU_SIZE_MIN )
&& ( usMBCRC16( ( UCHAR * ) ucMasterRTURcvBuf, usMasterRcvBufferPos ) == 0 ) )
if( ( usFrameLength >= MB_RTU_SER_PDU_SIZE_MIN )
&& ( 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.
*/
*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
* 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. */
*pucFrame = ( UCHAR * ) & ucMasterRTURcvBuf[MB_SER_PDU_PDU_OFF];
*pucFrame = ( UCHAR * ) & pucMBRTUFrame[MB_SER_PDU_PDU_OFF];
}
else
{
@ -199,14 +207,13 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
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
* slow with processing the received frame and the master sent another
* frame on the network. We have to abort sending the frame.
*/
if( eRcvState == STATE_M_RX_IDLE )
{
ENTER_CRITICAL_SECTION( );
/* First byte before the Modbus-PDU is the slave address. */
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
usMasterSndBufferCount = 1;
@ -217,11 +224,18 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
pucMasterSndBufferCur[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
pucMasterSndBufferCur[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
EXIT_CRITICAL_SECTION( );
/* Activate the transmitter. */
eSndState = STATE_M_TX_XMIT;
if ( xMBMasterSerialPortSendRequest( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount ) == FALSE )
{
eStatus = MB_EIO;
}
// The place to enable RS485 driver
vMBMasterPortSerialEnable( FALSE, TRUE );
}
@ -229,7 +243,6 @@ eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength
{
eStatus = MB_EIO;
}
EXIT_CRITICAL_SECTION( );
return eStatus;
}
@ -273,11 +286,15 @@ xMBMasterRTUReceiveFSM( void )
eSndState = STATE_M_TX_IDLE;
usMasterRcvBufferPos = 0;
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
eRcvState = STATE_M_RX_RCV;
if( xStatus && ucByte ) {
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
eRcvState = STATE_M_RX_RCV;
}
/* Enable t3.5 timers. */
#if CONFIG_FMB_TIMER_PORT_ENABLED
vMBMasterPortTimersT35Enable( );
#endif
break;
/* We are currently receiving a frame. Reset the timer after
@ -296,7 +313,9 @@ xMBMasterRTUReceiveFSM( void )
{
eRcvState = STATE_M_RX_ERROR;
}
#if CONFIG_FMB_TIMER_PORT_ENABLED
vMBMasterPortTimersT35Enable( );
#endif
break;
}
return xStatus;

View File

@ -38,6 +38,7 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "sys/lock.h"
#include "port.h"
@ -72,6 +73,13 @@ vMBPortSetMode( UCHAR ucMode )
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
// This function is kept to realize legacy freemodbus frame logging functionality

View File

@ -38,8 +38,18 @@
#define PORT_COMMON_H_
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h" // for queue
#include "esp_log.h" // for ESP_LOGE macro
#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"
#define INLINE inline
@ -174,6 +184,8 @@ void prvvMBTCPLogFrame( const CHAR * pucMsg, UCHAR * pucFrame, USHORT usFrameLen
void vMBPortSetMode( UCHAR ucMode );
UCHAR ucMBPortGetMode( void );
BOOL xMBPortSerialWaitEvent(QueueHandle_t xMbUartQueue, uart_event_t* pxEvent, ULONG xTimeout);
#ifdef __cplusplus
PR_END_EXTERN_C
#endif /* __cplusplus */

View File

@ -33,6 +33,8 @@
*
* File: $Id: portother.c,v 1.1 2010/06/06 13:07:20 wolti Exp $
*/
#include "driver/uart.h"
#include "port.h"
#include "driver/uart.h"
#include "freertos/queue.h" // for queue support
@ -85,15 +87,14 @@ static USHORT usMBPortSerialRxPoll(size_t xEventSize)
if (bRxStateEnabled) {
// 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.
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM
}
uart_flush_input(ucUartNumber);
// Send event EV_FRAME_RECEIVED to allow stack process packet
#if !CONFIG_FMB_TIMER_PORT_ENABLED
// Let the stack know that T3.5 time is expired and data is received
(void)pxMBPortCBTimerExpired(); // calls callback xMBRTUTimerT35Expired();
pxMBPortCBTimerExpired();
#endif
ESP_LOGD(TAG, "RX: %d bytes\n", usCnt);
}
@ -126,7 +127,7 @@ static void vUartTask(void *pvParameters)
uart_event_t xEvent;
USHORT usResult = 0;
for(;;) {
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
switch(xEvent.type) {
//Event of UART receving data
@ -135,6 +136,8 @@ static void vUartTask(void *pvParameters)
// This flag set in the event means that no more
// data received during configured timeout and UART TOUT feature is triggered
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
usResult = usMBPortSerialRxPoll(xEvent.size);
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,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 2,
.source_clk = UART_SCLK_APB,
.source_clk = UART_SCLK_APB
};
// Set UART config
xErr = uart_param_config(ucUartNumber, &xUartConfig);
@ -257,6 +260,17 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
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)vTaskSuspend(xMbTaskHandle);

View File

@ -89,7 +89,7 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
USHORT usCnt = 0;
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.
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
}
@ -134,7 +134,7 @@ static void vUartTask(void* pvParameters)
uart_event_t xEvent;
USHORT usResult = 0;
for(;;) {
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
switch(xEvent.type) {
//Event of UART receiving data
@ -143,6 +143,8 @@ static void vUartTask(void* pvParameters)
// This flag set in the event means that no more
// data received during configured timeout and UART TOUT feature is triggered
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
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
@ -266,6 +268,24 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
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)vTaskDelete(xMbTaskHandle);

View File

@ -74,7 +74,7 @@ BOOL xMBPortTimersInit(USHORT usTimeOut50us)
esp_timer_create_args_t xTimerConf = {
.callback = vTimerAlarmCBHandler,
.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,
#else
.dispatch_method = ESP_TIMER_TASK,

View File

@ -71,7 +71,7 @@ BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
esp_timer_create_args_t xTimerConf = {
.callback = vTimerAlarmCBHandler,
.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,
#else
.dispatch_method = ESP_TIMER_TASK,

View File

@ -30,7 +30,7 @@ extern BOOL xMBMasterPortSerialTxPoll(void);
#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";
// 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);
status = eMBMasterEnable();
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
EventBits_t flag = xEventGroupSetBits(mbm_opts->mbm_event_group,
(EventBits_t)MB_EVENT_STACK_STARTED);

View File

@ -159,7 +159,7 @@ static esp_err_t mbc_tcp_master_start(void)
status = eMBMasterEnable();
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
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
(void)xMBTCPPortMasterAddSlaveIp(0xFF, NULL, 0xFF);
// Wait for connection done event
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 stack could not connect to slaves for %d seconds.",
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC);
"mb stack could not connect to slaves for %d seconds.",
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC);
return ESP_OK;
}

View File

@ -560,6 +560,12 @@ static void vMBTCPPortServerTask(void *pvParameters)
pxClientInfo->xSockId, pxClientInfo->pcIpAddr, xErr);
break;
}
if (xShutdownSemaphore) {
xSemaphoreGive(xShutdownSemaphore);
vTaskDelete(NULL);
}
// Close client connection
xMBTCPPortCloseConnection(pxClientInfo);

View File

@ -1,5 +1,10 @@
version: "0.1.0"
version: "0.0.2"
description: ESP-MODBUS is the official Modbus library for Espressif SoCs.
dependencies:
idf: ">=4.1"
files:
exclude:
- "docs/_build/**/*"
- "docs/_build"
- "test/**/build/**/*"
- "test/**/build"

View File

@ -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
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.
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

View File

@ -2,5 +2,4 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
idf_component_register(SRCS "modbus_params.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES esp-modbus)
INCLUDE_DIRS "include")

View File

@ -3,10 +3,8 @@
#
CONFIG_MB_COMM_MODE_ASCII=y
CONFIG_MB_UART_BAUD_RATE=115200
CONFIG_FMB_TIMER_PORT_ENABLED=y
CONFIG_FMB_TIMER_GROUP=0
CONFIG_FMB_TIMER_INDEX=0
CONFIG_FMB_TIMER_PORT_ENABLED=n
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
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

View File

@ -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

View File

@ -4,8 +4,6 @@
CONFIG_MB_COMM_MODE_ASCII=y
CONFIG_MB_SLAVE_ADDR=1
CONFIG_MB_UART_BAUD_RATE=115200
CONFIG_FMB_TIMER_PORT_ENABLED=y
CONFIG_FMB_TIMER_GROUP=0
CONFIG_FMB_TIMER_INDEX=0
CONFIG_FMB_TIMER_PORT_ENABLED=n
CONFIG_FMB_TIMER_ISR_IN_IRAM=y
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y