在配置完并口的相关属性后,就可以对并口进行打开和读写操作了。它所使用的函数和普通文件的读写函数一样,都是open()、write()和read()。它们之间区别的只是并口是一个终端设备,因而在选择函数的具体参数时会有一些区别。另外,这儿会用到一些附加的函数,用于测试终端设备的联接情况等。下边将对其进行具体讲解。
1.打开并口
打开并口和打开普通文件一样linux qq,都是使用open()函数,如下所示:
fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
可以看见,这儿不仅普通的读写参数外,还有两个参数O_NOCTTY和O_NDELAY。
●O_NOCTTY标志用于通知Linux系统,该参数不会使打开的文件成为这个进程的控制终端。若果没有指定这个标志,这么任何一个输入(如鼠标终止讯号等)都将会影响用户的进程。
●O_NDELAY标志用于设置非阻塞形式。通知Linux系统,这个程序不关心DCD讯号线所处的状态(端口的另一端是否激活或则停止)。假如用户没有指定这个标志,则进程将会仍然处在睡眠状态,直至DCD讯号线被激活。
接出来可恢复并口的状态为阻塞状态,用于等待并口数据的读入,可用fcntl()函数实现,如下所示:
fcntl(fd,F_SETFL,0);
接着可以测试打开的文件描述符是否联接到一个终端设备linux串口读写程序,以进一步确认并口是否正确打开,如下所示:
isatty(fd);
该函数调用成功则返回0,若失败则返回-1。
这时红旗 linux,一个并口就早已成功打开了。接出来就可以对这个并口进行读和写操作。下边给出了一个完整的打开并口函数,同样考虑到了各类不同的情况。程序如下所示:
/*打开并口函数*/
intopen_port(intcom_port)
intfd;
#if(COM_TYPE==GNR_COM)/*使用普通并口*/
char*dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
#else/*使用USB转并口*/
char*dev[]={"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"};
#endif
if((com_portMAX_COM_NUM))
return-1;
/*打开并口*/
fd=open(dev[com_port-1],O_RDWR|O_NOCTTY|O_NDELAY);
if(fd<0)
perror("openserialport");
return(-1);
if(fcntl(fd,F_SETFL,0)<0)/*恢复并口为阻塞状态*/
perror("fcntlF_SETFLn");
if(isatty(fd)==0)/*测试打开的文件是否为终端设备*/
perror("Thisisnotaterminaldevice");
returnfd;
2.读写并口
读写并口操作与读写普通文件一样,使用read()和write()函数即可linux串口读写程序,如下所示:
read(fd,buff,BUFFER_SIZE);
write(fd,buff,strlen(buff));
下边两个实例给出了并口读和写的两个程序,其中用到上面所述说的open_port()和set_com_config()函数。写并口的程序将在宿主机上运行,读并口的程序将在目标板上运行。
写并口的程序如下所示:
/*com_writer.c*/
#include
#include
#include
#include
#include
#include
#include"uart_api.h"
intmain(void)
intfd;
charbuff[BUFFER_SIZE];
if((fd=open_port(HOST_COM_PORT))<0)/*打开并口*/
perror("open_port");
return1;
if(set_com_config(fd,115200,8,'N',1)<0)/*配置并口*/
perror("set_com_config");
return1;
do
printf("Inputsomewords(enter'quit'toexit):");
memset(buff,0,BUFFER_SIZE);
if(fgets(buff,BUFFER_SIZE,stdin)==NULL)
perror("fgets");
break;
write(fd,buff,strlen(buff));
}while(strncmp(buff,"quit",4));
close(fd);
return0;
读并口的程序如下所示:
/*com_reader.c*/
#include
#include
#include
#include
#include
#include
#include"uart_api.h"
intmain(void)
intfd;
charbuff[BUFFER_SIZE];
if((fd=open_port(TARGET_COM_PORT))<0)/*打开并口*/
perror("open_port");
return1;
if(set_com_config(fd,115200,8,'N',1)<0)/*配置并口*/
perror("set_com_config");
return1;
do
memset(buff,0,BUFFER_SIZE);
if(read(fd,buff,BUFFER_SIZE)>0)
printf("Thereceivedwordsare:%s",buff);
}while(strncmp(buff,"quit",4));
close(fd);
return0;
在宿主机上运行写并口的程序,而在目标板上运行读并口的程序,运行结果如下所示:
/*宿主机,写并口*/
$./com_writer
Inputsomewords(enter'quit'toexit):hello,Reader!
Inputsomewords(enter'quit'toexit):I'mWriter!
Inputsomewords(enter'quit'toexit):Thisisaserialporttestingprogram.
Inputsomewords(enter'quit'toexit):quit
/*目标板,读并口*/
$./com_reader
Thereceivedwordsare:hello,Reader!
Thereceivedwordsare:I'mWriter!
Thereceivedwordsare:Thisisaserialporttestingprogram.
Thereceivedwordsare:quit
另外,读者还可以考虑一下怎样使用select()函数实现并口的非阻塞读写,具体实例会在本章前面的实验中给出。
本文选自华清远见嵌入式培训教材《从实践学校嵌入式Linux应用程序开发》
热点链接:
1、嵌入式Linux并口应用编程之并口配置
2、嵌入式Linux并口应用编程基础知识
3、Linux下多路复用I/O插口
4、linux文件锁的实现及其应用
5、底层文件I/O操作的系统调用