www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式大雜燴
[導(dǎo)讀]【推薦】 本次分享的是好友Mculover666創(chuàng)建的一個開源項目解讀專欄,通過這個專欄我們可以了解、學(xué)習(xí)一些很實用的開源項目的用法及設(shè)計思想,強烈推薦!文末有交流群,我偶爾也在群里窺屏學(xué)習(xí),群內(nèi)大佬云集,技術(shù)交流氛圍很好~ 嵌入式開源項目精選專欄 本專


【推薦】 本次分享的是好友Mculover666創(chuàng)建的一個開源項目解讀專欄,通過這個專欄我們可以了解、學(xué)習(xí)一些很實用的開源項目的用法及設(shè)計思想,強烈推薦!文末有交流群,我偶爾也在群里窺屏學(xué)習(xí),群內(nèi)大佬云集,技術(shù)交流氛圍很好~


嵌入式開源項目精選專欄

本專欄由Mculover666創(chuàng)建,主要內(nèi)容為尋找嵌入式領(lǐng)域內(nèi)的優(yōu)質(zhì)開源項目,一是幫助開發(fā)者使用開源項目實現(xiàn)更多的功能,二是通過這些開源項目,學(xué)習(xí)大佬的代碼及背后的實現(xiàn)思想,提升自己的代碼水平,和其它專欄相比,本專欄的優(yōu)勢在于:

不會單純的介紹分享項目,還會包含作者親自實踐的過程分享,甚至還會有對它背后的設(shè)計思想解讀。

目前本專欄包含的開源項目有:

如果您自己編寫或者發(fā)現(xiàn)的開源項目不錯,歡迎留言或者私信投稿到本專欄,分享獲得雙倍的快樂!

1. SFUD

本期給大家?guī)淼拈_源項目是 SFUD,一款串行 Flash 通用驅(qū)動庫,作者armink,目前收獲 407 個 star,遵循 MIT 開源許可協(xié)議。

SFUD全稱Serial Flash Universal Driver,是一款開源的串行 SPI Flash 通用驅(qū)動庫,由于現(xiàn)有市面的串行 Flash 種類居多,各個 Flash 的規(guī)格及命令存在差異, SFUD 就是為了解決這些 Flash 的差異現(xiàn)狀而設(shè)計。

SFUD的特點在于:

  • 支持 SPI/QSPI 接口
  • 面向?qū)ο笤O(shè)計(同時支持多個 Flash 對象)
  • 可靈活裁剪、擴展性強
  • 支持 4 字節(jié)地址

項目地址:https://github.com/armink/SFUD

2. 移植SFUD

2.1. 移植思路

在移植過程中主要參考兩個資料:項目的readme文檔和demo工程。

對于這些開源項目,其實移植起來也就兩步:

  • ① 添加源碼到裸機工程中;
  • ② 實現(xiàn)需要的接口即可;

2.2. 準(zhǔn)備裸機工程

本文中我使用的是小熊派IoT開發(fā)套件,主控芯片為STM32L431RCT6:板載Flash型號為W25Q64JV,大小64Mbit,與STM32的QSPI接口相連:

移植之前需要準(zhǔn)備一份裸機工程,我使用STM32CubeMX生成,需要初始化以下配置:

  • 配置SPI Flash通信接口(SPI或QSPI)
  • 配置一個串口用于打印信息
  • printf重定向

具體過程請參考:

使用CubeMX配置好SPI或QSPI通信即可,不用編寫W25Q64驅(qū)動。

2.3. 添加SFUD到工程中

① 復(fù)制源碼到工程中:② 在keil中添加 SFUD 組件的源碼文件:

  • src\sfud.c:SFUD核心功能源碼;
  • src\sfud_sfdp.c:讀取并分析SFDP功能源碼;
  • port\sfud_port.c:SFUD移植接口;

③ 將sfud/inc頭文件路徑添加到keil中:

2.4. 實現(xiàn)SFUD移植接口

SFUD的移植接口都已經(jīng)寫好了,在sfud_port.c文件中,只需要在函數(shù)體中添加代碼即可。

① 底層SPI/QSPI讀寫接口:

/**
 * SPI write data then read data
 */

static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size);

