通过mtd读写flash_linux 对MTD分区nand flash的烧写和读取
int mtd_read_yaffs2_skip_bad(libmtd_t desc,const struct mtd_dev_info *mtd, int fd, int eb, intoffs,const char *img_name)
{int tmp, ret, out_fd, len, written = 0;intread_eb_num,i,sekOffs;intdata_length,left_to_read,readsize;
off_t seek;structstat st;char *buf,*dataAddr,*oobAddr;if (offs < 0 || offs >= mtd->eb_size) {
errmsg("bad offset %d, mtd%d eraseblock size is %d",
offs, mtd->mtd_num, mtd->eb_size);
errno=EINVAL;return -1;
}if (offs % mtd->subpage_size) {//start address must align to page (2048)0x800
errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
offs, mtd->mtd_num, mtd->subpage_size);
errno=EINVAL;return -1;
}
len= 0x193b3c0;//for test's length, you can read nand flash frome straddr to endaddr!!!//also can read all mtdx device!
if (len % (mtd->subpage_size + mtd->oob_size)){
errmsg("size of \"%s\" is %d byte, which is not aligned to"
"mtd%d min. I/O size %d, it is not a yaffs2 file", img_name, len, mtd->mtd_num,
mtd->subpage_size + mtd->oob_size);
errno=EINVAL;gotoout_close;
}
data_length= len / (mtd->subpage_size + mtd->oob_size) * mtd->subpage_size;
tmp= (offs + data_length + mtd->eb_size - 1) / mtd->eb_size;if (eb + tmp > mtd->eb_cnt) {
errmsg("\"%s\" image size(except oob size) is %d bytes, mtd%d size is %d"
"eraseblocks, the image does not fit if we write it"
"starting from eraseblock %d, offset %d",
img_name, data_length, mtd->mtd_num, mtd->eb_cnt, eb, offs);
errno=EINVAL;gotoout_close;
}/*Seek to the beginning of the eraseblock*/seek= (off_t)eb * mtd->eb_size +offs;if (lseek(fd, seek, SEEK_SET) !=seek) {
sys_errmsg("cannot seek mtd%d to offset %llu",
mtd->mtd_num, (unsigned long long)seek);gotoout_close;
}
readsize= mtd->subpage_size + mtd->oob_size;
printf("read size with oob size is: %d \n",readsize);
buf=xmalloc(readsize);
dataAddr=buf;
oobAddr= buf + mtd->subpage_size;
left_to_read=len;
read_eb_num=eb;
out_fd= open(img_name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, S_IRUSR |S_IWUSR);if(out_fd < 0){
printf("open write file error: %d \n",errno);return -1;
}while (left_to_read > 0) {int rd = 0;
ret=mtd_is_bad(mtd,fd,read_eb_num);if(ret >0){
read_eb_num= read_eb_num + 1;if(read_eb_num >= mtd->eb_cnt)
{if(left_to_read < 1){gotoout_free;
}
}else{
printf("skip bad blocks at offset: %d \n",read_eb_num);continue;
}
}else if(ret <0){
printf("get bad blocks error: %d\n",errno);
}if(left_to_read < (mtd->eb_size +mtd->oob_size)){
readsize=left_to_read;
}else{
readsize= (mtd->eb_size / mtd->subpage_size) *( mtd->subpage_size + mtd->oob_size);
}for(i=0;i< mtd->eb_size/mtd->subpage_size;i++){
ret= mtd_read(mtd,fd,read_eb_num,i*mtd->subpage_size,dataAddr,mtd->subpage_size);if(ret < 0){
printf("read data error: %d \n",errno);gotoout_free;
}
sekOffs= read_eb_num * mtd->eb_size + i*mtd->subpage_size;
seek=(off_t)sekOffs;//printf("seek %#llx sek offs %#x \n",seek,sekOffs);
ret = mtd_read_oob(desc,mtd,fd,seek,mtd->oob_size,oobAddr);if(ret < 0){
printf("read oob error: %d \n",errno);gotoout_free;
}
ret= write(out_fd, dataAddr, mtd->subpage_size);if(ret == -1) {
sys_errmsg("cannot write data \"%s\"", img_name);gotoout_free;
}
ret= write(out_fd, oobAddr, mtd->oob_size);if(ret == -1) {
sys_errmsg("cannot write oob \"%s\"", img_name);gotoout_free;
}
}
read_eb_num= read_eb_num +1;
left_to_read-=readsize;
printf("left_to_read :%-7d write_eb_num: %-3d,readsize:%-6d\n",left_to_read,read_eb_num,readsize);
}free(buf);
close(out_fd);return 0;
out_free:free(buf);
out_close:
close(out_fd);return -1;
}
更多推荐
所有评论(0)