繁体   English   中英

写在mtd块设备上

[英]Write on a mtd block device

我正在尝试使用MTD块设备在NAND闪存上写,但我不明白一切。

在这里读到

  • mtdblockN是只读块设备N.
  • mtdN是读/写字符设备N.
  • mtdNro是只读字符设备N.

但是我想用C语言简单write直接将字节写入分区,我不明白它是如何工作的(我读过一些我首先必须删除我要写的扇区)。

我应该使用哪种设备以及如何在此设备上书写?

对存储器技术设备进行读写操作并不是与任何其他类型的IO完全不同,除了在编写之前需要擦除扇区(擦除块)

为了使事情对自己简单,你总是可以只使用MTD-utils的(如flash_erasenanddumpnandwrite ,擦除,读取和写入分别),而无需编写代码。

但是,如果您确实想要务实地执行此操作,这是一个示例,请务必阅读所有注释,因为我将所有详细信息放在其中:

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

关于这一点的好处是因为您可以像使用其他设备那样使用标准工具,这使得理解write()open()read()功能以及对它们的期望很容易。

例如,如果使用write()时得到的值为EINVAL则可能意味着:

fd附在不适合书写的物体上; 或者使用O_DIRECT标志打开文件,并且buf中指定的地址,count中指定的值或当前文件偏移量未适当对齐。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM