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
linux programming: write to device file
提问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 ?
也许这有帮助?
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 dmesg
in 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.
希望这可以帮助。