0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何在MCU上進(jìn)行實(shí)際的部署

恩智浦MCU加油站 ? 來(lái)源:恩智浦MCU加油站 ? 作者:恩智浦MCU加油站 ? 2022-08-11 09:02 ? 次閱讀

本篇將是系列文章的最后一篇,在MCU上進(jìn)行實(shí)際的部署。 小編就不再給大家復(fù)習(xí)歷史了,直接開(kāi)始正題。如果想溫習(xí)前兩部分內(nèi)容,請(qǐng)點(diǎn)擊此處和此處。

首先給大家介紹一下我們將要使用的離線Flash燒寫(xiě)工具,名為JFlashLite,他有一個(gè)兄弟叫JFLash,既然是Lite就是輕量版本的JFlash工具。

當(dāng)然,需要大家自行下載Segger Jlink工具包。是的,我們需要一條JLink。隨后找到JFlashLite工具,他長(zhǎng)這樣(請(qǐng)忽略這里的1176,我們還沒(méi)有配置):

ca0e5400-190c-11ed-ba43-dac502259ad0.png 比起下圖他的哥哥JFlash,是不是很清爽的界面: ca385c6e-190c-11ed-ba43-dac502259ad0.png

當(dāng)然,我們今天的主角是JFlashLite,稍后會(huì)介紹如何進(jìn)行配置并下載

程序編寫(xiě)

工具介紹完了,下面正式開(kāi)始編寫(xiě)配套程序,所使用的平臺(tái)是i.MX RT1060, 開(kāi)發(fā)板是IMXRT1060EVKB:

劃分FLASH以及sdram區(qū)域,sdram區(qū)域負(fù)責(zé)加載flash中內(nèi)容,加速內(nèi)存訪問(wèn):我們的開(kāi)發(fā)板上有一個(gè)8MB的Flash,內(nèi)存映射地址為0x60000000,首先保留1MB的頭部區(qū)域以存儲(chǔ)代碼,其作用后續(xù)會(huì)提到。那么我們就剩下7MB大小的空間,由于數(shù)據(jù)一般較大,劃分4MB作為數(shù)據(jù)存儲(chǔ)區(qū),剩下的3MB存儲(chǔ)模型。同樣的,在sdram區(qū)域,內(nèi)存映射地址為0x80000000也同樣開(kāi)辟這樣大的兩塊內(nèi)存區(qū),不過(guò),為了防止數(shù)據(jù)溢出,我們僅針對(duì)于sdram區(qū)域,在數(shù)據(jù)區(qū)和模型區(qū)中間插入256B的數(shù)據(jù)保護(hù)區(qū),并填充0xdeadbeef,最終的內(nèi)存布局如下:

Flash上內(nèi)存分配

ca5d443e-190c-11ed-ba43-dac502259ad0.png

Sdram內(nèi)存分配

ca6d6f08-190c-11ed-ba43-dac502259ad0.png

利用JflashLite工具進(jìn)行燒寫(xiě):

打開(kāi)JFlashLite工具點(diǎn)擊…選擇器件為1062xxxxA:

ca83319e-190c-11ed-ba43-dac502259ad0.png

選擇對(duì)應(yīng)的數(shù)據(jù)文件以及模型進(jìn)行燒寫(xiě),燒寫(xiě)地址要依據(jù)上述定義的分配,即模型數(shù)據(jù)燒寫(xiě)到0x60100000,圖像數(shù)據(jù)燒寫(xiě)到0x60400000:

caa07470-190c-11ed-ba43-dac502259ad0.png

cac7d83a-190c-11ed-ba43-dac502259ad0.png

選擇好之后,點(diǎn)擊Program Device即可進(jìn)行燒寫(xiě);針對(duì)于模型數(shù)據(jù),yao注意將以.tflite結(jié)尾的模型文件,重命名為.bin文件。

Scf文件編寫(xiě),主要考慮到,運(yùn)行時(shí),將flash中的數(shù)據(jù),拷貝到sdram中,以提高運(yùn)行速度,這里聲明兩個(gè)區(qū)域負(fù)責(zé)存儲(chǔ)ER_tflite_model以及ER_test_data

