<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

RT-Thread記錄(十六、SFUD組件 Flash讀寫)

矜辰所致 ? 來源:矜辰所致 ? 作者:矜辰所致 ? 2022-07-06 10:35 ? 次閱讀
從本文開始,測試學習一些 RT-Thread 常用的組件與軟件包,先從剛學完的 SPI 設備開始。

目錄

前言
一、SFUD 組件簡介
1.1 基本簡介
1.2 SFUD 對 Flash 的管理
二、SFUD 組件操作函數
2.1 初始化相關函數
2.2 設備訪問函數
2.2.1 讀數據
2.2.2 擦除數據
2.2.3 寫數據
2.2.4 Flash 狀態相關
三、使用測試
3.1 使用步驟
3.1.1 使能 SPI 設備
3.1.2 使能 SFUD 組件包
3.1.3 掛載 SFUD 設備
3.1.4 應用程序查找設備
3.1.5 使用 API 進行讀寫操作
3.2 讀寫測試
結語

前言

RT-Thread 專欄更新至今,從開發環境到內核到設備模型,其實我們已經把使用 RT-Thread 的基礎知識都講過一遍,認真學習的朋友實際上都已經可以使用 RT-Thread 完成一些實際小項目了。

上一篇文章最后說過,RT-Thread 有一個很大的特點在于他的生態比一般的 RTOS 完善,我們在實際應用中,有許許多多現成的官方或者很多開發者提供的組件或者軟件包,我們可以直接導入工程進行使用。

針對我們 RT-Thread 實際應用,很多時候不僅是要知道基本的理論,還需要真正的知道怎么實際“用”起來。
基于本專欄的開發環境 RT-Thread Studio,本文開始我們來測試幾個典型的 組件與軟件包,來看看他們實際是如何使用的。

我們剛講完 SPI 設備,本文就從與 SPI 設備相關的組件 SFUD 組件說起。


說明,對于 RT-Thread記錄 中組件與軟件包部分的文章,我并不計劃講太多的原理,因為我們的最終目的還是在于應用,
在之間講解 RT-Thread 的基礎中,為了讓大家更明白 RT-Thread 內核以及 I/O 設備模型,也沒少分析源碼以及講解實現原理,核心的部分都是自己研究源碼。
對于 組件與軟件包 部分,我側重點會在與的記錄測試使用的過程,使得我們能夠快速上手。


