optical/NxFuncs/modbus/modbus_tcp.c

197 lines
4.9 KiB
C
Raw Normal View History

2025-09-04 01:45:08 +00:00
#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