加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、Flash相關(guān)驅(qū)動概覽
    • 二、Flash驅(qū)動解釋及例程
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

一網(wǎng)打盡串行Flash驅(qū)動資源(上)

07/11 12:10
740
閱讀需 27 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是恩智浦i.MXRT官方SDK里關(guān)于串行Flash相關(guān)的驅(qū)動與例程資源

經(jīng)常有同事以及 i.MXRT 客戶咨詢痞子衡,咱們恩智浦官方 SDK 里有哪些串行 Flash 相關(guān)的示例,每一次痞子衡都是按照詢問需求將 SDK 里相應(yīng)資源路徑發(fā)給對方。看來那句俗話說得也不盡然對,酒香也怕巷子深,今天痞子衡就給大家全面梳理一下 SDK 里和串行 Flash 相關(guān)的全部資源。

    Note 1: 本文內(nèi)容主要以 SDK_2_15_100_EVKB-IMXRT1050 軟件包里的資源為例Note 2: 本文共分為上下兩篇,本篇是上篇,主要介紹 drives 和 components

一、Flash相關(guān)驅(qū)動概覽

首先直接開門見山,痞子衡把 SDK 里和 Flash 有關(guān)系的驅(qū)動全部羅列如下,分布在 device driver、components、middleware、azure-rtos 里。這四個目錄下的驅(qū)動關(guān)系簡單概括如下:

1. device driver 就是芯片底層外設(shè)的 HAL 級驅(qū)動,代碼里直接操作外設(shè)寄存器。
2. components 是基于 device driver 而設(shè)計(jì)的面向某個外圍器件/具體小功能的驅(qū)動,代碼里直接調(diào)用 devcie driver 里的 API。
3. middleware 則是面向某類具體功能的更大型的軟件庫,代碼里一般調(diào)用 components 里的 API,強(qiáng)調(diào)與芯片外設(shè)底層隔離,主打平臺無關(guān)的通用性。
4. azure-rtos 本身是硬件無關(guān)的 RTOS,但是其也同時包含了一些類似 middleware 功能實(shí)現(xiàn),這些 middlware 會調(diào)用 components 里的 API。

二、Flash驅(qū)動解釋及例程

2.1 drivers

2.1.1 flexspi

fsl_flexspi 驅(qū)動是芯片外設(shè) FlexSPI 的 HAL 級驅(qū)動,其是操作 FlexSPI 寄存器以實(shí)現(xiàn) 1-8bit SPI 類主設(shè)備方式數(shù)據(jù)收發(fā),其 API 本身和 Flash 芯片操作并沒有直接的聯(lián)系,這從如下主要 API 原型可以看出來:

void?FLEXSPI_Init(FLEXSPI_Type?*base,?const?flexspi_config_t?*config);
void?FLEXSPI_SetFlashConfig(FLEXSPI_Type?*base,?flexspi_device_config_t?*config,?flexspi_port_t?port);
void?FLEXSPI_UpdateLUT(FLEXSPI_Type?*base,?uint32_t?index,?const?uint32_t?*cmd,?uint32_t?count);
status_t?FLEXSPI_WriteBlocking(FLEXSPI_Type?*base,?uint8_t?*buffer,?size_t?size);
status_t?FLEXSPI_ReadBlocking(FLEXSPI_Type?*base,?uint8_t?*buffer,?size_t?size);
status_t?FLEXSPI_TransferBlocking(FLEXSPI_Type?*base,?flexspi_transfer_t?*xfer);
status_t?FLEXSPI_TransferNonBlocking(FLEXSPI_Type?*base,?flexspi_handle_t?*handle,?flexspi_transfer_t?*xfer);

如下配套例程調(diào)用 fsl_flexspi 驅(qū)動里 API 實(shí)現(xiàn)了官方 RT1050-EVKB 板卡上的 hyperflash (S26KS512S) 和四線 nor flash (IS25WP064A) 的讀寫功能驗(yàn)證。

