linux编程:写入设备文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10362111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:03:02  来源:igfitidea点击:

linux programming: write to device file

clinux

提问by user1361391

I wrote this:

我是这样写的:

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
#include <errno.h>

int main( void )
{
        int fd;
        char buf[4]="abc";

        fd = open("/dev/mtd0", O_RDWR);
        lseek(fd, 1, SEEK_SET);
        write(fd, &buf, 4);
        close(fd);
        perror("perror output:");

        return 0;
}

The file /dev/mtd0 is created using nandsim kernel module, and run

文件 /dev/mtd0 是使用 nandsim 内核模块创建的,然后运行

mtdinfo /dev/mtd0

got meaningful output.After i run my program, it's output:

得到了有意义的输出。在我运行我的程序之后,它的输出是:

perror output:: Invalid argument

If there is any error in my program?

如果我的程序有任何错误?

回答by Jakub Oboza

You should have something like this

你应该有这样的东西

if(-1 == write(fd, &buf, 4)){
  perror("perror output:");
}
close(fd);

because perror shows last error.

因为 perror 显示最后一个错误。

http://www.cplusplus.com/reference/clibrary/cstdio/perror/

http://www.cplusplus.com/reference/clibrary/cstdio/perror/

and more about perror http://www.java-samples.com/showtutorial.php?tutorialid=597

以及更多关于 perror http://www.java-samples.com/showtutorial.php?tutorialid=597

回答by Viktor Latypov

Maybe this helps ?

也许这有帮助?

http://forums.freescale.com/t5/Other-Microcontrollers/Can-t-write-new-uboot-to-mtd0-in-linux-on-MPC8313E-RDB/td-p/34727

http://forums.freescale.com/t5/Other-Microcontrollers/Can-t-write-new-uboot-to-mtd0-in-linux-on-MPC8313E-RDB/td-p/34727

It all has to deal with access rights.

这一切都必须处理访问权限。

And as Jakub and Mat say, check the error code for each API call.

正如 Jakub 和 Mat 所说,检查每个 API 调用的错误代码。

回答by Kristof Provost

Yes, there is a problem. Your use of perror()is wrong.

是的,有问题。你的使用perror()是错误的。

You should first check if a system call indicates a problem before calling perror. The man page is quite explicit on the subject:

在调用 perror 之前,您应该首先检查系统调用是否表明存在问题。手册页对这个主题非常明确:

Note that errno is undefined after a successful library call: this call
may  well  change  this  variable, even though it succeeds, for example
because it internally used some other  library  function  that  failed.
Thus,  if  a failing call is not immediately followed by a call to per‐
ror(), the value of errno should be saved.

You should be checking the return codes of each system, and only call perror if they fail. Something like this:

您应该检查每个系统的返回代码,并且只有在它们失败时才调用 perror。像这样的东西:

fd = open("/dev/mtd0", O_RDWR);
if (fd < 0) {
    perror("open: ");
    return 1;
}
if (lseek(fd, 1, SEEK_SET) < 0) {
    perror("lseek: ");
    return 1;
}
if (write(fd, &buf, 4) < 0) {
    perror("write: ");
    return 1;
}
close(fd);

回答by angelo

The trouble is in this line:

问题出在这一行:

if (write(fd, &buf, 4) < 0) {

The second parameter to the write call has to be a pointer, "buf" is already a pointer, referencing it with the "&" you obtain a pointer to a pointer that is wrong: the correct call is:

write 调用的第二个参数必须是一个指针,“buf”已经是一个指针,用“&”引用它你会得到一个指向错误指针的指针:正确的调用是:

if (write(fd, (void*)buf, 4) < 0) {

回答by Gaston

You may have to write an entire page and not only 4 bytes.

您可能必须编写整个页面,而不仅仅是 4 个字节。

You can confirm this by typing the command dmesgin shell. Then you should see the following Kernel message:

您可以通过dmesg在 shell 中键入命令来确认这一点。然后您应该看到以下内核消息:

nand_do_write_ops: Attempt to write not page aligned data

nand_do_write_ops:尝试写入非页面对齐的数据

Then replace the code to write in the mtd by:

然后将要写入 mtd 的代码替换为:

char buf[2048]="abcdefghij";                      //Ajust size according to 
                                                  //mtd_info.writesize
mtd_info_t mtd_info;                              // the MTD structure

if (ioctl(fd, MEMGETINFO, &mtd_info) != 0) {...   // get the device info

memset(buf+10, 0xff, mtd_info.writesize - 10);    //Complete buf with 0xff's

if (write(fd, &buf, mtd_info.writesize) < 0) {... // write page

Also consider to check bad blocks (ioctl(fd, MEMGETBADBLOCK, ...) and erase blocks (ioctl(fd, MEMERASE, ...) before you write.

还要考虑在写入之前检查坏块 ( ioctl(fd, MEMGETBADBLOCK, ...) 和擦除块 ( ioctl(fd, MEMERASE, ...)。

Hope this helps.

希望这可以帮助。