Plug-in detection of USB serial communication on Linux board

In the project development, on the ARM9 board with the Linux system installed, it is necessary to detect the connection and disconnection between the USB port and the Windows client in real time, so as to interrupt the sending of commands. Due to the USB connection and the serial communication used for data interaction, the board starts. The script directly loads the module of g_serial.ko, and generates the port number of ttyGS0 in the dev directory. The port address will not disappear even if the serial communication is interrupted. Therefore, only by detecting the read and write status of the port within a certain period of time to judge whether the serial communication is normal enough, if it times out, it is considered that the connection is disconnected.

First, open the serial port

//Open usb in read and write mode, try 5 times
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;
}

Since g_serial.ko is used to load the serial port module, no additional serial port parameters need to be set.

clear port cache

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

Create a thread to send and receive port data

//Create a USB transceiver thread
pthread_t tid;
pthread_create(&tid, NULL, Thread_USB_SendRecv, this);

The thread function is as follows

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

Due to the blocking IO mode used in serial communication, when the returned nRet<0, it is considered that the usb communication is wrong or the connection is disconnected, so it is necessary to restart the USB, and the restart operation will reopen the /dev/ttyGS0 port, if it can communicate normally, continue Sending and receiving data is not used as a judgment of USB disconnection or unplugging.

The judgment of USB unplugging can only be processed when another monitoring thread times out, that is, if no data is read within the specified time, it is considered that the communication is disconnected or the USB cable is unplugged. Here a counter is used to set and reset the counter after reading the data.

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;
}

The monitoring thread is to re-create a thread to compare the counter every 1 second

int usbserial::CheckUSBPortConStatus()
{
    //use m_nIdleCount to set timeout.
    bool bRet = (m_nIdleCount++) < m_nTimeout;//Timeout time, unit 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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325340136&siteId=291194637