② 如果使用的是QSPI通信方式,還需要實現(xiàn)快速讀取數(shù)據(jù)的接口:

/**
 * QSPI fast read data
 */

static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size);

③ SFUD底層使用的SPI/QSPI接口和SPI設(shè)備對象初始化接口:

sfud_err sfud_spi_port_init(sfud_flash *flash);

關(guān)于SFUD底層所抽象出來的SPI設(shè)備對象,在接下來的設(shè)計思想解讀章節(jié)中會詳細(xì)講述。

本文中所使用的裸機工程是基于HAL庫的,在SFUD源碼的Demo中也有一份HAL庫的工程,因為基于HAL庫的移植接口實現(xiàn)都是一樣的,所以我直接將Demo中的sfud_port.c文件復(fù)制過來替換:復(fù)制過來之后,如果使用的不是STM32L4系列的芯片,則需要修改sfud_port.c中包含的頭文件:

2.5. 配置SFUD

SFUD的核心功能配置文件在sfud_cfg.h,修改說明如下:修改完了之后,還需要去修改剛剛復(fù)制替換的sfud_port.c文件,與剛剛填寫的配置信息相對應(yīng):至此,SFUD移植、配置完成,接下來就可以愉快的使用了!

3. 使用SFUD

使用時包含頭文件:

#include <sfud.h>

3.1. 初始化SFUD

初始化SFUD的API如下,該函數(shù)會初始化 Flash 設(shè)備表中的全部設(shè)備:

sfud_err sfud_init(void);

在QSPI模式下,SFUD 對于 QSPI 模式的支持僅限于快速讀命令,通過該函數(shù)可以配置 Flash 所使用的 QSPI 總線的實際支持的數(shù)據(jù)線最大寬度,例如:1 線(默認(rèn)值,即傳統(tǒng)的 SPI 模式)、2 線、4 線:

sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width);

所以,在main函數(shù)中編寫如下初始化函數(shù):

/* USER CODE BEGIN 2 */

/* SFUD初始化 */
if(sfud_init() != SFUD_SUCCESS)
{
 printf("SFUD init fail.\r\n");
}
/* 使能QSPI快讀 */
sfud_qspi_fast_read_enable(sfud_get_device(SFUD_W25Q64_DEVICE_INDEX), 1);

/* USER CODE END 2 */

編譯、下載之后,可以在串口終端中看到SFUD打印的日志:SFUD初始化Flash設(shè)備成功后進行接下來的讀寫測試。

3.2. Flash擦除/讀寫操作

① 讀取Flash數(shù)據(jù):

sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data);

② 擦除 Flash 數(shù)據(jù):

sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size);

③ 往Flash寫數(shù)據(jù):

sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data);

接下來使用作者編寫的demo測試。

首先在main.c開頭編寫代碼,開辟一塊緩沖區(qū)用于存放測試數(shù)據(jù):

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* SFUD讀寫Flash數(shù)據(jù)測試的緩沖區(qū) */
#define SFUD_DEMO_TEST_BUFFER_SIZE                     1024
static uint8_t sfud_demo_test_buf[SFUD_DEMO_TEST_BUFFER_SIZE];

/* SFUD讀寫Flash數(shù)據(jù)測試函數(shù) */
void sfud_demo(uint32_t addr, size_t size, uint8_t *data);

/* USER CODE END 0 */

然后在main.c最后添加測試函數(shù):

/* USER CODE BEGIN 4 */
/**
 * SFUD demo for the first flash device test.
 *
 * @param addr flash start address
 * @param size test flash size
 * @param size test flash data buffer
 */

