FreeModbus TCP传输初始化

先看一下初始化函数,参数只有端口。

/* modbus协议栈初始化 */
eMBErrorCode eMBTCPInit(USHORT ucTCPPort);

在网络通信过程中,502端口是专门为modbus保留的,其它应用不得占用该端口。在缺省配置的情况下,强制使用502端口。

FreeModbus TCP传输初始化_第1张图片

 

modbus协议栈的初始化,主要工作为tcp初始化,注册一些接口,设置节点号。

FreeModbus TCP传输初始化_第2张图片

特别要注意节点号问题,由于网络中通过IP地址寻址,因此节点号对于本机来说就没什么用了,本机必须使用0xFF。

 

但是对于专门用于通过以太网TCP-IP网络和MODBUS串行链路之间的网关对MODBUS或MODBUS+串行链路从站的通信来说。网关转发数据包给串行链路时,节点号被用来寻址从节点。

FreeModbus TCP传输初始化_第3张图片

 

modbus tcp端口初始化,主要就是创建modbus tcp服务器,监听端口,等待客户端连接。

/* modbus tcp端口初始化 */
BOOL xMBTCPPortInit(USHORT usTCPPort)
{
	struct tcp_pcb *pxPCBListenNew, *pxPCBListenOld;
	BOOL bOkay = FALSE;
	USHORT usPort;

	/* 默认端口502 */
	if(usTCPPort == 0)
	{
		usPort = MB_TCP_DEFAULT_PORT;
	}
	else
	{
		usPort = (USHORT)usTCPPort;
	}

	/* 创建tcp控制块 */
	if((pxPCBListenNew = pxPCBListenOld = tcp_new()) == NULL)
	{
		bOkay = FALSE;
	}
	/* 绑定端口 */
	else if(tcp_bind(pxPCBListenNew, IP_ADDR_ANY, (u16_t)usPort) != ERR_OK)
	{
		(void)tcp_close(pxPCBListenOld);
		bOkay = FALSE;
	}
	/* 监听端口 */
	else if((pxPCBListenNew = tcp_listen(pxPCBListenNew)) == NULL)
	{
		(void)tcp_close(pxPCBListenOld);
		bOkay = FALSE;
	}
	/* 注册连接回调函数 */
	else
	{
		tcp_accept(pxPCBListenNew, prvxMBTCPPortAccept);
		pxPCBListen = pxPCBListenNew;

	#ifdef MB_TCP_DEBUG
		vMBPortLog( MB_LOG_DEBUG, "MBTCP-ACCEPT", "Protocol stack ready.\r\n" );
#endif
	}
	bOkay = TRUE;
	return bOkay;
}

modbus tcp服务器同时只能接受一个客户端的连接。

/* 客户端连接回调函数 */
err_t prvxMBTCPPortAccept(void *pvArg, struct tcp_pcb *pxPCB, err_t xErr)
{
	err_t error;

	if(xErr != ERR_OK)
	{
		return xErr;
	}

	/* 之前没有客户端连接 */
	if(pxPCBClient == NULL)
	{
		pxPCBClient = pxPCB;

		/* 注册接收回调函数 */
		tcp_recv(pxPCB, prvxMBTCPPortReceive);

		/* 注册错误回调函数 */
		tcp_err(pxPCB, prvvMBTCPPortError);

		/* 回调函数参数 */
		tcp_arg(pxPCB, pxPCB);

		/* 接收字节数置0 */
		usTCPBufPos = 0;

#ifdef MB_TCP_DEBUG
		vMBPortLog(MB_LOG_DEBUG, "MBTCP-ACCEPT", "Accepted new client %d.%d.%d.%d\r\n",
							 ip4_addr1(&(pxPCB->remote_ip)), ip4_addr2(&(pxPCB->remote_ip)),
							 ip4_addr3(&(pxPCB->remote_ip)), ip4_addr4(&(pxPCB->remote_ip)));
#endif

		error = ERR_OK;
	}
	/* 已经有客户端连接,不允许第二个客户端连接 */
	else
	{
		prvvMBPortReleaseClient(pxPCB);
		error = ERR_OK;
	}

	return error;
}

 

你可能感兴趣的:(Modbus)