vxworks下的串口测试程序
VXWORKS串口设置说明:
一般有这么几步:
打开串口
设置串口raw模式,清空输入输出的缓冲区
设置波特率,数据位,停止位,校验方式
便可以开始读和写
打开串口:
fd = open("/tyCo/0", O_RDWR, 0);
"/tyCo/0" 串口1的设备名,O_RDWR:open for reading and writing
设置串口raw模式,清空输入输出的缓冲区
ioctl(fd,FIOSETOPTIONS,OPT_RAW);
ioctl(fd,FIOFLUSH,0);
ioctl(int fd,int function,int arg);这个函数解释如下:
function这个参数有如下:(tty)
FIOBAUDRATE |
设置波特率,arg为一整数,表示要设定的波特率 |
FIOGETOPTIONS |
取得设备控制字,arg表示读出的内容存放的位置 |
FIOSETOPTIONS |
设置设备控制字,arg表示要设置的选项 |
FIOGETNAME |
取得文件描述符对应的文件名,arg存放文件名的缓冲区 |
FIOREAD |
取得输入缓冲区内未读取的字符数,arg用于接收结果的整型指针 |
FIOWRITE |
取得输出缓冲区内的字符个数,arg用于接收结果的整型指针 |
FIOFLUSH |
清空输入输出缓冲区的字符 |
FIOCANCEL |
取消读和写 |
FIOSETOPTIONS对应的arg有 OPT_LINE,OPT_RAW,OPT_ECHO等等
关于这些的定义,可以在sioLib.h,ioLib.h里寻找。
设置波特率,数据位,停止位,校验方式
STOPB:两位停止位,默认是1位停止位。PARENB使能校验,PARODD奇校验,使能后默认是偶校验,未使能则是无校验
CS5,CS6,CS7,CS8:5,6,7,8位数据位
如:CS8|PARENB :8位数据位,1位停止位,偶校验;
CS8|PARENB|PARODD:8位数据位,1位停止位,奇校验;
CS8 :8位数据位,1位停止位,无校验;
CS8|STOPB:8位数据位,2位停止位,无校验;
int SerialOps = 0;
ioctl(fd,FIOBAUDRATE,9600); //9600波特率
SerialOps |= CS8;//8数据位,1位停止位,无校验
ioctl(fd,SIO_HW_OPTS_SET,SerialOps);//设置
SIO_HW_OPTS_SET(设置硬件选项)是在XXDrv里的function
SIO_HW_OPTS_SET对应的arg:
CLOCAL |
忽略modem控制信号 |
CREAD |
启动接收器 |
CSIZE |
指定数据位:CS5~CS8 |
HUPCL |
最后关闭时挂断modem连接 |
STOPB |
被设置时指定2位停止位,否则1位停止位 |
PARENB |
被设置时启用奇偶校验,否则不进行奇偶校验 |
PARODD |
被设置时启用奇校验,否则偶校验 (PARENB被设置时才有效) |
可以开始读写
int read
(
int fd, /* file descriptor from which to read */
char * buffer, /* pointer to buffer to receive bytes */
size_t maxbytes /* max no. of bytes to read into buffer */
)
int write
(
int fd, /* file descriptor on which to write */
char * buffer, /* buffer containing bytes to be written */
size_t nbytes /* number of bytes to write */
)
关于串口的设置,需要参考tty和xxDrv。详细的还是需要看书的。
下面举个例子:在有些的设置需要如下:
fd=open(tyco,2,0);
logMsg("/n%s;fd=%d/n",tyco,fd,0,0,0,0);
ioctl(fd, FIOOPTIONS, OPT_RAW);
ioctl(fd,FIOBAUDRATE,115200); //设置串口波特率为9600bps
ioctl(fd,FIOFLUSH,0);//清空输入输出缓冲
//ioctl(fd,SIO_HW_OPTS_SET,CS8|PARENB|PARODD|CLOCAL|CREAD); //设置 8 位数据位,1位停止位,带校验位,奇校验,没有流控制CLOCAL,使能读CREAD
//ioctl(fd,SIO_HW_OPTS_SET,CS8|PARENB|CLOCAL|CREAD); //设置 8 位数据位,1位停止位,带校验位,偶校验,没有流控制CLOCAL,使能读CREAD
ioctl(fd,SIO_HW_OPTS_SET,CS8|CLOCAL|CREAD); //设置 8 位数据位,1位停止位,带校验位,无校验,没有流控制CLOCAL,使能读CREAD
write(fd,str,48);//需放在清缓存后,mpc8280不用。和SIO_HW_OPTS_SET之后,因为会reset串口
上面粗字体,需要注意。有些需要,有些不需要的。
#include <ioLib.h> #include <stdio.h> #include <taskLib.h> #include <sioLib.h> #include <string.h> /*ioctl(com2_Fd,FIOSETOPTIONS,OPT_RAW);*/ int tyRecv(int fd,int fd2) { int readCnt1; char rd; char buff[512]; int i; FOREVER { i=0; taskDelay(25); ioctl(fd,FIONREAD,&readCnt1); /* 判断com1接收数据缓冲区是否有数据到来 */ if(readCnt1>0) { while(readCnt1>0) { read(fd,&rd,1); readCnt1--; buff[i++]=rd; taskDelay(1); } buff[i]='\0'; printf("read1 [%s] \n",buff); } i=0; taskDelay(25); ioctl(fd2,FIONREAD,&readCnt1); /* 判断com2接收数据缓冲区是否有数据到来 */ if(readCnt1>0) { while(readCnt1>0) { read(fd2,&rd,1); readCnt1--; buff[i++]=rd; taskDelay(1); } buff[i]='\0'; printf("read2 [%s] \n",buff); } } } int tySend(int fd,int fd2) { int wrtCount,i; char buff[]=" I am god of war!"; /* 发送内容 */ for(i=0;i<10;i++) { buff[0] = '1'+i; wrtCount = write(fd,buff,strlen(buff)); printf("write1 %d bytes \n",wrtCount); /* 写com1口,然后数据就会通过串口直连线发送到com2方了 */ taskDelay(60); buff[0] = 'a'+i; wrtCount = write(fd2,buff,strlen(buff)); printf("write2 %d bytes \n",wrtCount); /* 写com2口,然后数据就会通过串口直连线发送到com2方了 */ taskDelay(60); } } int com1_Fd,com2_Fd; int taskID; int taskID2; int test() { com1_Fd = open("/tyCo/0",2,0) ; /* 打开串口0,即serial<->com1 */ com2_Fd = open("/tyCo/1",2,0); /* 打开串口1,即serial2<->com2 */ ioctl(com1_Fd,FIOSETOPTIONS,OPT_RAW); ioctl(com2_Fd,FIOSETOPTIONS,OPT_RAW); /* 设置串口0,亦即com1的波特率9600,8数据为,1停止位,无校验位 */ if ( ERROR==ioctl(com1_Fd,FIOBAUDRATE,9600) ) { printf("can not set BAUDRATE!\n") ; return ERROR ; } if ( ERROR==ioctl(com1_Fd,SIO_HW_OPTS_SET,(CLOCAL|CREAD|CS8)&~(HUPCL|STOPB|PARENB))) { printf("can not set OPT!\n") ; return ERROR ; } ioctl(com1_Fd,FIOFLUSH,0); /* 设置串口1,亦即com2的波特率9600,8数据为,1停止位,无校验位 */ if ( ERROR==ioctl(com2_Fd,FIOBAUDRATE,9600) ) { printf("can not set BAUDRATE!\n") ; return ERROR ; } if ( ERROR==ioctl(com2_Fd,SIO_HW_OPTS_SET,(CLOCAL|CREAD|CS8)&~(HUPCL|STOPB|PARENB))) { printf("can not set OPT!\n") ; return ERROR ; } ioctl(com2_Fd,FIOFLUSH,0); printf("com1:0x%x com2:0x%x!\n",com1_Fd,com2_Fd) ; /* 发起接受数据的任务 */ taskID = taskSpawn("recv",60,0,0x2000,(FUNCPTR)tyRecv,com1_Fd,com2_Fd,0,0,0,0,0,0,0,0); /* 发起发送数据的任务*/ taskSpawn("send",80,0,0x2000,(FUNCPTR)tySend,com1_Fd,com2_Fd,0,0,0,0,0,0,0,0); } void del() { taskDelete(taskID); /*taskDelete(taskID2);*/ close(com1_Fd); close(com2_Fd); }
最后更新:2017-04-03 12:56:21