從本文開始,測試學習一些 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
文件(永遠要記住第一作者的文檔、官方的文檔永遠是最具有參考價值的)。☆
使用 RT-Thread Studio 打開 README 文件如下圖,基本的介紹,函數使用,說明該有的都有,大家可自行查看:
本文不深入分析源碼實現原理,對于理論只做簡單說明。
1.2 SFUD 對 Flash 的管理
我們以前講過,面向對象思想的程序設計,一般都會使用一個結構體 表示一個對象,我們講過的線程、IPC機制,I/O 設備都有他們的設備控制塊結構體。
對于 SPI Flash 設備,SFUD 也定義了一個結構體 sfud_flash
進行管理,其位置和內容如下圖:
在這個對象控制塊中,有一個成員為 chip
,其類型為芯片信息的結構體sfud_flash_chip
,如下圖:
在 SFUD 組件中,已經定義好了一些支持的 chip 信息,如下圖:
基本上包括了市面上通用的 SPI Flash 芯片,如果使用的flash不支持 SFUD 組件,可根據 README 文件自行添加。
簡單的概述就到這里,下面我們來看看 SFUD 組件提供的操作函數。
二、SFUD 組件操作函數
根據 SFUD 組件的 README 文件,SFUD 組件提供的 API 框架圖如下:
這里要說明一下,上面的 API 是 SFUD 對外標準的通用 API,就是不管用什么系統,或者使用裸機,移植好了 SFUD組件這些 API 都可以使用。
對于我們使用的 RT-Thread 來說,訪問設備的函數就是 SFUD 設備的標準 API。
但是對于初始化相關的部分來說,RT-Thread 官方給我們寫好了標準的驅動函數。
2.1 初始化相關函數
在工程文件中,與 RT-Thread 初始化驅動文件如下:
其提供的函數有( 對于 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
:
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
可查看結果:
3.1.2 使能 SFUD 組件包
和使能 SPI 設備一樣,在 RT-Thread Studio 打開 RT-Thread Settings 打開 SFUD 組件使能,如下圖:
使能完成,我們在應用層就可直接調用上一小節將的 SFUD 操作函數了。
在工程中, SFUD 組件相關的程序位置如下:
3.1.3 掛載 SFUD 設備
在使用 SFUD 設備前,需要掛載,類似把 SPI 設備掛載至 SPI 總線上一樣,使用如下操作:
忘了另外一塊開發板不是 W25Q128 而是 W25Q64,所以最終找到的是 W25Q64DW。
這里有個小問題說明一下, DBG 定義的問題,自己把mian里面的注釋稍微修改一下:
3.1.4 應用程序查找設備
使用 rt_sfud_flash_find
或者 rt_sfud_flash_find_by_dev_name
獲取設備句柄:
3.1.5 使用 API 進行讀寫操作
完成上述步驟,就可以根據自己的應用,使用上面介紹的 SFUD 組件操作函數訪問設備部分進行 Flash 的操作了。
比如:
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;
}
測試結果:
測試細節說明:
在測試的時候我使用了一個按鍵線程寫 flash,最開始的時候使用的是 512 字節大小的線程棧:
使用函數sfud_erase_write
會比 sfud_write
函數占用更多的內存。
結語
本文我們從上一篇文章剛學完的 SPI 設備相關的 SFUD 組件開始,接觸到了 RT-Thread 的組件與軟件包,可以看出,對于常用的設備使用 RT-Thread 開發有多么的方便了。
??
但是前提當然是得對 RT-Thread 的面向對象的思想,I/O 設備模型等基礎有一定的認識,如果只是為了使用,看一篇文章即可,如果是為了理解掌握,還得多多了解 RT-Thread 基礎相關知識,比如博主的 RT-Thread 專欄 = =! O(∩_∩)O哈哈~
再次申明一下,對于組件與軟件包,因為都是大佬開發者們寫好的驅動,所以我偏向的重點是在于學會使用,說明文檔在每個組件或者軟件包都有作者詳細的說明,那才是最好的參考資料。
??
希望大家多多支持!本文就到這里,謝謝!
-
FlaSh
+關注
關注
10文章
1633瀏覽量
147939 -
RTOS
+關注
關注
22文章
811瀏覽量
119593 -
組件
+關注
關注
1文章
512瀏覽量
17813 -
RT-Thread
+關注
關注
31文章
1285瀏覽量
40081 -
SFUD
+關注
關注
0文章
5瀏覽量
1060
發布評論請先 登錄
相關推薦
評論