Qt开发 —Linux板USB串口通讯的插拔检测

24 篇文章 3 订阅
13 篇文章 0 订阅

项目开发中,在安装linux系统的ARM9板上,需要实时检测USB口与Windows客户端的连接和断开情况,从而中断命令的发送,由于USB的连接和数据交互使用的串口通讯,在板子启动的脚本就直接加载了g_serial.ko的模块,在dev目录下生成了ttyGS0的端口号。串口通讯中断端口地址也不会消失,因此,只有通过在一定时间内检测端口的读写状态来判断串口通讯是够正常,如超时则认为连接断开。

首先,打开串口

//以读写方式打开usb,尝试5次
int fd = -1;
for(int i=0;i<5;i++)
{
    fd = open("/dev/ttyGS0",  O_RDWR|O_NOCTTY);
    if(fd<=0) 
        continue;//retry until reach 5 times
    else 
        break;
}

由于使用g_serial.ko加载串口模块,不需要额外设置串口参数。

清空端口缓存

tcflush(fd, TCIOFLUSH); //clear port caches

创建线程收发端口数据

//创建USB收发线程
pthread_t tid;
pthread_create(&tid, NULL, Thread_USB_SendRecv, this);
线程函数如下

void* Thread_USB_SendRecv(void *pData)
{
    usbserial* pUSBSerial = (usbserial*) pData;
    while(true)
    {
	int nRet =  pUSBSerial->ProcData();
	if(nRet < 0)
        {
	    //重启USB
	    pUSBSerial->ResetUSB();
	}
    }
    QPRINT("Thread_USB_SendRecv DEAD!!!!");
    return 0;
}

由于串口通讯使用的阻塞IO的模式,当返回的nRet<0时,认为usb通讯错误或断开了连接,因此需重启USB,重启操作即重新打开/dev/ttyGS0端口,如果能正常通讯则继续收发数据,这里不作为USB断开或拔出的判断。

USB拔出的判断只能在另一个监控线程处理超时,即规定时间内没有读取到数据则认为通讯断开或USB线拔出。这里使用一个计数器来设置,在read到数据后重置计数器。

ssize_t ReadForUSBHost(int fd, void* buf, size_t nbytes)
{
    ssize_t nRead = read(fd, buf, nbytes);
    if(nRead>0) m_nIdleCount = 0;//reset counter
    return nRead;
}

监控线程即重新开辟一个线程每隔1秒钟比对一下计数器

int usbserial::CheckUSBPortConStatus()
{
    //use m_nIdleCount to set timeout.
    bool bRet = (m_nIdleCount++) < m_nTimeout;//超时时间,单位s
    if( bRet != USB_GetLink() )
    {
	USB_SetLink( bRet );
	if(bRet == false) // lose link
	    QPRINT("USB link timeout, only set flag....");
	else // link again
	    QPRINT("USB get data again, ...");
	}
    return 1;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值