例程路徑:SDK_2_15_100_EVKB-IMXRT1050boardsevkbimxrt1050driver_examplesflexspi
  - Hyper Flash 驅(qū)動:driver_examplesflexspihyper_flashpolling_transferflexspi_hyper_flash_ops.c
  - Nor Flash 驅(qū)動:driver_examplesflexspinorpolling_transferflexspi_nor_flash_ops.c

其中例程里的 flexspi_xxx_flash_ops.c 源文件設(shè)計(jì)其實(shí)有那么一點(diǎn) components 的味道,從 API 命名來看其實(shí)現(xiàn)了面向 Flash 的讀寫擦功能,但是 API 里的代碼實(shí)現(xiàn)比較簡潔,沒有過度設(shè)計(jì),對于不同廠商/類型的 Flash 支持,主要依賴用戶定義的 LUT 表里的命令序列。

void?flexspi_nor/hyper_flash_init(FLEXSPI_Type?*base);
status_t?flexspi_nor_flash_erase_sector(FLEXSPI_Type?*base,?uint32_t?address);
status_t?flexspi_nor_flash_page_program(FLEXSPI_Type?*base,?uint32_t?dstAddr,?const?uint32_t?*src);
status_t?flexspi_nor_flash_read(FLEXSPI_Type?*base,?uint32_t?dstAddr,?const?uint32_t?*src,?uint32_t?length);

2.1.2 lpspi

fsl_lpspi 驅(qū)動是芯片外設(shè) LPSPI 的 HAL 級驅(qū)動,其是操作 LPSPI 寄存器以實(shí)現(xiàn) 1bit(4bit) SPI 主/從設(shè)備方式數(shù)據(jù)收發(fā),API 本身和 Flash 芯片也沒有直接的聯(lián)系。

void?LPSPI_MasterInit(LPSPI_Type?*base,?const?lpspi_master_config_t?*masterConfig,?uint32_t?srcClock_Hz);
void?LPSPI_SlaveInit(LPSPI_Type?*base,?const?lpspi_slave_config_t?*slaveConfig);
status_t?LPSPI_MasterTransferBlocking(LPSPI_Type?*base,?lpspi_transfer_t?*transfer);
status_t?LPSPI_MasterTransferNonBlocking(LPSPI_Type?*base,?lpspi_master_handle_t?*handle,?lpspi_transfer_t?*transfer);
status_t?LPSPI_SlaveTransferNonBlocking(LPSPI_Type?*base,?lpspi_slave_handle_t?*handle,?lpspi_transfer_t?*transfer);

該驅(qū)動的配套例程是單純的 SPI 總線傳輸,并沒有針對 Flash,這里就不展開了,但是它會在 components/flash 里被用到,后文會提及。

2.1.3 romapi

fsl_romapi 驅(qū)動是芯片固化 BootROM 所導(dǎo)出的通用 Flash API,在 BootROM 里集成了基于 FlexSPI 外設(shè)驅(qū)動而寫成的通用 Flash 驅(qū)動,這個 Flash 驅(qū)動設(shè)計(jì)差不多是 components 級別,具體源代碼原則上不可見,但其實(shí)我們可以在 middleware/mcu_bootloader 里大概知道。

例程路徑:SDK_2_15_100_EVKB-IMXRT1050boardsevkbimxrt1050driver_examplesfsl_romapi

該驅(qū)動的 API 比較有意思,既有面向 Flash 的寫擦功能,也有偏 FlexSPI 外設(shè) HAL 級別的接口。前者相比 flexspi 驅(qū)動配套的例程里對于 Flash 的支持就強(qiáng)大多了,用戶完全可以僅靠 API 定義的簡化參數(shù)來支持不同廠商/類型的 Flash;而后者存在的意義是為了讓用戶能夠進(jìn)一步設(shè)計(jì)面向 Flash 的功能函數(shù)。

