目录
概述
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生产和消费数据