Obtenir EINVAL en essayant d’écrire sur le périphérique mtd

Je me réfère au code dans cette réponse . J’ai ajouté une gestion d’erreur cependant. L’opération open() et le read() tous sans erreur et les 20 octets que j’ai lus sont tous 0xff . Cependant, en essayant d’écrire les 20 octets du tableau data[] , j’obtiens un EINVAL erreur EINVAL de la fonction write() . Quelle pourrait être la cause du problème? J’ai effacé la mémoire avant d’essayer d’écrire …

J’ai vu votre message original . J’ai le même problème récemment, et j’ai trouvé que la taille d’écriture est importante.

mtd_info_t (struct mtd_info_user) a une variable nommée writesize (référence: https://elixir.bootlin.com/linux/v3.2/source/include/mtd/mtd-abi.h#L125 )

 struct mtd_info_user { __u8 type; __u32 flags; __u32 size; /* Total size of the MTD */ __u32 erasesize; __u32 writesize; __u32 oobsize; /* Amount of OOB data per block (eg 16) */ __u64 padding; /* Old obsolete field; do not use */ }; 

lorsque vous écrivez dans le mtd, vous devriez remarquer écrire

 #include  #include  #include  #include  #include  #include  int main(){ mtd_info_t mtd_info; // the MTD structure erase_info_t ei; // the erase block structure int i; unsigned char read_buf[20] = {0x00}; // empty array for reading int fd = open("/dev/mtd0", O_RDWR); // open the mtd device for reading and // writing. Note you want mtd0 not mtdblock0 // also you probably need to open permissions // to the dev (sudo chmod 777 /dev/mtd0) ioctl(fd, MEMGETINFO, &mtd_info); // get the device info // dump it for a sanity check, should match what's in /proc/mtd printf("MTD Type: %x\nMTD total size: %x(hex) bytes\nMTD erase size: %x(hex) bytes\nMTD write size: %x(hex) bytes\n", mtd_info.type, mtd_info.size, mtd_info.erasesize, mtd_info.writesize); ei.length = mtd_info.erasesize; //set the erase block size for(ei.start = 0; ei.start < mtd_info.size; ei.start += ei.length) { ioctl(fd, MEMUNLOCK, &ei); // printf("Eraseing Block %#x\n", ei.start); // show the blocks erasing // warning, this prints a lot! ioctl(fd, MEMERASE, &ei); } lseek(fd, 0, SEEK_SET); // go to the first block read(fd, read_buf, sizeof(read_buf)); // read 20 bytes // sanity check, should be all 0xFF if erase worked for(i = 0; i<20; i++) printf("buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]); /********************************************************** * important part! * * notice the size of data array is mtd_info.writesize * **********************************************************/ uint32_t write_size = mtd_info.writesize; unsigned char data[write_size];//write 0 bzero(data, write_size); lseek(fd, 0, SEEK_SET); // go back to first block's start write(fd, data, sizeof(data)); // write our message lseek(fd, 0, SEEK_SET); // go back to first block's start read(fd, read_buf, sizeof(read_buf));// read the data // sanity check, now you see the message we wrote! for(i = 0; i<20; i++) printf("buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]); close(fd); return 0; } 

J'espère que ça peut aider