|
|
|
|
#include <iostream>
|
|
|
|
|
#include "modbus_lib/modbus-tcp.h"
|
|
|
|
|
#include "ysp_modbus_slave.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
# include <winsock2.h>
|
|
|
|
|
# include <ws2tcpip.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
#define REG_ADDR (header_length+1)
|
|
|
|
|
#define REG_NUM (header_length+3)
|
|
|
|
|
#define REG_VAL (header_length+3)
|
|
|
|
|
|
|
|
|
|
#define IP_LOCAL_ADDR "192.168.1.21"
|
|
|
|
|
#define TCP_PORT 502
|
|
|
|
|
#define MODBUS_UART "COM3" //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ò<EFBFBD><C3B2><EFBFBD> uart modbus
|
|
|
|
|
#define SERVER_ID 0x00000001 //Ĭ<>ϴӻ<CFB4><D3BB><EFBFBD>ַ
|
|
|
|
|
#define SLAVE_REG_ADDR 0x008E //<2F>ӻ<EFBFBD>modbus <20><>ַ<EFBFBD>ļĴ<C4BC><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
|
|
|
|
|
char slave_ip_addr[20] = { 0 }; //modbus slave tcp ip<69><70>ַ
|
|
|
|
|
unsigned short slave_tcp_port = TCP_PORT; //modbus slave tcp port<72>˿ں<CBBF>
|
|
|
|
|
|
|
|
|
|
extern int pro_delay_min;
|
|
|
|
|
|
|
|
|
|
ysp_modbus_regs_t ysp_modbus_data;
|
|
|
|
|
slave_add_t salve_addr = {0};
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
TCP,
|
|
|
|
|
TCP_PI,
|
|
|
|
|
RTU
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int xSlave_info_init()
|
|
|
|
|
{
|
|
|
|
|
salve_addr.slave_addr = SERVER_ID;
|
|
|
|
|
memset(&ysp_modbus_data, 0, sizeof(ysp_modbus_data));
|
|
|
|
|
//memcpy(slave_ip_addr, IP_LOCAL_ADDR, strlen(IP_LOCAL_ADDR));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//modbus <20>ӻ<EFBFBD>tcp ipaddr
|
|
|
|
|
void xSet_slave_ip_addr(const char* ip_addr)
|
|
|
|
|
{
|
|
|
|
|
if (ip_addr) {
|
|
|
|
|
memcpy(slave_ip_addr, ip_addr, strlen(ip_addr));
|
|
|
|
|
printf("slave_ip_addr=%s\n", slave_ip_addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
memcpy(slave_ip_addr, IP_LOCAL_ADDR, strlen(IP_LOCAL_ADDR));
|
|
|
|
|
printf("SLAVE_IP_ADDR is null,use default\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//modbus<75>ӻ<EFBFBD>tcp port
|
|
|
|
|
void xSet_slave_port(const char* tcp_port)
|
|
|
|
|
{
|
|
|
|
|
if (tcp_port) {
|
|
|
|
|
slave_tcp_port = atoi(tcp_port);
|
|
|
|
|
printf("tcp_port=%s\n", tcp_port);
|
|
|
|
|
printf("slave_tcp_port=%d\n", slave_tcp_port);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
slave_tcp_port = TCP_PORT;
|
|
|
|
|
printf("SLAVE_PORT is null,use default\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD> TCP Server socket
|
|
|
|
|
BYTE CreateTcpServerSock(int *LiSock, DWORD NetPort)
|
|
|
|
|
{
|
|
|
|
|
int i, tmp, ret, retval;
|
|
|
|
|
|
|
|
|
|
int len;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
u_long largp = 1L; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|
|
|
|
char tmp_buf[256];
|
|
|
|
|
|
|
|
|
|
if (-1 < *LiSock)
|
|
|
|
|
return *LiSock;
|
|
|
|
|
|
|
|
|
|
if (NetPort == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
*LiSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
|
|
|
|
|
|
if (*LiSock < 0)
|
|
|
|
|
{
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>socket<65><74><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|
|
|
|
retval = ioctlsocket(*LiSock, FIONBIO, (u_long FAR*)&largp);
|
|
|
|
|
if (SOCKET_ERROR == retval)
|
|
|
|
|
{
|
|
|
|
|
// retval = WSAGetLastError();
|
|
|
|
|
// sprintf(tmp_buf, "ioctlsocket<65><74><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD>, SocketError=%d, SocketId = %d", retval, *LiSock);
|
|
|
|
|
// DebugPrint(tmp_buf);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
///<2F><><EFBFBD><EFBFBD>socket<65><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
|
|
tmp = MODBUS_TCP_MAX_ADU_LENGTH;
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_RCVBUF, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
tmp = MODBUS_TCP_MAX_ADU_LENGTH;
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_SNDBUF, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
|
|
|
|
|
len = 4;
|
|
|
|
|
tmp_buf[0] = 1;
|
|
|
|
|
|
|
|
|
|
tmp = setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, len);
|
|
|
|
|
tmp = getsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, &len);
|
|
|
|
|
tmp = 1;
|
|
|
|
|
// setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
//set_keepalive(*LiSock, keep_alive, keep_idle, keep_interval, keep_count);
|
|
|
|
|
|
|
|
|
|
//<2F><>TCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
memset((char*)&addr, 0, sizeof(addr));
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
addr.sin_port = htons(NetPort);
|
|
|
|
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
|
|
|
|
|
//printf("TIP_(%04d): Port = %d, NetCommIpAddr(%08x), addr.sin_addr.s_addr(%08x)\n", getpid(), commid+1, *NetCommIpAddr, addr.sin_addr.s_addr);
|
|
|
|
|
if (bind(*LiSock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
|
|
|
|
{
|
|
|
|
|
//printf("errno = %d\n", errno);
|
|
|
|
|
//close(*LiSock);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
//printf("succeed!\n");
|
|
|
|
|
|
|
|
|
|
ret = listen(*LiSock, 4);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
//close(*LiSock);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return *LiSock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
char* com = (char*)lp;
|
|
|
|
|
CHAR rcv_buf[1024] = { 0 };
|
|
|
|
|
int s = -1,sockt=-1,extrasock=-1;
|
|
|
|
|
int i = 0;
|
|
|
|
|
int rc = 0;
|
|
|
|
|
modbus_t* ctx = NULL;
|
|
|
|
|
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];//<2F><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int header_length;
|
|
|
|
|
uint16_t* ptr,*ptr1;
|
|
|
|
|
int use_backend=TCP;
|
|
|
|
|
uint16_t reg_addr, reg_val, reg_num;
|
|
|
|
|
uint16_t tmp = 0;
|
|
|
|
|
modbus_mapping_t* mb_mapping;
|
|
|
|
|
fd_set fdset_ro, fdset_wr, fdset_ex;
|
|
|
|
|
struct timeval timeout;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
socklen_t addrlen;
|
|
|
|
|
//struct tcp_info info;
|
|
|
|
|
time_t ictime, recvtime;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
һ<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>master<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
<EFBFBD><EFBFBD> accept ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>accept
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
ctx = modbus_new_tcp(slave_ip_addr, slave_tcp_port);
|
|
|
|
|
//modbus_set_slave(ctx, SERVER_ID);
|
|
|
|
|
}
|
|
|
|
|
else if (use_backend == TCP_PI) {
|
|
|
|
|
ctx = modbus_new_tcp_pi(slave_ip_addr, "502");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ctx = modbus_new_rtu(MODBUS_UART, 115200, 'N', 8, 1);
|
|
|
|
|
modbus_set_slave(ctx, SERVER_ID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//modbus_set_indication_timeout(ctx, 4, 0);
|
|
|
|
|
header_length = modbus_get_header_length(ctx);
|
|
|
|
|
modbus_set_debug(ctx, TRUE);
|
|
|
|
|
printf("modbus set debug true\n");
|
|
|
|
|
|
|
|
|
|
mb_mapping = modbus_mapping_new(0, 0, sizeof(ysp_modbus_regs_t) / 2 + sizeof(slave_add_t) / 2, 0);
|
|
|
|
|
printf("total regs nums = %d\n", sizeof(ysp_modbus_regs_t) / 2 + sizeof(slave_add_t) / 2);
|
|
|
|
|
if (mb_mapping == NULL) {
|
|
|
|
|
fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno));
|
|
|
|
|
modbus_free(ctx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(;;){
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
if (s < 0) {
|
|
|
|
|
std::cout << "modbus start listen\n" << std::endl;
|
|
|
|
|
s = modbus_tcp_listen(ctx, 1);
|
|
|
|
|
if (-1 == s) {
|
|
|
|
|
std::cout << "modbus tcp listen fial,check ip or port,exit thread\n" << std::endl;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (use_backend == TCP_PI) {
|
|
|
|
|
if (s < 0) {
|
|
|
|
|
s = modbus_tcp_pi_listen(ctx, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
if (s < 0)
|
|
|
|
|
break;
|
|
|
|
|
FD_ZERO(&fdset_ro);
|
|
|
|
|
FD_ZERO(&fdset_wr);
|
|
|
|
|
FD_ZERO(&fdset_ex);
|
|
|
|
|
FD_SET(s, &fdset_ro);
|
|
|
|
|
FD_SET(s, &fdset_wr);
|
|
|
|
|
FD_SET(s, &fdset_ex);
|
|
|
|
|
memset((char*)&timeout, 0, sizeof(struct timeval));
|
|
|
|
|
if (select(s + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1)
|
|
|
|
|
{
|
|
|
|
|
Sleep(1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (FD_ISSET(s, &fdset_ex))
|
|
|
|
|
{
|
|
|
|
|
//printf("<22>رշ<D8B1><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>\n");
|
|
|
|
|
closesocket(s);
|
|
|
|
|
s = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (FD_ISSET(s, &fdset_ro))
|
|
|
|
|
{
|
|
|
|
|
std::cout << std::endl << "modbus accept wait connect (hold)\n" << std::endl;
|
|
|
|
|
sockt = modbus_tcp_accept(ctx, &s);
|
|
|
|
|
std::cout << "modbus accept new connect\n" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (use_backend == TCP_PI) {
|
|
|
|
|
modbus_tcp_pi_accept(ctx, &s);
|
|
|
|
|
}
|
|
|
|
|
ictime = time(NULL);
|
|
|
|
|
recvtime = ictime;
|
|
|
|
|
std::cout << "modbus receive loop\n" << std::endl;
|
|
|
|
|
for (;;) {//ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
#if 0
|
|
|
|
|
if (s < 0)
|
|
|
|
|
break;
|
|
|
|
|
FD_ZERO(&fdset_ro);
|
|
|
|
|
FD_ZERO(&fdset_wr);
|
|
|
|
|
FD_ZERO(&fdset_ex);
|
|
|
|
|
FD_SET(s, &fdset_ro);
|
|
|
|
|
FD_SET(s, &fdset_wr);
|
|
|
|
|
FD_SET(s, &fdset_ex);
|
|
|
|
|
memset((char*)&timeout, 0, sizeof(struct timeval));
|
|
|
|
|
if (select(s + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1)
|
|
|
|
|
{
|
|
|
|
|
//Sleep(1);
|
|
|
|
|
//continue; /* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>continue<75><65>*/
|
|
|
|
|
}else if (FD_ISSET(s, &fdset_ex))
|
|
|
|
|
{
|
|
|
|
|
//printf("<22>رշ<D8B1><D5B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>\n");
|
|
|
|
|
closesocket(s);
|
|
|
|
|
s = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (FD_ISSET(s, &fdset_ro))// accept(*s, (struct sockaddr *) &addr, &addrlen);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
//std::cout << std::endl << "second accept wait connect (hold)\n" << std::endl;
|
|
|
|
|
extrasock = accept(s, (struct sockaddr *) &addr, &addrlen);
|
|
|
|
|
//std::cout << "second accept new connect\n" << std::endl;
|
|
|
|
|
if (extrasock < 0)
|
|
|
|
|
;
|
|
|
|
|
else {
|
|
|
|
|
if (sockt < 0) {
|
|
|
|
|
sockt = extrasock;
|
|
|
|
|
extrasock = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
closesocket(extrasock);
|
|
|
|
|
extrasock = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (NULL == ctx)
|
|
|
|
|
return 0;
|
|
|
|
|
if (0 > sockt)
|
|
|
|
|
break;
|
|
|
|
|
FD_ZERO(&fdset_ro);
|
|
|
|
|
FD_ZERO(&fdset_wr);
|
|
|
|
|
FD_ZERO(&fdset_ex);
|
|
|
|
|
FD_SET(sockt, &fdset_ro);
|
|
|
|
|
FD_SET(sockt, &fdset_wr);
|
|
|
|
|
FD_SET(sockt, &fdset_ex);
|
|
|
|
|
ictime = time(NULL);
|
|
|
|
|
if (ictime - recvtime > pro_delay_min*10)
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
printf("TCP connection timeout of% d seconds, no valid data received", ictime - recvtime);
|
|
|
|
|
recvtime = ictime;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
memset((char*)&timeout, 0, sizeof(struct timeval));
|
|
|
|
|
if (select(sockt + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1)
|
|
|
|
|
{
|
|
|
|
|
Sleep(1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (FD_ISSET(sockt, &fdset_ex))
|
|
|
|
|
{
|
|
|
|
|
//printf("<22>ر<EFBFBD><D8B1><EFBFBD><D7BD><EFBFBD>\n");
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#if 1
|
|
|
|
|
if (FD_ISSET(sockt, &fdset_wr))
|
|
|
|
|
{
|
|
|
|
|
int ierrlen, ierr;
|
|
|
|
|
|
|
|
|
|
ierrlen = sizeof(ierr);
|
|
|
|
|
rc = getsockopt(sockt, SOL_SOCKET, SO_ERROR, (char *)&ierr, &ierrlen);
|
|
|
|
|
if (SOCKET_ERROR == rc)
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (FD_ISSET(sockt, &fdset_ro)) // <20>ɶ<EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
|
rc = modbus_receive(ctx, query);
|
|
|
|
|
/* Filtered queries return 0 */
|
|
|
|
|
} while (rc == 0);//<2F><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>᷵<EFBFBD><E1B7B5>0,CRC<52><43><EFBFBD><EFBFBD><EFBFBD>᷵<EFBFBD><E1B7B5>-1<><31>errno=EMBBADCRC,<2C><><EFBFBD><EFBFBD><EFBFBD>᷵<EFBFBD>ؽ<EFBFBD><D8BD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
/* The connection is not closed on errors which require on reply such as
|
|
|
|
|
bad CRC in RTU. */
|
|
|
|
|
if (rc == -1 && errno != EMBBADCRC) {
|
|
|
|
|
/* Quit */
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
std::cout << "error once connect over 1" << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (rc == -1)
|
|
|
|
|
{
|
|
|
|
|
if (errno == EMBBADCRC)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "bad crc in query" << std::endl;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
std::cout << "parse modbus frame error: %s\n" << std::endl;
|
|
|
|
|
std::cout << "error once connect over 2" << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//int len = sizeof(info);
|
|
|
|
|
//getsockopt(sockt, IPPROTO_TCP, TCP_INFO, &info, (socklen t *)&len);if (info.tcpi state == TCP CLOSE WAIT && info.tcpi state != TCP ESTABLISHED)
|
|
|
|
|
#if 0
|
|
|
|
|
rc = recv(sockt, rcv_buf, 1,0);
|
|
|
|
|
if (rc <= 0)
|
|
|
|
|
{
|
|
|
|
|
if (errno == ETIMEDOUT)
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
printf("Client TCP may unexpectedly interrupt!\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
Sleep(5);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recvtime = time(NULL);
|
|
|
|
|
std::cout << "modbus new msg\n" << std::endl;
|
|
|
|
|
switch (query[header_length])
|
|
|
|
|
{
|
|
|
|
|
case MODBUS_FC_READ_COILS://0x01 Read Coils in mb_mapping->tab_bits<74><73>IO<49><4F><EFBFBD><EFBFBD>״̬
|
|
|
|
|
printf("unsurported function 2\n");
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>,<2C>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
|
|
|
|
modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_READ_DISCRETE_INPUTS://0x02 Read Discrete Inputs in mb_mapping->tab_input_bits<74><73>IO<49><4F><EFBFBD><EFBFBD>״̬
|
|
|
|
|
printf("unsurported function 2\n");
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>,<2C>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
|
|
|
|
modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
|
|
|
|
|
continue;
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_READ_HOLDING_REGISTERS://0x03 Read Holding Registers in mb_mapping->tab_registers:REG<45><47><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|
|
|
|
std::cout << "modbus function 0x03\n" << std::endl;
|
|
|
|
|
if (MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) < (sizeof(ysp_modbus_regs_t) / 2 + sizeof(slave_add_t) / 2))
|
|
|
|
|
{
|
|
|
|
|
printf("reg vaild\n");
|
|
|
|
|
//<2F><>ȡʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>
|
|
|
|
|
if ((MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR) + MODBUS_GET_INT16_FROM_INT8(query, REG_NUM)) > (sizeof(ysp_modbus_regs_t) / 2) + (sizeof(slave_add_t) / 2))
|
|
|
|
|
{
|
|
|
|
|
printf("reply to this special register address by an exception\n");
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
|
|
|
|
|
modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
printf("update data\n");
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (fill_ysp_data(&ysp_modbus_data)) {
|
|
|
|
|
printf("get data from database fail, erase regs\n");
|
|
|
|
|
//memset(&ysp_modbus_data, 0, sizeof(&ysp_modbus_data)); <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8>ϴν<CFB4><CEBD><EFBFBD>
|
|
|
|
|
}
|
|
|
|
|
printf("time h32:%d\n", ysp_modbus_data.time_H32);
|
|
|
|
|
printf("time l32:%d\n", ysp_modbus_data.time_L32);
|
|
|
|
|
ptr = (uint16_t*)&ysp_modbus_data;
|
|
|
|
|
for (i = 0; i < (sizeof(ysp_modbus_regs_t) / 2); i++)
|
|
|
|
|
{
|
|
|
|
|
mb_mapping->tab_registers[i] = ptr[i];
|
|
|
|
|
}
|
|
|
|
|
ptr1 = (uint16_t*)&salve_addr;
|
|
|
|
|
mb_mapping->tab_registers[i] = ptr1[1];//iԽС<D4BD><D0A1>Խ<EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>
|
|
|
|
|
mb_mapping->tab_registers[i + 1] = ptr1[0];//ptr1[0] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ͵<C7B5>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
|
|
|
|
|
//mb_mapping->tab_registers[i] =0x3344;
|
|
|
|
|
//mb_mapping->tab_registers[i+1] = 0x5566;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_READ_INPUT_REGISTERS://0x04 Read Input Registers in mb_mapping->tab_input_registers:REG<45><47><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>ڶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ<EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD>ĵ<DEB8><C4B5><EFBFBD>,<2C>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_WRITE_SINGLE_COIL://0x05 Write Single Coil:slave_addr+cmd+reg_addr+[FF 00 or 00 00]+crc corresponding to mb_mapping->tab_bits
|
|
|
|
|
//д<><D0B4><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_WRITE_SINGLE_REGISTER://0x06 Write Single Register:slave_addr+cmd+reg_addr+reg_val+crc corresponding to mb_mapping->tab_registers
|
|
|
|
|
//д<><D0B4><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
|
|
|
|
printf("function code 0x06\n");
|
|
|
|
|
reg_addr = MODBUS_GET_INT16_FROM_INT8(query, REG_ADDR);
|
|
|
|
|
reg_val = MODBUS_GET_INT16_FROM_INT8(query, REG_VAL);
|
|
|
|
|
printf("reg_addr=%d reg_val=0x%04x\n", reg_addr, reg_val);
|
|
|
|
|
if (reg_addr == SLAVE_REG_ADDR)
|
|
|
|
|
{
|
|
|
|
|
printf("modify slave address succ\n");
|
|
|
|
|
salve_addr.slave_addr = reg_val;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_WRITE_MULTIPLE_COILS://0x0F Write Multiple Coils:slave_addr+cmd+reg_addr+coil_num+bit_arr+crc corresponding to mb_mapping->tab_bits
|
|
|
|
|
//д<><D0B4><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>,<2C>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
|
|
|
|
break;
|
|
|
|
|
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS://0x10 Write Multiple Registers:slave_addr+cmd+reg_addr+reg_num+reg_val_arr+crc corresponding to mb_mapping->tab_registers
|
|
|
|
|
//д<><D0B4><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|
|
|
|
break;
|
|
|
|
|
default://
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
|
|
|
|
|
rc = modbus_reply(ctx, query, rc, mb_mapping);
|
|
|
|
|
if (rc == -1) {
|
|
|
|
|
printf("reply modbus frame error:%s\n", modbus_strerror(errno));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int xModbus_task_init()
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3><CCA3><EFBFBD><EFBFBD>ؾ<EFBFBD><D8BE><EFBFBD>
|
|
|
|
|
int a = 0;
|
|
|
|
|
|
|
|
|
|
xSlave_info_init();
|
|
|
|
|
Sleep(10);
|
|
|
|
|
HANDLE h = CreateThread(NULL, 0, xModbus_msg_ThreadProc, NULL, 0, 0);
|
|
|
|
|
printf("start Modbus thread\n");
|
|
|
|
|
//WaitForSingleObject(h, INFINITE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//CloseHandle(h);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|