197 lines
4.9 KiB
C
197 lines
4.9 KiB
C
|
|
|
|||
|
|
#include "modbus_tcp.h"
|
|||
|
|
#include "trigger.h"
|
|||
|
|
|
|||
|
|
#if (MAX_MODBUS_TCP_NODE > 0)
|
|||
|
|
#include "ethernet.h"
|
|||
|
|
|
|||
|
|
//------------------------------
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ
|
|||
|
|
typedef struct
|
|||
|
|
{
|
|||
|
|
SocketCtrl * pSocket;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD>ƿ<EFBFBD><C6BF><EFBFBD>
|
|||
|
|
int transing; // 0, <20><><EFBFBD><EFBFBD>; 1, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<F3A3ACB5><C8B4>ذ<EFBFBD>
|
|||
|
|
u16 transId; // <20><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD>㿪ʼ<E3BFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
u32 begtime; // <20><><EFBFBD>͵<EFBFBD>ʱ<EFBFBD><CAB1>
|
|||
|
|
int expectAnswerPduLen; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PDU<44><55><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>¼
|
|||
|
|
ModbusTcpADU request; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
ModbusTcpADU answer; // Ӧ<><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
}ModbusTcpCtrl;
|
|||
|
|
|
|||
|
|
//------------------------------
|
|||
|
|
|
|||
|
|
#define MODBUSTCP_SIDX TCP_CLIENT_SN_BEG
|
|||
|
|
|
|||
|
|
ModbusTcpCtrl g_modbusTcpCtrl[MAX_MODBUS_TCP_NODE];
|
|||
|
|
|
|||
|
|
//------------------------------
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#define ModbusTcpSendData EthernetSendData
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#define ModbusTcpGetData EthernetGetData
|
|||
|
|
// <20>ѽ<EFBFBD><D1BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
|||
|
|
#define ModbusTcpGetRsLen EthernetGetRsLen
|
|||
|
|
// <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD>
|
|||
|
|
#define ModbusTcpGetSdFreeLen EthernetGetSdFreeLen
|
|||
|
|
|
|||
|
|
//------------------------------
|
|||
|
|
|
|||
|
|
void InitModbusTcp()
|
|||
|
|
{
|
|||
|
|
int i;
|
|||
|
|
memset(&g_modbusTcpCtrl, 0, sizeof(ModbusTcpCtrl)*MAX_MODBUS_TCP_NODE);
|
|||
|
|
|
|||
|
|
for (i = 0; i < MAX_MODBUS_TCP_NODE; i++)
|
|||
|
|
{
|
|||
|
|
g_modbusTcpCtrl[i].pSocket = GetCtrlFromSocketIdx(MODBUSTCP_SIDX+i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20>첽<EFBFBD><ECB2BD><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>modbustcp<63><70><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ͨѶ
|
|||
|
|
void ModbusTcpServerRun(void)
|
|||
|
|
{
|
|||
|
|
int i;
|
|||
|
|
int rslt;
|
|||
|
|
ModbusTcpADU * pRequestAdu;
|
|||
|
|
ModbusTcpADU * pAnswerAdu;
|
|||
|
|
|
|||
|
|
for (i = 0; i < MAX_MODBUS_TCP_NODE; i++)
|
|||
|
|
{
|
|||
|
|
if (g_modbusTcpCtrl[i].transing == 1) // <20><><EFBFBD>ڷ<EFBFBD><DAB7>ͣ<EFBFBD><CDA3>ȴ<EFBFBD><C8B4>ذ<EFBFBD>
|
|||
|
|
{
|
|||
|
|
pRequestAdu = &(g_modbusTcpCtrl[i].request);
|
|||
|
|
pAnswerAdu = &(g_modbusTcpCtrl[i].answer);
|
|||
|
|
|
|||
|
|
rslt = ModbusTcpGetRsLen(g_modbusTcpCtrl[i].pSocket);
|
|||
|
|
if (rslt >= g_modbusTcpCtrl[i].expectAnswerPduLen)
|
|||
|
|
{
|
|||
|
|
rslt = ModbusTcpGetData(g_modbusTcpCtrl[i].pSocket, pAnswerAdu->datbuff, g_modbusTcpCtrl[i].expectAnswerPduLen);
|
|||
|
|
if (rslt == g_modbusTcpCtrl[i].expectAnswerPduLen)
|
|||
|
|
{
|
|||
|
|
if ( pRequestAdu->normal.transId == pAnswerAdu->normal.transId &&
|
|||
|
|
pRequestAdu->normal.cmd == pAnswerAdu->normal.cmd &&
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
1 )
|
|||
|
|
{
|
|||
|
|
// <20>յ<EFBFBD><D5B5><EFBFBD>ȷ<EFBFBD>ظ<EFBFBD>
|
|||
|
|
printf("get ModbusTcp %d ACK\r\n", i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
g_modbusTcpCtrl[i].transing = 0;
|
|||
|
|
}
|
|||
|
|
else if (rslt == LEN_ERR_ANSWER) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
rslt = ModbusTcpGetData(g_modbusTcpCtrl[i].pSocket, pAnswerAdu->datbuff, LEN_ERR_ANSWER);
|
|||
|
|
if (rslt == LEN_ERR_ANSWER)
|
|||
|
|
{
|
|||
|
|
if ( pRequestAdu->normal.transId == pAnswerAdu->normal.transId &&
|
|||
|
|
pRequestAdu->normal.cmd == (pAnswerAdu->normal.cmd | 0x80) &&
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
1 )
|
|||
|
|
{
|
|||
|
|
// <20>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>
|
|||
|
|
printf("get ModbusTcp %d NAK\r\n", i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
g_modbusTcpCtrl[i].transing = 0;
|
|||
|
|
}
|
|||
|
|
else if (rslt > 0)
|
|||
|
|
{
|
|||
|
|
printf("get ModbusTcp %d dat err len = %d\r\n", i, rslt); // <20><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD>
|
|||
|
|
g_modbusTcpCtrl[i].transing = 0;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
u32 time;
|
|||
|
|
time = GetMsSoftTimer();
|
|||
|
|
if (time - g_modbusTcpCtrl[i].begtime > 100)
|
|||
|
|
{
|
|||
|
|
printf("wait ModbusTcp %d answer timout\r\n", i); // <20><>ʱ
|
|||
|
|
g_modbusTcpCtrl[i].transing = 0;
|
|||
|
|
}
|
|||
|
|
// <20>ȴ<EFBFBD><C8B4><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
u16 SwapHighLow(u16 data)
|
|||
|
|
{
|
|||
|
|
u16 temp;
|
|||
|
|
temp = LOBYTE(data); // DATA_L
|
|||
|
|
temp <<= 8;
|
|||
|
|
temp += HIBYTE(data); // DATA_H;
|
|||
|
|
return temp;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>: д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|||
|
|
int ModbusTcpWriteRegs(int nidx, u16 addr, u16 * regAry, u16 nums)
|
|||
|
|
{
|
|||
|
|
int i, pdulen;
|
|||
|
|
ModbusTcpADU * pRequestAdu;
|
|||
|
|
// ModbusTcpADU * pAnswerAdu;
|
|||
|
|
|
|||
|
|
if (nidx < 0 || nidx > MAX_MODBUS_TCP_NODE || nums < 1 || regAry == NULL)
|
|||
|
|
{
|
|||
|
|
printf("ModbusTcpWriteRegs trans para err, nidx=%d, nums=%d\r\n", nidx, nums);
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (g_modbusTcpCtrl[nidx].transing != 0)
|
|||
|
|
{
|
|||
|
|
printf("ModbusTcpWriteRegs trans at %d is busy\r\n", nidx);
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (nums > MAX_WR_REG_NUMS)
|
|||
|
|
{
|
|||
|
|
nums = MAX_WR_REG_NUMS;
|
|||
|
|
}
|
|||
|
|
pdulen = 6 + nums*2;
|
|||
|
|
|
|||
|
|
pRequestAdu = &(g_modbusTcpCtrl[nidx].request);
|
|||
|
|
// pAnswerAdu = &(g_modbusTcpCtrl[nidx].answer);
|
|||
|
|
|
|||
|
|
//--------
|
|||
|
|
// MBAP
|
|||
|
|
pRequestAdu->writeRegArrayRequest.transId = SwapHighLow(g_modbusTcpCtrl[nidx].transId); // <20><><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|||
|
|
pRequestAdu->writeRegArrayRequest.protId = SwapHighLow(0); // Э<><D0AD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>MODBUS Э<><D0AD><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6>Ϊ0x00<30><30>0x00
|
|||
|
|
pRequestAdu->writeRegArrayRequest.len = SwapHighLow(pdulen + 1); // ֡<><D6A1><EFBFBD>ȡ<EFBFBD>
|
|||
|
|
pRequestAdu->writeRegArrayRequest.unitId = 0x01; // <20><>Ԫ<EFBFBD><D4AA>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
//--------
|
|||
|
|
// MODBUS PDU
|
|||
|
|
pRequestAdu->writeRegArrayRequest.cmd = WRITE_MULTIPLE_REGISTER; // д<><D0B4><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|||
|
|
pRequestAdu->writeRegArrayRequest.regBegAddr = SwapHighLow(addr); // <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ʼλ<CABC><CEBB>ַ 0x0000<30><30>0xFFFF
|
|||
|
|
pRequestAdu->writeRegArrayRequest.regsNum = SwapHighLow(nums); // <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x0001<30><31>0x007B<37><42>123<32><33>
|
|||
|
|
pRequestAdu->writeRegArrayRequest.bytes = nums * 2; // <20>ֽ<EFBFBD><D6BD><EFBFBD> N = <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> * 2
|
|||
|
|
for (i = 0; i < nums; i++)
|
|||
|
|
{
|
|||
|
|
pRequestAdu->writeRegArrayRequest.regsArray[i] = SwapHighLow(regAry[i]); // <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>MSB
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------
|
|||
|
|
// <20><>¼<EFBFBD><C2BC>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
g_modbusTcpCtrl[nidx].transing = 1; // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|||
|
|
g_modbusTcpCtrl[nidx].begtime = GetMsSoftTimer(); // <20><>¼<EFBFBD><C2BC>ʼ<EFBFBD><CABC><EFBFBD>͵<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
|||
|
|
g_modbusTcpCtrl[nidx].expectAnswerPduLen = 5;
|
|||
|
|
|
|||
|
|
g_modbusTcpCtrl[nidx].transId++;
|
|||
|
|
//--------
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
ModbusTcpSendData(g_modbusTcpCtrl[nidx].pSocket, pRequestAdu->datbuff, LEN_MBAP+pdulen);
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|