??
本 RT-Thread 專欄記錄的開發環境:
RT-Thread記錄(一、RT-Thread 版本、RT-Thread Studio開發環境 及 配合CubeMX開發快速上手)
RT-Thread記錄(二、RT-Thread內核啟動流程 — 啟動文件和源碼分析)
??
RT-Thread 內核篇系列博文鏈接:
RT-Thread記錄(三、RT-Thread 線程操作函數及線程管理與FreeRTOS的比較)
RT-Thread記錄(四、RT-Thread 時鐘節拍和軟件定時器
RT-Thread記錄(五、RT-Thread 臨界區保護)
RT-Thread記錄(六、IPC機制之信號量、互斥量和事件集)
RT-Thread記錄(七、IPC機制之郵箱、消息隊列)
RT-Thread記錄(八、理解 RT-Thread 內存管理)
RT-Thread記錄(九、RT-Thread 中斷處理與階段小結)
??
STM32L051C8 上使用 RT-Thread 應用篇系列博文連接:
RT-Thread 應用篇 — 在STM32L051上使用 RT-Thread (一、無線溫濕度傳感器 之 新建項目)
RT-Thread 應用篇 — 在STM32L051上使用 RT-Thread (二、無線溫濕度傳感器 之 CubeMX配置)
RT-Thread 應用篇 — 在STM32L051上使用 RT-Thread (三、無線溫濕度傳感器 之 I2C通訊)
RT-Thread 應用篇 — 在STM32L051上使用 RT-Thread (四、無線溫濕度傳感器 之 串口通訊)
??
RT-Thread 設備篇系列博文鏈接:
RT-Thread記錄(十、全面認識 RT-Thread I/O 設備模型)
RT-Thread記錄(十一、I/O 設備模型之UART設備 — 源碼解析)
RT-Thread記錄(十二、I/O 設備模型之UART設備 — 使用測試)
RT-Thread記錄(十三、I/O 設備模型之PIN設備)
RT-Thread記錄(十四、I/O 設備模型之ADC設備)
RT-Thread記錄(十五、I/O 設備模型之SPI設備)
??
RT-Thread 組件與軟件包系列博文鏈接:
本文是第一篇

一、SFUD 組件簡介

SFUD (全稱 Serial Flash Universal Driver)是一款開源的串行 SPI Flash 通用驅動庫。

1.1 基本簡介

基礎介紹借用官方的說明:由于現有市面的串行 Flash 種類居多,各個 Flash 的規格及命令存在差異, SFUD 就是為了解決這些 Flash 的差異現狀而設計,讓我們的產品能夠支持不同品牌及規格的 Flash,提高了涉及到 Flash 功能的軟件的可重用性及可擴展性,同時也可以規避 Flash 缺貨或停產給產品所帶來的風險。

在 RT-Thread 中,SFUD 組件的 SPI 驅動是以 RTThread 的I/O設備模型框架為基礎設計的。

使用 SFUD 組件,我們不用自己寫 SPI Flash 的驅動。

支持 SPI/QSPI 接口、面向對象(同時支持多個 Flash 對象)、可靈活裁剪、擴展性強、支持 4 字節地址。

☆ SFUD是個開源的組件,對于該組件真正權威的參考說明就是該組件作者寫好的 README.md 文件(永遠要記住第一作者的文檔、官方的文檔永遠是最具有參考價值的)?!?/p>

使用 RT-Thread Studio 打開 README 文件如下圖,基本的介紹,函數使用,說明該有的都有,大家可自行查看:

pYYBAGLCtyuAYErkAAKnDPPIaB8359.png

pYYBAGLCtyyAUkaZAAGPyurEM98582.png

本文不深入分析源碼實現原理,對于理論只做簡單說明。

1.2 SFUD 對 Flash 的管理

我們以前講過,面向對象思想的程序設計,一般都會使用一個結構體 表示一個對象,我們講過的線程、IPC機制,I/O 設備都有他們的設備控制塊結構體。

對于 SPI Flash 設備,SFUD 也定義了一個結構體 sfud_flash 進行管理,其位置和內容如下圖:

poYBAGLCty2AWngeAADgvNZgXAE958.png

在這個對象控制塊中,有一個成員為 chip ,其類型為芯片信息的結構體sfud_flash_chip,如下圖:

pYYBAGLCty2AYYTKAACU4w5z0a8214.png

在 SFUD 組件中,已經定義好了一些支持的 chip 信息,如下圖:

poYBAGLCty6AdrjuAAEqmSG15e8676.png

基本上包括了市面上通用的 SPI Flash 芯片,如果使用的flash不支持 SFUD 組件,可根據 README 文件自行添加。

簡單的概述就到這里,下面我們來看看 SFUD 組件提供的操作函數。

二、SFUD 組件操作函數

根據 SFUD 組件的 README 文件,SFUD 組件提供的 API 框架圖如下:

pYYBAGLCty6AABv-AAEoVaT5V1I877.png

這里要說明一下,上面的 API 是 SFUD 對外標準的通用 API,就是不管用什么系統,或者使用裸機,移植好了 SFUD組件這些 API 都可以使用。

對于我們使用的 RT-Thread 來說,訪問設備的函數就是 SFUD 設備的標準 API。

但是對于初始化相關的部分來說,RT-Thread 官方給我們寫好了標準的驅動函數。

2.1 初始化相關函數

在工程文件中,與 RT-Thread 初始化驅動文件如下:

poYBAGLCty6ANEBjAAAxMkyhjMk597.png

其提供的函數有( 對于 RT-Thread 中初始化相關的函數使用,在本文后面使用測試小節會有詳細示例說明):

/**
 * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
使用 SFUD 探測 spi_dev_name 從設備,
并將 spi_dev_name 連接的 flash 初始化為塊設備,名稱 spi_flash_dev_name
 */
rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name);

/**
 * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration.
 * rt_sfud_flash_probe 調用了此函數
使得與底層 SFUD 本身的初始化文件關聯起來
 */
rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name,
        struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg);