#define m_text_start                   0x80000400
#define FLASH_LOAD 7 * 1024 * 1024
LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_start {   ; load region size_region
  VECTOR_ROM m_interrupts_start FIXED m_interrupts_size { ; load address = execution address
    * (.isr_vector,+FIRST)
  }
  ER_m_text m_text_start FIXED m_text_size - FLASH_LOADER_SIZE { ; load address = execution address
    * (InRoot$$Sections)
    .ANY (+RO)
  }
 
#if (defined(FLASH_LOAD))
  ER_ test_data +0 EMPTY 4 * 1024 * 1024 {}
  ER_PLACEHOLDER1 +0 EMPTY FILL 0xdeadbeef 256{} 
  ER_tflite_model +0 EMPTY 3 * 1024 * 1024 {}  
  ER_PLACEHOLDER2+0 EMPTY FILL 0xdeadbeef 256{}
  ER_EMPTY m_text_start + m_text_size EMPTY 0{}
#endif

主代碼編寫(xiě),針對(duì)于邊界溢出檢測(cè)代碼,簡(jiǎn)單起見(jiàn),只檢測(cè)首地址處值,不同則表示溢出,死循環(huán)等待

typedef struct {
uint32_t n, h, w, c;
uint8_t data[0];
}data_t;
// use a split area, total 7MB:
// tflite model 3MB
// img_data 4MB
#define FLASH_BASE (0x60100000)
#define MB(x)  (x * 1024 * 1024)

#define lr_model_data_len (MB(3))
#define lr_model_data  FLASH_BASE
#define lr_model_data_end (lr_model_data + lr_model_data_len)

#define lr_img_data_len  (MB(4))
#define lr_img_data  (lr_model_data_end)  // 0x60200000
#define lr_img_data_end (lr_img_data + lr_img_data_len)

// declare the sdram memory
extern uint8_t Image$$ER_tflite_model$$ZI$$Base[];
#define model_data Image$$ER_tflite_model$$ZI$$Base

extern uint8_t Image$$ER_test_data$$ZI$$Base[];
#define img_data Image$$ER_test_data$$ZI$$Base

extern uint8_t Image$$ER_PLACEHOLDER1$$ZI$$Base[];
#define PLACEHOLDER1 Image$$ER_PLACEHOLDER1$$ZI$$Base

extern uint8_t Image$$ER_PLACEHOLDER2$$ZI$$Base[];
#define PLACEHOLDER2 Image$$ER_PLACEHOLDER2$$ZI$$Base

#define DO_MEMCPY(name) memcpy((void*)name, (void*)lr_##name, lr_##name##_len)
#define PRE_INIT() 
    do{ 
DO_MEMCPY(model_data);
DO_MEMCPY(img_data); 
            while(0xdeadbeef != *(uint32_t*) PLACEHOLDER1) ;   
                         while(0xdeadbeef != *(uint32_t*) PLACEHOLDER2) ;          
    }while(0);

定義好了一些宏之后,就是模型的初始化函數(shù):

void tflite_engine_init(){
#ifdef FLASH_LOAD
PRE_INIT()
#endif
SysTick_Config(CLOCK_GetCoreSysClkFreq() / 1000);
MODEL_AllocateTensor((void*)tensorArena, sizeof(tensorArena));
if (MODEL_Init(model_data) != kStatus_Success)
    {
        PRINTF("Failed initializing model");
        for (;;) {}
    }
}

測(cè)試數(shù)據(jù)如何獲取呢,利用我們剛才定義的data_t結(jié)構(gòu)體:

data_t *image = (data_t*)img_data;
image_data_ptr = image->data;

這樣,我們就拿到了存儲(chǔ)在flash并且已經(jīng)被搬運(yùn)到了sdram上的數(shù)據(jù)了,接下來(lái)就是編譯運(yùn)行了。

實(shí)際運(yùn)行與測(cè)試

測(cè)試時(shí)候,要注意首先確保我們的開(kāi)發(fā)板已經(jīng)是XIP啟動(dòng),即從Nor Flash啟動(dòng),并且保證在flash的頭部,燒寫(xiě)過(guò)一個(gè)完整的可執(zhí)行鏡像,比如hello_world程序,其中會(huì)包含F(xiàn)lash的一些配置信息,這一步小編就不再舉例,還請(qǐng)大家自行準(zhǔn)備。

這樣,我們的BootRom會(huì)據(jù)此幫我們配置好Flash,程序中就不用手動(dòng)調(diào)用Flash的初始化代碼了。

還要注意,代碼要全部運(yùn)行在SDRAM或是其他介質(zhì)上,因?yàn)槲覀円呀?jīng)將flash據(jù)為己有了。

