C-无法从串行端口获取数据结构



我想以下面的代码发送和接收文件。但是功能上有错误的" xmodem_receive"。

" xmodem_send"函数正在通过" tty/ama0"发送" xmodem_chunk",并且接收数据为" ret = saferead(fd,& chunk,sizeof(chunk),sizeof(chunk)),in" xmodem_receive"中但是,这一行中没有阅读数据!相反,这条线停止了我的代码。有人教我至少需要运行此代码吗?

这是代码(省略)。

#define X_STX 0x02
#define X_EOT 0x04
#define X_ACK 0x06
#define X_NAK 0x15
#define min(a, b)   ((a) < (b) ? (a) : (b))
#define DEBUG 0
struct xmodem_chunk {
    uint8_t start;
    uint8_t blk;
    uint8_t blk_neg;
    uint8_t payload[1024];
    uint16_t crc;
} __attribute__((packed));
#define CRC_POLY 0x1021
int saferead(int fd, const void *p, size_t want){
      int ret;
      int ret_sum = 0;
      errno = 0;
      while (want){
          ret = read(fd, (uint8_t*)p, want);
          if(ret == 0)
                return -1; /* EOF */
          if(ret <= 0){
               if(errno != EINTR && errno != EAGAIN ) {
               return -1;
          }
          errno = 0;
          continue;
         }
         want -= ret;
         p = (uint8_t*) p + ret;
         ret_sum += ret;
     }
     return ret_sum;
   }
static int xmodem_send(int serial_fd, const char *filename)
   {
      int ret, fd;
      uint8_t eof = X_EOT; 
      struct xmodem_chunk chunk; 
      fd = open(filename, O_RDONLY); 
      if(fd < 0){ 
          perror("open");
          return -errno;
      } 

      fstat(fd, &stat); 
      len = stat.st_size; 
      buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); 
      if(!buf){ 
          perror("mmap");
          return -errno;
      }
      printf("Sending %s n", filename);
      chunk.start = X_STX; 
      while (len){
          size_t z = 0;
          int next = 0;
          char status;
          z = min(len, sizeof(chunk.payload)); 
          memcpy(chunk.payload, buf, z);
          memset(chunk.payload + z, 0xff, sizeof(chunk.payload) - z); 
          chunk.crc = swap16(crc16(chunk.payload, sizeof(chunk.payload)));
          chunk.blk_neg = 0xff - chunk.blk; 
          int i;
          for(i = 0; i < 3; i++){
               ret = safewrite(serial_fd, &chunk, sizeof(chunk)); 
               if(ret != sizeof(chunk)){
                   return -errno;
               }
          }
         if(next){
             chunk.blk++;
             len -= z;
             buf += z;
         }
     }
     ret = safewrite(serial_fd, &eof, sizeof(eof));
     if(ret != sizeof(eof))
         return -errno;
     return 0;
 }
 static xmodem_receive(int serial_fd, char* filename){
     size_t len;
     int ret, fd;
     size_t retry;
     struct xmodem_chunk chunk;
     struct stat stat;
     FILE *fp;
     uint8_t eof = X_EOT;
     int eof_count=0;

     retry = 3;
     fp = fopen(filename, "ab+");

    while(1){
        int garbage_count=0;
        int correct_count=0;
        uint8_t chunk_payload[1024];
        uint8_t garbage_payload[3][1024];
        uint16_t garbage_crc[3];
        size_t z = 0;   
        while(retry){
                int next = 0;
                ret = saferead(fd, &chunk, sizeof(chunk)); <--This line is the problem.
                z = sizeof(chunk.payload);
                if(chunk.start != X_STX){
                     printf("error STXn");
                     return 0; // error
                }
                printf("retry partn");
                if(chunk.crc != swap16(crc16(chunk.payload, sizeof(chunk.payload)))){ 
                     if(garbage_count > 1){
                         int i;
                         for(i=0; i < garbage_count; i++){
                            if(chunk.crc == swap16(crc16(garbage_payload[i], sizeof(chunk.payload)))){
                                correct_count++;
                                memcpy(chunk_payload, garbage_payload[i], len);
                            }
                        }
                        if(correct_count < 1){
                            memcpy(garbage_payload[garbage_count], &chunk.payload, len);
                            garbage_count++;
                        }
                        printf("garbage#1n");  
                     }else{
                         memcpy(garbage_payload[0], &chunk.payload, len);
                         garbage_crc[0] = chunk.crc;
                         garbage_count++;
                         printf("garbage#2n");
                     }

                 }else{
                     printf("correctn");
                     correct_count++;
                     memcpy(chunk_payload , &chunk.payload, len);
                 }
         }
         safewrite(fd, &chunk_payload, z);           
     }
     close(fd);
     return 0;
 }

  int main(int argc, char **argv){
        int a, ret, serial_fd;
        serial_fd = open_serial("/dev/ttyUSB0", 115200);
        // serial_fd = open_serial("/dev/ttyAMA0", 115200);
        ret = xmodem_receive(serial_fd, "sample.jpg");
        // ret = xmodem_send(serial_fd, "sample.jpg");
  } 

