Reputation: 65
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
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?
Upvotes: 4
Views: 21156
Reputation: 629
You may have to write an entire page and not only 4 bytes.
You can confirm this by typing the command dmesg
in shell.
Then you should see the following Kernel message:
nand_do_write_ops: Attempt to write not page aligned data
Then replace the code to write in the mtd by:
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.
Hope this helps.
Upvotes: 1
Reputation: 1
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:
if (write(fd, (void*)buf, 4) < 0) {
Upvotes: 0
Reputation: 26322
Yes, there is a problem. Your use of perror()
is wrong.
You should first check if a system call indicates a problem before calling perror. The man page is quite explicit on the subject:
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:
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);
Upvotes: 2
Reputation: 14467
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.
Upvotes: 1
Reputation: 5421
You should have something like this
if(-1 == write(fd, &buf, 4)){
perror("perror output:");
}
close(fd);
because perror shows last error.
http://www.cplusplus.com/reference/clibrary/cstdio/perror/
and more about perror http://www.java-samples.com/showtutorial.php?tutorialid=597
Upvotes: 2