/**
 * Delete SPI flash device
 	刪除SPI SFUD 設備
 */
rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev);

/**
 * Find sfud flash device by SPI device name
通過 SPI 設備名稱 找到一個 SFUD Flash 設備
 */
sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name);

/**
 * Find sfud flash device by flash device name
 通過 Flash 設備名稱 找到一個 SFUD Flash 設備
 */
sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name);

函數我們不做深入分析,大家需要學會使用,以前有很多文章都有源碼分析說明,源碼自己查看,比如其中比較關鍵的一個函數 rt_sfud_flash_probe_ex

pYYBAGLCty-AeK7AAADqwvJfwls736.png

2.2 設備訪問函數

設備訪問函數,SFUD 組件中 README 文件都有說明的,函數使用的注意事項可查看組件說明文件。

這里統一列一下方便以后復制使用:

2.2.1 讀數據

/*
參數	描述
flash	Flash 設備對象
addr	起始地址
size	從起始地址開始讀取數據的總大小
data	讀取到的數據
*/
sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data)

2.2.2 擦除數據

部分擦除:

/*
參數	描述
flash	Flash 設備對象
addr	起始地址
size	從起始地址開始擦除數據的總大小
*/
sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size)

全片擦除:

/*
參數	描述
flash	Flash 設備對象
*/
sfud_err sfud_chip_erase(const sfud_flash *flash)

2.2.3 寫數據

直接寫:

/*
參數	描述
flash	Flash 設備對象
addr	起始地址
size	從起始地址開始寫入數據的總大小
data	待寫入的數據
*/
sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)

先擦除再寫:

/*
參數	描述
flash	Flash 設備對象
addr	起始地址
size	從起始地址開始寫入數據的總大小
data	待寫入的數據
*/
sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)

2.2.4 Flash 狀態相關

讀取 Flash 狀態:

/*
參數	描述
flash	Flash 設備對象
status	當前狀態寄存器值
*/
sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status)

修改 Flash 狀態:

/*
參數	描述
flash	Flash 設備對象
is_volatile	是否為易閃失的,true: 易閃失的,及斷電后會丟失
status	當前狀態寄存器值
*/
sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status)

三、使用測試

本小節說明一下在 RT-Thread Studio 上使用 SFUD組件的步驟,然后我們使用示例進行基本的測試:

3.1 使用步驟

3.1.1 使能 SPI 設備

根據文章 RT-Thread記錄(十五、I/O 設備模型之SPI設備)接描述 中 《3.1 SPI 設備使用步驟》說明使能 SPI 總線。

注冊 SPI 總線設備,使用list_device可查看結果:

poYBAGLCty-AC-z2AAAhQsXu_8k506.png

3.1.2 使能 SFUD 組件包

和使能 SPI 設備一樣,在 RT-Thread Studio 打開 RT-Thread Settings 打開 SFUD 組件使能,如下圖:

pYYBAGLCty-AfmfZAADxVIRSdxg771.png

使能完成,我們在應用層就可直接調用上一小節將的 SFUD 操作函數了。

在工程中, SFUD 組件相關的程序位置如下:

poYBAGLCty-AYkJJAABct_Lykcc159.png

3.1.3 掛載 SFUD 設備

在使用 SFUD 設備前,需要掛載,類似把 SPI 設備掛載至 SPI 總線上一樣,使用如下操作:

pYYBAGLCtzCABg97AACLX9gDoiw659.png

忘了另外一塊開發板不是 W25Q128 而是 W25Q64,所以最終找到的是 W25Q64DW。

這里有個小問題說明一下, DBG 定義的問題,自己把mian里面的注釋稍微修改一下:

poYBAGLCtzCARZ0QAAC13QELDbo774.png

3.1.4 應用程序查找設備

使用 rt_sfud_flash_find 或者 rt_sfud_flash_find_by_dev_name 獲取設備句柄:

pYYBAGLCtzCAJnnOAAB3tt49smM978.png

3.1.5 使用 API 進行讀寫操作

完成上述步驟,就可以根據自己的應用,使用上面介紹的 SFUD 組件操作函數訪問設備部分進行 Flash 的操作了。

比如:

poYBAGLCtzGAaYtuAABNRmtwwCM535.png

