为原始串行I / O构建C模板

时间:2018-11-11 22:51:55

标签: io serial-port bitrate flow-control data-loss

当前,我正在Linux中创建软件,其中数据需要以56k的速度以未修改的原始格式从COM1到达计算机。

我可以通过在unix终端上执行以下命令来手动实现此目的:

screen /dev/ttyS0 57600
stty -F /dev/ttyS0 -ixon

每次,我都会使用以下命令验证数据:

od -tx1 -w11 -v /dev/ttyS0

如果我省略了上面的第二条命令,那么字符代码11和13将永远不会显示在屏幕上。我认为这与软件流控制有关。在我的通讯设置中,我不使用流控制,也不希望linux重新映射任何字符。

因此,我尝试创建可以有效产生相同结果的代码,但是我认为我的串行设置不正确,因为执行代码时,字符不同。

我知道期望值是什么,因为我创建了通过串行端口连接PC的远程硬件,而现在远程硬件一次又一次地传输相同的字符串序列。

现在,如果我运行此代码,然后停止执行并决定在unix终端中运行上述三个命令,则输出是100%正确的。

这是代码:

#include <termios.h>
#include <stdio.h>
#include <stropts.h>
#include <poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B57600 /* Want 56K speed */
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define MODEMDEVICE "/dev/ttyS0" /* My serial port */

int main(){

  int res; //result value from call
  struct termios oldtio,newtio;
  struct pollfd fds[2];
  fds[0].fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
  if (fds[0].fd <0) {perror(MODEMDEVICE); return -1; }
  fds[0].events=POLLIN;

  tcgetattr(fds[0].fd,&oldtio); /* save current port settings */

  /* Assign new settings. Could I somehow crunch this down? */
  newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | ICRNL | ~IXON | ~IXOFF;
  newtio.c_oflag = 0;
  newtio.c_lflag = ICANON;
  newtio.c_cc[VMIN]=1;
  newtio.c_cc[VTIME]=0;
  tcflush(fds[0].fd, TCIFLUSH);
  tcsetattr(fds[0].fd,TCSANOW,&newtio);
  // Wait for data

  unsigned char buf[1024]; //Get a huge buffer incase this PC is super slow
  int ct=22; //count 22 bytes before new line
  unsigned int ms=0,entn=0; //Set entry number + delayed ms to 0
  printf("%04u: ",entn); //print entry # 0 label
  while (1){
    res=poll(fds,1,1);
    if (res > 0){
      if (fds[0].revents & POLLIN){
        // Here we have something
        res = read(fds[0].fd,buf,sizeof(buf));
        if (res > 1){
          //show how long we waited for next data if over 1ms
          if (ms > 0){printf("(%u)",ms);ms=0;}
          int n;
          for (n=0;n<res;n++){
            printf("%02X ",buf[n]); //print characters as hex
            ct--; 
            if (ct==0){
              //We printed 22 characters so print a new line and next label
              ct=22;
              printf("\n");
              entn++;
              printf("%04u: ",entn);
            }
          }
        }
      }
    }else{
      //No data so add 1ms to the total
      ms++;
    }
    //Loop is endless
  }
  return 0;
}

如何修复我的代码,以便可以使用它,而不必每次都运行上述三个命令才能看到正确的输出?

0 个答案:

没有答案