C 无法将完整脚本写入串行端口上的设备
脚本文件包含6000多个字节,这些字节被复制到缓冲区中。然后,缓冲区的内容被写入连接到串行端口的设备。但是,写入函数仅返回4608字节,而缓冲区包含6117字节。我无法理解为什么会发生这种情况C 无法将完整脚本写入串行端口上的设备,c,linux,C,Linux,脚本文件包含6000多个字节,这些字节被复制到缓冲区中。然后,缓冲区的内容被写入连接到串行端口的设备。但是,写入函数仅返回4608字节,而缓冲区包含6117字节。我无法理解为什么会发生这种情况 { FILE *ptr; long numbytes; int i; ptr=fopen("compass_script(1).4th","r");//Opening the script file if(ptr==NULL) return
{
FILE *ptr;
long numbytes;
int i;
ptr=fopen("compass_script(1).4th","r");//Opening the script file
if(ptr==NULL)
return 1;
fseek(ptr,0,SEEK_END);
numbytes = ftell(ptr);//Number of bytes in the script
printf("number of bytes in the calibration script %ld\n",numbytes);
//Number of bytes in the script is 6117.
fseek(ptr,0,SEEK_SET);
char writebuffer[numbytes];//Creating a buffer to copy the file
if(writebuffer == NULL)
return 1;
int s=fread(writebuffer,sizeof(char),numbytes,ptr);
//Transferring contents into the buffer
perror("fread");
fclose(ptr);
fd = open("/dev/ttyUSB3",O_RDWR | O_NOCTTY | O_NONBLOCK);
//Opening serial port
speed_t baud=B115200;
struct termios serialset;//Setting a baud rate for communication
tcgetattr(fd,&serialset);
cfsetispeed(&serialset,baud);
cfsetospeed(&serialset,baud);
tcsetattr(fd,TCSANOW,&serialset);
long bytesw=0;
tcflush(fd,TCIFLUSH);
printf("\nnumbytes %ld",numbytes);
bytesw=write(fd,writebuffer,numbytes);
//Writing the script into the device connected to the serial port
printf("bytes written%ld\n",bytesw);//Only 4608 bytes are written
close (fd);
return 0;
}
嗯,这就是规格。写入文件时,进程通常会被阻止,直到写入整个数据。这意味着只有当所有数据都已写入磁盘缓冲区时,进程才会再次运行。对于设备来说,情况并非如此,因为设备驱动程序负责确定一次要写入多少数据。这意味着,根据设备驱动程序的不同,您将获得所有数据驱动,仅部分数据驱动,甚至完全没有数据驱动。这完全取决于设备以及驱动程序如何实现其控制 在地板上,设备驱动程序通常有有限的内存来填充缓冲区,并且能够接受有限的数据量。这里有两种策略,驱动程序可以阻止进程,直到有更多的缓冲区空间来处理它,或者它可以返回,只进行部分写入 您的程序负责接受部分读取并继续写入缓冲区的其余部分,或者将问题传递回客户机模块并再次仅返回部分写入。这种方法是最灵活的,并且在任何地方都可以实现。现在,你有了部分写作的理由,但关键在于你自己,你必须决定下一步该做什么 另外,在对
ftell()
函数调用返回值使用long
和对fwrite()
函数调用使用int
时,要小心。。。虽然您的数据量不大,并且不可能无法将这些值分别转换为long
和int
,但这两个调用的返回类型分别为size\u t
和ssize\u t
resp。(与波特率值使用的speed\u t
类型类似)long
可以是32位,而size\u t
可以是64位类型
您所能做的最好的事情是确保整个缓冲区由一些代码段编写,如下一个代码段:
char *p = buffer;
while (numbytes > 0) {
ssize_t n = write(fd, p, numbytes);
if (n < 0) {
perror("write");
/* driver signals some error */
return 1;
}
/* writing 0 bytes is weird, but possible, consider putting
* some code here to cope for that possibility. */
/* n >= 0 */
/* update pointer and numbytes */
p += n;
numbytes -= n;
}
/* if we get here, we have written all numbytes */
char*p=缓冲区;
而(单位>0){
ssize_t n=写入(fd,p,numbytes);
if(n<0){
佩罗(“书面”);
/*司机发出错误信号*/
返回1;
}
*写0字节是奇怪的,但可能的,考虑把
*这里有一些代码来应对这种可能性*/
/*n>=0*/
/*更新指针和numbytes*/
p+=n;
numbytes-=n;
}
/*如果我们到了这里,我们已经写了所有的数字*/
恐怕没有人能帮助你。你需要自己解决这个问题嗯..”O_NONBLOCK'…是的,在我发布问题后,我就知道了。非常感谢!嗯,1)代码有问题,但没有检查各种函数的结果fseek()、fread()、tcgetattr()
,以及至少4个其他人,等等。这似乎是第一步,而且比在上面发布更有效。2) 请尝试用二进制文件打开该文件fopen(“compass_脚本(1.4th)”,“rb”)
将由我自己发布该代码片段。回答得好+是的,那很有帮助。