2012-04-28 65 views
3

我写了这个:linux编程:写入设备文件

#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; 
} 

使用nandsim内核模块中创建的文件/ dev/mtd0,并运行

mtdinfo /dev/mtd0 

得到有意义的output.After我运行我的程序,它的输出:

perror output:: Invalid argument 

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

+2

您的错误报告是错误的。您需要检查每个系统调用/库函数的返回值,并在调用_failed_之后使用'perror' _right,而不需要中介函数调用。正如所写的,你所做的'perror'调用根本不会给你任何信息。 – Mat 2012-04-28 09:07:23

回答

2

是的,存在问题。您使用perror()是错误的。

在调用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. 

你应该检查每个系统的返回代码,并只调用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); 
0

麻烦的是在这一行:

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

的第二个参数写入调用必须是一个指针,“BUF”已经是一个指针,以引用它在“&”获得一个指针的指针是错误的:正确的调用是:

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

在C中,对于堆栈中的数组,'&buf'和'&buf [0]'以相同的地址结束,所以它不是错误的来源(尽管它仍然是应该纠正的)。 – jszakmeister 2013-05-16 09:12:57

1

您可能需要写一整页而不是只4个字节。

您可以在shell中输入命令dmesg来确认。 然后,你应该看到下面的内核消息:

nand_do_write_ops:尝试不写页对齐数据

,然后更换代码编写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 

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

希望这会有所帮助。