Write on a mtd block device

前端 未结 1 1417
春和景丽
春和景丽 2021-01-31 22:29

I\'m trying to write on a NAND flash memory using MTD block device but I don\'t understand everything.

As I read here

  • mtdblockN is the read on
1条回答
  •  梦如初夏
    2021-01-31 23:02

    Reading and writing from/to memory technology devices isn't really all that different than any other type of IO, with the exception that before you write you need to erase the sector (erase block)

    To make things simple on yourself you can always just use the mtd-utils (such as flash_erase, nanddump and nandwrite, for erasing, read, and writing respectively) without the need for writing code.

    However if you do want to do it pragmatically, here's an example, make sure to read all the comments as I put all the details in there:

    #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 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;
    }
    

    The nice thing about this is since you can use the standards utils as you do from other devices, it makes it easy to understand what write(), open(), and read() do and what to expect from them.

    For example if while using write() you got a value of EINVAL it could mean:

    fd is attached to an object which is unsuitable for writing; or the file was opened with the O_DIRECT flag, and either the address specified in buf, the value specified in count, or the current file offset is not suitably aligned.

    0 讨论(0)
提交回复
热议问题