void sfud_demo(uint32_t addr, size_t size, uint8_t *data)
{
    sfud_err result = SFUD_SUCCESS;
    extern sfud_flash *sfud_dev;
    const sfud_flash *flash = sfud_get_device(SFUD_W25Q64_DEVICE_INDEX);
    size_t i;
    /* prepare write data */
    for (i = 0; i < size; i++)
    {
        data[i] = i;
    }
    /* erase test */
    result = sfud_erase(flash, addr, size);
    if (result == SFUD_SUCCESS)
    {
        printf("Erase the %s flash data finish. Start from 0x%08X, size is %zu.\r\n", flash->name, addr, size);
    }
    else
    {
        printf("Erase the %s flash data failed.\r\n", flash->name);
        return;
    }
    /* write test */
    result = sfud_write(flash, addr, size, data);
    if (result == SFUD_SUCCESS)
    {
        printf("Write the %s flash data finish. Start from 0x%08X, size is %zu.\r\n", flash->name, addr, size);
    }
    else
    {
        printf("Write the %s flash data failed.\r\n", flash->name);
        return;
    }
    /* read test */
    result = sfud_read(flash, addr, size, data);
    if (result == SFUD_SUCCESS)
    {
        printf("Read the %s flash data success. Start from 0x%08X, size is %zu. The data is:\r\n", flash->name, addr, size);
        printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n");
        for (i = 0; i < size; i++)
        {
            if (i % 16 == 0)
            {
                printf("[%08X] ", addr + i);
            }
            printf("%02X ", data[i]);
            if (((i + 1) % 16 == 0) || i == size - 1)
            {
                printf("\r\n");
            }
        }
        printf("\r\n");
    }
    else
    {
        printf("Read the %s flash data failed.\r\n", flash->name);
    }
    /* data check */
    for (i = 0; i < size; i++)
    {
    
        if (data[i] != i % 256)
        {
            printf("Read and check write data has an error. Write the %s flash data failed.\r\n", flash->name);
            break;
        }
    }
    if (i == size)
    {
        printf("The %s flash test is success.\r\n", flash->name);
    }
}

/* USER CODE END 4 */

main函數(shù)中,SFUD初始化代碼之后,調(diào)用該函數(shù)進行Flash測試:

/* 測試Flash讀寫 */
sfud_demo(0sizeof(sfud_demo_test_buf), sfud_demo_test_buf);

編譯、下載,在串口終端中查看結(jié)果:

3.3. 移植前后內(nèi)存占用情況

SFUD中獲取Flash信息有兩種方式:

  • 使用SFDP 參數(shù)方式:開關(guān)宏 SFUD_USING_SFDP;
  • 使用庫自帶的 Flash 參數(shù)信息表:開關(guān)宏 SFUD_USING_FLASH_INFO_TABLE;

本文中兩種方式都開啟,所以移植之后較大,實際使用中可以視情況關(guān)閉這兩個功能。

SFDP功能關(guān)閉后,只會查詢該庫在 /sfud/inc/sfud_flash_def.h 中提供的 Flash 信息表,代碼量會降低,但是軟件適配性也隨之降低。

查表功能關(guān)閉后,該庫只驅(qū)動支持 SFDP 規(guī)范的 Flash,也會適當(dāng)?shù)慕档筒糠执a量。

一般情況下上述二者必須要選擇一個,在實際使用時視情況而定,但是也可以兩者都不開啟,直接指定好具體的某款 Flash 參數(shù)。

4. SFUD設(shè)計思想解讀

4.1. Flash設(shè)備對象

SFUD中最重要的就是Flash設(shè)備對象,一切操作都是對這個Flash設(shè)備對象進行的,每個Flash設(shè)備對象獨立,所以SFUD也支持系統(tǒng)中存在多個Flash設(shè)備對象。

Flash設(shè)備對象管理著Flash存儲器的所有信息,原型在sfud_def.h中,定義如下:

/**
 * serial flash device
 */

typedef struct {
    char *name;                                  /**< serial flash name */
    size_t index;                                /**< index of flash device information table  @see flash_table */
    sfud_flash_chip chip;                        /**< flash chip information */
    sfud_spi spi;                                /**< SPI device */
    bool init_ok;                                /**< initialize OK flag */
    bool addr_in_4_byte;                         /**< flash is in 4-Byte addressing */
    struct {
        void (*delay)(void);                     /**< every retry's delay */
        size_t times;                            /**< default times for error retry */
    } retry;
    void *user_data;                             /**< some user data */

#ifdef SFUD_USING_QSPI
    sfud_qspi_read_cmd_format read_cmd_format;   /**< fast read cmd format */
#endif

#ifdef SFUD_USING_SFDP
    sfud_sfdp sfdp;                              /**< serial flash discoverable parameters by JEDEC standard */
#endif

} sfud_flash, *sfud_flash_t;

