AT+QFUPL在Linux系统上如何设计程序

许多串口工具是没法直接发送文件的。

在执行AT+QFUPL="filename" 返回connect后,直接向串口里拖动文件进去不行。

读文件,打开串口写入文件

第一次尝试 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s <file> <serial_port>\n", argv[0]);
        return 1;
    }

    char *file_name = argv[1];
    char *serial_port = argv[2];

    struct stat file_stat;

    stat(file_name, &file_stat);

    // 打开文件
    FILE *file = fopen(file_name, "rb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    // 打开串口
    int serial_fd = open(serial_port, O_WRONLY | O_NOCTTY);
    if (serial_fd < 0) {
        perror("Error opening serial port");
        fclose(file);
        return 1;
    }

    // 配置串口参数
    struct termios options;
    tcgetattr(serial_fd, &options);
    cfsetispeed(&options, B115200); // 输入波特率
    cfsetospeed(&options, B115200); // 输出波特率
    tcsetattr(serial_fd, TCSANOW, &options);

    // 读取文件内容并写入串口
    char *buffer;
    size_t bytes_read;


//    write(serial_fd, "at+qfdel=\"*\"\r\n", 20 );
    char at[30]="AT+QFUPL=\"testfota.bin\",";
    char atbuf[100];
    int len = file_stat.st_size;

    ssize_t  bytes_written = 0;

    sprintf(atbuf, "%s%d,50\r", at, len);

    printf("atbuf: %s\n", atbuf);

    write(serial_fd, atbuf, strlen(atbuf));

   buffer = (char*)malloc(len);

   memset(buffer,0,len);

    while ((bytes_read = fread(buffer, sizeof(char), len, file)) > 0) {
        printf("bytes_r: %d\n", bytes_read);
        bytes_written = write(serial_fd, buffer, bytes_read);
        if (bytes_written < 0) {
            perror("Error writing to serial port");
            break;
        }
    }
    printf("bytes_w: %d\n", bytes_written);
    printf("bytes_r: %d\n", bytes_read);

    free(buffer);
    // 关闭文件和串口
    fclose(file);
    close(serial_fd);

    return 0;
}

但是结果验证不对。

实际写入的文件大小和查询到的文件大小对不上。

实际上的文件大小是8640196字节

为什么结果会对不上呢?

优化程序

适当添加了一点点延时。不要过早close 掉fd

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Usage: %s <file> <serial_port> target_file_name\n", argv[0]);       return 1;
    }

    char *file_name = argv[1];
    char *serial_port = argv[2];
    char *targetfile = argv[3];

    struct stat file_stat;
    stat(file_name, &file_stat);
    FILE *file = fopen(file_name, "rb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    int serial_fd = open(serial_port, O_WRONLY | O_NOCTTY);
    if (serial_fd < 0) {
        perror("Error opening serial port");
        fclose(file);
        return 1;
    }

    struct termios options;
    memset(&options, 0 , sizeof(options));
    tcgetattr(serial_fd, &options);
    cfmakeraw(&options);
    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    tcsetattr(serial_fd, TCSANOW, &options);
    tcflush(serial_fd,TCIOFLUSH);

    char *buffer;
    size_t bytes_read;
    int len = file_stat.st_size;

    buffer = (char*)malloc(len);
    memset(buffer,0,len);

    bytes_read = fread(buffer, 1, len, file);
    printf("bytes_r: %d\n", bytes_read);
    char at[30]="AT+QFUPL=";
    char atbuf[100];

    ssize_t  bytes_written = 0;

    sprintf(atbuf, "%s\"%s\", %d\r", at,targetfile, len);

    printf("atbuf: %s\n", atbuf);

    write(serial_fd, atbuf, strlen(atbuf) +1);
    sleep(1);

   bytes_written = write(serial_fd, buffer, bytes_read);
   if(bytes_written < 0) {
         perror("Error writing to serial port");
   }

    printf("bytes_w: %d\n", bytes_written);
    printf("bytes_r: %d\n", bytes_read);

    sleep(2);
    tcflush(serial_fd,TCIOFLUSH);
    free(buffer);
    fclose(file);
    close(serial_fd);

    return 0;
}

尝试几次验证可行。

逐字节传输

TA发送完AT指令后,串口很快进入到数传模式。数传模式下,没有要求一次性将数据全部发送完,可以用逐字节的方式发送,理论上就没有上面的问题,待整理上传。

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值