这是完整的代码(很抱歉让您等待)

`
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/mman.h>

#define X_STX 0x02
#define X_EOT 0x04
#define X_ACK 0x06
#define X_NAK 0x15
#define min(a, b)   ((a) < (b) ? (a) : (b))
#define DEBUG 0
struct xmodem_chunk {
    uint8_t start;
    uint8_t blk;
    uint8_t blk_neg;
    uint8_t payload[1024];
    uint16_t crc;
} __attribute__((packed));
#define CRC_POLY 0x1021
/* 'Safe' write */
int safewrite(int fd, const void *p, size_t want){
    int ret;
    int ret_sum = 0;
    errno = 0;
    while(want){
        ret = write(fd, (uint8_t *)p,want);
        if(ret <= 0) {
            if (errno != EINTR && errno != EAGAIN){
                return -1;
            }
            errno = 0;
            continue;
        }
        want -= ret;
        p = (uint8_t*) p + ret;
        ret_sum += ret;
    }
    return ret_sum;
}
int saferead(int fd, const void *p, size_t want){
    int ret;
    int ret_sum = 0;
    errno = 0;
    while (want){
        ret = read(fd, (uint8_t*)p, want);
        if(ret == 0)
            return -1; /* EOF */
        if(ret <= 0){
            if(errno != EINTR && errno != EAGAIN ) {
                return -1;
            }
            errno = 0;
            continue;
        }
        want -= ret;
        p = (uint8_t*) p + ret;
        ret_sum += ret;
    }
    return ret_sum;
}
static uint16_t crc_update(uint16_t crc_in, int incr)
{
    uint16_t xor = crc_in >> 15;
    uint16_t out = crc_in << 1;
    if(incr)
        out++;
    if(xor)
        out ^= CRC_POLY; // xor 0b1000000100001
    return out;
}
static uint16_t crc16(const uint8_t *data, uint16_t size) 
{
    uint16_t crc, i;
    for(crc = 0; size > 0; size--, data++) 
        for(i = 0x80; i; i >> 1) 
            crc = crc_update(crc, *data & i); 
    for ( i = 0; i < 16; i++)
        crc = crc_update(crc, 0);
    return crc;
}
static uint16_t swap16(uint16_t in) 
{
    return (in >> 8) | ((in & 0xff) << 8);
}
enum {
    PROTOCOL_XMODEM,
    PROTOCOL_YMODEM,
};
static int xymodem_send(int serial_fd, const char *filename)
{
    size_t len; 
    int ret, fd;
    uint8_t answer;
    struct stat stat;
    const uint8_t *buf;
    uint8_t eof = X_EOT; 
    struct xmodem_chunk chunk; 
    int skip_payload = 0;
    fd = open(filename, O_RDONLY); 
    if(fd < 0){ 
        perror("open");
        return -errno;
    }   

    fstat(fd, &stat); 
    len = stat.st_size;
    buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
    if(!buf){ 
        perror("mmap");
        return -errno;
    }
    if(DEBUG) {
        printf("Wainting for receiver ping ...");
        fflush(stdout); 
        do {
            ret = read(serial_fd, &answer, sizeof(answer)); 
            if(ret != sizeof(answer)){
                perror("read");
                return -errno;
            }
        }while (answer != 'C'); 
        printf("dome.n");
    }
    printf("Sending %s ", filename);
/*
    if(protocol == PROTOCOL_YMODEM) {
        strncpy ((char*) chunk.payload, filename, sizeof(chunk.payload));
        chunk.blk = 0;
        skip_payload = 1;
    }else {
        chunk.blk = 1;
    }
*/
    chunk.start = X_STX; 
    while (len){
        size_t z = 0;
        int next = 0;
        char status;
        z = min(len, sizeof(chunk.payload)); 
        memcpy(chunk.payload, buf, z);
        memset(chunk.payload + z, 0xff, sizeof(chunk.payload) - z); // 
        chunk.crc = swap16(crc16(chunk.payload, sizeof(chunk.payload)));
        chunk.blk_neg = 0xff - chunk.blk; 
        int i;
        for(i = 0; i < 3; i++){
            ret = safewrite(serial_fd, &chunk, sizeof(chunk)); 
            if(ret != sizeof(chunk)){
                return -errno;
            }
        }
        if(next){
            chunk.blk++;
            len -= z;
            buf += z;
        }
    }
    ret = safewrite(serial_fd, &eof, sizeof(eof));
    if(ret != sizeof(eof))
        return -errno;
    ret = safewrite(serial_fd, &eof, sizeof(eof));
    if (ret != sizeof(eof))
        return -errno;
    ret = safewrite(serial_fd, &eof, sizeof(eof));
    if (ret != sizeof(eof))
        return -errno;
    printf("done.n");
    return 0;
}
static xmodem_receive(int serial_fd, char* filename){
    size_t len;
    int ret, fd;
    size_t retry;
    uint8_t expected_blkno;
    size_t nrecv;
    uint16_t crch, crcl;
    size_t datalen;
    struct xmodem_chunk chunk;
    struct stat stat;
    int file_size=0;
    int c;
    FILE *fp;
    char* exet;
    uint8_t send_start;
    uint8_t eof = X_EOT;
    int eof_count=0;

    retry = 3;
    fp = fopen(filename, "ab+");

    while(1){
        int v_stx_count=0;
        int inv_stx_count=0;
        int garbage_blk_count=0;
        int correct_blk_count=0;
        int garbage_count=0;
        int correct_count=0;
        uint8_t chunk_payload[1024];
        uint8_t garbage_payload[3][1024];
        uint16_t garbage_crc[3];
        int val_payload_crc_pr = 0;
        int val_payload_crc_cr = 0;
        int val_payload_crc_nx = 0;
        int pr_val_crc=0;
        int nx_val_crc=0;
        int val_crc=0;
        size_t z = 0;   
        while(retry){
                int next = 0;
                ret = saferead(fd, &chunk, 1);
                printf("read chunk");
                z = sizeof(chunk.payload);
                if(chunk.start != X_STX){
                    printf("error STXn");
                    return 0; // error
                }
                printf("retry partn");
                if(chunk.crc != swap16(crc16(chunk.payload, sizeof(chunk.payload)))){ 
                    if(garbage_count > 1){
                        int i;
                        for(i=0; i < garbage_count; i++){
                            if(chunk.crc == swap16(crc16(garbage_payload[i], sizeof(chunk.payload)))){
                                correct_count++;
                                memcpy(chunk_payload, garbage_payload[i], len);
                            }
                        }
                        if(correct_count < 1){
                            memcpy(garbage_payload[garbage_count], &chunk.payload, len);
                            garbage_count++;
                        }
                        printf("garbage#1n");  
                    }else{
                        // ごみの登録
                        memcpy(garbage_payload[0], &chunk.payload, len);
                        garbage_crc[0] = chunk.crc;
                        garbage_count++;
                        printf("garbage#2n");
                    }

                }else{
                    printf("correctn");
                    correct_count++;
                    memcpy(chunk_payload , &chunk.payload, len);
                }

        }
        safewrite(fd, &chunk_payload, z);            

    }
    close(fd);
    return 0;
}
static int open_serial(const char *path, int baud)
{
    int fd;
    struct termios tty;
    fd = open(path, O_RDWR | O_SYNC);
    if(fd < 0) {
        perror("open");
        return -errno;
    }
    memset(&tty, 0, sizeof(tty));
    if(tcgetattr(fd, &tty) != 0) {
        perror("tcgetattr");
        return -errno;
    }
    cfsetospeed(&tty, baud);
    cfsetispeed(&tty, baud);
    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit
    tty.c_iflag &= ~IGNBRK;             // disable break processing
    tty.c_lflag = 0;                // nosignaling chars, no echo,
    // no canonical processing
    tty.c_oflag = 0;                // no remapping, no delays
    tty.c_cc[VMIN] = 1;             // read doesn't block
    tty.c_cc[VTIME] = 5;                // 0.5 seconds read timeout
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);     // shut off xon/xoff ctrl
    tty.c_cflag |= (CLOCAL | CREAD);        // ignore modem controlsm
    tty.c_cflag &= ~(PARENB | PARODD);      // ignore modem controls,
    // enable reading
    tty.c_cflag &= ~(PARENB | PARODD);      // shut off party
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        perror("tcsetattr");
        return -errno;
    }
    return fd;
}
static void dump_serial(int serial_fd)
{
    char in;
    for (;;) {
        read(serial_fd, &in, sizeof(in));
        printf("%c", in);
        fflush(stdout);
    }
}
int main(int argc, char **argv){
    int a, ret, serial_fd;
    serial_fd = open_serial("/dev/ttyUSB0", 115200);

    ret = xmodem_receive(serial_fd, "sample.jpg");
//  dump_serial(serial_fd);
}   
`

您的程序永远不会收到任何数据,因为它从未尝试使用串行端口执行I/O。 Xmodem_receive()从不使用其参数serial_fd

static xmodem_receive(int serial_fd, char* filename){

相反,此例程使用非初始化的变量fd用作呼叫 saferead() and safewrite()的参数。

    int ret, fd;
...
                ret = saferead(fd, &chunk, 1);
...
        safewrite(fd, &chunk_payload, z);            

要复杂这个错误,您不必费心检查这些呼叫的返回值,因此由于使用非初始化变量(即无效的文件描述符)而引起的任何错误都会被静默丢弃。

相关内容

  • 没有找到相关文章

最新更新