【主题】在vxware下的vxworks学习串口编程
对于没有真实环境的朋友
在虚拟机下安装vxworks学习她是不二之选了
那在学习驱动方面,又从什么入门好呢?
面对最为普遍的串口,从串口驱动入门,了解vxworks的IO系统、设备驱动开发等等,也是满好的方式吧
没有目标机的朋友,怎么学习串口呢,其实很简单,
本文就是做个引子,说说虚拟机下的vxworks串口编程的环境建立
学习条件:
1 开发主机,就是你的PC拉,要有com1,com2串口哦
2 在vmware下配置好基于x86 pcPentium的vxworks
3 一根串口直连线,这个应该好买的
实现步骤:
1 首先用串口直连线把你的com1和com2连接起来
2 其次,配置vmware的虚拟设备,添加Serial<->com1;Serial2<->com2
如下图所示:
3 然后,在tornado下配置你的vxworks
默认的vxworks配置组件是包含INCLUDE_TTY_DEV的,所以这步当然不用管了
4 在1的基础上,运行你的vxworks
启动后,在shell下devs可以看到/tyCo/0, tyCo/1两个串口设备
这实际上是逻辑意义上的串口设备
恩,就这么简单,环境搭建好了 写个小程序测试一下吧 ^-^
#include <ioLib.h>
#include <stdio.h>
#include <taskLib.h>
#include <sioLib.h>
#include <string.h>
int tyRecv(int fd)
{
int readCnt1;
char rd;
char buff[512];
int i;
FOREVER
{
i=0;
taskDelay(50);
ioctl(fd,FIONREAD,(int) &readCnt1); /* 判断com2接收数据缓冲区是否有数据到来 */
if(readCnt1>0)
{
while(readCnt1>0)
{
read(fd,&rd,1);
readCnt1--;
buff[i++]=rd;
}
buff[i]='/0';
printf("read '%s' from com2 whose data were sent by com1/n",buff);
}
}
}
int tySend(int fd)
{
int wrtCount;
char buff[]="I am god of war!"; /* 发送内容 */
wrtCount = write(fd,buff,strlen(buff));
printf("write %d bytes to com1/n",wrtCount); /* 写com1口,然后数据就会通过串口直连线发送到com2方了 */
}
int testMain()
{
int com1_Fd,com2_Fd;
com1_Fd = open("/tyCo/0",2,0) ; /* 打开串口0,即serial<->com1 */
com2_Fd = open("/tyCo/1",2,0); /* 打开串口1,即serial2<->com2 */
/* 设置串口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);
/* 发起接受数据的任务 */
taskSpawn("recv",60,0,0x2000,(FUNCPTR)tyRecv,com2_Fd,0,0,0,0,0,0,0,0,0);
/* 发起发送数据的任务*/
taskSpawn("send",80,0,0x2000,(FUNCPTR)tySend,com1_Fd,0,0,0,0,0,0,0,0,0);
}
下载运行testMain
输出如下:
write 16 bytes to com1
read 'I am god of war!' from com2 whose data were sent by com1
证明通信成功了
最好说一下注意事项
1 即使vmware不配置serial,serial2,vxworks只要包含TTY组件,起来后,devs都是有/tyCo/x的
这就是说明了这个只是逻辑意义上的物理设备,真正要在vmware下通信,还是要配上PC机的物理串口
2 这个很关键,当时我就是没注意到这点,搞了半天也没用串口调式助手监测到数据
/tyCo/0 是对应vmware的serial 的
/tyCo/1 是对应vmware的serial2 的
当时我无意间这样配置的
即我把serial2 用物理串口com1,然后打开串口调试助手,打开com2 监听数据
然后我的程序这样,程序的思想是
1 写方面:打开/tyCo/0,写com1,然后串口调试助手监听com2
2 读方面:发起了收任务,等待com2 发来数据
#include <ioLib.h>
#include <stdio.h>
#include <taskLib.h>
#include <sioLib.h>
#include <string.h>
int tyRecv(int fd)
{
int readCnt1;
char rd;
char buff[512];
int i;
FOREVER
{
i=0;
taskDelay(50);
ioctl(fd,FIONREAD,(int) &readCnt1);
if(readCnt1>0)
{
while(readCnt1>0)
{
read(fd,&rd,1);
readCnt1--;
buff[i++]=rd;
}
buff[i]='/0';
printf("read '%s' from com1 whose data were sent by com2/n",buff);
}
}
}
int testMain()
{
int fd,wrtCount;
char buff[]="I am god of war!";
fd = open("/tyCo/0",2,0) ;
/* 我打开了/tyCo/0 ,但前面说了,/tyCo/0是对应serial的,而我现在vmware只配了serial2 */
/* 所以程序运行没看到任何期待的结果,解决办法在后面 */
/* set com1 hardware option */
if ( ERROR==ioctl(fd,FIOBAUDRATE,9600) )
{
printf("can not set BAUDRATE!/n") ;
return ERROR ;
}
if ( ERROR==ioctl(fd,SIO_HW_OPTS_SET,(CLOCAL|CREAD|CS8)&~(HUPCL|STOPB|PARENB)))
{
printf("can not set OPT!/n") ;
return ERROR ;
}
ioctl(fd,FIOFLUSH,0);
wrtCount = write(fd,buff,strlen(buff)); /*write to com1*/
printf("write %d bytes to com1/n",wrtCount);
/* Start receiving task */
taskSpawn("recv",60,0,0x2000,(FUNCPTR)tyRecv,fd,0,0,0,0,0,0,0,0,0);
}
然后运行程序,结果在串口调试助手的接收区怎么也收不到数据
在串口调试助手的发送区发数据,结果我的recv任务也是死活打印不出信息
后来把fd = open("/tyCo/0",2,0) ; 改成fd = open("/tyCo/1",2,0) ;
这样,就和vmware配置的serial2<->com1对应起来了
然后一切就都OK了
下面就是正常通信的截图了
串口调试助手com2的接收区受到了com1发来的'I am god of war!'
而vxworks下的收任务也收到了串口调试助手com2的发送区发送来的数据了
下面就看大家自己的研究学习了
还有就是串口i8250芯片的modem控制寄存器的D4位置1的话,是开启自回绕模式
也就是发送移位寄存器的输出在芯片内部被回送到接收移位寄存器的输入
利用这个特点,可以编写程序测试8250的工作是否正常工作,无需任何附加装置
这样,没有线,写这个口,也能读出刚刚写入到这个口的数据
但是我没成功,希望大大给点指点啊哈