I have tried to implemented MODbust master on TCP on RCM 6700.
Havig really hard time with “int MBM_Send_ADU ( *ADUaddress, ADUlength );”
Any samples?
The following code extract should give you a start:
/*** BeginHeader MBM_Send_ADU_TCP */
int MBM_Send_ADU_TCP(uint32_t IPAddress, char *Packet, int ByteCount);
#define MMTCP_STATE_WAIT 0
#define MMTCP_STATE_STARTED 1
#define MMTCP_STATE_REMAINDER 2
#define MMTCP_STATE_DONE 3
#define MMTCP_STATE_ERROR 4
/*** EndHeader */
_modbus_dbg
int MBM_Send_ADU_TCP(uint32_t IPAddress, char *Packet, int ByteCount)
{
static tcp_Socket MMSocket;
static far char MMTCPBuffer[1024];
int i;
uint32_t ulTemp;
int16_t iTemp;
int iExpected;
int iMMTState;
int bytes_read;
char cDiscard;
int iResponse;
iResponse = MB_SUCCESS;
#if MODBUS_PRINT
if(cModbusPrintEnabled)
{
printf("Tx TCP:");
for(i=0; i 2)
break;
}
if(0 != sock_established(&MMSocket))
{
sock_flushnext(&MMSocket);
iTemp = sock_write(&MMSocket, Packet, ByteCount);
iExpected = MBM_HowMany(&Packet[6]) - 2; // Subtract CRC bytes
ulTemp = LocalTimeCorrected(); // Record when we sent packet
iMMTState = MMTCP_STATE_WAIT;
do
{
if((LocalTimeCorrected() - ulTemp) > 2) // Taking too long...
iMMTState = MMTCP_STATE_ERROR;
switch(iMMTState)
{
case MMTCP_STATE_WAIT:
if(sock_bytesready(&MMSocket) >= 8 ) // Got the minimum expected data so goto next stage
iMMTState = MMTCP_STATE_STARTED;
break;
case MMTCP_STATE_STARTED:
sock_read(&MMSocket, mbADU, 8 ); // Know this will not block as we checked in previous state...
if(mbADU[7] >= 0x80) // Not a good response...
iExpected = 1; // Just the error code to get
else
iExpected -= 2; // Have address and function code...
iMMTState = MMTCP_STATE_REMAINDER;
break;
case MMTCP_STATE_REMAINDER:
if(sock_bytesready(&MMSocket) >= iExpected)
{
sock_read(&MMSocket, &mbADU[8], iExpected);
sock_close(&MMSocket);
while(sock_bytesready(&MMSocket) != -1) // Flush any unread data just in case
{
sock_read(&MMSocket, &cDiscard, 1);
if((LocalTimeCorrected() - ulTemp) > 2) // Taking too long so...
{
sock_abort(&MMSocket);
break;
}
}
iMMTState = MMTCP_STATE_DONE;
}
break;
case MMTCP_STATE_ERROR:
sock_abort(&MMSocket);
return(MBM_PACKET_ERROR);
break;
}
} while(iMMTState != MMTCP_STATE_DONE);
// receive the response into the same buffer used for the transmit data
return(MB_SUCCESS);
}
else
sock_abort(&MMSocket);
}
return(MBM_PACKET_ERROR);
}
The LocalTimeCorrected() function is my own time function which takes into account the offset calculated via SNTP, you can just use the normal SEC_TIMER.
This code uses a fixed small 1024 byte buffer for the TCP socket for efficiency.
Regards,
Peter
2 Likes
Peter, you can use bbcode markup in your posts here. Wrap code in opening/closing “code” blocks, using square brackets. Not sure if I can embed it in my comment or not…
code goes here
Thanks for the tip Tom, done…
Thank you Peter, it’ll help me alot.
Regards,
Konstantin.