3.2 讀寫測試

在上面的使用步驟說明中,其實我已經把自己做的簡單測試都說了一遍,這里我們上一下測試部分代碼,然后看一下測試效果:

#include 
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include 
#include "board.h"
#include "drv_spi.h"
#include "spi_flash_sfud.h"


#ifndef DBG_TAG
#define DBG_TAG "main"
#endif
#ifndef DBG_LVL
#define DBG_LVL DBG_LOG
#endif

#include 

//省略...

sfud_flash *test_sfud = NULL;

const uint8_t test_data[] = "this is a test data!";

//省略...

static void key1_thread_entry(void *par){

    while(1){
        if(key1_read == 0){
            rt_thread_mdelay(10); //去抖動
            if(key1_read == 0){
                rt_kprintf("write flash ..\r\n");
//                sfud_write(test_sfud, 13, sizeof(test_data), test_data);
                sfud_erase_write(test_sfud, 13, sizeof(test_data), test_data);
             }
             while(key1_read == 0){rt_thread_mdelay(10);//去抖動
            }
        }
        rt_thread_mdelay(1);
   }
}

static void key2_thread_entry(void *par){
    uint8_t read_data[30] = {0};
//    void *str = RT_NULL;
    while(1){
        if(key2_read == 0){
            rt_thread_mdelay(10); //去抖動
            if(key2_read == 0){
                rt_kprintf("read flash ..\r\n");
//                sfud_read(test_sfud, 0, sizeof(test_data), (uint8_t *)str);
                sfud_read(test_sfud, 13, sizeof(test_data), read_data);
                rt_kprintf("%s",read_data);
             }
             while(key2_read == 0){rt_thread_mdelay(10);//去抖動
            }
        }
        rt_thread_mdelay(1);
   }
}

//省略...

int main(void)
{

//省略...
    rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_4);  // CS 腳:PA4

    /* 使用 SFUD 探測 spi10 從設備,并將 spi10 連接的 flash 初始化為塊設備,名稱 W25Q128 */
    if (RT_NULL == rt_sfud_flash_probe("W25Q64", "spi10"))
    {
        return -RT_ERROR;
    };

//  test_sfud = rt_sfud_flash_find("spi10"); //
    test_sfud = rt_sfud_flash_find_by_dev_name("W25Q64");

    if(RT_NULL == test_sfud){
          LOG_E("find sfud_flash failed!...\n");
    }

   //省略...
    return RT_EOK;
}

測試結果:

pYYBAGLCtzKAZJiFAABKrs1Upi0960.png

測試細節說明:

在測試的時候我使用了一個按鍵線程寫 flash,最開始的時候使用的是 512 字節大小的線程棧:

poYBAGLCtzKAP3SqAABO8T2l2og905.png

使用函數sfud_erase_write 會比 sfud_write 函數占用更多的內存。

結語

本文我們從上一篇文章剛學完的 SPI 設備相關的 SFUD 組件開始,接觸到了 RT-Thread 的組件與軟件包,可以看出,對于常用的設備使用 RT-Thread 開發有多么的方便了。

??
但是前提當然是得對 RT-Thread 的面向對象的思想,I/O 設備模型等基礎有一定的認識,如果只是為了使用,看一篇文章即可,如果是為了理解掌握,還得多多了解 RT-Thread 基礎相關知識,比如博主的 RT-Thread 專欄 = =! O(∩_∩)O哈哈~

再次申明一下,對于組件與軟件包,因為都是大佬開發者們寫好的驅動,所以我偏向的重點是在于學會使用,說明文檔在每個組件或者軟件包都有作者詳細的說明,那才是最好的參考資料。
??

希望大家多多支持!本文就到這里,謝謝!

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FlaSh
    +關注

    關注

    10

    文章

    1566

    瀏覽量

    146845
  • RTOS
    +關注

    關注

    20

    文章

    780

    瀏覽量

    118886
  • 組件
    +關注

    關注

    1

    文章

    366

    瀏覽量

    17638
  • RT-Thread
    +關注

    關注

    31

    文章

    1183

    瀏覽量

    38996
  • SFUD
    +關注

    關注

    0

    文章

    4

    瀏覽量

    1037
