简体   繁体   English

写在mtd块设备上

[英]Write on a mtd block device

I'm trying to write on a NAND flash memory using MTD block device but I don't understand everything. 我正在尝试使用MTD块设备在NAND闪存上写,但我不明白一切。

As I read here 在这里读到

  • mtdblockN is the read only block device N mtdblockN是只读块设备N.
  • mtdN is the read/write char device N mtdN是读/写字符设备N.
  • mtdNro is the read only char device N mtdNro是只读字符设备N.

But I'd like to directly write bytes to the partition using a simple write in C and I don't understand how it works (I read somewhre that I first must erase the sectors I want to write on). 但是我想用C语言简单write直接将字节写入分区,我不明白它是如何工作的(我读过一些我首先必须删除我要写的扇区)。

Which device should I use and how to write on this device? 我应该使用哪种设备以及如何在此设备上书写?

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

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

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

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

For example if while using write() you got a value of EINVAL it could mean: 例如,如果使用write()时得到的值为EINVAL则可能意味着:

fd is attached to an object which is unsuitable for writing; fd附在不适合书写的物体上; 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. 或者使用O_DIRECT标志打开文件,并且buf中指定的地址,count中指定的值或当前文件偏移量未适当对齐。

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

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