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