2012-04-28 14 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; 
} 

ファイルは/ dev/mtd0はnandsimカーネルモジュールを使用して作成され、そして

mtdinfo /dev/mtd0 

を実行するには、私が実行して意味のあるoutput.Afterを得ました私のプログラムに誤りがあった場合

perror output:: Invalid argument 

:私のプログラムは、それが出力ですか?

+2

エラー報告が間違っています。個々のシステムコール/ライブラリ関数の戻り値をチェックし、関数呼び出しを介さずに 'perror' _right after_ a _failed_呼び出しを使う必要があります。書かれているように、あなたが持っている 'perror'呼び出しは、まったく情報を与えません。 – Mat

答えて

2

はい、問題があります。 perror()の使用は間違っています。

まず、perrorを呼び出す前にシステムコールに問題があるかどうかを確認してください。 manページには、件名にきわめて明確です:

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) { 

書き込みコールへの2番目のパラメータがポインタである必要があり、「bufは」とそれを参照する、すでにポインタであります「&は、」あなたは間違っているポインタへのポインタを取得:正しい呼び出しは次のとおりです。

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

Cでは、スタック上にある配列の場合、 '&buf'と'&buf [0] 'は同じアドレスで終わるので、エラーの原因ではありません(まだ修正すべきものですが)。 – jszakmeister

1

あなたはページ全体だけでなく、4バイトを記述する必要があります。

これは、シェルにdmesgというコマンドを入力することで確認できます。 そして、あなたは以下のカーネルメッセージが表示されるはずです。また

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 

:その後でMTDに書き込むためのコードを置き換えないページ整列データ

を書き込もう:

nand_do_write_opsを書き込む前に不良ブロック(ioctl(fd, MEMGETBADBLOCK, ...)をチェックし、ブロック(ioctl(fd, MEMERASE, ...)を消去することを検討してください。

これが役に立ちます。

関連する問題