status_t?ROM_FLEXSPI_NorFlash_Init(uint32_t?instance,?flexspi_nor_config_t?*config);
status_t?ROM_FLEXSPI_NorFlash_ProgramPage(uint32_t?instance,?flexspi_nor_config_t?*config,?uint32_t?dstAddr,?const?uint32_t?*src);
status_t?ROM_FLEXSPI_NorFlash_EraseSector(uint32_t?instance,?flexspi_nor_config_t?*config,?uint32_t?address);
status_t?ROM_FLEXSPI_NorFlash_CommandXfer(uint32_t?instance,?flexspi_xfer_t?*xfer);
status_t?ROM_FLEXSPI_NorFlash_UpdateLut(uint32_t?instance,?uint32_t?seqIndex,?const?uint32_t?*lutBase,?uint32_t?seqNumber);

總結(jié)一下,使用 fsl_romapi 例程相比 fsl_flexspi 例程去操作 Flash,好處是省代碼空間且不需要考慮 Read-While-Write 限制(僅對驅(qū)動本身執(zhí)行而言,無需代碼重定向,但是全局中斷問題仍要考慮),壞處是源代碼是個黑盒子,出問題不容易定位。

2.2 components

2.2.1 mx25r_flash

mx25r_flash 組件其實(shí)是為 LPC54114 板卡上的旺宏寬電壓四線 NOR Flash MX25R 系列而設(shè)計(jì)的,其在 SDK_2_xxx_LPCXpresso54114boardslpcxpresso54114driver_examplesspipolling_flash 例程里有被調(diào)用,而在 i.MXRT 系列 SDK 里并沒有相關(guān)例程使用它(不要疑問為啥會出現(xiàn)在軟件包里,多就是好)。這個組件設(shè)計(jì)得挺有意思,其代碼實(shí)現(xiàn)完全與芯片具體外設(shè)隔離,外設(shè)接口傳輸函數(shù)是通過 callback 形式傳入的,充滿了代碼抽象(面向?qū)ο螅┑奈兜?,有興趣可以查看源碼。

mx25r_err_t?mx25r_init(struct?mx25r_instance?*instance,?transfer_cb_t?callback,?void?*callback_prv);
mx25r_err_t?mx25r_cmd_read(struct?mx25r_instance?*instance,?uint32_t?address,?uint8_t?*buffer,?uint32_t?size);
mx25r_err_t?mx25r_cmd_write(struct?mx25r_instance?*instance,?uint32_t?address_256_align,?uint8_t?*buffer,?uint32_t?size_256_max);
mx25r_err_t?mx25r_cmd_sector_erase(struct?mx25r_instance?*instance,?uint32_t?address);

2.2.2 internal_flash

internal_flash 組件從名字上看像是為片內(nèi) Flash 而設(shè)計(jì)的,但是 i.MXRT 系列并無片內(nèi) Flash(RT1024/1064 只是 SIP 了串行 NOR Flash,本質(zhì)上還是片外)。大家不要被這個名字騙了,這個組件最早確實(shí)是用于恩智浦 Kinetis/LPC 系列片內(nèi) Flash 的,但是在 i.MX RT 上因?yàn)榕涮?EVK 上有支持 XIP 的外置 NOR Flash,所以這個組件也沿用給這些外置 NOR Flash 了,因此其是基于 flexspi 驅(qū)動的組件。

在 componentsinternal_flashfsl_adapter_flash.h 文件里一共定義了 10 個 API 接口,其中如下 4 個是必須要實(shí)現(xiàn)的,其余 6 個可以不用實(shí)現(xiàn)(跟 Kinetis/LPC 片內(nèi) Flash 特性緊相關(guān))。因?yàn)?RT1050-EVKB 默認(rèn)連接的 hyperflash,所以該組件也僅為其做了相應(yīng)實(shí)現(xiàn) componentsinternal_flashhyper_flash。這個組件代碼實(shí)現(xiàn)跟 flexspi 驅(qū)動配套例程里對于 Flash 的支持差不多。

