通过串口发送文件

时间:2013-03-06 02:50:57

标签: c linux file-io serial-port

使用此代码,我正在尝试将文件发送到CC430f5137并从中接收回来。我正在使用2个程序,一个是以下程序(它用于发送和接收文件到我的Linux VM,另一个是用于CC430f5137的程序(它包含rx,我的设备的tx代码,在windows中)。我可以能够将单个字节(例如,A)从文件发送到我的设备,但不能发送多个字节。

//sample1.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <termios.h>
#define BUFSIZE            1300 //1

int open_serial( char *dev_name, int baud, int vtime, int vmin )
{
    int fd;
    struct termios  newtio;

    fd = open( dev_name, O_RDWR | O_NOCTTY );
    if ( fd < 0 )
    {
        printf( "Device OPEN FAIL %s\n", dev_name );
        return  -1;
    }
    memset(&newtio, 0, sizeof(newtio));
    newtio.c_iflag = IGNPAR|INLCR;  // non-parity void UARTHandler(int fd);
    newtio.c_oflag = 0;
    newtio.c_cflag = CS8 | CLOCAL | CREAD; // NO-rts/cts

    switch( baud )
    {
        case 115200 : newtio.c_cflag |= B115200; break;
        case 57600  : newtio.c_cflag |= B57600;  break;
        case 38400  : newtio.c_cflag |= B38400;  break;
        case 19200  : newtio.c_cflag |= B19200;  break;
        case 9600   : newtio.c_cflag |= B9600;   break;
        case 4800   : newtio.c_cflag |= B4800;   break;
        case 2400   : newtio.c_cflag |= B2400;   break;
        default     : newtio.c_cflag |= B115200; break;
    }
    //set input mode (non-canonical, no echo,.....)
    newtio.c_lflag = 0;
    newtio.c_cc[VTIME] = vtime;
    newtio.c_cc[VMIN]  = vmin;
    tcflush  ( fd, TCIFLUSH );
    tcsetattr( fd, TCSANOW, &newtio );

    return fd;
}

int sendfile(int fd)      //void sendfile(int fd)
{
    int fd1,readc;
    unsigned short fileLength;
    unsigned char buf[BUFSIZE];

    fd1=open("cert.pem",O_RDONLY);

    fileLength=lseek(fd1,0,SEEK_END);
    printf("file length is %d bytes\n",fileLength);
    lseek(fd1,0,SEEK_SET);

    write(fd,(unsigned char*)&fileLength, 2);
           while(fileLength>0)
            {
                if(fileLength>=BUFSIZE)
                {
                    readc=read(fd1,buf,BUFSIZE);
                    if(readc==-1)
                    {
                    printf("read failed!!\n");
                    }
                    if(read>0)
                    {
                    buf[BUFSIZE]='\0';
                    printf("%s\n",buf);
                    if(write(fd,buf,BUFSIZE))
                    fileLength -= BUFSIZE;
                    }
                }
                else
                {
                    readc=read(fd1,buf,fileLength);
                    if(readc==-1)
                    {
                    printf("read failed!!\n");
                    }
                    if(readc>0)
                    {
                    buf[fileLength]='\0';
                    printf("%s\n",buf);
                    if(write(fd, buf, fileLength))
                    fileLength=0;
                    }
                }
            }
    printf("%s\n",fd);
    printf("file sent succssfully\n");
    return fd1;//close(fd1);
    close(fd);

}

void receivefile(int fd)
    {
        char buf[1300],read_byte,buf2[1300];
        int fd2,readc;
        unsigned short fileLength;

        fd2=open("test.pem", O_WRONLY|O_CREAT);

                if(fd2<0)
                {
                printf("file open failed!!\n");
                        }
                while(!(read(fd,(unsigned char*)&fileLength,2)>0));

                printf("i am in receive file\n");

                while(fileLength>0) 
                {
                    readc = read(fd, buf, BUFSIZE);
                    if(readc==-1)
                    {
                    printf("read failed!!\n");
                    }
                printf("read %d bytes, value is %s\n",readc,buf);

                    if(readc >0)
                    {
                    buf[readc]='\0';
                    printf("buf value is%s\n", buf);
                    write(fd2,buf,readc);
                    fileLength -= readc;
                    }
                }
            close(fd2);
            close(fd);
    }

void close_serial( int fd )
{
    close( fd );
    printf("ClosePort!!\n");
}

int  main( int argc, char **argv )
{
    int fd;
    int baud;
    char  dev_name[128];

    if ( argc != 3)
    {
        printf( " sample_serial [device] [baud]\n" \
               "    device : /dev/ttySAC0 ...\n"    \
               "    baud   : 2400 ... 115200\n" );
        return -1;
    }
    printf( " Serial test start...  (%s)\n", __DATE__ );

    strcpy( dev_name, argv[1] );
    baud    = strtoul( argv[2], NULL, 10 );

    fd = open_serial( dev_name, baud, 4, 1);

    sendfile(fd);
    receivefile(fd);        
    close_serial( fd );        
    printf( " Serial test end\n" );

    return  0;
}

这是从文件到串口发送1个字节的输出

  [root@localhost ~]# gcc -std=c99 -std=gnu99 sample1.c -o out1
  sample1.c:151:50: warning: backslash and newline separated by space
  sample1.c:152:45: warning: backslash and newline separated by space
  [root@localhost ~]# ./out1 /dev/ttyUSB20 115200
  Serial test start...  (Mar  6 2013)
  file length is 2 bytes
  A
  wrote 3 bytes
  file sent succssfully
  i am in receive file
  read 1 bytes, value is A
  buf value isA
  read 1 bytes, value is A
  buf value isA
  read 1 bytes, value is A
  buf value isA
  read 1 bytes, value is A
  buf value isA

这是从文件向串口发送多个字节的输出

  [root@localhost ~]# gcc -std=c99 -std=gnu99 sample1.c -o out1
  sample1.c:151:50: warning: backslash and newline separated by space
  sample1.c:152:45: warning: backslash and newline separated by space
  [root@localhost ~]# ./out1 /dev/ttyUSB20 115200
  Serial test start...  (Mar  6 2013)
  file length is 2 bytes
  i am doing well today
  wrote 3 bytes
  file sent succssfully
  i am in receive file
  read 1 bytes, value is
  buf value is
  read 1 bytes, value is 
  buf value is
  read 1 bytes, value is 
  buf value is
  read 1 bytes, value is 
  buf value is

如你所见,我没有收到文件内容,我正在收回空字符   从我的设备,即使我发送多个字节到我的设备。

sendfile()工作正常,我可以写“cert.pem”到port.I有一个   从端口读取文件并写回“test.pem”的问题。我得到了输出   接收器程序中给出的一些打印语句,但是连续获取数据。标记在一个   合适的方式。我也重置了所有连接。

2 个答案:

答案 0 :(得分:2)

你做错了 - 不是重新发明通过串行链接发送二进制文件问题的解决方案,而是使用现有的标准解决方案,例如ZMODEM

当你这样做时,你不必编写Linux端程序,因为已经存在一个免费程序,你可以将现有程序移植到你的CC430f5137,无论是什么。

答案 1 :(得分:1)

让我们从明显的开始。

a:Sendfile中没有任何循环结构......

b:缓冲区溢出,如下所示:

unsigned char buf[BUFSIZE];
...
buf[BUFSIZE]=0

c:你有这样的调试'读取1个字节,值是A'但它不在代码中。很难修复你没有发布的代码...