Lettura e scrittura da/verso dispositivi di tecnologia di memoria non è poi così diverso da qualsiasi altro tipo di IO, con l'eccezione che prima di scrivere è necessario cancellare il settore (cancellare blocco)
Per rendere le cose semplici su di te puoi sempre usare semplicemente mtd-utils (come flash_erase
, nanddump
e nandwrite
, per cancellare, leggere e scrivere rispettivamente) senza la necessità di scrivere codice.
Tuttavia, se si vuole farlo in modo pragmatico, ecco un esempio, assicurarsi di leggere tutti i commenti che come ho messo tutti i dettagli in là:
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
int main()
{
mtd_info_t mtd_info; // the MTD structure
erase_info_t ei; // the erase block structure
int i;
unsigned char data[20] = { 0xDE, 0xAD, 0xBE, 0xEF, // our data to write
0xDE, 0xAD, 0xBE, 0xEF,
0xDE, 0xAD, 0xBE, 0xEF,
0xDE, 0xAD, 0xBE, 0xEF,
0xDE, 0xAD, 0xBE, 0xEF};
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 bytes\nMTD erase size: %x bytes\n",
mtd_info.type, mtd_info.size, mtd_info.erasesize);
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]);
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;
}
La cosa bella di questo è perché si può usa gli strumenti di utilità standard come fai da altri dispositivi, facilita la comprensione di cosa fanno write()
, open()
e read()
e cosa aspettarsi da loro.
Per esempio, se durante l'utilizzo write()
hai un valore EINVAL
potrebbe significare:
fd è collegato a un oggetto che non è adatto per la scrittura; oppure il file è stato aperto con il flag O_DIRECT e l'indirizzo specificato in buf, il valore specificato in count, o l'offset del file corrente non è adeguatamente allineato.
Non sono sicuro se questo aiuta, ma avete visto gli esempi forniti qui: [link] (http://www.linuxforu.com/2012/01/working-with-mtd-devices/), sezione "Accesso agli MTD dalle applicazioni" – Habi
Sì, l'ho visto ;-) Al momento sto provandolo – marmottus
I dispositivi MTD consentono di accedere al flash raw. Se si desidera creare, modificare, rimuovere file e così via. Questo dovrebbe essere fatto su un filesystem (yaffs2 nel tuo caso). L'accesso al flash tramite dispositivi MTD non fornisce tale livello. – Rerito