2012-04-28 69 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, ...)。

希望這會有所幫助。