收藏 人收藏

    評論

    相關推薦

    RT-Thread記錄(一、版本開發環境及配合CubeMX)

    RT-Thread 學習記錄的第一篇文章,RT-Thread記錄(一、RT-Thread 版本、RT-T
    的頭像 發表于 06-20 00:28 ?4588次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(一、版本開發環境及配合CubeMX)

    RT-Thread記錄(十七、 AT組件-使用at軟件包)

    AT 組件RT-Thread 一個比較典型的組件, 解決了不同網絡模塊AT命令之間的差異導致的重復開發的問題,大幅度簡化了MCU+無線模塊方案開發。
    的頭像 發表于 07-06 20:33 ?3870次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(十七、 AT<b class='flag-5'>組件</b>-使用at軟件包)

    RT-Thread記錄(二、RT-Thread內核啟動流程)

    在前面我們RT-Thread Studio工程基礎之上講一講RT-Thread內核啟動流程.
    的頭像 發表于 06-20 00:30 ?4523次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(二、<b class='flag-5'>RT-Thread</b>內核啟動流程)

    RT-Thread記錄(五、RT-Thread 臨界區保護)

    本文聊聊臨界區,以及RT-Thread對臨界區的處理
    的頭像 發表于 06-20 16:06 ?4441次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>記錄</b>(五、<b class='flag-5'>RT-Thread</b> 臨界區保護)

    如何更好地使用RT-Thread AT組件?

    本文介紹了RT-Thread AT組件的基本知識和AT客戶端的使用方法,幫助開發者更好地使用RT-Thread AT組件。
    發表于 03-30 07:23

    RT-Thread Studio配置QSPI和SFUD的相關資料推薦

    SFUD配置1前言本次采用的是正點原子STM32F767系列的板子,區別于F1及F4上的SPI,F7增加了QSPI。其上板載的W25Q256FV型號的Flash也是通過QSPI實現通信讀寫的。網上關于
    發表于 12-10 06:17

    如何使用RT-Thread AT組件

    文章目錄前言硬件準備軟件準備百問網STM32F103ESP8266 01SESP8266介紹ESP8266 01S 技術規格參數RT-Thread源碼RT-Thread AT組件前言本文介紹
    發表于 12-10 06:14

    關于RT-Thread OTA HTTP升級的日志記錄

    ] =============================================================[I/FAL] RT-Thread Flash Abstraction Layer
    發表于 05-18 15:45

    【原創精選】RT-Thread征文精選技術文章合集

    、I/O 設備模型之SPI設備)RT-Thread記錄十六、SFUD組件 Flash
    發表于 07-26 14:56

    基于RT-Thread的EasyFlash移植參考示例

    1、簡介本目錄下主要存放了基于 RT-Thread 的移植參考示例。主要基于以下兩種底層 Flash 驅動fal : Flash 抽象層SFUD : 萬能 SPI
    發表于 11-23 15:46

    RT-Thread 應用筆記 - RTC Alarm 組件的使用

    RT-Thread 應用筆記 - 不正確使用LOG也會引發hard faultRT-Thread 應用筆記 - RTC Alarm 組件的使用RT-Thread 應用筆記 - free
    發表于 01-25 18:18 ?10次下載
    <b class='flag-5'>RT-Thread</b> 應用筆記 - RTC Alarm <b class='flag-5'>組件</b>的使用

    RT-Thread學習筆記 RT-Thread的架構概述

    的種種優越之處。RT-Thread 是一款完全由國內團隊開發維護的嵌入式實時操作系統(RTOS),具有完全的自主知識產權。經過 16 個年頭的沉淀,伴隨著物聯網的興起,它正演變成一個功能強大、組件豐富
    的頭像 發表于 07-09 11:27 ?4079次閱讀
    <b class='flag-5'>RT-Thread</b>學習筆記 <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread文檔_RT-Thread 簡介

    RT-Thread文檔_RT-Thread 簡介
    發表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡介

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發表于 02-22 18:31 ?8次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    RT-Thread文檔_FAL 組件

    RT-Thread文檔_FAL 組件
    發表于 02-22 18:41 ?0次下載
    <b class='flag-5'>RT-Thread</b>文檔_FAL <b class='flag-5'>組件</b>
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>