在vxware下的vxworks学习串口编程

【主题】在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的工作是否正常工作,无需任何附加装置
这样,没有线,写这个口,也能读出刚刚写入到这个口的数据
但是我没成功,希望大大给点指点啊哈

 

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
VxWorks 操作系统中,可以使用 ioctl() 函数来进行串口配置和数据传输。下面是一个示例代码,用于在 VxWorks 中接收串口数据: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ioLib.h> #include <taskLib.h> #include <semLib.h> #include <sysLib.h> #include <tyLib.h> /* 串口设备名 */ #define SERIAL_DEV_NAME "/tyCo/1" /* 串口接收缓冲区大小 */ #define SERIAL_RX_BUF_SIZE 1024 /* 串口接收信号量 */ SEM_ID serialRxSem; /* 串口接收缓冲区 */ char serialRxBuf[SERIAL_RX_BUF_SIZE]; /* 串口接收任务 */ void serialRxTask(void) { int fd; int nBytes; int i; char c; /* 打开串口设备 */ fd = open(SERIAL_DEV_NAME, O_RDONLY, 0); if (fd == ERROR) { printf("Failed to open serial device %s!\n", SERIAL_DEV_NAME); return; } while (1) { /* 接收数据 */ nBytes = read(fd, &c, 1); if (nBytes == ERROR) { printf("Failed to read from serial device %s!\n", SERIAL_DEV_NAME); break; } else if (nBytes == 0) { printf("No data received from serial device %s!\n", SERIAL_DEV_NAME); break; } /* 将接收到的数据存入缓冲区 */ serialRxBuf[i++] = c; if (i >= SERIAL_RX_BUF_SIZE) { i = 0; } /* 发送接收信号量 */ semGive(serialRxSem); } /* 关闭串口设备 */ close(fd); } /* 主函数 */ int main(int argc, char* argv[]) { /* 创建串口接收信号量 */ serialRxSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); /* 创建串口接收任务 */ taskSpawn("serialRxTask", 100, 0, 4096, (FUNCPTR) serialRxTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); while (1) { /* 等待串口接收信号量 */ semTake(serialRxSem, WAIT_FOREVER); /* 处理接收到的数据 */ // TODO: Add your code here } return 0; } ``` 在上面的代码中,serialRxTask() 函数是一个用于接收串口数据的任务。在该函数中,我们首先打开指定的串口设备,然后不断地从串口中读取数据,并将其保存到串口接收缓冲区中。每当收到一个字符时,我们就向串口接收信号量发送一个信号,通知主函数有数据需要处理。在主函数中,我们不断等待串口接收信号量的到来,并处理接收到的数据。请注意,这只是一个示例代码,您需要根据具体的应用场景对其进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值