下面是內(nèi)存鏡像的樣子,首先是model:

caed9214-190c-11ed-ba43-dac502259ad0.png

再者是測(cè)試數(shù)據(jù),前四個(gè)uint32類型的數(shù)據(jù)剛好是小編這里定義的數(shù)據(jù)長(zhǎng)度100張128*128*3的rgb彩色圖:

cb15207c-190c-11ed-ba43-dac502259ad0.png

連上板子和PC,并打開(kāi)串口控制臺(tái)即可查看輸出結(jié)果,小編所選用的模型是一個(gè)水果識(shí)別的模型,下面是最后一組數(shù)據(jù)的輸出結(jié)果,證明我們的程序運(yùn)行成功!

cb448380-190c-11ed-ba43-dac502259ad0.png

展望

當(dāng)然,小編給大家分享的這個(gè)方法,不僅可以應(yīng)用在神經(jīng)網(wǎng)絡(luò)AI推理上,可以當(dāng)作一個(gè)低配版的flashloader,以供大家靈活地更新靜態(tài)數(shù)據(jù)資源。

審核編輯:彭靜
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    17162

    瀏覽量

    351349
  • FlaSh
    +關(guān)注

    關(guān)注

    10

    文章

    1635

    瀏覽量

    148091
  • 工具包
    +關(guān)注

    關(guān)注

    0

    文章

    46

    瀏覽量

    9541

原文標(biāo)題:一種基于MCU的神經(jīng)網(wǎng)絡(luò)模型在線更新方案之MCU實(shí)戰(zhàn)篇

