代码之家  ›  专栏  ›  技术社区  ›  Mike -- No longer here

使用系统设置以最少的代码行将原始字节写入串行(linux C)

  •  1
  • Mike -- No longer here  · 技术社区  · 6 年前

    我正试图找到一种方法,用C语言编写自己的程序(代码行数尽可能少),它要求4个参数为十六进制数。然后,这些数字将被转换为其原始字符串等价物,然后通过串行线(无需等待串行输入)以系统确定的波特率(通过stty命令)发送。

    因此,沿串行线发送的整个输出如下所示:

    源代码(在本例中,字符代码为123) 目的地(在本例中,字符代码为46) 参数1 参数2 参数3 参数4 校验和(在本例中,字符代码为79)

    因此,如果我指定以下作为命令行参数:

    31 41 32 42

    然后,第3到第6字节的数据应变为:

    1 A 2 B

    虽然这段代码并不是百分之百完整,但有没有更简单的方法在命令行上获取一组字符串格式的原始十六进制值,并将它们全部转换为一个4字节的字符串,我可以将其附加到7字节的数据包中,然后通过串行端口一次性发送?

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    //including this file causes "too few arguments to function "write"" error
    #include <unistd.h>
    
    int main(int argc,char* argv[]){
      if (argc < 5){
          printf("4 hex values needed\n");
          return -1;
      }
      int fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);
      if (fd < 0){
          printf("Can't open port\n");
          return -1;
      }
      unsigned char src,dest,byte1,byte2,byte3,byte4,checksum;
      src=(unsigned char)123;
      dest=(unsigned char)46;
      byte1=(unsigned char)strtoll(argv[1],NULL,16);
      byte2=(unsigned char)strtoll(argv[2],NULL,16);
      byte3=(unsigned char)strtoll(argv[3],NULL,16);
      byte4=(unsigned char)strtoll(argv[4],NULL,16);
      checksum=(unsigned char)79;
      write(fd,src);
      write(fd,dest);
      write(fd,byte1);
      write(fd,byte2);
      write(fd,byte3);
      write(fd,byte4);
      write(fd,checksum);
      close(fd);
      return 0;
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   user3386109    6 年前

    您可以声明 buffer 它保存消息,并使用初始值设定项初始化源、目标和校验和字节。然后您可以使用 for 循环以转换参数。最后 write 需要一段长度。 因此 open 以及 close 可以这样实现:

    unsigned char buffer[] = { 123, 46, 0, 0, 0, 0, 79 };
    for (int i = 1; i < 5; i++)
        buffer[i+1] = strtol(argv[i], NULL, 16);
    write(fd, buffer, sizeof(buffer));