SPI NAND驅(qū)動性能測試分析與優(yōu)化 (qq.com)
一.前言
https://mp.weixin.qq.com/s/hgogGTFzBDx83sFjDX8lVw一文中我們詳細介紹了SPI NAND,也實現(xiàn)了相關(guān)的驅(qū)動(如果需要驅(qū)動源碼可以和我聯(lián)系)。X1和x4模式的擦除,寫,讀等都測試OK了?,F(xiàn)在我們需要進行性能測試和優(yōu)化。https://mp.weixin.qq.com/s/uLraKF5kWMTHLpTggh2Q4Q一文中也介紹了ONFI。
二. 性能測試
既然是追求性能,所以我們后面就都基于X4模式進行了。
我們分別進行擦除,寫,讀全盤測試(128MB),然后使用定時器計算操作的時間。
性能測試代碼如下:
nand_set_qe(1,3); /* 使能QE模式 */
/* 擦除 */
pre = iot_timer_get_time();
for(uint32_t block=0; block < dev.blocks_per_lun*dev.luns; block++)
{
if(0 != (res = nand_block_erase(block*dev.pages_per_block)))
{
iot_printf("block %d erase err
",block,res);
}
}
cur = iot_timer_get_time();
if(cur < pre)
{
used = 0xFFFFFFFF - pre + cur;
}
else
{
used = cur-pre;
}
printf("erase time:%duS
",used);
/* 編程 */
memset(w_buffer,0xFF,sizeof(w_buffer));
w_buffer[dev.page_size] = 0xFF; /* 壞塊標志不能擦除 */
pre = iot_timer_get_time();
for(uint32_t block=0; block < dev.blocks_per_lun*dev.luns; block++)
{
for(uint32_t page=0; page< dev.pages_per_block; page++)
{
if(0 != (res = nand_write_page_x4(w_buffer, block*dev.pages_per_block+page, 0, dev.page_size+dev.page_spare_size)))
{
iot_printf("write page %d err %d
",block*dev.pages_per_block+page,res);
}
}
}
cur = iot_timer_get_time();
if(cur < pre)
{
used = 0xFFFFFFFF - pre + cur;
}
else
{
used = cur-pre;
}
printf("write time:%duS
",(cur-pre));
/* 讀 */
pre = iot_timer_get_time();
for(uint32_t block=0; block < dev.blocks_per_lun*dev.luns; block++)
{
for(uint32_t page=0; page< dev.pages_per_block; page++)
{
if(0 != (res = nand_read_page_x4(r_buffer, block*dev.pages_per_block+page, 0, dev.page_size+dev.page_spare_size)))
{
iot_printf("write page %d err %d
",block*dev.pages_per_block+page,res);
}
}
}
cur = iot_timer_get_time();
if(cur < pre)
{
used = 0xFFFFFFFF - pre + cur;
}
else
{
used = cur-pre;
}
printf("read time:%duS
",(cur-pre));
測試結(jié)果如下
對于寫
128MB花了17.40S
所以速度是7.36MB/S
三. 性能分析
我們使用邏輯分析儀抓取總線波形,用于進行性能分析
參考文章https://mp.weixin.qq.com/s/bCdgCNsGPbYjSzjv8VJyRA
我們以編程為例,擦除和讀類似。
編程PAGE的代碼如下,有三個步驟
即先寫數(shù)據(jù)到CACHE,然后寫使能,最后執(zhí)行CACHE到PAGE的數(shù)據(jù)編程。
int nand_write_page_x4(uint8_t* buffer, uint32_t pageaddr, uint16_t start, uint16_t len)
{
int res = 0;
res = nand_write_to_cache_x4(start, len, buffer);
if(res == 0)
{
res = nand_write_enable();
if(res == 0)
{
res = nand_write_cache_to_page(pageaddr,NAND_PROG_CHECK_RETRY);
if(res == 0)
{
return 0;
}
else
{
return -3;
}
}
else
{
return -2;
}
}
else
{
return -1;
}
}
查看邏輯分析儀抓取到的數(shù)據(jù)如下,對應(yīng)如下三個步驟
(1)總線上寫數(shù)據(jù)到NAND的Cache
(2)寫使能,并查詢寫使能OK
(3)執(zhí)行CACHE到PAGE編程,并查詢完成
從以上時間戳可以看到三個步驟分別對應(yīng)的時間是
第一次開始
19:48:31.513.198.648,PROGRAM LOAD x4(32),0000, ,FF,FF,FF,FF,FF,FF,FF,FF,........,
開始寫使能
19:48:31.513.259.134,WRITE ENABLE(06), , , , , , , , , , , ,
開始編程
19:48:31.513.273.890,PROGRAM EXECUTE(10),0040BE, , , , , , , , , , ,
編程完成
19:48:31.513.344.141,GET FEATURE(0F),C0, ,00, , , , , , , ,.,
下一次開始
19:48:31.513.435.474,PROGRAM LOAD x4(32),0000, ,FF,FF,FF,FF,FF,FF,FF,FF,........,
一個PAGE編程的周期
所以一個PAGE的編程時間是下一次開始和前一次開始的時間間隔
435.474-198.648=236.826uS
一次操作是寫2048+128字節(jié),對應(yīng)236.826uS,換算就是8.76MB/S比使用軟件定時器測試的7.36MB/S大一點,因為軟件額外一些邏輯處理需要一些時間,比如獲取定時器時間,塊之間的循環(huán)切換等。
波形如下
總線上數(shù)據(jù)傳輸時間
總線寫數(shù)據(jù)時間即第一次開始到開始寫使能,
259.134-198.648=60.486uS
如下如圖,后面6.96uS是兩次傳輸之間的間隔,即軟件完成一次傳輸?shù)较乱淮蝹鬏斨g的時間,也算在這個階段了。
寫使能時間
由于編程完之后,NAND會自動寫禁止,所以每次都需要重新寫使能。
執(zhí)行寫使能后要回讀是否設(shè)置成功(當(dāng)然回讀也可以省略但是出于可靠性考慮還是建議回讀,如果回讀未使能再重試)。
對應(yīng)如下
273.890-259.134=14.756uS
編程時間
344.141-273.890=70.251
軟件處理時間
從下可以看出編程完成到下一次開始,還有
91uS
這一部分是軟件處理時間,主要是軟件從NAND控制器的緩存區(qū)中將數(shù)據(jù)搬運到用戶存儲中去。
所以整理下各階段的時間消耗如下
總線傳輸 | 寫使能 | 編程 | 軟件處理 | 總 | |
---|---|---|---|---|---|
時間 | 60.49 | 14.76 | 70.25 | 91 | 236.5 |
占比 | 25.58% | 6.24% | 29.7% | 38.48% | 100% |
可以看出軟件處理實際占用時間比例最大,主要是從控制器的緩沖區(qū)中將數(shù)據(jù)搬運到用戶存儲的時間。
四. 性能優(yōu)化
針對以上性能分析過程,對各個階段考慮優(yōu)化
1. 總線傳輸
已經(jīng)使用了X4模式, 如果還要縮短該階段的時間,只能繼續(xù)提高頻率了,目前是80M的時鐘,手冊中參數(shù)是3.3V快讀可達133MHz。
針對讀還可以使用DTR雙邊沿模式但是這時最大時鐘頻率只有70MHz,雙邊沿也就是140M所以比133M也大不了多少。
2. 寫使能時間
由于每次編程之后,NAND自動寫禁止,所以該步驟不能少,可以減少回讀操作大約節(jié)省7uS,但是出于可靠性設(shè)計,建議還是回讀,如果回讀不成功則重試。
3. 編程時間
手冊中描述的時間是不使能ECC也最少要300uS,我們實測是70uS左右,所以手冊已經(jīng)寫的很保守了,這里也沒有優(yōu)化空間了。
4軟件處理時間
這一部分主要是軟件在用戶存儲和NAND控制器的緩存之間拷貝數(shù)據(jù)的時間。
最好是這一部分工作由控制器完成,而不是軟件去搬運,比如軟件指定一個地址,控制器自動從這個地址讀,或者寫入這個地址,而不是通過緩存再轉(zhuǎn)一遍,減少拷貝時間。
軟件時間還包括邏輯處理時間,比如一次傳輸?shù)较乱淮蝹鬏?,需要配?a href="http://m.hljzzgx.com/tags/寄存器/" target="_blank">寄存器,進行判斷,等邏輯處理。
由于軟件是分層設(shè)計包括HW層寄存器的封裝,HAL層傳輸?shù)?a target="_blank">接口,以設(shè)備驅(qū)動層,
對于HW層封裝可以使用宏或者內(nèi)聯(lián)函數(shù)替代函數(shù),減少函數(shù)調(diào)用時間,HW層和HAL不做參數(shù)檢查,因為接口調(diào)用頻繁等,在設(shè)備驅(qū)動層做參數(shù)檢查。
/**
* n int nfc_set_datalen(uint8_t id, uint16_t len)
* param[in] id port id
* param[in] len data len
*
etval 0 ok
*
etval < 0 param err
*
*/
NFC_INLINE int nfc_set_datalen(uint8_t id, uint16_t len)
{
uint32_t tmp;
(void)id;
tmp = NFC_READ_REG(CFG_NFC_ENA_ADDR);
tmp &= ~NFC_DATA_LEN_MASK;
tmp |= (len < < NFC_DATA_LEN_OFFSET);
NFC_WRITE_REG(CFG_NFC_ENA_ADDR,tmp);
return 0;
}
六.波形文件
這里分享一些實際抓取到的波形文件供參考
波形文件使用軟件Acute TravelLogic Analyzer打開查看。
鏈接:https://pan.baidu.com/s/103HHT4qcvFjGn1q-jJhAUg?pwd=iqlm
提取碼:iqlm
七. 總結(jié)
從以上分析可以看出最大的優(yōu)化空間是減少軟件從控制器緩沖區(qū)去搬運數(shù)據(jù)的時間,這一部分時間占最大頭,可IP設(shè)計優(yōu)化直接硬件搬運數(shù)據(jù)到用戶存儲。
審核編輯:湯梓紅
-
NAND
+關(guān)注
關(guān)注
16文章
1681瀏覽量
136118 -
存儲
+關(guān)注
關(guān)注
13文章
4296瀏覽量
85798 -
SPI
+關(guān)注
關(guān)注
17文章
1706瀏覽量
91501 -
性能測試
+關(guān)注
關(guān)注
0文章
209瀏覽量
21327
發(fā)布評論請先 登錄
相關(guān)推薦
評論