目錄
前言:
簡(jiǎn)介:
對(duì)照:
測(cè)試:
使用:
照片存儲(chǔ):
基于卷積神經(jīng)網(wǎng)絡(luò)的數(shù)字識(shí)別:
————————————————
前言:
感謝深圳雷龍公司寄送的樣品,其中包括兩張2代的4gbit和32gbit的SD NAND FLASH芯片以及一份測(cè)試板卡。
簡(jiǎn)介:
根據(jù)官方文檔的描述,這款芯片采用LGA-8封裝,具有標(biāo)準(zhǔn)SDIO接口,并同時(shí)兼容SPI和SD接口。因此,可以直接移植標(biāo)準(zhǔn)驅(qū)動(dòng)代碼,支持使用SD NAND FLASH的SOC也可以用于TF卡啟動(dòng)。
以下是該芯片的主要參數(shù)(以CSNP32GCR01-BOW手冊(cè)為準(zhǔn)):
接口:符合標(biāo)準(zhǔn)SD Specification Version 2.0規(guī)范,包括1-I/O和4-I/O兩種模式。
默認(rèn)模式:在默認(rèn)模式下,時(shí)鐘頻率可變范圍為0-25 MHz,接口速度高達(dá)12.5 MB/sec(使用4條并行數(shù)據(jù)線路)。
高速模式:在高速模式下,時(shí)鐘頻率可變范圍為0-50 MHz,接口速度高達(dá)25 MB/sec(使用4條并行數(shù)據(jù)線路)。
目前,一些樹莓派和一些國產(chǎn)的微處理器經(jīng)常通過SD卡進(jìn)行系統(tǒng)的移植,但一些設(shè)計(jì)不合理的卡槽經(jīng)常不能保護(hù)SD卡,反而會(huì)損壞折斷。相比之下,SD NAND可以通過貼片直接嵌入嵌入式設(shè)備中,更適合嵌入式環(huán)境的開發(fā)。同時(shí),裸露的SD卡槽和松動(dòng)的SD卡時(shí)常會(huì)影響系統(tǒng)的穩(wěn)定性,因此一個(gè)可以反復(fù)擦拭的穩(wěn)定存儲(chǔ)芯片顯得十分重要。
通過將測(cè)試板和芯片進(jìn)行簡(jiǎn)單的焊接,我們可以像使用SD卡一樣對(duì)SD NAND FLASH進(jìn)行測(cè)試。
測(cè)試:
首先,我們使用CrystalDiskMark 8.0.4c對(duì)這款儲(chǔ)存器進(jìn)行了測(cè)試:
本次測(cè)試的是512MB的容量的產(chǎn)品,容量是真實(shí)的。我們可以看出,在包括順序讀取、順序?qū)懭?、隨機(jī)讀取和隨機(jī)寫入的四個(gè)測(cè)試方式下,SD NAND取得了不錯(cuò)的測(cè)試結(jié)果,接近官方數(shù)據(jù),可以成功進(jìn)行高速存儲(chǔ)。
使用:
此外,我們還利用k210與SD NAND進(jìn)行了照片的存儲(chǔ)和基于卷積神經(jīng)網(wǎng)絡(luò)的數(shù)字識(shí)別。
1.照片存儲(chǔ):
通過向SD NAND內(nèi)燒錄micropython代碼,實(shí)現(xiàn)了k210對(duì)照片的拍攝和存儲(chǔ)。存儲(chǔ)速度非常快。
import sensor, lcd
from Maix import GPIO
from fpioa_manager import fm
from board import board_info
import os, sys
import time
import image
#### image size ####
set_windowing = (224, 224)
#### sensor config ####
sensor.reset(freq=22000000, dual_buff=False)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # 320x240
try:
sensor.set_jb_quality(95) # for IDE display quality
except Exception:
pass # no IDE support
if set_windowing:
sensor.set_windowing(set_windowing)
# sensor.set_auto_gain(False)
# sensor.set_auto_whitebal(False, rgb_gain_db=(0x52,0x40,0x4d))
# sensor.set_saturation(0)
# sensor.set_brightness(4)
# sensor.set_contrast(0)
# sensor.set_hmirror(True) # image horizonal mirror
# sensor.set_vflip(True) # image vertical flip
# sensor.set_auto_whitebal(False)
sensor.skip_frames()
#### lcd config ####
lcd.init(type=1, freq=15000000)
lcd.rotation(2)
#### boot key ####
boot_pin = 16 # board_info.BOOT_KEY
fm.register(boot_pin, fm.fpioa.GPIOHS0)
key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)
######################################################
#### main ####
def capture_main(key):
def draw_string(img, x, y, text, color, scale, bg=None , full_w = False):
if bg:
if full_w:
full_w = img.width()
else:
full_w = len(text)*8*scale+4
img.draw_rectangle(x-2,y-2, full_w, 16*scale, fill=True, color=bg)
img = img.draw_string(x, y, text, color=color,scale=scale)
return img
def del_all_images():
os.chdir("/sd")
images_dir = "cap_images"
if images_dir in os.listdir():
os.chdir(images_dir)
types = os.listdir()
for t in types:
os.chdir(t)
files = os.listdir()
for f in files:
os.remove(f)
os.chdir("..")
os.rmdir(t)
os.chdir("..")
os.rmdir(images_dir)
# del_all_images()
os.chdir("/sd")
dirs = os.listdir()
images_dir = "cap_images"
last_dir = 0
for d in dirs:
if d.startswith(images_dir):
if len(d) > 11:
n = int(d[11:])
if n > last_dir:
last_dir = n
images_dir = "{}_{}".format(images_dir, last_dir+1)
print("save to ", images_dir)
if images_dir in os.listdir():
img = image.Image()
img = draw_string(img, 2, 200, "please del cap_images dir", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
sys.exit(1)
os.mkdir(images_dir)
last_cap_time = 0
last_btn_status = 1
save_dir = 0
save_count = 0
os.mkdir("{}/{}".format(images_dir, save_dir))
while(True):
img0 = sensor.snapshot()
if set_windowing:
img = image.Image()
img = img.draw_image(img0, (img.width() - set_windowing[0])//2, img.height() - set_windowing[1])
else:
img = img0.copy()
# img = img.resize(320, 240)
if key.value() == 0:
time.sleep_ms(30)
if key.value() == 0 and (last_btn_status == 1) and (time.ticks_ms() - last_cap_time > 500):
last_btn_status = 0
last_cap_time = time.ticks_ms()
else:
if time.ticks_ms() - last_cap_time > 5000:
img = draw_string(img, 2, 200, "release to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
img = draw_string(img, 2, 200, "release to capture", color=lcd.WHITE,scale=1, bg=lcd.RED)
if time.ticks_ms() - last_cap_time > 2000:
img = draw_string(img, 2, 160, "keep push to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
time.sleep_ms(30)
if key.value() == 1 and (last_btn_status == 0):
if time.ticks_ms() - last_cap_time > 5000:
img = draw_string(img, 2, 200, "change object type", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
time.sleep_ms(1000)
save_dir += 1
save_count = 0
dir_name = "{}/{}".format(images_dir, save_dir)
os.mkdir(dir_name)
else:
draw_string(img, 2, 200, "capture image {}".format(save_count), color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
f_name = "{}/{}/{}.jpg".format(images_dir, save_dir, save_count)
img0.save(f_name, quality=95)
save_count += 1
last_btn_status = 1
img = draw_string(img, 2, 0, "will save to {}/{}/{}.jpg".format(images_dir, save_dir, save_count), color=lcd.WHITE,scale=1, bg=lcd.RED, full_w=True)
lcd.display(img)
del img
del img0
def main():
try:
capture_main(key)
except Exception as e:
print("error:", e)
import uio
s = uio.StringIO()
sys.print_exception(e, s)
s = s.getvalue()
img = image.Image()
img.draw_string(0, 0, s)
lcd.display(img)
main()
2.基于卷積神經(jīng)網(wǎng)絡(luò)的數(shù)字識(shí)別:
我們向SD NAND內(nèi)燒錄了功能代碼、模型參數(shù)和模型結(jié)構(gòu)。SD NAND可以很好地存儲(chǔ)以上內(nèi)容,并通過k210正確加載模型。在使用過程中,SD NAND表現(xiàn)出了出色的穩(wěn)定性,沒有出現(xiàn)崩潰或彈出的情況。
# generated by maixhub, tested on maixpy3 v0.4.8
# copy files to TF card and plug into board and power on
import sensor, image, lcd, time
import KPU as kpu
import gc, sys
input_size = (224, 224)
labels = ['1', '2', '3', '4', '5', '6', '7', '8']
anchors = [0.45, 1.55, 1.46, 2.54, 1.22, 1.55, 1.58, 2.59, 1.47, 2.78]
def lcd_show_except(e):
import uio
err_str = uio.StringIO()
sys.print_exception(e, err_str)
err_str = err_str.getvalue()
img = image.Image(size=input_size)
img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))
lcd.display(img)
def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing(sensor_window)
sensor.set_vflip(1)
sensor.run(1)
lcd.init(type=1)
lcd.rotation(lcd_rotation)
lcd.clear(lcd.WHITE)
if not labels:
with open('labels.txt','r') as f:
exec(f.read())
if not labels:
print("no labels.txt")
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)
lcd.display(img)
return 1
try:
img = image.Image("startup.jpg")
lcd.display(img)
except Exception:
img = image.Image(size=(320, 240))
img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)
lcd.display(img)
try:
task = None
task = kpu.load(model_addr)
kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]
while(True):
img = sensor.snapshot()
t = time.ticks_ms()
objects = kpu.run_yolo2(task, img)
t = time.ticks_ms() - t
if objects:
for obj in objects:
pos = obj.rect()
img.draw_rectangle(pos)
img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))
img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))
lcd.display(img)
except Exception as e:
raise e
finally:
if not task is None:
kpu.deinit(task)
if __name__ == "__main__":
try:
# main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
main(anchors = anchors, labels=labels, model_addr="/sd/model-54796.kmodel")
except Exception as e:
sys.print_exception(e)
lcd_show_except(e)
finally:
gc.collect()
通過以上兩個(gè)實(shí)驗(yàn),SD NAND代替?zhèn)鹘y(tǒng)的SD/TF卡進(jìn)行數(shù)據(jù)存儲(chǔ)表現(xiàn)出了極大的優(yōu)勢(shì)和穩(wěn)定性。
審核編輯 黃宇
-
芯片
+關(guān)注
關(guān)注
455文章
50714瀏覽量
423131 -
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4296瀏覽量
85798 -
TF卡
+關(guān)注
關(guān)注
2文章
80瀏覽量
12145 -
卷積神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
4文章
367瀏覽量
11863 -
測(cè)評(píng)
+關(guān)注
關(guān)注
0文章
42瀏覽量
3098
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論