mirror of
https://github.com/espressif/esp-modbus.git
synced 2025-07-29 18:07:17 +02:00
modbus master fix event loop and kconfig
This commit is contained in:
@ -118,12 +118,6 @@ build_idf_v4.3:
|
||||
variables:
|
||||
TEST_TARGETS: "esp32 esp32s2 esp32c3"
|
||||
|
||||
build_idf_v4.2:
|
||||
extends: .build_pytest_template
|
||||
image: espressif/idf:release-v4.2
|
||||
variables:
|
||||
TEST_TARGETS: "esp32 esp32s2"
|
||||
|
||||
.target_test_template:
|
||||
image: $TARGET_TEST_ENV_IMAGE
|
||||
stage: target_test
|
||||
@ -200,7 +194,7 @@ build_docs:
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
- build-docs -l en -t esp32
|
||||
- ./generate_docs
|
||||
|
||||
.deploy_docs_template:
|
||||
stage: deploy
|
||||
|
8
Kconfig
8
Kconfig
@ -57,8 +57,8 @@ menu "Modbus configuration"
|
||||
|
||||
config FMB_MASTER_TIMEOUT_MS_RESPOND
|
||||
int "Slave respond timeout (Milliseconds)"
|
||||
default 150
|
||||
range 50 3000
|
||||
default 3000
|
||||
range 150 15000
|
||||
help
|
||||
If master sends a frame which is not broadcast, it has to wait sometime for slave response.
|
||||
if slave is not respond in this time, the master will process timeout error.
|
||||
@ -66,7 +66,7 @@ menu "Modbus configuration"
|
||||
config FMB_MASTER_DELAY_MS_CONVERT
|
||||
int "Slave conversion delay (Milliseconds)"
|
||||
default 200
|
||||
range 50 400
|
||||
range 150 2000
|
||||
help
|
||||
If master sends a broadcast frame, it has to wait conversion time to delay,
|
||||
then master can send next frame.
|
||||
@ -107,7 +107,7 @@ menu "Modbus configuration"
|
||||
config FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS
|
||||
int "Response timeout for ASCII communication mode (ms)"
|
||||
default 1000
|
||||
range 300 2000
|
||||
range 200 5000
|
||||
depends on FMB_COMM_MODE_ASCII_EN
|
||||
help
|
||||
This option defines response timeout of slave in milliseconds for ASCII communication mode.
|
||||
|
12
docs/_static/modbus_docs_versions.js
vendored
12
docs/_static/modbus_docs_versions.js
vendored
@ -1,16 +1,14 @@
|
||||
var DOCUMENTATION_VERSIONS = {
|
||||
DEFAULTS: { has_targets: true,
|
||||
supported_targets: [ "esp32", "esp32s2", "esp32s3", "esp32c3" ]
|
||||
},
|
||||
VERSIONS: [
|
||||
{ name: "latest" },
|
||||
{ name: "v1.0.1", old:false },
|
||||
{ name: "v1.0.0", old:true }
|
||||
{ name: "latest", has_targets: true, supported_targets: [ "esp32", "esp32s2", "esp32s3", "esp32c2", "esp32c3", "esp32c6", "esp32h2" ] },
|
||||
],
|
||||
IDF_TARGETS: [
|
||||
{ text: "ESP32", value: "esp32"},
|
||||
{ text: "ESP32-S2", value: "esp32s2"},
|
||||
{ text: "ESP32-S3", value: "esp32s3"},
|
||||
{ text: "ESP32-C3", value: "esp32c3"}
|
||||
{ text: "ESP32-C2", value: "esp32c2"},
|
||||
{ text: "ESP32-C3", value: "esp32c3"},
|
||||
{ text: "ESP32-C6", value: "esp32c6"},
|
||||
{ text: "ESP32-H2", value: "esp32h2"}
|
||||
]
|
||||
};
|
||||
|
@ -29,5 +29,5 @@ html_static_path = ['../_static']
|
||||
project_slug = 'esp-modbus'
|
||||
versions_url = './_static/modbus_docs_versions.js'
|
||||
|
||||
idf_targets = ['esp32', 'esp32s2', 'esp32c3']
|
||||
idf_targets = [ 'esp32' ]
|
||||
languages = ['en']
|
||||
|
27
docs/generate_docs
Executable file
27
docs/generate_docs
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf docs
|
||||
build-docs --target esp32 --language en
|
||||
|
||||
# Modifes target field of html files
|
||||
ELEMENT="<script type='text/javascript'>
|
||||
window.onload =(function() {
|
||||
var myAnchor = document.getElementById('target-select');
|
||||
var mySpan = document.createElement('input');
|
||||
mySpan.style.float = 'left';
|
||||
mySpan.setAttribute('type', 'text');
|
||||
mySpan.setAttribute('maxLength', '10');
|
||||
mySpan.value = 'all targets';
|
||||
mySpan.setAttribute('disabled', true);
|
||||
myAnchor.parentNode.replaceChild(mySpan, myAnchor);
|
||||
})();
|
||||
</script>"
|
||||
|
||||
FILES=$(find . -path "*/_build/en/esp32/html/*.html")
|
||||
|
||||
for FILE in ${FILES}
|
||||
do
|
||||
echo ${ELEMENT} >> "${FILE}"
|
||||
done
|
||||
|
||||
|
@ -110,7 +110,7 @@ eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG
|
||||
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF ] = usNCoils >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
|
||||
}
|
||||
@ -217,7 +217,7 @@ eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LO
|
||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF ] = usCoilData >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
@ -327,7 +327,7 @@ eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||
*ucMBFrame++ = pucDataBuffer[usRegIndex++];
|
||||
}
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
|
@ -92,7 +92,7 @@ eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT u
|
||||
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF ] = usNDiscreteIn >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
|
@ -122,7 +122,7 @@ eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRe
|
||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF] = usRegData >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
@ -200,7 +200,7 @@ eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
|
||||
}
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
@ -286,7 +286,7 @@ eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRe
|
||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
@ -392,7 +392,7 @@ eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
|
||||
}
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
|
@ -93,7 +93,7 @@ eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs
|
||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
|
||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
|
@ -103,7 +103,7 @@ typedef enum
|
||||
MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
|
||||
MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
|
||||
MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast ,then delay sometime.*/
|
||||
}eMBMasterTimerMode;
|
||||
} eMBMasterTimerMode;
|
||||
|
||||
/* ----------------------- Function prototypes ------------------------------*/
|
||||
/*! \ingroup modbus
|
||||
|
@ -99,6 +99,9 @@ PR_BEGIN_EXTERN_C
|
||||
#define MB_ASCII_BITS_PER_SYMB ( CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB )
|
||||
#endif
|
||||
|
||||
#define MB_EVENT_QUEUE_SIZE ( CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE )
|
||||
#define MB_EVENT_QUEUE_TIMEOUT ( pdMS_TO_TICKS( CONFIG_FMB_EVENT_QUEUE_TIMEOUT ) )
|
||||
|
||||
/*! \brief The character timeout value for Modbus ASCII.
|
||||
*
|
||||
* The character timeout value is not fixed for Modbus ASCII and is therefore
|
||||
|
@ -70,17 +70,18 @@ typedef enum
|
||||
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||
typedef enum {
|
||||
EV_MASTER_NO_EVENT = 0x0000,
|
||||
EV_MASTER_READY = 0x0001, /*!< Startup finished. */
|
||||
EV_MASTER_FRAME_RECEIVED = 0x0002, /*!< Frame received. */
|
||||
EV_MASTER_EXECUTE = 0x0004, /*!< Execute function. */
|
||||
EV_MASTER_FRAME_SENT = 0x0008, /*!< Frame sent. */
|
||||
EV_MASTER_FRAME_TRANSMIT = 0x0010, /*!< Frame transmission. */
|
||||
EV_MASTER_ERROR_PROCESS = 0x0020, /*!< Frame error process. */
|
||||
EV_MASTER_PROCESS_SUCCESS = 0x0040, /*!< Request process success. */
|
||||
EV_MASTER_ERROR_RESPOND_TIMEOUT = 0x0080, /*!< Request respond timeout. */
|
||||
EV_MASTER_ERROR_RECEIVE_DATA = 0x0100, /*!< Request receive data error. */
|
||||
EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0200 /*!< Request execute function error. */
|
||||
} eMBMasterEventType;
|
||||
EV_MASTER_TRANS_START = 0x0001, /*!< Transaction start flag */
|
||||
EV_MASTER_READY = 0x0002, /*!< Startup finished. */
|
||||
EV_MASTER_FRAME_RECEIVED = 0x0004, /*!< Frame received. */
|
||||
EV_MASTER_EXECUTE = 0x0008, /*!< Execute function. */
|
||||
EV_MASTER_FRAME_SENT = 0x0010, /*!< Frame sent. */
|
||||
EV_MASTER_FRAME_TRANSMIT = 0x0020, /*!< Frame transmission. */
|
||||
EV_MASTER_ERROR_PROCESS = 0x0040, /*!< Frame error process. */
|
||||
EV_MASTER_PROCESS_SUCCESS = 0x0080, /*!< Request process success. */
|
||||
EV_MASTER_ERROR_RESPOND_TIMEOUT = 0x0100, /*!< Request respond timeout. */
|
||||
EV_MASTER_ERROR_RECEIVE_DATA = 0x0200, /*!< Request receive data error. */
|
||||
EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0400 /*!< Request execute function error. */
|
||||
} eMBMasterEventEnum;
|
||||
|
||||
typedef enum {
|
||||
EV_ERROR_INIT, /*!< No error, initial state. */
|
||||
@ -89,6 +90,14 @@ typedef enum {
|
||||
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
|
||||
EV_ERROR_OK /*!< No error, processing completed. */
|
||||
} eMBMasterErrorEventType;
|
||||
|
||||
typedef struct _MbEventType {
|
||||
eMBMasterEventEnum eEvent; /*!< event itself. */
|
||||
uint64_t xTransactionId; /*!< ID of the transaction */
|
||||
uint64_t xPostTimestamp; /*!< timestamp of event posted */
|
||||
uint64_t xGetTimestamp; /*!< timestamp of event get */
|
||||
} xMBMasterEventType;
|
||||
|
||||
#endif
|
||||
|
||||
/*! \ingroup modbus
|
||||
@ -115,18 +124,21 @@ BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
|
||||
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||
BOOL xMBMasterPortEventInit( void );
|
||||
|
||||
BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
|
||||
BOOL xMBMasterPortEventPost( eMBMasterEventEnum eEvent );
|
||||
|
||||
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
|
||||
BOOL xMBMasterPortEventGet( /*@out@ */ xMBMasterEventType * eEvent );
|
||||
|
||||
eMBMasterEventType
|
||||
xMBMasterPortFsmWaitConfirmation( eMBMasterEventType eEventMask, ULONG ulTimeout);
|
||||
eMBMasterEventEnum
|
||||
xMBMasterPortFsmWaitConfirmation( eMBMasterEventEnum eEventMask, ULONG ulTimeout);
|
||||
|
||||
void vMBMasterOsResInit( void );
|
||||
|
||||
BOOL xMBMasterRunResTake( LONG time );
|
||||
|
||||
void vMBMasterRunResRelease( void );
|
||||
|
||||
uint64_t xMBMasterPortGetTransactionId( void );
|
||||
|
||||
#endif // MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||
/* ----------------------- Serial port functions ----------------------------*/
|
||||
|
||||
|
@ -62,7 +62,7 @@ PR_BEGIN_EXTERN_C
|
||||
#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 )
|
||||
#define MB_FUNC_ERROR ( 128u )
|
||||
/* ----------------------- Type definitions ---------------------------------*/
|
||||
typedef enum
|
||||
typedef enum
|
||||
{
|
||||
MB_EX_NONE = 0x00,
|
||||
MB_EX_ILLEGAL_FUNCTION = 0x01,
|
||||
|
@ -36,8 +36,9 @@
|
||||
*/
|
||||
|
||||
/* ----------------------- System includes ----------------------------------*/
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ----------------------- Platform includes --------------------------------*/
|
||||
#include "port.h"
|
||||
@ -316,171 +317,171 @@ eMBMasterPoll( void )
|
||||
static UCHAR ucFunctionCode;
|
||||
static USHORT usLength;
|
||||
static eMBException eException;
|
||||
static BOOL xTransactionIsActive = FALSE;
|
||||
static uint64_t xCurTransactionId = 0;
|
||||
int i;
|
||||
int j;
|
||||
eMBErrorCode eStatus = MB_ENOERR;
|
||||
eMBMasterEventType eEvent;
|
||||
xMBMasterEventType xEvent;
|
||||
eMBMasterErrorEventType errorType;
|
||||
|
||||
/* Check if the protocol stack is ready. */
|
||||
if( eMBState != STATE_ENABLED )
|
||||
{
|
||||
if( eMBState != STATE_ENABLED ) {
|
||||
return MB_EILLSTATE;
|
||||
}
|
||||
|
||||
/* Check if there is a event available. If not return control to caller.
|
||||
* Otherwise we will handle the event. */
|
||||
if ( xMBMasterPortEventGet( &eEvent ) == TRUE )
|
||||
{
|
||||
while( eEvent ) {
|
||||
if ( xMBMasterPortEventGet( &xEvent ) == TRUE ) {
|
||||
switch( xEvent.eEvent ) {
|
||||
// In some cases it is possible that more than one event set
|
||||
// together (even from one subset mask) than process them consistently
|
||||
if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_READY ) ) {
|
||||
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_READY", __func__);
|
||||
case EV_MASTER_READY:
|
||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_READY", xEvent.xTransactionId);
|
||||
vMBMasterSetErrorType( EV_ERROR_INIT );
|
||||
vMBMasterRunResRelease( );
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_READY );
|
||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
|
||||
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_FRAME_TRANSMIT", __func__);
|
||||
break;
|
||||
case EV_MASTER_FRAME_TRANSMIT:
|
||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_TRANSMIT", xEvent.xTransactionId);
|
||||
/* Master is busy now. */
|
||||
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL transmit buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
|
||||
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBSendFrame, usMBMasterGetPDUSndLength() );
|
||||
if (eStatus != MB_ENOERR)
|
||||
{
|
||||
if (eStatus != MB_ENOERR) {
|
||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %u", __func__, (unsigned)eStatus );
|
||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Frame send error = %d", xEvent.xTransactionId, (unsigned)eStatus );
|
||||
}
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
|
||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {
|
||||
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_SENT", __func__ );
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
|
||||
xTransactionIsActive = TRUE;
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_SENT );
|
||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED ) ) {
|
||||
if (xTransactionIsActive) {
|
||||
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_RECEIVED", __func__ );
|
||||
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBRcvFrame, &usLength);
|
||||
xCurTransactionId = xEvent.xTransactionId;
|
||||
break;
|
||||
case EV_MASTER_FRAME_SENT:
|
||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_SENT", xEvent.xTransactionId );
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
|
||||
}
|
||||
break;
|
||||
case EV_MASTER_FRAME_RECEIVED:
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_RECEIVED", xEvent.xTransactionId );
|
||||
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBRcvFrame, &usLength);
|
||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||
MB_PORT_CHECK(ucMBSendFrame, MB_EILLSTATE, "Send buffer initialization fail.");
|
||||
// Check if the frame is for us. If not ,send an error process event.
|
||||
if ( ( eStatus == MB_ENOERR ) && ( ( ucRcvAddress == ucMBMasterGetDestAddress() )
|
||||
|| ( ucRcvAddress == MB_TCP_PSEUDO_ADDRESS) ) ) {
|
||||
if ( ( ucMBRcvFrame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR ) == ( ucMBSendFrame[MB_PDU_FUNC_OFF] ) ) {
|
||||
ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, (unsigned)eStatus);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)ucMBRcvFrame, (unsigned)usLength, ESP_LOG_DEBUG);
|
||||
|
||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ": Packet data received successfully (%u).", xEvent.xTransactionId, (unsigned)eStatus);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)ucMBRcvFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
||||
} else {
|
||||
ESP_LOGE( MB_PORT_TAG, "Drop incorrect frame, receive_func(%u) != send_func(%u)",
|
||||
(UCHAR)ucMBRcvFrame[MB_PDU_FUNC_OFF], (UCHAR)ucMBSendFrame[MB_PDU_FUNC_OFF]);
|
||||
ucMBRcvFrame[MB_PDU_FUNC_OFF], ucMBSendFrame[MB_PDU_FUNC_OFF]);
|
||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
}
|
||||
} else {
|
||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
ESP_LOGD( MB_PORT_TAG, "%s: Packet data receive failed (addr=%u)(%u).",
|
||||
__func__, (unsigned)ucRcvAddress, (unsigned)eStatus);
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ": Packet data receive failed (addr=%u)(%u).",
|
||||
xEvent.xTransactionId, (unsigned)ucRcvAddress, (unsigned)eStatus);
|
||||
}
|
||||
} else {
|
||||
// Ignore the `EV_MASTER_FRAME_RECEIVED` event because the respond timeout occurred
|
||||
// and this is likely respond to previous transaction
|
||||
ESP_LOGE( MB_PORT_TAG, "Drop data received outside of transaction.");
|
||||
ESP_LOGE( MB_PORT_TAG, "Drop data received outside of transaction (%" PRIu64 ")", xEvent.xTransactionId );
|
||||
}
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED );
|
||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_EXECUTE ) ) {
|
||||
MB_PORT_CHECK(ucMBRcvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
|
||||
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_EXECUTE", __func__);
|
||||
ucFunctionCode = ucMBRcvFrame[MB_PDU_FUNC_OFF];
|
||||
eException = MB_EX_ILLEGAL_FUNCTION;
|
||||
/* If receive frame has exception. The receive function code highest bit is 1.*/
|
||||
if (ucFunctionCode & MB_FUNC_ERROR)
|
||||
{
|
||||
eException = (eMBException)ucMBRcvFrame[MB_PDU_DATA_OFF];
|
||||
} else {
|
||||
for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
|
||||
{
|
||||
/* No more function handlers registered. Abort. */
|
||||
if (xMasterFuncHandlers[i].ucFunctionCode == 0)
|
||||
break;
|
||||
case EV_MASTER_EXECUTE:
|
||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||
MB_PORT_CHECK(ucMBRcvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
|
||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE", xEvent.xTransactionId);
|
||||
ucFunctionCode = ucMBRcvFrame[MB_PDU_FUNC_OFF];
|
||||
eException = MB_EX_ILLEGAL_FUNCTION;
|
||||
/* If receive frame has exception. The receive function code highest bit is 1.*/
|
||||
if (ucFunctionCode & MB_FUNC_ERROR) {
|
||||
eException = (eMBException)ucMBRcvFrame[MB_PDU_DATA_OFF];
|
||||
} else {
|
||||
for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode)
|
||||
{
|
||||
vMBMasterSetCBRunInMasterMode(TRUE);
|
||||
/* If master request is broadcast,
|
||||
* the master need execute function for all slave.
|
||||
*/
|
||||
if ( xMBMasterRequestIsBroadcast() )
|
||||
{
|
||||
usLength = usMBMasterGetPDUSndLength();
|
||||
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
|
||||
{
|
||||
vMBMasterSetDestAddress(j);
|
||||
eException = xMasterFuncHandlers[i].pxHandler(ucMBRcvFrame, &usLength);
|
||||
/* No more function handlers registered. Abort. */
|
||||
if (xMasterFuncHandlers[i].ucFunctionCode == 0) {
|
||||
break;
|
||||
}
|
||||
if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
|
||||
vMBMasterSetCBRunInMasterMode(TRUE);
|
||||
/* If master request is broadcast,
|
||||
* the master need execute function for all slave.
|
||||
*/
|
||||
if ( xMBMasterRequestIsBroadcast() ) {
|
||||
usLength = usMBMasterGetPDUSndLength();
|
||||
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
|
||||
{
|
||||
vMBMasterSetDestAddress(j);
|
||||
eException = xMasterFuncHandlers[i].pxHandler(ucMBRcvFrame, &usLength);
|
||||
}
|
||||
} else {
|
||||
eException = xMasterFuncHandlers[i].pxHandler( ucMBRcvFrame, &usLength );
|
||||
}
|
||||
vMBMasterSetCBRunInMasterMode( FALSE );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
eException = xMasterFuncHandlers[i].pxHandler( ucMBRcvFrame, &usLength );
|
||||
}
|
||||
vMBMasterSetCBRunInMasterMode( FALSE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If master has exception, will send error process event. Otherwise the master is idle.*/
|
||||
if ( eException != MB_EX_NONE )
|
||||
{
|
||||
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
|
||||
vMBMasterSetErrorType(EV_ERROR_OK);
|
||||
ESP_LOGD( MB_PORT_TAG, "%s: set event EV_ERROR_OK", __func__ );
|
||||
/* If master has exception, will send error process event. Otherwise the master is idle.*/
|
||||
if ( eException != MB_EX_NONE ) {
|
||||
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
} else {
|
||||
if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
|
||||
vMBMasterSetErrorType(EV_ERROR_OK);
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":set event EV_ERROR_OK", xEvent.xTransactionId );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE is expired", xEvent.xTransactionId );
|
||||
}
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
|
||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_ERROR_PROCESS ) ) {
|
||||
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_ERROR_PROCESS", __func__ );
|
||||
/* Execute specified error process callback function. */
|
||||
errorType = eMBMasterGetErrorType( );
|
||||
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
|
||||
switch ( errorType )
|
||||
{
|
||||
case EV_ERROR_RESPOND_TIMEOUT:
|
||||
vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_RECEIVE_DATA:
|
||||
vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_EXECUTE_FUNCTION:
|
||||
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_OK:
|
||||
vMBMasterCBRequestSuccess( );
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %u.", __func__, (unsigned)errorType);
|
||||
break;
|
||||
break;
|
||||
case EV_MASTER_ERROR_PROCESS:
|
||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_ERROR_PROCESS", xEvent.xTransactionId);
|
||||
/* Execute specified error process callback function. */
|
||||
errorType = eMBMasterGetErrorType( );
|
||||
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
|
||||
switch ( errorType )
|
||||
{
|
||||
case EV_ERROR_RESPOND_TIMEOUT:
|
||||
vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_RECEIVE_DATA:
|
||||
vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_EXECUTE_FUNCTION:
|
||||
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
|
||||
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||
break;
|
||||
case EV_ERROR_OK:
|
||||
vMBMasterCBRequestSuccess( );
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":incorrect error type = %d.", xEvent.xTransactionId, (int)errorType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
vMBMasterPortTimersDisable( );
|
||||
uint64_t xProcTime = xCurTransactionId ? ( xEvent.xPostTimestamp - xCurTransactionId ) : 0;
|
||||
ESP_LOGD( MB_PORT_TAG, "Transaction (%" PRIu64 "), processing time(us) = %" PRId64, xCurTransactionId, xProcTime );
|
||||
xCurTransactionId = 0;
|
||||
vMBMasterSetErrorType( EV_ERROR_INIT );
|
||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_ERROR_PROCESS );
|
||||
vMBMasterRunResRelease( );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Unexpected event triggered 0x%02x.", xEvent.xTransactionId, (int)xEvent.eEvent );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Something went wrong and task unblocked but there are no any correct events set
|
||||
ESP_LOGE( MB_PORT_TAG, "%s: Unexpected event triggered 0x%02x.", __func__, (int)eEvent );
|
||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ": Unexpected event triggered 0x%02x.", xEvent.xTransactionId, (int)xEvent.eEvent );
|
||||
eStatus = MB_EILLSTATE;
|
||||
}
|
||||
return eStatus;
|
||||
@ -489,37 +490,37 @@ eMBMasterPoll( void )
|
||||
// Get whether the Modbus Master is run in master mode.
|
||||
BOOL xMBMasterGetCBRunInMasterMode( void )
|
||||
{
|
||||
return xMBRunInMasterMode;
|
||||
return atomic_load(&xMBRunInMasterMode);
|
||||
}
|
||||
|
||||
// Set whether the Modbus Master is run in master mode.
|
||||
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
||||
{
|
||||
xMBRunInMasterMode = IsMasterMode;
|
||||
atomic_store(&(xMBRunInMasterMode), IsMasterMode);
|
||||
}
|
||||
|
||||
// Get Modbus Master send destination address.
|
||||
UCHAR ucMBMasterGetDestAddress( void )
|
||||
{
|
||||
return ucMBMasterDestAddress;
|
||||
return atomic_load(&ucMBMasterDestAddress);
|
||||
}
|
||||
|
||||
// Set Modbus Master send destination address.
|
||||
void vMBMasterSetDestAddress( UCHAR Address )
|
||||
{
|
||||
ucMBMasterDestAddress = Address;
|
||||
atomic_store(&(ucMBMasterDestAddress), Address);
|
||||
}
|
||||
|
||||
// Get Modbus Master current error event type.
|
||||
eMBMasterErrorEventType inline eMBMasterGetErrorType( void )
|
||||
{
|
||||
return eMBMasterCurErrorType;
|
||||
return atomic_load(&eMBMasterCurErrorType);
|
||||
}
|
||||
|
||||
// Set Modbus Master current error event type.
|
||||
void IRAM_ATTR vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
|
||||
{
|
||||
eMBMasterCurErrorType = errorType;
|
||||
atomic_store(&(eMBMasterCurErrorType), errorType);
|
||||
}
|
||||
|
||||
/* Get Modbus Master send PDU's buffer address pointer.*/
|
||||
@ -531,25 +532,25 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
|
||||
/* Set Modbus Master send PDU's buffer length.*/
|
||||
void vMBMasterSetPDUSndLength( USHORT SendPDULength )
|
||||
{
|
||||
usMasterSendPDULength = SendPDULength;
|
||||
atomic_store(&(usMasterSendPDULength), SendPDULength);
|
||||
}
|
||||
|
||||
/* Get Modbus Master send PDU's buffer length.*/
|
||||
USHORT usMBMasterGetPDUSndLength( void )
|
||||
{
|
||||
return usMasterSendPDULength;
|
||||
return atomic_load(&usMasterSendPDULength);
|
||||
}
|
||||
|
||||
/* Set Modbus Master current timer mode.*/
|
||||
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
|
||||
{
|
||||
eMasterCurTimerMode = eMBTimerMode;
|
||||
atomic_store(&(eMasterCurTimerMode), eMBTimerMode);
|
||||
}
|
||||
|
||||
/* Get Modbus Master current timer mode.*/
|
||||
eMBMasterTimerMode MB_PORT_ISR_ATTR xMBMasterGetCurTimerMode( void )
|
||||
{
|
||||
return eMasterCurTimerMode;
|
||||
return atomic_load(&eMasterCurTimerMode);
|
||||
}
|
||||
|
||||
/* The master request is broadcast? */
|
||||
@ -561,7 +562,7 @@ BOOL MB_PORT_ISR_ATTR xMBMasterRequestIsBroadcast( void )
|
||||
/* The master request is broadcast? */
|
||||
void vMBMasterRequestSetType( BOOL xIsBroadcast )
|
||||
{
|
||||
xFrameIsBroadcast = xIsBroadcast;
|
||||
atomic_store(&(xFrameIsBroadcast), xIsBroadcast);
|
||||
}
|
||||
|
||||
// Get Modbus Master communication mode.
|
||||
|
@ -252,7 +252,9 @@ xMBMasterRTUReceiveFSM( void )
|
||||
BOOL xStatus = FALSE;
|
||||
UCHAR ucByte;
|
||||
|
||||
assert(( eSndState == STATE_M_TX_IDLE ) || ( eSndState == STATE_M_TX_XFWR ));
|
||||
if ( ( eSndState != STATE_M_TX_IDLE ) && ( eSndState != STATE_M_TX_XFWR ) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Always read the character. */
|
||||
xStatus = xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
||||
@ -328,7 +330,9 @@ xMBMasterRTUTransmitFSM( void )
|
||||
BOOL xNeedPoll = TRUE;
|
||||
BOOL xFrameIsBroadcast = FALSE;
|
||||
|
||||
assert( eRcvState == STATE_M_RX_IDLE );
|
||||
if ( eRcvState != STATE_M_RX_IDLE ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch ( eSndState )
|
||||
{
|
||||
|
@ -91,6 +91,10 @@
|
||||
#define MB_TCP_SEND_TIMEOUT (pdMS_TO_TICKS(MB_TCP_SEND_TIMEOUT_MS))
|
||||
#define MB_TCP_PORT_MAX_CONN (CONFIG_FMB_TCP_PORT_MAX_CONN)
|
||||
|
||||
// Set the API unlock time to maximum response time
|
||||
// The actual release time will be dependent on the timer time
|
||||
#define MB_MAX_RESPONSE_TIME_MS (5000)
|
||||
|
||||
#define MB_TCP_FRAME_LOG_BUFSIZE (256)
|
||||
|
||||
#define MB_PORT_HAS_CLOSE (1) // Define to explicitly close port on destroy
|
||||
|
@ -44,14 +44,11 @@
|
||||
#include "mb.h"
|
||||
#include "mbport.h"
|
||||
#include "port.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "mbconfig.h"
|
||||
#include "port_serial_slave.h"
|
||||
/* ----------------------- Variables ----------------------------------------*/
|
||||
static QueueHandle_t xQueueHdl;
|
||||
|
||||
#define MB_EVENT_QUEUE_SIZE (6)
|
||||
#define MB_EVENT_QUEUE_TIMEOUT (pdMS_TO_TICKS(CONFIG_FMB_EVENT_QUEUE_TIMEOUT))
|
||||
|
||||
/* ----------------------- Start implementation -----------------------------*/
|
||||
BOOL
|
||||
xMBPortEventInit( void )
|
||||
|
@ -35,26 +35,24 @@
|
||||
*/
|
||||
|
||||
/* ----------------------- Modbus includes ----------------------------------*/
|
||||
#include "mb_m.h"
|
||||
#include "mbport.h"
|
||||
#include "mbconfig.h"
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "mb_m.h"
|
||||
#include "mbport.h"
|
||||
#include "mbconfig.h"
|
||||
|
||||
#include "port.h"
|
||||
#include "mbport.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||
/* ----------------------- Defines ------------------------------------------*/
|
||||
// Event bit mask for xMBMasterPortEventGet()
|
||||
#define MB_EVENT_POLL_MASK (EventBits_t)( EV_MASTER_READY | \
|
||||
EV_MASTER_FRAME_RECEIVED | \
|
||||
EV_MASTER_EXECUTE | \
|
||||
EV_MASTER_FRAME_SENT | \
|
||||
EV_MASTER_FRAME_TRANSMIT | \
|
||||
EV_MASTER_ERROR_PROCESS )
|
||||
|
||||
// Event bit mask for eMBMasterWaitRequestFinish()
|
||||
#define MB_EVENT_REQ_MASK (EventBits_t)( EV_MASTER_PROCESS_SUCCESS | \
|
||||
@ -62,12 +60,13 @@
|
||||
EV_MASTER_ERROR_RECEIVE_DATA | \
|
||||
EV_MASTER_ERROR_EXECUTE_FUNCTION )
|
||||
|
||||
#define MB_EVENT_RESOURCE (EventBits_t)( 0x0080 )
|
||||
|
||||
/* ----------------------- Variables ----------------------------------------*/
|
||||
static EventGroupHandle_t xResourceMasterHdl;
|
||||
static SemaphoreHandle_t xResourceMasterHdl;
|
||||
static EventGroupHandle_t xEventGroupMasterHdl;
|
||||
static EventGroupHandle_t xEventGroupMasterConfirmHdl;
|
||||
static QueueHandle_t xQueueMasterHdl;
|
||||
|
||||
static uint64_t xTransactionID = 0;
|
||||
|
||||
/* ----------------------- Start implementation -----------------------------*/
|
||||
|
||||
@ -78,45 +77,60 @@ xMBMasterPortEventInit( void )
|
||||
xEventGroupMasterConfirmHdl = xEventGroupCreate();
|
||||
MB_PORT_CHECK((xEventGroupMasterHdl != NULL) && (xEventGroupMasterConfirmHdl != NULL),
|
||||
FALSE, "mb stack event group creation error.");
|
||||
xQueueMasterHdl = xQueueCreate(MB_EVENT_QUEUE_SIZE, sizeof(xMBMasterEventType));
|
||||
MB_PORT_CHECK(xQueueMasterHdl, FALSE, "mb stack event group creation error.");
|
||||
vQueueAddToRegistry(xQueueMasterHdl, "MbMasterPortEventQueue");
|
||||
xTransactionID = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL MB_PORT_ISR_ATTR
|
||||
xMBMasterPortEventPost( eMBMasterEventType eEvent )
|
||||
xMBMasterPortEventPost( eMBMasterEventEnum eEvent)
|
||||
{
|
||||
BOOL bStatus = FALSE;
|
||||
eMBMasterEventType eTempEvent = eEvent;
|
||||
BaseType_t xStatus, xHigherPriorityTaskWoken = pdFALSE;
|
||||
assert(xQueueMasterHdl != NULL);
|
||||
xMBMasterEventType xEvent;
|
||||
xEvent.xPostTimestamp = esp_timer_get_time();
|
||||
|
||||
if (eEvent & EV_MASTER_TRANS_START) {
|
||||
atomic_store(&(xTransactionID), xEvent.xPostTimestamp);
|
||||
}
|
||||
xEvent.eEvent = (eEvent & ~EV_MASTER_TRANS_START);
|
||||
|
||||
if( (BOOL)xPortInIsrContext() == TRUE )
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
BaseType_t xResult = xEventGroupSetBitsFromISR( xEventGroupMasterHdl,
|
||||
(EventBits_t) eTempEvent,
|
||||
&xHigherPriorityTaskWoken );
|
||||
// Was the message posted successfully?
|
||||
if( xResult == pdPASS ) {
|
||||
// If xHigherPriorityTaskWoken is now set to pdTRUE
|
||||
// then a context switch should be requested.
|
||||
if (xHigherPriorityTaskWoken) portYIELD_FROM_ISR();
|
||||
bStatus = TRUE;
|
||||
} else {
|
||||
bStatus = FALSE;
|
||||
if( (BOOL)xPortInIsrContext() == TRUE ) {
|
||||
xStatus = xQueueSendFromISR(xQueueMasterHdl, (const void*)&xEvent, &xHigherPriorityTaskWoken);
|
||||
if ( xHigherPriorityTaskWoken ) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
if (xStatus != pdTRUE) {
|
||||
ESP_EARLY_LOGV(MB_PORT_TAG, "%s: Post message failure = %d.", __func__, xStatus);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
xStatus = xQueueSend(xQueueMasterHdl, (const void*)&xEvent, MB_EVENT_QUEUE_TIMEOUT);
|
||||
MB_PORT_CHECK((xStatus == pdTRUE), FALSE, "%s: Post message failure.", __func__);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set event bits if the function is called from task
|
||||
// The return result is not checked here because
|
||||
// It might be that event bit was cleared automatically as a
|
||||
// task that was waiting for the bit was removed from the Blocked state.
|
||||
(void) xEventGroupSetBits( xEventGroupMasterHdl, (EventBits_t)eTempEvent );
|
||||
bStatus = TRUE;
|
||||
}
|
||||
return bStatus;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
eMBMasterEventType
|
||||
xMBMasterPortFsmWaitConfirmation( eMBMasterEventType eEventMask, ULONG ulTimeout)
|
||||
BOOL
|
||||
xMBMasterPortEventGet(xMBMasterEventType *peEvent)
|
||||
{
|
||||
assert(xQueueMasterHdl != NULL);
|
||||
BOOL xEventHappened = FALSE;
|
||||
|
||||
if (xQueueReceive(xQueueMasterHdl, peEvent, portMAX_DELAY) == pdTRUE) {
|
||||
peEvent->xTransactionId = atomic_load(&xTransactionID);
|
||||
// Set event bits in confirmation group (for synchronization with port task)
|
||||
xEventGroupSetBits(xEventGroupMasterConfirmHdl, peEvent->eEvent);
|
||||
peEvent->xGetTimestamp = esp_timer_get_time();
|
||||
xEventHappened = TRUE;
|
||||
}
|
||||
return xEventHappened;
|
||||
}
|
||||
|
||||
eMBMasterEventEnum
|
||||
xMBMasterPortFsmWaitConfirmation( eMBMasterEventEnum eEventMask, ULONG ulTimeout)
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
uxBits = xEventGroupWaitBits( xEventGroupMasterConfirmHdl, // The event group being tested.
|
||||
@ -128,38 +142,19 @@ xMBMasterPortFsmWaitConfirmation( eMBMasterEventType eEventMask, ULONG ulTimeout
|
||||
// Clear confirmation events that where set in the mask
|
||||
xEventGroupClearBits( xEventGroupMasterConfirmHdl, (uxBits & eEventMask) );
|
||||
}
|
||||
return (eMBMasterEventType)(uxBits & eEventMask);
|
||||
return (eMBMasterEventEnum)(uxBits & eEventMask);
|
||||
}
|
||||
|
||||
BOOL
|
||||
xMBMasterPortEventGet( eMBMasterEventType* eEvent )
|
||||
uint64_t xMBMasterPortGetTransactionId( )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
BOOL xEventHappened = FALSE;
|
||||
uxBits = xEventGroupWaitBits( xEventGroupMasterHdl, // The event group being tested.
|
||||
MB_EVENT_POLL_MASK, // The bits within the event group to wait for.
|
||||
pdTRUE, // Masked bits should be cleared before returning.
|
||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
portMAX_DELAY); // Wait forever for either bit to be set.
|
||||
// Check if poll event is correct
|
||||
if (MB_PORT_CHECK_EVENT(uxBits, MB_EVENT_POLL_MASK)) {
|
||||
*eEvent = (eMBMasterEventType)(uxBits & MB_EVENT_POLL_MASK);
|
||||
// Set event bits in confirmation group (for synchronization with port task)
|
||||
xEventGroupSetBits( xEventGroupMasterConfirmHdl, *eEvent );
|
||||
xEventHappened = TRUE;
|
||||
} else {
|
||||
ESP_LOGE(MB_PORT_TAG,"%s: Incorrect event triggered = %u.", __func__, (unsigned)uxBits);
|
||||
*eEvent = (eMBMasterEventType)uxBits;
|
||||
xEventHappened = FALSE;
|
||||
}
|
||||
return xEventHappened;
|
||||
return atomic_load(&xTransactionID);
|
||||
}
|
||||
|
||||
// This function is initialize the OS resource for modbus master.
|
||||
void vMBMasterOsResInit( void )
|
||||
{
|
||||
xResourceMasterHdl = xEventGroupCreate();
|
||||
MB_PORT_CHECK((xResourceMasterHdl != NULL), ; , "Resource create error.");
|
||||
xResourceMasterHdl = xSemaphoreCreateBinary();
|
||||
MB_PORT_CHECK((xResourceMasterHdl != NULL), ; , "%s: Resource create error.", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,14 +167,10 @@ void vMBMasterOsResInit( void )
|
||||
*/
|
||||
BOOL xMBMasterRunResTake( LONG lTimeOut )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
uxBits = xEventGroupWaitBits( xResourceMasterHdl, // The event group being tested.
|
||||
MB_EVENT_RESOURCE, // The bits within the event group to wait for.
|
||||
pdTRUE, // Masked bits should be cleared before returning.
|
||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
lTimeOut); // Resource wait timeout.
|
||||
MB_PORT_CHECK((uxBits == MB_EVENT_RESOURCE), FALSE , "Take resource failure.");
|
||||
ESP_LOGD(MB_PORT_TAG,"%s:Take resource (%" PRIx32 ") (%" PRIu32 " ticks).", __func__, (uint32_t)uxBits, (uint32_t)lTimeOut);
|
||||
BaseType_t xStatus = pdTRUE;
|
||||
xStatus = xSemaphoreTake( xResourceMasterHdl, lTimeOut );
|
||||
MB_PORT_CHECK((xStatus == pdTRUE), FALSE , "%s: Resource take failure.", __func__);
|
||||
ESP_LOGD(MB_PORT_TAG,"%s:Take MB resource (%lu ticks).", __func__, lTimeOut);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -189,11 +180,10 @@ BOOL xMBMasterRunResTake( LONG lTimeOut )
|
||||
*/
|
||||
void vMBMasterRunResRelease( void )
|
||||
{
|
||||
EventBits_t uxBits = xEventGroupSetBits( xResourceMasterHdl, MB_EVENT_RESOURCE );
|
||||
if (uxBits != MB_EVENT_RESOURCE) {
|
||||
// The returned resource mask may be = 0, if the task waiting for it is unblocked.
|
||||
// This is not an error but expected behavior.
|
||||
ESP_LOGD(MB_PORT_TAG,"%s: Release resource (%" PRIx32 ") fail.", __func__, (uint32_t)uxBits);
|
||||
BaseType_t xStatus = pdFALSE;
|
||||
xStatus = xSemaphoreGive( xResourceMasterHdl );
|
||||
if (xStatus != pdTRUE) {
|
||||
ESP_LOGD(MB_PORT_TAG,"%s: Release resource fail.", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,8 +198,7 @@ void vMBMasterRunResRelease( void )
|
||||
*/
|
||||
void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData, USHORT ucPDULength)
|
||||
{
|
||||
BOOL ret = xMBMasterPortEventPost(EV_MASTER_ERROR_RESPOND_TIMEOUT);
|
||||
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_ERROR_RESPOND_TIMEOUT' failed!", __func__);
|
||||
(void)xEventGroupSetBits( xEventGroupMasterHdl, EV_MASTER_ERROR_RESPOND_TIMEOUT );
|
||||
ESP_LOGD(MB_PORT_TAG,"%s:Callback respond timeout.", __func__);
|
||||
}
|
||||
|
||||
@ -223,8 +212,7 @@ void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData
|
||||
*/
|
||||
void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData, USHORT ucPDULength)
|
||||
{
|
||||
BOOL ret = xMBMasterPortEventPost(EV_MASTER_ERROR_RECEIVE_DATA);
|
||||
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_ERROR_RECEIVE_DATA' failed!", __func__);
|
||||
(void)xEventGroupSetBits( xEventGroupMasterHdl, EV_MASTER_ERROR_RECEIVE_DATA );
|
||||
ESP_LOGD(MB_PORT_TAG,"%s:Callback receive data timeout failure.", __func__);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("Err rcv buf", (void *)pucPDUData, (USHORT)ucPDULength, ESP_LOG_DEBUG);
|
||||
}
|
||||
@ -241,8 +229,7 @@ void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData, U
|
||||
*/
|
||||
void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData, USHORT ucPDULength)
|
||||
{
|
||||
BOOL ret = xMBMasterPortEventPost(EV_MASTER_ERROR_EXECUTE_FUNCTION);
|
||||
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_ERROR_EXECUTE_FUNCTION' failed!", __func__);
|
||||
xEventGroupSetBits( xEventGroupMasterHdl, EV_MASTER_ERROR_EXECUTE_FUNCTION );
|
||||
ESP_LOGD(MB_PORT_TAG,"%s:Callback execute data handler failure.", __func__);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL("Exec func buf", (void*)pucPDUData, (USHORT)ucPDULength, ESP_LOG_DEBUG);
|
||||
}
|
||||
@ -252,13 +239,9 @@ void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUDat
|
||||
* @note There functions will block modbus master poll while execute OS waiting.
|
||||
* So,for real-time of system. Do not execute too much waiting process.
|
||||
*/
|
||||
void vMBMasterCBRequestSuccess( void ) {
|
||||
/**
|
||||
* @note This code is use OS's event mechanism for modbus master protocol stack.
|
||||
* If you don't use OS, you can change it.
|
||||
*/
|
||||
BOOL ret = xMBMasterPortEventPost(EV_MASTER_PROCESS_SUCCESS);
|
||||
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_PROCESS_SUCCESS' failed!", __func__);
|
||||
void vMBMasterCBRequestSuccess( void )
|
||||
{
|
||||
(void)xEventGroupSetBits( xEventGroupMasterHdl, EV_MASTER_PROCESS_SUCCESS );
|
||||
ESP_LOGD(MB_PORT_TAG,"%s: Callback request success.", __func__);
|
||||
}
|
||||
|
||||
@ -273,14 +256,14 @@ void vMBMasterCBRequestSuccess( void ) {
|
||||
*/
|
||||
eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
eMBMasterEventType xRecvedEvent;
|
||||
eMBMasterEventEnum xRecvedEvent;
|
||||
|
||||
EventBits_t uxBits = xEventGroupWaitBits( xEventGroupMasterHdl, // The event group being tested.
|
||||
MB_EVENT_REQ_MASK, // The bits within the event group to wait for.
|
||||
pdTRUE, // Masked bits should be cleared before returning.
|
||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
portMAX_DELAY ); // Wait forever for either bit to be set.
|
||||
xRecvedEvent = (eMBMasterEventType)(uxBits);
|
||||
xRecvedEvent = (eMBMasterEventEnum)(uxBits);
|
||||
if (xRecvedEvent) {
|
||||
ESP_LOGD(MB_PORT_TAG,"%s: returned event = 0x%x", __func__, (int)xRecvedEvent);
|
||||
if (!(xRecvedEvent & MB_EVENT_REQ_MASK)) {
|
||||
@ -298,7 +281,7 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
|
||||
eErrStatus = MB_MRE_EXE_FUN;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(MB_PORT_TAG,"%s: Incorrect event or timeout xRecvedEvent = 0x%" PRIx32 "", __func__, (uint32_t)uxBits);
|
||||
ESP_LOGE(MB_PORT_TAG,"%s: Incorrect event or timeout xRecvedEvent = 0x%x", __func__, (int)uxBits);
|
||||
// https://github.com/espressif/esp-idf/issues/5275
|
||||
// if a no event is received, that means vMBMasterPortEventClose()
|
||||
// has been closed, so event group has been deleted by FreeRTOS, which
|
||||
@ -311,9 +294,22 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
|
||||
|
||||
void vMBMasterPortEventClose(void)
|
||||
{
|
||||
vEventGroupDelete(xEventGroupMasterHdl);
|
||||
vEventGroupDelete(xEventGroupMasterConfirmHdl);
|
||||
vEventGroupDelete(xResourceMasterHdl);
|
||||
if (xQueueMasterHdl) {
|
||||
vEventGroupDelete(xEventGroupMasterHdl);
|
||||
xQueueMasterHdl = NULL;
|
||||
}
|
||||
if (xQueueMasterHdl) {
|
||||
vQueueDelete(xQueueMasterHdl);
|
||||
xQueueMasterHdl = NULL;
|
||||
}
|
||||
if (xEventGroupMasterConfirmHdl) {
|
||||
vEventGroupDelete(xEventGroupMasterConfirmHdl);
|
||||
xEventGroupMasterConfirmHdl = NULL;
|
||||
}
|
||||
if (xResourceMasterHdl) {
|
||||
vSemaphoreDelete(xResourceMasterHdl);
|
||||
xResourceMasterHdl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,8 +27,8 @@
|
||||
extern BOOL xMBMasterPortSerialTxPoll(void);
|
||||
|
||||
/*-----------------------Master mode use these variables----------------------*/
|
||||
#define MB_RESPONSE_TICS pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND + 10)
|
||||
|
||||
// Actual wait time depends on the response timer
|
||||
#define MB_SERIAL_API_RESP_TICS (pdMS_TO_TICKS(MB_MAX_RESPONSE_TIME_MS))
|
||||
|
||||
static mb_master_interface_t* mbm_interface_ptr = NULL;
|
||||
static const char *TAG = "MB_CONTROLLER_MASTER";
|
||||
@ -176,7 +176,7 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
|
||||
eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY;
|
||||
esp_err_t error = ESP_FAIL;
|
||||
|
||||
if (xMBMasterRunResTake(MB_RESPONSE_TICS)) {
|
||||
if (xMBMasterRunResTake(MB_SERIAL_API_RESP_TICS)) {
|
||||
|
||||
uint8_t mb_slave_addr = request->slave_addr;
|
||||
uint8_t mb_command = request->command;
|
||||
@ -194,43 +194,43 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
|
||||
{
|
||||
case MB_FUNC_READ_COILS:
|
||||
mb_error = eMBMasterReqReadCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size , (LONG)MB_RESPONSE_TICS );
|
||||
(USHORT)mb_size , (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_WRITE_SINGLE_COIL:
|
||||
mb_error = eMBMasterReqWriteCoil((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
*(USHORT*)data_ptr, (LONG)MB_RESPONSE_TICS );
|
||||
*(USHORT*)data_ptr, (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_WRITE_MULTIPLE_COILS:
|
||||
mb_error = eMBMasterReqWriteMultipleCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (UCHAR*)data_ptr, (LONG)MB_RESPONSE_TICS);
|
||||
(USHORT)mb_size, (UCHAR*)data_ptr, (LONG)MB_SERIAL_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_READ_DISCRETE_INPUTS:
|
||||
mb_error = eMBMasterReqReadDiscreteInputs((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TICS );
|
||||
(USHORT)mb_size, (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_READ_HOLDING_REGISTER:
|
||||
mb_error = eMBMasterReqReadHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TICS );
|
||||
(USHORT)mb_size, (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_WRITE_REGISTER:
|
||||
mb_error = eMBMasterReqWriteHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
*(USHORT*)data_ptr, (LONG)MB_RESPONSE_TICS );
|
||||
*(USHORT*)data_ptr, (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
|
||||
case MB_FUNC_WRITE_MULTIPLE_REGISTERS:
|
||||
mb_error = eMBMasterReqWriteMultipleHoldingRegister( (UCHAR)mb_slave_addr,
|
||||
(USHORT)mb_offset, (USHORT)mb_size,
|
||||
(USHORT*)data_ptr, (LONG)MB_RESPONSE_TICS );
|
||||
(USHORT*)data_ptr, (LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_READWRITE_MULTIPLE_REGISTERS:
|
||||
mb_error = eMBMasterReqReadWriteMultipleHoldingRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (USHORT*)data_ptr,
|
||||
(USHORT)mb_offset, (USHORT)mb_size,
|
||||
(LONG)MB_RESPONSE_TICS );
|
||||
(LONG)MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
case MB_FUNC_READ_INPUT_REGISTER:
|
||||
mb_error = eMBMasterReqReadInputRegister( (UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG) MB_RESPONSE_TICS );
|
||||
(USHORT)mb_size, (LONG) MB_SERIAL_API_RESP_TICS );
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ", __FUNCTION__, (unsigned)mb_command);
|
||||
|
@ -29,9 +29,10 @@
|
||||
|
||||
/*-----------------------Master mode use these variables----------------------*/
|
||||
|
||||
// The response time is average processing time + data transmission
|
||||
#define MB_RESPONSE_TIMEOUT pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND)
|
||||
#define MB_TCP_CONNECTION_TOUT pdMS_TO_TICKS(CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000)
|
||||
#define MB_TCP_CONNECTION_TOUT (pdMS_TO_TICKS(CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000))
|
||||
|
||||
// Actual wait time depends on the response timer
|
||||
#define MB_TCP_API_RESP_TICS (pdMS_TO_TICKS(MB_MAX_RESPONSE_TIME_MS))
|
||||
|
||||
static mb_master_interface_t* mbm_interface_ptr = NULL;
|
||||
static const char *TAG = "MB_CONTROLLER_MASTER";
|
||||
@ -257,7 +258,7 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
|
||||
eMBMasterReqErrCode mb_error = MB_MRE_MASTER_BUSY;
|
||||
esp_err_t error = ESP_FAIL;
|
||||
|
||||
if (xMBMasterRunResTake(MB_RESPONSE_TIMEOUT)) {
|
||||
if (xMBMasterRunResTake(MB_TCP_API_RESP_TICS)) {
|
||||
|
||||
uint8_t mb_slave_addr = request->slave_addr;
|
||||
uint8_t mb_command = request->command;
|
||||
@ -275,44 +276,44 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
|
||||
{
|
||||
case MB_FUNC_READ_COILS:
|
||||
mb_error = eMBMasterReqReadCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
(USHORT)mb_size, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_WRITE_SINGLE_COIL:
|
||||
mb_error = eMBMasterReqWriteCoil((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
*(USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
*(USHORT *)data_ptr, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_WRITE_MULTIPLE_COILS:
|
||||
mb_error = eMBMasterReqWriteMultipleCoils((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (UCHAR *)data_ptr,
|
||||
(LONG)MB_RESPONSE_TIMEOUT);
|
||||
(LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_READ_DISCRETE_INPUTS:
|
||||
mb_error = eMBMasterReqReadDiscreteInputs((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
(USHORT)mb_size, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_READ_HOLDING_REGISTER:
|
||||
mb_error = eMBMasterReqReadHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
(USHORT)mb_size, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_WRITE_REGISTER:
|
||||
mb_error = eMBMasterReqWriteHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
*(USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
*(USHORT *)data_ptr, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
|
||||
case MB_FUNC_WRITE_MULTIPLE_REGISTERS:
|
||||
mb_error = eMBMasterReqWriteMultipleHoldingRegister((UCHAR)mb_slave_addr,
|
||||
(USHORT)mb_offset, (USHORT)mb_size,
|
||||
(USHORT *)data_ptr, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
(USHORT *)data_ptr, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_READWRITE_MULTIPLE_REGISTERS:
|
||||
mb_error = eMBMasterReqReadWriteMultipleHoldingRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (USHORT *)data_ptr,
|
||||
(USHORT)mb_offset, (USHORT)mb_size,
|
||||
(LONG)MB_RESPONSE_TIMEOUT);
|
||||
(LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
case MB_FUNC_READ_INPUT_REGISTER:
|
||||
mb_error = eMBMasterReqReadInputRegister((UCHAR)mb_slave_addr, (USHORT)mb_offset,
|
||||
(USHORT)mb_size, (LONG)MB_RESPONSE_TIMEOUT);
|
||||
(USHORT)mb_size, (LONG)MB_TCP_API_RESP_TICS);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ", __FUNCTION__, (unsigned)mb_command);
|
||||
@ -507,7 +508,6 @@ static esp_err_t mbc_tcp_master_get_parameter(uint16_t cid, char* name, uint8_t*
|
||||
} else {
|
||||
ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s",
|
||||
__FUNCTION__, (unsigned)reg_info.cid, (char*)esp_err_to_name(error));
|
||||
error = ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
free(pdata);
|
||||
// Set the type of parameter found in the table
|
||||
|
@ -655,7 +655,7 @@ static int xMBTCPPortMasterCheckConnState(fd_set *pxFdSet)
|
||||
return xCount;
|
||||
}
|
||||
|
||||
static void xMBTCPPortMasterFsmSetError(eMBMasterErrorEventType xErrType, eMBMasterEventType xPostEvent)
|
||||
static void xMBTCPPortMasterFsmSetError(eMBMasterErrorEventType xErrType, eMBMasterEventEnum xPostEvent)
|
||||
{
|
||||
vMBMasterPortTimersDisable();
|
||||
vMBMasterSetErrorType(xErrType);
|
||||
@ -861,7 +861,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
|
||||
} else if (xRet == ERR_BUF) {
|
||||
// After retries a response with incorrect TID received, process failure.
|
||||
xMBTCPPortMasterFsmSetError(EV_ERROR_RECEIVE_DATA, EV_MASTER_ERROR_PROCESS);
|
||||
ESP_LOGW(TAG, MB_SLAVE_FMT(", frame error."),
|
||||
ESP_LOGD(TAG, MB_SLAVE_FMT(", frame error."),
|
||||
(int)pxCurrInfo->xIndex, (int)pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
|
||||
} else {
|
||||
ESP_LOGE(TAG, MB_SLAVE_FMT(", critical error=%d."),
|
||||
|
@ -1,8 +1,8 @@
|
||||
version: "1.0.10"
|
||||
version: "1.0.11"
|
||||
description: ESP-MODBUS is the official Modbus library for Espressif SoCs.
|
||||
url: https://github.com/espressif/esp-modbus
|
||||
dependencies:
|
||||
idf: ">=4.1"
|
||||
idf: ">=4.3"
|
||||
files:
|
||||
exclude:
|
||||
- "docs/**/*"
|
||||
|
Reference in New Issue
Block a user