其中Flash設(shè)備的通信接口信息由 sfud_spi 對象管理,包括SPI讀寫數(shù)據(jù)函數(shù),加鎖解鎖函數(shù)定義如下:

/**
 * SPI device
 */

typedef struct __sfud_spi {
    /* SPI device name */
    char *name;
    /* SPI bus write read data function */
    sfud_err (*wr)(const struct __sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
                   size_t read_size);
#ifdef SFUD_USING_QSPI
    /* QSPI fast read function */
    sfud_err (*qspi_read)(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
                          uint8_t *read_buf, size_t read_size);
#endif
    /* lock SPI bus */
    void (*lock)(const struct __sfud_spi *spi);
    /* unlock SPI bus */
    void (*unlock)(const struct __sfud_spi *spi);
    /* some user data */
    void *user_data;
} sfud_spi, *sfud_spi_t;

4.2. JESD216 SFDP標(biāo)準(zhǔn)

SFDP全稱 Serial Flash Discoverable Parameter,它是 JEDEC (固態(tài)技術(shù)協(xié)會)制定的串行 Flash 功能的參數(shù)表標(biāo)準(zhǔn)。

該標(biāo)準(zhǔn)規(guī)定了,每個 Flash 中會存在一個參數(shù)表,該表中會存放 Flash 容量、寫粒度、擦除命令、地址模式等 Flash 規(guī)格參數(shù)。目前,除了部分廠家舊款 Flash 型號會不支持該標(biāo)準(zhǔn),其他絕大多數(shù)新出廠的 Flash 均已支持 SFDP 標(biāo)準(zhǔn)。

所以 SFUD 在初始化時會優(yōu)先讀取 SFDP 表參數(shù),以達(dá)到SFUD在支持SFDP標(biāo)準(zhǔn)的Flash上全部適用的效果,更加通用。

那么SFDP標(biāo)準(zhǔn)的內(nèi)容是什么呢?SFDP標(biāo)準(zhǔn)強制規(guī)范必須要有:

  • SFDP標(biāo)題頭
  • 1st參數(shù)頭
  • JEDEC Flash基本參數(shù)表格

SFDP標(biāo)題頭一般為“S”“F”“U”“D”,如果能讀取出這四個字符,則認(rèn)為該款Flash支持SFDP標(biāo)準(zhǔn),比如在sfud_sfdp源碼中校驗代碼如下:

/* check SFDP header */
if (!(header[0] == 'S' &&
      header[1] == 'F' &&
      header[2] == 'D' &&
      header[3] == 'P')) {
    SFUD_DEBUG("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').");
    return false;
}

接下來是一些預(yù)留空內(nèi)容,屬于廠商可選內(nèi)容,F(xiàn)lash廠商可以在這些空白內(nèi)容中添加自己的廠商ID識別號、SFDP版本號、參數(shù)長度以及存放參數(shù)表格的地址指針,比如讀取W25Q64的結(jié)果中顯示:接下來的 JEDEC Flash基本參數(shù)表格里面規(guī)范和定義了該器件的一些最基本的讀取方式、指令內(nèi)容、扇區(qū)大小和芯片容量等信息:

4.3. 添加庫目前不支持的 Flash

如果你使用的Flash型號比較老或者不支持SFDP,SFUD庫當(dāng)然考慮到了這一點,所以提供了Flash設(shè)備參數(shù)表,在sfdu_flash_def.h文件的 SFUD_FLASH_CHIP_TABLE 就能看到當(dāng)前所有支持的 Flash:如果你使用的Flash型號既不支持SFDP,也不在此Flash設(shè)備參數(shù)表中,那么就需要手動添加到該設(shè)備參數(shù)表中才可以正常使用。

具體的添加方式請參考SFUD項目的README文檔中2.5節(jié),講述的非常詳細(xì)。

5. 項目工程源碼獲取和問題交流

目前我將SFUD源碼、我移植到小熊派STM32L431RCT6開發(fā)板的工程源碼上傳到了QQ群里(包含好幾份HAL庫,QQ相對速度快點),可以在QQ群里下載,有問題也可以在群里交流,當(dāng)然也歡迎大家分享出來自己移植的工程到QQ群里:放上QQ群二維碼:

接收更多精彩文章及資源推送,歡迎訂閱我的微信公眾號:『mculover666』。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