2012-04-28 2 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() неверно.

Прежде чем приступить к вызову, вы должны проверить, является ли системный вызов проблемой. страницы людей довольно четко по теме:

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

Второй параметр вызова записи должен быть указатель «ЬиЕ» уже является указателем, ссылки на его «&» вы получаете указатель на указатель, который является неправильным: правильный вызов:

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

В C для массивов, находящихся в стеке, '& buf' и' & buf [0] 'заканчивается одним и тем же адресом, поэтому он не является источником ошибки (хотя это еще что-то, что нужно исправить). – jszakmeister

1

вы, возможно, придется написать целую страницу, а не только 4 байта.

Вы можете это подтвердить, набрав команду dmesg в оболочке. Тогда вы должны увидеть следующее Kernel сообщение:

nand_do_write_ops: Попытка не писать страницы выровнен данные

Затем замените код для записи в МПД по:

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, ...), прежде чем писать.

Надеюсь, это поможет.

Смежные вопросы