2016-12-22 9 views
2

Я хотел был бы отправить и получить файл в нижнем коде. , но в функции есть «xmodem_receive».Не удалось получить структуру данных из последовательного порта

функция "xmodem_send" является отправка "xmodem_chunk" через "TTY/AMA0" и прием данных не "RET = saferead (FD, & кусок, SizeOf (фрагмент))" в "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 STX\n"); 
        return 0; // error 
       } 
       printf("retry part\n"); 
       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#1\n"); 
        }else{ 
         memcpy(garbage_payload[0], &chunk.payload, len); 
         garbage_crc[0] = chunk.crc; 
         garbage_count++; 
         printf("garbage#2\n"); 
        } 


       }else{ 
        printf("correct\n"); 
        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 STX\n"); 
        return 0; // error 
       } 
       printf("retry part\n"); 
       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#1\n"); 
        }else{ 
         // ごみの登録 
         memcpy(garbage_payload[0], &chunk.payload, len); 
         garbage_crc[0] = chunk.crc; 
         garbage_count++; 
         printf("garbage#2\n"); 
        } 


       }else{ 
        printf("correct\n"); 
        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); 

} 
` 
+0

Что делает ** open_serial() ** делать? Где код? С чем связан этот последовательный порт? Каковы параметры линии? – sawdust

+0

Извините, @sawdust. Я хочу, чтобы tty/AMA0 подключился к tty/USB0 без подтверждения и подтверждения. Поэтому я устанавливаю и запускаю этот код в качестве приемника и отправляю каждый пакет три раза. – NEWBIEEBIEE

+0

@sawdust. вы правы, я не нормальный, и мне нужно поправиться на английском. – NEWBIEEBIEE

ответ

2

Ваша программа никогда не получает каких-либо данных, потому что он никогда не пытается выполнить I/O с последовательным портом. xmodem_receive() никогда не использует свой параметр serial_fd.

static xmodem_receive(int serial_fd, char* filename){ 

Вместо этого процедура использует неинициализированную переменную fd в качестве аргументов в вызовах saferead() и safewrite().

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

Для соединения этой ошибки, вы не потрудились проверить возвращаемые значения из этих вызовов, так что любые ошибки, связанные с использованием неинициализированного переменным (т.е. недопустимого дескриптора файла) получить просто отбрасываются.