Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 无法将完整脚本写入串行端口上的设备_C_Linux - Fatal编程技术网

C 无法将完整脚本写入串行端口上的设备

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

脚本文件包含6000多个字节,这些字节被复制到缓冲区中。然后,缓冲区的内容被写入连接到串行端口的设备。但是,写入函数仅返回4608字节,而缓冲区包含6117字节。我无法理解为什么会发生这种情况

{   
    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”)
将由我自己发布该代码片段。回答得好+是的,那很有帮助。