Построение шаблона C для необработанного последовательного ввода-вывода - PullRequest
0 голосов
/ 12 ноября 2018

В настоящее время я создаю программное обеспечение в Linux, в котором данные должны поступать на компьютер со скоростью 56 КБ в неизмененном исходном формате от COM1.

Я могу достичь этого вручную, выполнив следующие команды на терминале Unix:

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

И каждый раз я проверяю данные с помощью этой команды:

od -tx1 -w11 -v /dev/ttyS0

Если бы я пропустил вторую команду выше, тогда коды символов 11 и 13 никогда не были бы напечатаны на экране. Я думаю, что это связано с программным управлением потоком. В моих настройках связи я не использую управление потоком и не хочу, чтобы linux переназначал любые символы.

Итак, я попытался создать код, который бы эффективно давал те же результаты, но я думаю, что мои серийные настройки неверны, потому что когда я выполнял код, символы не совпадали.

Я знаю, какие значения следует ожидать, потому что я создал удаленное оборудование, к которому подключен ПК через последовательный порт, и удаленное оборудование прямо сейчас передает одну и ту же последовательность строк снова и снова.

Теперь, если я запустил этот код, а затем остановил выполнение и решил запустить три команды, указанные выше, в терминале 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;
}

Как мне исправить мой код, чтобы я мог использовать его вместо того, чтобы каждый раз запускать три вышеуказанные команды, чтобы увидеть правильный вывод?

...