虚拟机串口与主机串口通信·小程序(上)

  

主机串口用到的工具是SSCOM32,虚拟机串口工具是VSPD。即通过VSPD工具,可以将二者的串口相连,可以想象成有一根串口线连接了主机和虚拟机。

第一步 确定端口
打开VSPD,如下图,点击“Port pairs”-“create pair“。我们要用到的就是COM1和COM2。此时,二者状态都是:close。
虚拟机串口与主机串口通信·小程序(上)虚拟机串口与主机串口通信·小程序(上)
虚拟机串口与主机串口通信·小程序(上)

然后,打开虚拟机,“虚拟机”-“设置”-“串口”-选择端口号,并开启,确认。
虚拟机串口与主机串口通信·小程序(上)

如下图,这样代表该串口已打开。
虚拟机串口与主机串口通信·小程序(上)

再打开SSCOM,选择“串口2”,打开串口。
虚拟机串口与主机串口通信·小程序(上)

同样,在VSPD中观察到串口已经被打开。
虚拟机串口与主机串口通信·小程序(上)

第二步 测试
虚拟机串口向主机发:
虚拟机串口与主机串口通信·小程序(上)

可以看到,主机串口收到了“hello”。
虚拟机串口与主机串口通信·小程序(上)

说到这里,复习一下“终端”。
1、控制台终端:tty0~tty6,也叫虚拟终端。(tty0是当前正在使用的虚拟终端的别名)
2、伪终端:pty(图形终端,远程控制终端)
3、串口终端:ttyS0~ttyS4
控制终端:tty。即当前正在使用的终端(以上的任何一种都有可能是控制终端)。
这个,自己输入输出重定向练习练习就清楚了~

  

& lt; br>同时,在vspd中也能看到二者传输的信息:
虚拟机串口与主机串口通信·小程序(上)> <br/> <强>第三步初始化串口配置信息</强> <br/>一般来说,我们可以手动修改虚拟机和主机的串口配置信息(波特率,校验位,停止位等等),但是每次都要修改是不是很麻烦呢,所以,可以写一个初始化串口配置信息的文件,在通信之前执行就可以了。<br/> & lt; br>初始化串口的代码如下:<br/> port.h </p>
  <pre> <代码>的ifndef _PORT_H_
  #定义_PORT_H_
  
  # include & lt; stdio.h>
  # include & lt;termios.h>
  # include & lt;unistd.h>
  # include & lt;sys/types.h>
  # include & lt;sys/stat.h>
  # include & lt;fcntl.h>/* *
  struct termios {
  tcflag_t c_iflag;//输入模式
  tcflag_t c_oflag;//输出模式
  tcflag_t c_cflag;//控制模式
  tcflag_t c_lflag;//本地模式
  cc_t c_cc(国立);//控制字符
  };
  *///设置波特率
  空白setSpeed (struct termios * ptio, int速度);//设置数据位
  空白setData (struct termios * ptio, int数据);//设置奇偶校验
  空白setParity (struct termios * ptio, int国旗);//0 -忽略奇偶校验1 -设置奇校验2 -设置偶校验//设置停止位
  空白setStop (struct termios * ptio, int停止);//初始化串口返回值:fd
  int portInit (char devname [], int, int数据,int, int停止);
  
  # endif </代码> </pre>
  </p> <p> port.c
  <pre> <代码> # include“port.h”//设置波特率
  空白setSpeed (struct termios * ptio, int速度)
  {
  开关(速度)
  {
  9600年情况:
  cfsetispeed (ptio B9600);
  cfsetospeed (ptio B9600);
  打破;
  14400年情况:
  打破;
  19200年情况:
  cfsetispeed (ptio B19200);
  cfsetospeed (ptio B19200);
  打破;
  38400年情况:
  cfsetispeed (ptio B38400);
  cfsetospeed (ptio B38400);
  打破;
  115200年情况:
  cfsetispeed (ptio B115200);
  cfsetospeed (ptio B115200);
  打破;
  默认值:
  打破;
  }
  }//设置数据位
  空白setData (struct termios * ptio, int数据)
  {
  ptio→c_cflag,=~ CSIZE;
  
  开关(数据)
  {
  例5:
  ptio→c_cflag |=CS5;
  打破;
  例6:
  ptio→c_cflag |=密室;
  打破;
  例7:
  ptio→c_cflag |=CS7;
  打破;
  例8:
  ptio→c_cflag |=密室第8章;
  打破;
  默认值:
  打破;
  }
  }//设置奇偶校验0 -忽略奇偶校验1 -设置奇校验2 -设置偶校验
  空白setParity (struct termios * ptio, int标志)
  {
  开关(国旗)
  {
  例0:
  ptio→c_cflag,=~ PARENB;
  打破;
  案例1:
  ptio→c_cflag |=PARENB;
  ptio→c_cflag |=PARODD;
  ptio→c_iflag |=(INPCK | ISTRIP);
  打破;
  案例2:
  ptio→c_iflag |=(INPCK | ISTRIP);
  ptio→c_cflag |=PARENB;
  ptio→c_cflag,=~ PARODD;
  打破;
  默认值:
  打破;
  }
  }//设置停止位(若停止位为1,则清除CSTOPB;若停止位为2,则激活CSTOPB)
  空白setStop (struct termios * ptio, int停止)
  {
  开关(停止)
  {
  案例1:
  ptio→c_cflag,=~ CSTOPB;
  打破;
  案例2:
  ptio→c_cflag |=CSTOPB;
  打破;
  默认值:
  打破;
  }
  }//初始化串口返回值:fd
  int portInit (char devname [], int, int数据,int, int停止)
  {
  int fd;
  struct termios tio={0};//打开串口设备
  fd=开放(devname O_RDWR);
  如果(fd==1)
  {
  printf(“开放端口:% s失败。\ n”, devname);
  返回;
  }//获取原有串口配置
  tcgetattr (fd, tio);//激活选项有CLOCAL和CREAD,用于本地连接和接收使能
  tio。c_cflag |=CLOCAL | CREAD;//设置波特率
  setSpeed(及tio、速度);//设置数据位,需要使用掩码设置
  setData(及tio、数据);//设置奇偶校验
  setParity(及tio、旗);//设置停止位
  setStop(及tio,停止);//设置最少字符和等待时间
  tio。c_cc [VTIME]=0;
  tio。c_cc [VMIN]=1;//最小字符,缓冲区里达到数量时才返回//设置不采用流控制
  tio。c_cflag,=~ CRTSCTS;//清除(输入)缓存
  tcflush (fd, TCIFLUSH);//设置串口默认为堵塞模式
  fcntl (fd F_SETFL 0);//激活配置
  tcsetattr (fd, TCSANOW和tio);
  
  返回fd;
  }<h2 class=虚拟机串口与主机串口通信·小程序(上)