hal_flash_status_t?HAL_FlashInit(void);
hal_flash_status_t?HAL_FlashProgram(uint32_t?dest,?uint32_t?size,?uint8_t?*pData);
hal_flash_status_t?HAL_FlashEraseSector(uint32_t?dest,?uint32_t?size);
hal_flash_status_t?HAL_FlashRead(uint32_t?src,?uint32_t?size,?uint8_t?*pData);

internal_flash 組件設(shè)計(jì)的意義在于 SDK 其它例程中如果有 IAP 操作或者存儲運(yùn)行參數(shù)需求,均可以調(diào)用這個統(tǒng)一接口來實(shí)現(xiàn),當(dāng)然客戶應(yīng)用有相應(yīng)需求,也一樣可以使用。

2.2.3 flash

flash 組件里一共有三個:nor、nand、mflash,咱們一個個來說:

2.2.3.1 nor

先來介紹 nor 組件,從如下 API 命名來看,肯定是面向 NOR Flash 的讀寫擦功能,接口設(shè)計(jì)上對于底層外設(shè)采用了輕度抽象的方法,形參不涉及具體外設(shè),但是函數(shù)實(shí)現(xiàn)里不同外設(shè)需要不同的實(shí)現(xiàn),這也是為什么我們能看到 norflexspi 和 norlpspi 兩個文件夾里的源代碼。雖然底層外設(shè)不同,但是它們要操作的均是相同的串行 NOR Flash。

status_t?Nor_Flash_Init(nor_config_t?*config,?nor_handle_t?*handle);
status_t?Nor_Flash_Read(nor_handle_t?*handle,?uint32_t?address,?uint8_t?*buffer,?uint32_t?length);
status_t?Nor_Flash_Page_Program(nor_handle_t?*handle,?uint32_t?address,?uint8_t?*buffer);
status_t?Nor_Flash_Erase_Sector(nor_handle_t?*handle,?uint32_t?address);
status_t?Nor_Flash_Is_Busy(nor_handle_t?*handle,?bool?*isBusy);

norflexspi 里的代碼實(shí)現(xiàn)跟 romapi 驅(qū)動實(shí)現(xiàn)有點(diǎn)像,其會從 Flash 里讀取 SFDP 表進(jìn)行解析從而自動獲取所需操作命令,不依賴用戶填充 LUT 命令。

例程路徑:SDK_2_15_000_EVKB-IMXRT1050boardsevkbimxrt1050component_examplesflash_componentflexspi_nor

norlpspi 里的代碼實(shí)現(xiàn)則比較簡單,因?yàn)?LPSPI 外設(shè)本身主要支持 1bit SPI 傳輸,所以其也僅實(shí)現(xiàn)了一線方式對 Flash 進(jìn)行讀寫擦,這部分命令是通用的,也無需用戶填充 LUT。

2.2.3.2 nand

再來介紹 nand 組件,從如下 API 命名來看,肯定是面向 NAND Flash 的讀寫擦功能,接口設(shè)計(jì)上對于底層外設(shè)同樣采用了輕度抽象的方法,形參不涉及具體外設(shè),但是函數(shù)實(shí)現(xiàn)里不同外設(shè)需要不同的實(shí)現(xiàn),這也是為什么我們能看到 nandflexspi 和 norsemc 兩個文件夾里的源代碼。不過 flexspi 外設(shè)和 semc 外設(shè)所支持的 NAND 不是一個產(chǎn)品,前者是串行 NAND,后者是并行 NAND,完全是兩類不同的存儲器標(biāo)準(zhǔn)。

nandflexspi 里的代碼實(shí)現(xiàn)則比較簡潔,因?yàn)榇?NAND 發(fā)展不如串行 NOR 那樣豐富多樣,所以其使用了固定 LUT 里的預(yù)設(shè)命令序列,基本能夠支持華邦等主流四線串行 NAND 產(chǎn)品。

