目錄
概述
1.? 軟硬件環境
1.1 軟件開發環境
1.2 硬件環境?
2 FIFO的函數接口
3 FIFO的應用函數實現
3.1 實現步驟
3.2? 代碼設計?
3.3 測試代碼實現
3.4 源代碼文件
4 編譯和測試
4.1 編譯代碼
?4.2 測試
概述
本文介紹了在nRF52832開發板上使用Zephyr操作系統進行FIFO(先進先出隊列)功能開發的軟硬件環境及實現步驟。軟件開發環境基于Nordic提供的nRF Connect SDK,集成了Zephyr平臺、編譯工具鏈和VS Code開發環境。硬件環境為nRF52832開發板,具備豐富的接口和調試功能。文章詳細描述了FIFO的API函數及其使用方法,包括初始化、數據放入和獲取等操作。通過生產者-消費者模型,展示了如何在Zephyr中實現FIFO功能,并提供了完整的代碼示例。最后,文章介紹了使用VS Code編譯和測試代碼的過程,確保功能正常運行。
1.? 軟硬件環境
1.1 軟件開發環境
nordic提供了基于zephyr平臺sdk, 其提供了大量的demo可供開發者參考和使用,同時nordi還提供一個集成的軟件庫工具,方便開發者安裝相應的SDK和編譯工具鏈。集成環境同時包含了其他的一些軟件,非常便于進行項目開發。
軟件工具 | 功能 | 版本信息 |
nRF Connect SDK? | nordic提供基于zephyr的代碼庫 | v2.9.0? |
nRF Connect SDK Toolchain | 代碼編譯工具 | v2.9.1 |
VS-CODE | 集成開發環境 | v1.99.3? |
nRF Connect for Desktop | nordic集成工具鏈 | v5.1.0 |
nRF Connect | 手機App |
手機App下載地址:
https://nav.nordicsemi.com/search?query=nRF%20Connect
1.2 硬件環境?
本案例是在nRF52832開發板(nRF52-DK)上實現的,該開發板nRF52832的主要特點如下:
1)板載j-link調試接口
2)引出所有 IO接口,用戶可根據實際應用,外載其他設備
3)支持4個LED
4)支持4路Key接口
5)板載UART調試接口,方便打印調試信息
2 FIFO的函數接口
zephyr OS提供了操作FIFO API,其具體函數如下:
函數 | 描述 |
---|---|
K_FIFO_DEFINE(name) | 定義并初始化FIFO |
k_fifo_init(fifo) | 運行時初始化FIFO |
k_fifo_put(fifo, data) | 向FIFO放入數據 |
k_fifo_get(fifo, timeout) | 從FIFO獲取數據 |
k_fifo_is_empty(fifo) | 檢查FIFO是否為空 |
?具有使用方法可以參考原文:
Zephyr OS 中的 FIFO 接口應用介紹-CSDN博客
3 FIFO的應用函數實現
3.1 實現步驟
在zephyr OS使用FIFO功能的步驟如下:
Step-1: 使用K_FIFO_DEFINE初始化一個FIFO
Step-2:? ?使用k_fifo_put接口發送數據
Step-3:? ?使用?k_fifo_get 函數接收數據,同時釋放內存?
注意點:
在在zephyr OS使用FIFO需要包括如下頭文件:#include <zephyr/kernel.h>
3.2? 代碼設計?
1)定義User的數據格式
struct user_data_t {void *fifo_reserved;int value;
};
2)創建和初始化FIFO
static K_FIFO_DEFINE(fifo_tx_data);
?3) 設計Producer用于生產數據
void producer_thread( void )
{printk(" \r\n");printk(" \r\n");printk("Produced: run thread \r\n ");for (int i = 0; i < 300; i++) {// 動態分配數據項struct user_data_t *tx = k_malloc(sizeof(*tx));tx->value = i;// 放入FIFOk_fifo_put(&fifo_tx_data, tx);printk("Produced: %d \r\n", i);k_sem_give(&nus_write_sem);k_sleep(K_MSEC(100));}
}
4)設計consumer用于使用數據
void consumer_thread( void )
{int err;printk(" \r\n");printk(" \r\n");err = k_sem_take(&nus_write_sem, K_MSEC(1000));if (err) {printk("Consumed: NUS send timeout \r\n");}struct user_data_t *item = k_fifo_get(&fifo_tx_data, K_NO_WAIT);if (item != NULL) {printk("Consumed: %d \r\n", item->value);k_free(item);} else {printk("Consumed: Timeout waiting for data \r\n");}
}
3.3 測試代碼實現
1)定義生產者線程?
/*** producer */int main_producer_handler(void){for (;;) {producer_thread();}}#define STACKSIZE 1024#define PRIORITY 7K_THREAD_DEFINE( main_producer_id, STACKSIZE, main_producer_handler, NULL, NULL,NULL, PRIORITY, 0, 0);
2) 定義消費者線程?
/*** consumer */int main_customers_handler(void){for (;;) {consumer_thread();}}#define STACKSIZE_CUSTOMER 1024#define PRIORITY_CUSTOMER 8K_THREAD_DEFINE( main_customers_id, STACKSIZE_CUSTOMER, main_customers_handler, NULL, NULL,NULL, PRIORITY_CUSTOMER, 0, 0);
3.4 源代碼文件
/* USER CODE BEGIN Header */
/********************************************************************************* File Name : test_fifo.h* Description : FIFO test demo ******************************************************************************* @attention** COPYRIGHT: Copyright (c) 2025 mingfei_tang* DATE: MAR 27th, 2025*******************************************************************************/
/* USER CODE END Header */
#include "test_fifo.h"
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>K_SEM_DEFINE(nus_write_sem, 0, 1);// 數據項結構
struct user_data_t {void *fifo_reserved;int value;
};static K_FIFO_DEFINE(fifo_tx_data);void producer_thread( void )
{printk(" \r\n");printk(" \r\n");printk("Produced: run thread \r\n ");for (int i = 0; i < 300; i++) {// 動態分配數據項struct user_data_t *tx = k_malloc(sizeof(*tx));tx->value = i;// 放入FIFOk_fifo_put(&fifo_tx_data, tx);printk("Produced: %d \r\n", i);k_sem_give(&nus_write_sem);k_sleep(K_MSEC(100));}
}void consumer_thread( void )
{int err;printk(" \r\n");printk(" \r\n");err = k_sem_take(&nus_write_sem, K_MSEC(1000));if (err) {printk("Consumed: NUS send timeout \r\n");}struct user_data_t *item = k_fifo_get(&fifo_tx_data, K_NO_WAIT);if (item != NULL) {printk("Consumed: %d \r\n", item->value);k_free(item);} else {printk("Consumed: Timeout waiting for data \r\n");}
}/*** producer */int main_producer_handler(void){for (;;) {producer_thread();}}#define STACKSIZE 1024#define PRIORITY 7K_THREAD_DEFINE( main_producer_id, STACKSIZE, main_producer_handler, NULL, NULL,NULL, PRIORITY, 0, 0);/*** consumer */int main_customers_handler(void){for (;;) {consumer_thread();}}#define STACKSIZE_CUSTOMER 1024#define PRIORITY_CUSTOMER 8K_THREAD_DEFINE( main_customers_id, STACKSIZE_CUSTOMER, main_customers_handler, NULL, NULL,NULL, PRIORITY_CUSTOMER, 0, 0); /** End of */
4 編譯和測試
4.1 編譯代碼
使用Vs-code創建工程,并且編寫代碼,其軟件架構如下:
?4.2 測試
編譯完成后,下載代碼至MCU,運行代碼,其運行結果如下:
1) 啟動過程
2) 使用FIFO生產和消費數據