mx27ads bsp核心採用2.6.19
, 選擇檔案系統中的yaffs2
file systems ---> miscellaneous filesystems ---> <*> yaffs2 file system support
建立測試的yaffs image
mkdir userfs
echo test > userfs/test
mkyaffsimage userfs userfs.yaffs
寫入nand flash
nandwrite –a –o /dev/mtd/8 userfs.yaffs
掛載yaffs mtd
mount –t yaffs /dev/mtdblock/8 /mnt/rwfs
發現mount報錯, 只有乙個lost+found目錄, 其餘空空如也. 看樣子只好分析yaffs和nand flash**了.
mx27的使用的是8bit 512bytes+16bytes oob/page 的128m
nand flash, 分析yaffs與nand flash驅動**, 發現yaffs中呼叫yaffs_mtdif.c中的nandmtd_writechunktonand函式將它的chunk寫入flash,包含乙個512位元組的資料與yaffs_spare結構, 512位元組資料對應nand flash 一page, 所以不需要關心他的512位元組資料區; yaffs_spare結構,在yaffs_guts.h中定義的
typedef struct yaffs_spare;
正好是16位元組, 那就是使用這16位元組作為oob. 其中ecc1與ecc2是用來計算ecc的, 只有使用yaffs自身的ecc時才用到, 我們這裡使用mtd的硬體ecc, 可以忽略不計, 省下了yaffs用來存放檔案系統相關的資訊(yaffs_tags)8個bytes. 而mx27 nand flash 其oob定義如下:
static struct nand_ecclayout nand_hw_eccoob_8 = ,
.oobfree = , }
};oobfree有兩塊, , 總共10個位元組. 需要將這8個位元組儲存到oob區中, 就需要乙個轉換. 繼續分析yaffs_mtdif.c時,發現2.6.19核心在yaffs寫入oob時先使用translate_spare2oob將yaffs_spare轉換為乙個8bytes資料塊,然後通過mtd->write_oob使用mtd_oob_auto方式寫入oob資料;
…#if (linux_version_code > kernel_version(2,6,17))
__u8 spareasbytes[8]; /* oob */
//只有資料
if (data && !spare)
retval = mtd->write(mtd, addr, dev->ndatabytesperchunk,
&dummy, data);
else if (spare)
else
ops.len = data ? dev->ndatabytesperchunk : ops.ooblen;
ops.datbuf = (u8 *)data;
ops.ooboffs = 0;
ops.oobbuf = spareasbytes;
retval = mtd->write_oob(mtd, addr, &ops);
}#endif
…繼續深入分析, 發現mtd-write_oob實際上是呼叫的是nand_do_write_ops或nand_do_write_oob(都在driver/mtd/nand/nand_base.c), 在這兩個函式中在處理oob資料時都呼叫了同乙個函式nand_fill_oob:
static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
struct mtd_oob_ops *ops)
boffs = free->offset + woffs;
bytes = min_t(size_t, len,
(free->length - woffs));
woffs = 0;
} else
memcpy(chip->oob_poi + boffs, oob, bytes);
oob += bytes;
}return oob;
}default:
bug();
}return null;
}可以看出nand_fill_oob使用了2種方式來組織oob的處理方式: mtd_oob_place與mtd_oob_raw為一種, 直接將oob資料複製到要寫入oob的資料快取chip->oob_poi; mtd_oob_auto講oob資料複製到要寫入oob的資料快取oobfree位置上. 這就是mtd_oob_raw與mtd_oob_auto的最終解釋了.
再來看mkyaffsimage的**:
static int write_chunk(__u8 *data, __u32 objid, __u32 chunkid, __u32 nbytes)
yaffs_calctagsecc(&t);
yaffs_loadtagsintospare(&s,&t);
yaffs_calcecc(data,&s);
npages++;
return write(outfile,&s,sizeof(yaffs_spare)); }
他在512位元組之後是包含了16位元組yaffs_spare的,這個16位元組的yaffs_spare就是他的oob結構. 但是這個16位元組並沒有通過translate_spare2oob轉換, 而是直接寫入image中了.
再看通過nandwrite -a -o 寫入mtd時的**
if (!noecc)
} else
}可見nandwrite在寫入oob時是也是通過mtd_nandecc_autoplace(等同mtd_oob_auto)方式寫入的.
比較一下yaffs流程與mkyaffsimage流程:
yaffs流程是通過translate_spare2oob將8bytes的yaffs_tags轉為8bytes資料塊,然後通過write_oob將這8bytes寫入到oob的oobfree塊區; 讀出來的時候反過來translate_oob2spare, 就可以還原成yaffs_tags; 而mkyaffsimage建立yaffs image時卻是直接將yaffs_spare寫入檔案, 通過nandwrite -a -o 寫入mtd時, 直接使用這塊yaffs_spare作為oob資料寫入, 雖然使用方式也是mtd_oob_auto; 這就造成yaffs讀取chunk時無法讀取正確的yaffs_spare資料了;
由此可見只要在mkyaffsimage寫入yaffs_spare時, 只要將寫入的資料轉換為yaffs中寫入flash之前一致的資料即可.
以下是修改過的write_chunk
static int write_chunk(__u8 *data, __u32 objid, __u32 chunkid, __u32 nbytes)
yaffs_calctagsecc(&t);
yaffs_loadtagsintospare(&s,&t);
yaffs_calcecc(data,&s);
npages++;
#if 0
return write(outfile,&s,sizeof(yaffs_spare));
#else
memset(oobdata,0xff,16);
translate_spare2oob( &s, oobdata )
//因為採用的是硬體ecc, 這裡忽略了yaffs自身的ecc
return write(outfile, oobdata, 16);
#endif
}
基於linux 3 10的yaffs2移植
git clone git cd yaffs2 patch ker.sh c m linux3.10 mini24402.然後在linux的源 fs中多了乙個yaffs2的資料夾,到此yaffs2檔案系統就已經新增到linux3.10中了。在linux核心源 根目錄執行 make menuconfi...
基於ADS1 2下的ARM應用開發
1.巨集定義中volatile uint8 uint8等效於unsigned char,而volatile關鍵字主要作用是針對變數可能在編譯器控制之外被修改的情況,強制讓編譯器放棄對這個變數的優化。volatile 因為c編譯器的優化作用以及作業系統的cache等的影響,某些變數的值在記憶體中和暫存...
基於STM32的ADS1115使用例程
ads1232之stm32程式 stm32測試高精度adc篇 一 cherrymcu的部落格 csdn部落格 ads1232 基於ad7190的精密電子稱 4.8khz超低聲24位 adc,內建pga deming 0的部落格 csdn部落格 ad7190 cs5532 基於stm32的ads111...