在mtd块设备上写 [英] Write on a mtd block device

查看:1166
本文介绍了在mtd块设备上写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当我读取这里




  • mtdblockN 是只读块设备N

  • mtdN 是读/写字符设备N

  • mtdNro 只读char设备N



但是我想直接使用简单的将字节写入分区在C中写入,我不明白它是如何工作的(我读了一些,我首先必须擦除我想写的扇区)。



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

解决方案



为了简化自己,您可以随时使用mtd-utils(例如 flash_erase nanddump nandwrite ,用于分别擦除,读取和写入),而无需编写代码。



然而,如果你想做一个务实的做法,这里是一个例子,确保阅读所有的意见,因为我把所有的细节在那里:

  #include< stdio.h> 
#include< fcntl.h>
#include< sys / ioctl.h>
#include< mtd / mtd-user.h>

int main()
{
mtd_info_t mtd_info; // MTD结构
erase_info_t ei; //擦除块结构
int i;

unsigned char data [20] = {0xDE,0xAD,0xBE,0xEF,//我们要写入的数据
0xDE,0xAD,0xBE,0xEF,
0xDE,0xAD, 0xBE,0xEF,
0xDE,0xAD,0xBE,0xEF,
0xDE,0xAD,0xBE,0xEF};
unsigned char read_buf [20] = {0x00}; //空数组读

int fd = open(/ dev / mtd0,O_RDWR); //打开mtd设备阅读和
//写。注意你想要mtd0不是mtdblock0
//你可能需要打开权限
//到dev(sudo chmod 777 / dev / mtd0)

ioctl(fd,MEMGETINFO ,& mtd_info); //获取设备信息

//转储它的理智检查,应该匹配/ proc / mtd
printf(MTD类型:%x\\\
MTD总大小:% x bytes\\\
MTD erase size:%x bytes\\\

mtd_info.type,mtd_info.size,mtd_info.erasesize);

ei.length = mtd_info.erasesize; //为(ei.start = 0; ei.start< mtd_info.size; ei.start + = ei.length)设置擦除块大小

{
ioctl(fd, MEMUNLOCK,& ei);
// printf(擦除块%#x\\\
,ei.start); //显示块擦除
//警告,这打印很多!
ioctl(fd,MEMERASE,& ei);
}

lseek(fd,0,SEEK_SET); //转到第一个块
read(fd,read_buf,sizeof(read_buf)); //读取20字节

//理性检查,如果擦除工作,应为全部0xFF
(i = 0; i <20; i ++)
printf(buf [ %d] = 0x%02x\\\
,i,(unsigned int)read_buf [i]);

lseek(fd,0,SEEK_SET); //返回到第一个块的开始
write(fd,data,sizeof(data)); //写我们的消息

lseek(fd,0,SEEK_SET); //返回第一个块的开始
read(fd,read_buf,sizeof(read_buf)); //读取数据

//理性检查,现在看到我们写的消息! (i = 0; i< 20; i ++)
printf(buf [%d] = 0x%02x\\\
,i,(unsigned int)read_buf [i]);


关闭(fd);
return 0;
}

这是一件很棒的事情,因为你可以使用标准的工具从其他设备,它可以轻松了解 write() open() read()

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



fd附加到不适合写入的对象;或使用O_DIRECT标志打开文件,并且buf中指定的地址,count中指定的值或当前文件偏移量不适当对齐。




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 only block device N
  • mtdN is the read/write char device N
  • mtdNro is the read only char device 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).

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)

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 <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.

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.

这篇关于在mtd块设备上写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