文章出處:【微信號(hào):NXP_SMART_HARDWARE,微信公眾號(hào):恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    何在資源有限的MCU上進(jìn)行圖形應(yīng)用設(shè)計(jì)

    第二種是以NXP官方推出的GUI Guider為代表的動(dòng)態(tài)加載策略,即只加載在系統(tǒng)啟動(dòng)后顯示的屏幕,后面如果需要顯示哪一個(gè)屏幕再動(dòng)態(tài)加載。
    發(fā)表于 10-20 09:56 ?2994次閱讀

    何在TINA上進(jìn)行電荷放大器的仿真?

    想請(qǐng)問(wèn)一下,電荷放大器選用什么樣的運(yùn)放比較好,儀器放大器可以嗎? 如何在TINA上進(jìn)行電荷放大器的仿真?
    發(fā)表于 08-19 06:18

    何在原電路上進(jìn)行添加保護(hù)電路和修改 ,請(qǐng)高手指導(dǎo)!

    剛畢業(yè)的小白 領(lǐng)導(dǎo)讓設(shè)計(jì)拾音器 有一篇TI家最簡(jiǎn)單的電路資料,經(jīng)過(guò)元器件和選型后,確定了麥克風(fēng)用PUI家POM-3535L,放大器用TI的OPA172,脈沖調(diào)制用TI的PCM1800E,但只能實(shí)現(xiàn)簡(jiǎn)單聲音信號(hào),如何在原電路上進(jìn)行添加保護(hù)電路和修改 ,請(qǐng)高手指導(dǎo)!
    發(fā)表于 11-07 16:53

    何在最大分辨率的LCD上進(jìn)行DouthGaSUS分布?

    何在最大分辨率的LCD上進(jìn)行DouthGaSUS分布?請(qǐng)你幫幫我好嗎?
    發(fā)表于 08-16 09:07

    何在STM32F103上進(jìn)行CAN通信的管腳重映射配置和使用

    CAN通信管腳重映射1. 摘要本篇筆記主要介紹,如何在STM32F103上進(jìn)行CAN通信的管腳重映射配置和使用2. 準(zhǔn)備工作1), IAR 8.3.12), 運(yùn)行...
    發(fā)表于 08-19 06:20

    何在stm32f103上進(jìn)行匯編語(yǔ)言測(cè)試呢

    何在stm32f103上進(jìn)行匯編語(yǔ)言測(cè)試呢?有哪些步驟?
    發(fā)表于 10-08 08:45

    何在MCU上進(jìn)行內(nèi)存管理與分配

    從事嵌入式產(chǎn)品開(kāi)發(fā)已有十余年了,從最開(kāi)始的8051一直用到現(xiàn)在流行的Cortex M系列的內(nèi)核的單片機(jī)。從最開(kāi)始用VC6.0開(kāi)發(fā)PC端的軟件到現(xiàn)在使用Mircrosoft WPF框架進(jìn)行PC端的軟件開(kāi)發(fā)。發(fā)現(xiàn)現(xiàn)在的新人對(duì)MCU的內(nèi)存管理與分配上真是一無(wú)所知。我就談?wù)勅?/div>
    發(fā)表于 11-04 06:06

    何在MDK5上進(jìn)行STM32設(shè)計(jì)跑馬燈程序并進(jìn)行編譯及仿真?

    何在MDK5上進(jìn)行STM32設(shè)計(jì)跑馬燈程序并進(jìn)行編譯及仿真?
    發(fā)表于 11-10 07:57

    何在esp8266 Node MCU的硬件上部署LVGL

    前言本文,介紹如何在esp8266 Node MCU的硬件上部署LVGL項(xiàng)目。使用的屏幕使用型號(hào)是ST7735 TFT 128x128屏幕。(一)arduinoIDE esp8266環(huán)境配置自行
    發(fā)表于 12-08 07:15

    何在MCU片內(nèi)進(jìn)行Flash讀寫(xiě)呢

    何在MCU片內(nèi)進(jìn)行Flash讀寫(xiě)呢?其過(guò)程是怎樣的?
    發(fā)表于 12-13 06:51

    何在Ubuntu系統(tǒng)上進(jìn)行中文支持

    1、Ubuntu系統(tǒng)上進(jìn)行中文支持Firefly 的Ubuntu系統(tǒng)默認(rèn)是英文版,現(xiàn)在剛剛發(fā)布了最新的雙系統(tǒng)固件Ubuntu上有了很多更新。這里就順便說(shuō)明下如何在Ubuntu系統(tǒng)上進(jìn)行中文支持:這是
    發(fā)表于 06-13 17:21

    在FPGA上進(jìn)行圖像處理及其示例

    借助FPGA技術(shù)和NI視覺(jué)開(kāi)發(fā)模塊,您可以對(duì)從相機(jī)采集的圖像進(jìn)行高速現(xiàn)場(chǎng)可編程門(mén)陣列(FPGA)處理。 FPGA處理尤其適用于要求圖像采集和處理之間具有低延遲的應(yīng)用。 本文概述了如何在FPGA上進(jìn)行圖像處理。
    發(fā)表于 11-17 06:00 ?1.9w次閱讀

    使用Devtron在Kubernetes多集群上進(jìn)行開(kāi)發(fā)

    在本文中,您將學(xué)習(xí)如何在多集群環(huán)境中使用 Devtron 在 K8S 上進(jìn)行應(yīng)用開(kāi)發(fā)。
    的頭像 發(fā)表于 11-17 09:50 ?848次閱讀

    2分鐘快速教你如何在華為模擬器ensp上進(jìn)行抓包?

    2分鐘快速教你如何在華為模擬器ensp上進(jìn)行抓包?
    的頭像 發(fā)表于 12-05 11:25 ?4577次閱讀

    何在AT32 MCU上使用FPU功能

    何在AT32 MCU上使用FPU功能
    的頭像 發(fā)表于 11-01 17:18 ?4074次閱讀
    如<b class='flag-5'>何在</b>AT32 <b class='flag-5'>MCU</b>上使用FPU功能