ZYNQ TCP client 一种断连检测&重连方法

ZYNQ TCP client 断连检测

  • 定时向服务器发送数据,如果数据发送失败,lwip会执行用户注册的错误回调函数
  • 在回调函数中删除连接,并复位phy(硬复位或软复位,防止 phy内部出现错误)
  • 在主循环定时检测连接状态,进行重新连接

1.在应用层读写phy寄存器

在应用层能获取phy状态的关键是使用phy读取函数,phy读取函数的关键参数是XEmacPs的实例。

LONG XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
		     u32 RegisterNum, u16 *PhyDataPtr)

追踪zynq lwip初始化步骤就会发现,在low_level_init 函数返回时,netif->state中保存了xemac的指针,而xemac->state 中保存了 xemacpsif的指针。

static err_t low_level_init(struct netif *netif)
{
	UINTPTR mac_address = (UINTPTR)(netif->state);
	struct xemac_s *xemac;
	xemacpsif_s *xemacpsif;
	s32_t status = XST_SUCCESS;
	NetIf = netif;

	xemacpsif = mem_malloc(sizeof *xemacpsif);
	xemac = mem_malloc(sizeof *xemac);

	xemac->state = (void *)xemacpsif;

...........省略.............

	/* replace the state in netif (currently the emac baseaddress)
	 * with the mac instance pointer.
	 */
	netif->state = (void *)xemac;

	return ERR_OK;
}

而xemacpsif 结构体中保存了我们需要的XEmacPs实例。

/* structure within each netif, encapsulating all information required for
 * using a particular temac instance
 */
typedef struct {
	XEmacPs emacps;

	/* queue to store overflow packets */
	pq_queue_t *recv_q;
	pq_queue_t *send_q;

	/* pointers to memory holding buffer descriptors (used only with SDMA) */
	void *rx_bdspace;
	void *tx_bdspace;

	unsigned int last_rx_frms_cntr;

} xemacpsif_s;

2. 网线断开重连逻辑

//错误处理函数
static void client_err(void *arg, err_t err)
{
	close_tcp_client();
}

void close_tcp_client(void)
{
	err_t err1;
	if (client_pcb != NULL) {
		tcp_close(client_pcb);
		tcp_sent(client_pcb, NULL);
		tcp_err(client_pcb, NULL);
		err1 = tcp_close(client_pcb);
		if (err1 != ERR_OK) {
			/* Free memory with abort */
			tcp_abort(client_pcb);
		}
		client_pcb = NULL;
	}
	tcp_connect_ok = ERR_CLSD;
	reconnect_flag = 1;
}

void rfid_reconnect(void)
{
	uint16_t reg_val;
	struct xemac_s *xemac = (struct xemac_s *)(server_netif.state);
	xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
	if(reconnect_flag == 1)
	{
		XEmacPs_PhyRead(&(xemacpsif->emacps),1,1,&reg_val);
		if(reg_val & 0x04){
			//添加client 连接初始化函数
            client_init();
			reconnect_flag = 0;
		}
	}
}


//主循环中调用方式
while (1) {
    if (TcpFastTmrFlag) {
        rfid_reconnect();

        tcp_fasttmr();
        TcpFastTmrFlag = 0;
    }
    if (TcpSlowTmrFlag) {
        tcp_slowtmr();
        TcpSlowTmrFlag = 0;

    }
    xemacif_input(netif);
    transfer_data();
}

在应用层通过mdio接口获取phy第一个寄存器(BMSR)的bit2,检测网线插拔状态

在这里插入图片描述

3. SDK工程源码

https://download.csdn.net/download/qq_33878427/87842487

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值