Merging release 2.0 branch with CVS trunk
r2601 | ffr | 2008-05-30 10:26:57 +1000 (Fri, 30 May 2008) | 2 lines
This commit is contained in:
committed by
Douglas Clowes
parent
4a937e1608
commit
0749b0effa
135
site_ansto/hardsup/modbustcp.c
Normal file
135
site_ansto/hardsup/modbustcp.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
M O D B U S T C P . C
|
||||
|
||||
Paul Barron, January 2008
|
||||
|
||||
RTU Modbus functions designed for use with the WEST4100 Temperature Controller.
|
||||
If another modbus device is required at ANSTO sections of this code will need
|
||||
to be modified.
|
||||
|
||||
MBAP: Modbus Application Protocol Header
|
||||
PDU: Protocol Data Unit
|
||||
|
||||
Modbus TCP Packet Format
|
||||
| MBAP | PDU |
|
||||
|Transact Identifier|Protocol Identifier|Length Field|Unit ID|Funct Code|Data|
|
||||
| 2 Bytes | 2 Bytes | 2 Bytes | 1 Byte| 1 Byte | n |
|
||||
|
||||
Paul Barron, January 2008
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <rs232controller.h>
|
||||
#include "modbustcp.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int ModbusTCPException(unsigned char *response);
|
||||
|
||||
int MsgGenModbusTCP(unsigned char *ModbusMsg, int ModbusMsgLength, unsigned char *TcpPacket,
|
||||
int *TcpPacketLength)
|
||||
{
|
||||
unsigned char MBAPbyte1 = 1, MBAPbyte2 = 1;
|
||||
unsigned char lengthByte1, lengthByte2;
|
||||
int index;
|
||||
|
||||
// Check if Device Address is Valid. This is based on RS485 having up to
|
||||
// 32 devices, since we currently only have one device this won't be a problem.
|
||||
if ((ModbusMsg[0] > 32) || (ModbusMsg[0] < 1))
|
||||
{
|
||||
printf("Error: Modbus Address out of Range: %X\n",ModbusMsg[0]);
|
||||
return MODBUSTCP_BadDataAddress;
|
||||
}
|
||||
|
||||
// Check if Function code is Valid
|
||||
if ((ModbusMsg[1] > 16) || (ModbusMsg[1] < 1))
|
||||
{
|
||||
printf("Error: Modbus Function Code Invalid: %X\n",ModbusMsg[1]);
|
||||
return MODBUSTCP_BadFunction;
|
||||
}
|
||||
|
||||
// Calculate Legth Field
|
||||
// Length should never be greater than 255 but just in case.
|
||||
if ((ModbusMsgLength)>255){
|
||||
lengthByte1=ModbusMsgLength/255;
|
||||
lengthByte2=ModbusMsgLength%255;
|
||||
}
|
||||
else{
|
||||
lengthByte1=0;
|
||||
lengthByte2=ModbusMsgLength;
|
||||
}
|
||||
|
||||
sprintf((char *)TcpPacket,"%c%c%c%c%c%c",MBAPbyte1,MBAPbyte2,0,0,lengthByte1,lengthByte2);
|
||||
|
||||
for(index=0;index<=ModbusMsgLength;index++)sprintf((char *)&TcpPacket[index+6],"%c",ModbusMsg[index]);
|
||||
|
||||
*TcpPacketLength=ModbusMsgLength+6;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int transactModbusTCP(prs232 self, unsigned char *query, int queryLength, unsigned char *response, int responseLength)
|
||||
{
|
||||
unsigned char TCPquery[40];
|
||||
int iRet, index, TCPqueryLength;
|
||||
|
||||
// Generate the TCP message
|
||||
iRet=MsgGenModbusTCP(query,queryLength,TCPquery,&TCPqueryLength);
|
||||
|
||||
// Send the message and Read the reply
|
||||
memset(response,0,responseLength); // puts zeros in reply up until reply length
|
||||
if ((iRet=transactRS232(self,TCPquery,/*strlen(pCommand)*/12,response,20))<=0)
|
||||
{
|
||||
printf("Comms error!\n");
|
||||
return iRet; // Comms problem
|
||||
}
|
||||
|
||||
// Check that the response transact and protocol identifier are the same
|
||||
if( (strncmp((char *)TCPquery,(char *)response,3)) == 0)
|
||||
{
|
||||
// Check that there is not a modbus error, see page 98 from WEST4100 User manual.
|
||||
if ( response[7] > 0x80 )
|
||||
{
|
||||
iRet=ModbusTCPException(response);
|
||||
|
||||
return iRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return the modbus response minus the TCP Header
|
||||
for(index=0;index<6;index++)
|
||||
response[index]=response[index+6];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
return MODBUSTCP_TCPError;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int ModbusTCPException(unsigned char *response)
|
||||
{
|
||||
if(response[8] == 0x01){
|
||||
printf("Exception Code 01h: Illegal Function\n");
|
||||
return MODBUSTCP_IllegalFunction;
|
||||
}else if(response[8] == 0x02){
|
||||
printf("Exception Code 02h: Illegal Data Address\n");
|
||||
return MODBUSTCP_IllegalDataAddress;
|
||||
}else if(response[8] == 0x03){
|
||||
printf("Exception Code 03h: Illegal Data Value\n");
|
||||
return MODBUSTCP_IllegalDataValue;
|
||||
}else{
|
||||
printf("Error code is greater than 81h, 82h or 83h\n");
|
||||
return MODBUSTCP_UnsupportedError;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
Reference in New Issue
Block a user