= 0;
aTime.tv_usec = 300000;
ret = select( pSer->m_fd+1,&fdRead,NULL,NULL,&aTime );
if (ret < 0 )
{
//关闭串口
pSer->ClosePort( );
break;
}
if (ret > 0)
{
//判断是否读事件
if (FD_ISSET(pSer->m_fd,&fdRead))
{
//data available, so get it!
pSer->m_DatLen = read( pSer->m_fd, pSer->DatBuf, 1500 );
// 对接收的数据进行处理,这里为简单的数据回发
if( pSer->m_DatLen > 0 )
{
pSer->PackagePro( pSer->DatBuf, pSer->m_DatLen);
}
// 处理完毕
}
}
}
printf( 'ReceiveThreadFunc finished\n');
pthread_exit( NULL );
return 0;
}
需要注意的是,select( )函数中的时间参数在嵌入式Linux中每次都需要重新赋值,否则会自动归0。
CSerial类的实现代码请参见Serial.CPP文件。
CSerial类的调用
CSerial类的具体使用也比较简单,主要是对于类中定义的4个公共函数的调用,以下为 Step2_SerialTest.cpp中相关代码。
class CSerial m_Serial;
int main( int argc,char* argv[] )
{
int i1;
int portno, baudRate;
char cmdline[256];
printf( 'Step2_SerialTest V1.0\n' );
// 解析命令行参数:串口号 波特率
if( argc > 1 ) strcpy( cmdline, argv[1] );
else portno = 1;
if( argc > 2 )
{
strcat( cmdline, ' ' );
strcat( cmdline, argv[2] );
scanf( cmdline, '%d %d', &portno, &baudRate );
}
else
{
baudRate = 115200;
}
printf( 'port:%d baudrate:%d\n', portno, baudRate);
//打开串口相应地启动了串口数据接收线程
i1 = m_Serial.OpenPort( portno, baudRate, '8', '1', 'N');
if( i1<0 )
{
printf( 'serial open fail\n');
return -1;
}
//进入主循环,这里每隔1s输出一个提示信息
for( i1=0; i1<10000;i1++)
{
sleep(1);
printf( '%d \n', i1+1);
}
m_Serial.ClosePort( );
return 0;
}
从上面的代码可以看出,程序的主循环只需要实现一些管理性的功能,在本例程中仅仅是每隔1s输出一个提示信息,在实际的应用中,可以把一些定时查询状态的操作、看门狗的喂狗等操作放在主循环中,这样充分利用了嵌入式Linux多任务的编程优势,利用内核的任务调度机制,将各个应用功能模块化,以便于程序的设计和管理。这里顺便再提一下,在进行多个串口编程时,也可以利用本例程中的CSerial类为基类,根据应用需求派生多个CSerial派生类实例,每一个派生类只是重新实现虚函数PackagePro(…),这样每个串口都具有一个独立的串口数据处理线程,利用Linux内核的任务调度机制以实现多串口通讯功能。