mirror of
https://github.com/espressif/esp-modbus.git
synced 2026-08-03 20:24:09 +02:00
modbus tcp fix uid settings
This commit is contained in:
@@ -143,6 +143,7 @@ typedef union {
|
||||
// TCP/UDP communication structure
|
||||
struct {
|
||||
mb_mode_type_t ip_mode; /*!< Modbus communication mode */
|
||||
uint8_t slave_uid; /*!< Modbus slave address field for UID */
|
||||
uint16_t ip_port; /*!< Modbus port */
|
||||
mb_tcp_addr_type_t ip_addr_type; /*!< Modbus address type */
|
||||
void* ip_addr; /*!< Modbus address table for connection */
|
||||
|
||||
@@ -165,6 +165,7 @@ eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
|
||||
* frame processing is still disabled until eMBEnable( ) is called.
|
||||
*
|
||||
* \param usTCPPort The TCP port to listen on.
|
||||
* \param ucSlaveUid The UID field for slave to listen on.
|
||||
* \return If the protocol stack has been initialized correctly the function
|
||||
* returns eMBErrorCode::MB_ENOERR. Otherwise one of the following error
|
||||
* codes is returned:
|
||||
@@ -172,7 +173,7 @@ eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
|
||||
* slave addresses are in the range 1 - 247.
|
||||
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
|
||||
*/
|
||||
eMBErrorCode eMBTCPInit( USHORT usTCPPort );
|
||||
eMBErrorCode eMBTCPInit( UCHAR ucSlaveUid, USHORT usTCPPort );
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Release resources used by the protocol stack.
|
||||
|
||||
@@ -86,6 +86,10 @@ PR_BEGIN_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
/*! \brief The option is required for support of RTU over TCP.
|
||||
*/
|
||||
#define MB_TCP_UID_ENABLED ( CONFIG_FMB_TCP_UID_ENABLED )
|
||||
|
||||
/*! \brief This option defines the number of data bits per ASCII character.
|
||||
*
|
||||
* A parity bit is added before the stop bit which keeps the actual byte size at 10 bits.
|
||||
|
||||
+12
-6
@@ -202,11 +202,16 @@ eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eM
|
||||
|
||||
#if MB_TCP_ENABLED > 0
|
||||
eMBErrorCode
|
||||
eMBTCPInit( USHORT ucTCPPort )
|
||||
eMBTCPInit( UCHAR ucSlaveUid, USHORT ucTCPPort )
|
||||
{
|
||||
eMBErrorCode eStatus = MB_ENOERR;
|
||||
|
||||
if( ( eStatus = eMBTCPDoInit( ucTCPPort ) ) != MB_ENOERR )
|
||||
/* Check preconditions */
|
||||
if( ucSlaveUid > MB_ADDRESS_MAX )
|
||||
{
|
||||
eStatus = MB_EINVAL;
|
||||
}
|
||||
else if( ( eStatus = eMBTCPDoInit( ucTCPPort ) ) != MB_ENOERR )
|
||||
{
|
||||
eMBState = STATE_DISABLED;
|
||||
}
|
||||
@@ -222,7 +227,7 @@ eMBTCPInit( USHORT ucTCPPort )
|
||||
peMBFrameReceiveCur = eMBTCPReceive;
|
||||
peMBFrameSendCur = eMBTCPSend;
|
||||
pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBTCPPortClose : NULL;
|
||||
ucMBAddress = MB_TCP_PSEUDO_ADDRESS;
|
||||
ucMBAddress = ucSlaveUid;
|
||||
eMBCurrentMode = MB_TCP;
|
||||
eMBState = STATE_DISABLED;
|
||||
}
|
||||
@@ -371,7 +376,8 @@ eMBPoll( void )
|
||||
if( eStatus == MB_ENOERR )
|
||||
{
|
||||
/* Check if the frame is for us. If not ignore the frame. */
|
||||
if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
|
||||
if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST )
|
||||
|| ( ucRcvAddress == MB_TCP_PSEUDO_ADDRESS ) )
|
||||
{
|
||||
( void )xMBPortEventPost( EV_EXECUTE );
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_PORT_TAG, &ucMBFrame[MB_PDU_FUNC_OFF], usLength, ESP_LOG_DEBUG);
|
||||
@@ -401,8 +407,8 @@ eMBPoll( void )
|
||||
}
|
||||
|
||||
/* If the request was not sent to the broadcast address we
|
||||
* return a reply. */
|
||||
if( ucRcvAddress != MB_ADDRESS_BROADCAST )
|
||||
* return a reply. In case of TCP the slave answers to broadcast address. */
|
||||
if( ( ucRcvAddress != MB_ADDRESS_BROADCAST ) || ( eMBCurrentMode == MB_TCP ) )
|
||||
{
|
||||
if( eException != MB_EX_NONE )
|
||||
{
|
||||
|
||||
@@ -124,10 +124,14 @@ eMBTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLength )
|
||||
*pusLength = usLength - MB_TCP_FUNC;
|
||||
eStatus = MB_ENOERR;
|
||||
|
||||
/* Modbus TCP does not use any addresses. Fake the source address such
|
||||
* that the processing part deals with this frame.
|
||||
/* The regular Modbus TCP does not use any addresses. Fake the MBAP UID in this case.
|
||||
* The MBAP UID field support is used for RTU over TCP option if enabled.
|
||||
*/
|
||||
#if MB_TCP_UID_ENABLED
|
||||
*pucRcvAddress = pucMBTCPFrame[MB_TCP_UID];
|
||||
#else
|
||||
*pucRcvAddress = MB_TCP_PSEUDO_ADDRESS;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -152,6 +156,7 @@ eMBTCPSend( UCHAR _unused, const UCHAR * pucFrame, USHORT usLength )
|
||||
*/
|
||||
pucMBTCPFrame[MB_TCP_LEN] = ( usLength + 1 ) >> 8U;
|
||||
pucMBTCPFrame[MB_TCP_LEN + 1] = ( usLength + 1 ) & 0xFF;
|
||||
|
||||
if( xMBTCPPortSendResponse( pucMBTCPFrame, usTCPLength ) == FALSE )
|
||||
{
|
||||
eStatus = MB_EIO;
|
||||
|
||||
@@ -123,10 +123,14 @@ eMBMasterTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLeng
|
||||
*pusLength = usLength - MB_TCP_FUNC;
|
||||
eStatus = MB_ENOERR;
|
||||
|
||||
/* Modbus TCP does not use any addresses. Fake the source address such
|
||||
* that the processing part deals with this frame.
|
||||
/* Get MBAP UID field if its support is enabled.
|
||||
* Otherwise just ignore this field.
|
||||
*/
|
||||
#if MB_TCP_UID_ENABLED
|
||||
*pucRcvAddress = pucMBTCPFrame[MB_TCP_UID];
|
||||
#else
|
||||
*pucRcvAddress = MB_TCP_PSEUDO_ADDRESS;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -137,20 +141,27 @@ eMBMasterTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLeng
|
||||
}
|
||||
|
||||
eMBErrorCode
|
||||
eMBMasterTCPSend( UCHAR _unused, const UCHAR * pucFrame, USHORT usLength )
|
||||
eMBMasterTCPSend( UCHAR ucAddress, const UCHAR * pucFrame, USHORT usLength )
|
||||
{
|
||||
eMBErrorCode eStatus = MB_ENOERR;
|
||||
UCHAR *pucMBTCPFrame = ( UCHAR * ) pucFrame - MB_TCP_FUNC;
|
||||
USHORT usTCPLength = usLength + MB_TCP_FUNC;
|
||||
|
||||
/* The MBAP header is already initialized because the caller calls this
|
||||
* function with the buffer returned by the previous call. Therefore we
|
||||
* only have to update the length in the header. Note that the length
|
||||
* header includes the size of the Modbus PDU and the UID Byte. Therefore
|
||||
* the length is usLength plus one.
|
||||
/* Note that the length in the MBAP header includes the size of the Modbus PDU
|
||||
* and the UID Byte. Therefore the length is usLength plus one.
|
||||
*/
|
||||
pucMBTCPFrame[MB_TCP_LEN] = ( usLength + 1 ) >> 8U;
|
||||
pucMBTCPFrame[MB_TCP_LEN + 1] = ( usLength + 1 ) & 0xFF;
|
||||
|
||||
/* Set UID field in the MBAP if it is supported.
|
||||
* If the RTU over TCP is not supported, the UID = 0 or 0xFF.
|
||||
*/
|
||||
#if MB_TCP_UID_ENABLED
|
||||
pucMBTCPFrame[MB_TCP_UID] = ucAddress;
|
||||
#else
|
||||
pucMBTCPFrame[MB_TCP_UID] = 0x00;
|
||||
#endif
|
||||
|
||||
if( xMBMasterTCPPortSendResponse( pucMBTCPFrame, usTCPLength ) == FALSE )
|
||||
{
|
||||
eStatus = MB_EIO;
|
||||
|
||||
@@ -50,7 +50,7 @@ void eMBMasterTCPStart( void );
|
||||
void eMBMasterTCPStop( void );
|
||||
eMBErrorCode eMBMasterTCPReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame,
|
||||
USHORT * pusLength );
|
||||
eMBErrorCode eMBMasterTCPSend( UCHAR _unused, const UCHAR * pucFrame,
|
||||
eMBErrorCode eMBMasterTCPSend( UCHAR ucAddress, const UCHAR * pucFrame,
|
||||
USHORT usLength );
|
||||
BOOL xMBMasterTCPTimerExpired(void);
|
||||
|
||||
|
||||
@@ -989,6 +989,7 @@ xMBMasterTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
|
||||
// Apply TID field to the frame before send
|
||||
pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U);
|
||||
pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF);
|
||||
|
||||
int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS);
|
||||
if (xRes < 0) {
|
||||
ESP_LOGE(TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."),
|
||||
|
||||
@@ -72,7 +72,7 @@ static esp_err_t mbc_tcp_slave_start(void)
|
||||
eMBErrorCode status = MB_EIO;
|
||||
|
||||
// Initialize Modbus stack using mbcontroller parameters
|
||||
status = eMBTCPInit((USHORT)mbs_opts->mbs_comm.ip_port);
|
||||
status = eMBTCPInit((UCHAR)mbs_opts->mbs_comm.slave_uid, (USHORT)mbs_opts->mbs_comm.ip_port);
|
||||
MB_SLAVE_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
|
||||
"mb stack initialization failure, eMBInit() returns (0x%x).", status);
|
||||
|
||||
|
||||
@@ -106,8 +106,9 @@ static void* vxMBTCPPortRespQueueRecv(QueueHandle_t xRespQueueHandle)
|
||||
BaseType_t xStatus = xQueueReceive(xRespQueueHandle,
|
||||
(void*)&pvResp,
|
||||
pdMS_TO_TICKS(MB_TCP_RESP_TIMEOUT_MS));
|
||||
MB_PORT_CHECK((xStatus == pdTRUE), NULL, "Could not get respond confirmation.");
|
||||
MB_PORT_CHECK((pvResp), NULL, "Incorrect response processing.");
|
||||
if (xStatus != pdTRUE) {
|
||||
ESP_LOGD(TAG, "Could not get respond confirmation.");
|
||||
}
|
||||
return pvResp;
|
||||
}
|
||||
|
||||
@@ -599,7 +600,7 @@ static void vMBTCPPortServerTask(void *pvParameters)
|
||||
// Wait while response is not processed by stack by timeout
|
||||
UCHAR* pucSentBuffer = vxMBTCPPortRespQueueRecv(xConfig.xRespQueueHandle);
|
||||
if (pucSentBuffer == NULL) {
|
||||
ESP_LOGE(TAG, "Response time exceeds configured %d [ms], ignore packet.",
|
||||
ESP_LOGD(TAG, "Response is ignored, time exceeds configured %d [ms].",
|
||||
MB_TCP_RESP_TIMEOUT_MS);
|
||||
} else {
|
||||
USHORT usSentTid = MB_TCP_GET_FIELD(pucSentBuffer, MB_TCP_TID);
|
||||
|
||||
Reference in New Issue
Block a user