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