- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想用下面的代码发送和接收文件。但函数有错误,“xmodem_receive”。
“xmodem_send”函数通过“tty/AMA0”发送“xmodem_chunk”,接收数据为“xmodem_receive”中的“ret = saferead(fd, &chunk, sizeof(chunk))”但是这一行没有读取数据!相反,这一行停止了我的代码。有人教我至少需要运行这段代码吗?
这是代码(略)。
#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);
}
`
最佳答案
您的程序从不接收任何数据,因为它从不尝试使用串行端口执行 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);
要复合此错误,您不必费心去检查这些调用的返回值,因此由于使用未初始化的变量(即无效的文件描述符)而导致的任何错误都会被悄无声息地丢弃。
关于c - 无法从串口获取数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41282541/
我通过 spring ioc 编写了一些 Rest 应用程序。但我无法解决这个问题。这是我的异常(exception): org.springframework.beans.factory.BeanC
我对 TestNG、Spring 框架等完全陌生,我正在尝试使用注释 @Value通过 @Configuration 访问配置文件注释。 我在这里想要实现的目标是让控制台从配置文件中写出“hi”,通过
为此工作了几个小时。我完全被难住了。 这是 CS113 的实验室。 如果用户在程序(二进制计算器)结束时选择继续,我们需要使用 goto 语句来到达程序的顶部。 但是,我们还需要释放所有分配的内存。
我正在尝试使用 ffmpeg 库构建一个小的 C 程序。但是我什至无法使用 avformat_open_input() 打开音频文件设置检查错误代码的函数后,我得到以下输出: Error code:
使用 Spring Initializer 创建一个简单的 Spring boot。我只在可用选项下选择 DevTools。 创建项目后,无需对其进行任何更改,即可正常运行程序。 现在,当我尝试在项目
所以我只是在 Mac OS X 中通过 brew 安装了 qt。但是它无法链接它。当我尝试运行 brew link qt 或 brew link --overwrite qt 我得到以下信息: ton
我在提交和 pull 时遇到了问题:在提交的 IDE 中,我看到: warning not all local changes may be shown due to an error: unable
我跑 man gcc | grep "-L" 我明白了 Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more inf
我有一段代码,旨在接收任何 URL 并将其从网络上撕下来。到目前为止,它运行良好,直到有人给了它这个 URL: http://www.aspensurgical.com/static/images/a
在过去的 5 个小时里,我一直在尝试在我的服务器上设置 WireGuard,但在完成所有设置后,我无法 ping IP 或解析域。 下面是服务器配置 [Interface] Address = 10.
我正在尝试在 GitLab 中 fork 我的一个私有(private)项目,但是当我按下 fork 按钮时,我会收到以下信息: No available namespaces to fork the
我这里遇到了一些问题。我是 node.js 和 Rest API 的新手,但我正在尝试自学。我制作了 REST API,使用 MongoDB 与我的数据库进行通信,我使用 Postman 来测试我的路
下面的代码在控制台中给出以下消息: Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child el
我正在尝试调用一个新端点来显示数据,我意识到在上一组有效的数据中,它在数据周围用一对额外的“[]”括号进行控制台,我认为这就是问题是,而新端点不会以我使用数据的方式产生它! 这是 NgFor 失败的原
我正在尝试将我的 Symfony2 应用程序部署到我的 Azure Web 应用程序,但遇到了一些麻烦。 推送到远程时,我在终端中收到以下消息 remote: Updating branch 'mas
Minikube已启动并正在运行,没有任何错误,但是我无法 curl IP。我在这里遵循:https://docs.traefik.io/user-guide/kubernetes/,似乎没有提到关闭
每当我尝试docker组成任何项目时,都会出现以下错误。 我尝试过有和没有sudo 我在这台机器上只有这个问题。我可以在Mac和Amazon WorkSpace上运行相同的容器。 (myslabs)
我正在尝试 pip install stanza 并收到此消息: ERROR: No matching distribution found for torch>=1.3.0 (from stanza
DNS 解析看起来不错,但我无法 ping 我的服务。可能是什么原因? 来自集群中的另一个 Pod: $ ping backend PING backend.default.svc.cluster.l
我正在使用Hibernate 4 + Spring MVC 4当我开始 Apache Tomcat Server 8我收到此错误: Error creating bean with name 'wel
我是一名优秀的程序员,十分优秀!