status_t?Nand_Flash_Init(nand_config_t?*config,?nand_handle_t?*handle);
status_t?Nand_Flash_Read_Page(nand_handle_t?*handle,?uint32_t?pageIndex,?uint8_t?*buffer,?uint32_t?length);
status_t?Nand_Flash_Page_Program(nand_handle_t?*handle,?uint32_t?pageIndex,?const?uint8_t?*src,?uint32_t?length);
status_t?Nand_Flash_Erase_Block(nand_handle_t?*handle,?uint32_t?blockIndex);

2.2.3.3 mflash

最后要重點(diǎn)介紹 mflash 組件,其分為 drv 層和 file 層兩種不同類型的 API,drv 層提供基于芯片外設(shè)的底層 Flash 操作(詳見 mflashmimxrt1052 文件夾下代碼),file 層則是基于 drv 層里的 API 而設(shè)計(jì)的輕量級靜態(tài)文件系統(tǒng),簡單理解就是將 Flash 虛擬成一個由具有固定最大長度的預(yù)定義命名文件集組成的存儲空間,我們可以將小數(shù)據(jù)以文件名索引的方式寫入 Flash,適用于需要存儲運(yùn)行參數(shù)或者設(shè)備配置數(shù)據(jù)的場合。

bool?mflash_is_initialized(void);
status_t?mflash_init(const?mflash_file_t?*dir_template,?bool?init_drv);
status_t?mflash_file_save(char?*path,?uint8_t?*data,?uint32_t?size);
status_t?mflash_file_mmap(char?*path,?uint8_t?**pdata,?uint32_t?*psize);

int32_t?mflash_drv_init(void);
int32_t?mflash_drv_sector_erase(uint32_t?sector_addr);
int32_t?mflash_drv_page_program(uint32_t?page_addr,?uint32_t?*data);
int32_t?mflash_drv_read(uint32_t?addr,?uint32_t?*buffer,?uint32_t?len);
void?*mflash_drv_phys2log(uint32_t?addr,?uint32_t?len);
uint32_t?mflash_drv_log2phys(void?*ptr,?uint32_t?len);

mflash 組件會在 middleware 以及 rtos 里被廣泛使用,這個痞子衡將會在下篇里再具體介紹。

至此,恩智浦i.MXRT官方SDK里關(guān)于串行Flash相關(guān)的驅(qū)動與例程資源痞子衡便介紹完畢了,掌聲在哪里~~~

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級 參考價格 更多信息
74HC595BQ,115 1 NXP Semiconductors 74HC(T)595 - 8-bit serial-in, serial or parallel-out shift register with output latches; 3-state QFN 16-Pin
$0.41 查看
CMWX1ZZABZ-078 1 Murata Manufacturing Co Ltd LORA MODULE

ECAD模型

下載ECAD模型
$16.04 查看
24LC256-I/ST 1 Microchip Technology Inc 32K X 8 I2C/2-WIRE SERIAL EEPROM, PDSO8, 4.40 MM, PLASTIC, TSSOP-8

ECAD模型

下載ECAD模型
$1.05 查看
恩智浦

恩智浦

恩智浦半導(dǎo)體創(chuàng)立于2006年,其前身為荷蘭飛利浦公司于1953年成立的半導(dǎo)體事業(yè)部,總部位于荷蘭埃因霍溫。恩智浦2010年在美國納斯達(dá)克上市。恩智浦2010年在美國納斯達(dá)克上市。恩智浦半導(dǎo)體致力于打造全球化解決方案,實(shí)現(xiàn)智慧生活,安全連結(jié)。

恩智浦半導(dǎo)體創(chuàng)立于2006年,其前身為荷蘭飛利浦公司于1953年成立的半導(dǎo)體事業(yè)部,總部位于荷蘭埃因霍溫。恩智浦2010年在美國納斯達(dá)克上市。恩智浦2010年在美國納斯達(dá)克上市。恩智浦半導(dǎo)體致力于打造全球化解決方案,實(shí)現(xiàn)智慧生活,安全連結(jié)。收起

查看更多

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會定期分享嵌入式相關(guān)文章