许多串口工具是没法直接发送文件的。
在执行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指令后,串口很快进入到数传模式。数传模式下,没有要求一次性将数据全部发送完,可以用逐字节的方式发送,理论上就没有上面的问题,待整理上传。