Skip to content
Snippets Groups Projects
Commit 10dccf3b authored by al.schwinn's avatar al.schwinn
Browse files

[SIL-251] Modbus controller does not reconnect properly in case of

network failure (and sporadic crash)
parent 8c53ebaa
No related branches found
No related tags found
No related merge requests found
...@@ -26,8 +26,25 @@ namespace Silecs ...@@ -26,8 +26,25 @@ namespace Silecs
MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC) MBConnection::MBConnection(PLC* thePLC) : Connection(thePLC)
{ {
LOG(ALLOC) << "MBConnection (create): " << thePLC->getName(); LOG(ALLOC) << "MBConnection (create): " << thePLC->getName();
readCtx_ = writeCtx_ = NULL;
//Connection use IP address to limit the naming-server accesses
readCtx_ = modbus_new_tcp((char *) thePLC->getIPAddress().c_str(), MODBUS_TCP_DEFAULT_PORT /*=502*/);
writeCtx_ = modbus_new_tcp((char *) thePLC->getIPAddress().c_str(), MODBUS_TCP_DEFAULT_PORT /*=502*/);
/*TODO: To be adjusted with the next stable libmodbus release (>3.1.1)
which will fix the current timeout response time issue (see libmodbus forum).
Define Modbus response timeout
struct timeval response_timeout;
response_timeout.tv_sec = 0;
response_timeout.tv_usec = 10000;
modbus_set_response_timeout(readCtx_ , &response_timeout);
modbus_set_response_timeout(writeCtx_ , &response_timeout);
*/
//modbus_set_debug(*ctx, TRUE);
} }
...@@ -35,25 +52,24 @@ namespace Silecs ...@@ -35,25 +52,24 @@ namespace Silecs
{ {
//Close the connection before removing resources //Close the connection before removing resources
//disable(); must be done before removing resource //disable(); must be done before removing resource
modbus_free(writeCtx_);
modbus_free(readCtx_);
} }
bool MBConnection::open(PLC* thePLC) bool MBConnection::open(PLC* thePLC)
{ {
//Open read and write Modbus channels (using IP address to limit the naming-server accesses) int readErr = modbus_connect(readCtx_);
int readErr = IeMdbOpen(&readCtx_, NULL, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress()); int writeErr = modbus_connect(writeCtx_);
int writeErr = IeMdbOpen(&writeCtx_, NULL, (char *) thePLC->getIPAddress().c_str(), (int)thePLC->getBaseAddress()); return ((readErr != -1) && (writeErr != -1));
return ((readErr == 0) && (writeErr == 0));
} }
bool MBConnection::close(PLC* thePLC) bool MBConnection::close(PLC* thePLC)
{ {
int err = 0; modbus_close(readCtx_);
err |= IeMdbClose(readCtx_); modbus_close(writeCtx_);
err |= IeMdbClose(writeCtx_); return true;
readCtx_ = writeCtx_ = NULL;
return (err == 0);
} }
......
...@@ -109,50 +109,6 @@ double IeMdbGetTime(unsigned char *dt) // from PLC ...@@ -109,50 +109,6 @@ double IeMdbGetTime(unsigned char *dt) // from PLC
return((double)plctm + ms); return((double)plctm + ms);
} }
/*----------------------------------------------------------*/
/* This function creates a synchronous OSI-ON-TCP socket
* channel used for sending/receiving communication with PLC.
* 'hostName': Name of the host (in)
* 'plcIP': PLC ip address string (in)
* return socket descriptor or <0 on error (see const. error)
*
* Details:
* 'plcIP' parameter is necessary only when 'hostName' is NULL.
* Only one synchronous channel per PLC at the same time
* supported in that version.
*/
int IeMdbOpen (modbus_t** ctx, char *hostName, char *plcIP, int baseAddress)
{
*ctx = modbus_new_tcp(plcIP, MODBUS_TCP_DEFAULT_PORT /*=502*/);
//modbus_set_debug(*ctx, TRUE);
if (modbus_connect(*ctx) == -1)
{
modbus_free(*ctx);
return IE_CONNECT_ERROR;
}
return 0;
}
/*----------------------------------------------------------*/
/* This function closes the synchronous OSI-ON-TCP socket
* channel.
* 'sk': socket descriptor (in) - MUST BE a synch. pipe
* return 0 or <0 on error (see constant error)
*
* Details:
*/
int IeMdbClose(modbus_t* ctx)
{
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
return 0;
}
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
int IeMBwriteData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data) int IeMBwriteData(modbus_t* ctx, uint16_t start_addr, uint16_t count, uint8_t* data)
{ {
......
...@@ -36,20 +36,6 @@ void IeMdbSetTime(unsigned char *dt, time_t epoch); // to PLC ...@@ -36,20 +36,6 @@ void IeMdbSetTime(unsigned char *dt, time_t epoch); // to PLC
*/ */
double IeMdbGetTime(unsigned char *dt); // from PLC double IeMdbGetTime(unsigned char *dt); // from PLC
/*----------------------------------------------------------*/
/* This function creates a synchronous OSI-ON-TCP socket
* channel used for sending/receiving communication with PLC.
* 'hostName': Name of the host (in)
* 'plcIP': PLC ip address string (in)
* return socket descriptor or <0 on error (see const. error)
*
* Details:
* 'plcIP' parameter is necessary only when 'hostName' is NULL.
* Only one synchronous channel per PLC at the same time
* supported in that version.
*/
int IeMdbOpen (modbus_t** ctx, char *hostName, char *plcIP, int baseAddress);
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
/* This function send a data segment to the PLC using the /* This function send a data segment to the PLC using the
* MODBUS protocole. * MODBUS protocole.
...@@ -72,15 +58,5 @@ int IeMBwriteData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t* ...@@ -72,15 +58,5 @@ int IeMBwriteData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t*
*/ */
int IeMBreadData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t* dataBuffer); int IeMBreadData(modbus_t* ctx, uint16_t dataAddr, uint16_t dataSize, uint8_t* dataBuffer);
/*----------------------------------------------------------*/
/* This function closes the synchronous OSI-ON-TCP socket
* channel.
* 'cid1': connection id (in) - MUST BE a synch. pipe
* return 0 or <0 on error (see constant error)
*
* Details:
*/
int IeMdbClose(modbus_t* ctx);
#endif /* _IEMDB_H_ */ #endif /* _IEMDB_H_ */
#endif //MODBUS_SUPPORT_ENABLED #endif //MODBUS_SUPPORT_ENABLED
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment