您的位置:首页 > 理论基础 > 计算机网络

write and read mtd device(轉載自http://stackoverflow.com/questions/15336285/write-on-a-mtd-block-devic)

2014-12-22 10:12 477 查看
#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;
int nwrite = 0;

unsigned char data[1024*1024*2] = { 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[1024*1024*2] = {0x00};                // empty array for reading

for(i = 0; i<20; i++)
printf("initial buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]);

int fd = open("/dev/mtd1", 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("after erase buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]);

lseek(fd, 0, SEEK_SET);        // go back to first block's start
ioctl(fd, MEMUNLOCK, &ei);
if((nwrite = write(fd, data, sizeof(data))) != 1024*1024*2) { // write our message
printf("write data error, nwrite = %d\n", nwrite);
}
printf("write data, nwrite = %d\n", nwrite);

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<100; i++) {
printf("after write buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]);
}

close(fd);
return 0;
}


And another question: How are bad blocks handled in this case? You do a sanity check but how does the kernel deal with dead blocks which are un-writable anymore? – marmottus Mar 11 '13 at 14:21

@marmottus - for the changing sectors, that's pretty easy to get by, you just need to modify the lseek command and use the erase size from the mtd_info structure. Bad blocks (on raw flash) are your responsibility to deal with... most flash chips implement some sort of FTL (flash translation layer) which takes care of BBM and ware leveling for you, that's typically done in hardware, you need to consult the spec for your NAND flash to know for sure – Mike Mar 11 '13 at 14:26

 

轉載自http://stackoverflow.com/questions/15336285/write-on-a-mtd-block-device
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