Zephyr RTOS -- Stacks

Posted 搬砖-工人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zephyr RTOS -- Stacks相关的知识,希望对你有一定的参考价值。

文章目录

本笔记基于 Zephyr 版本 2.6.0-rc2

 

前言

本人正在学习 Zephyr,一个可移植性较强,可以兼容多种开发板及物联网设备的操作系统,如果你感兴趣,可以点此查看我的 学习笔记总述 进行了解!

 

摘要

前面讲了 Queue 是一个内核对象,类似于 FIFO,本文中的 堆栈(Stack) 也是一个内核对象,但它类似于 LIFO;Queue 允许线程和 ISR 添加和删除 任何大小 的数据项,但 堆栈(Stack) 允许线程和 ISR 添加和删除的整数数据值的数量 有限

 

1. Concepts

可以定义任意数量的堆栈 (仅受可用 RAM 限制)。每个堆栈由其内存地址引用。

堆栈具有以下关键属性:

  • 一个已添加但尚未取出整数数据值的 队列(queue)。队列是使用 stack_data_t 值数组实现的,并且必须在本机字边界上对齐。stack_data_t 类型对应于本机字大小,即 32 位或 64 位,具体取决于 CPU 架构和编译模式。
  • 可以在数组中排队的数据值 最大数量(maximum quantity)

堆栈必须先初始化,然后才能使用。初始化将堆栈的队列设置为空。

数据值可以由线程或 ISR 添加到堆栈中。如果存在,则该值直接提供给等待线程;否则,该值将添加到 LIFO 的队列中。内核不会检测向已经达到其最大排队值数量的堆栈中添加数据值的尝试。

Note:
将数据值添加到已经满的堆栈将导致数组溢出,并导致不可预测的行为。

数据值可以由线程从堆栈中移除。如果堆栈的队列为空,则线程可以选择等待它被给定。任意数量的线程可以同时等待一个空栈。添加数据项时,会将其分配给等待时间最长的最高优先级线程。

Note:
内核确实允许 ISR 从堆栈中删除项目,但是如果堆栈为空,ISR 不得尝试等待。

 

2. Implementation

2.1 Defining a Stack

使用 k_stack 的类型进行定义,通过调用 k_stack_init()k_stack_alloc_init() 来进行初始化。使用后者时,不提供缓冲区,而是从调用线程的资源池中分配缓冲区。

#define MAX_ITEMS 10

stack_data_t my_stack_array[MAX_ITEMS];
struct k_stack my_stack;

k_stack_init(&my_stack, my_stack_array, MAX_ITEMS);

上面的代码定义了一个空的堆栈,这个堆栈最多支持 10 个字节大小的数据。也可以使用下面的方式定义堆栈:

K_STACK_DEFINE(my_stack, MAX_ITEMS);

 

2.2 Pushing to a Stack

通过调用 k_stack_push() 将数据项添加到堆栈中。

在上面的示例之上,下面的代码展示了线程如何通过将其内存地址保存在堆栈中来创建数据结构池。

/* define array of data structures */
struct my_buffer_type 
    int field1;
    ...
    ;
struct my_buffer_type my_buffers[MAX_ITEMS];

/* save address of each data structure in a stack */
for (int i = 0; i < MAX_ITEMS; i++) 
    k_stack_push(&my_stack, (stack_data_t)&my_buffers[i]);

 

2.3 Popping from a Stack

从堆栈中获取数据项需要调用 k_stack_pop()

基于上面的示例,下面的代码展示了线程如何动态分配未使用的数据结构。当不再需要数据结构时,线程必须将其地址推回到堆栈上,以允许数据结构被重用。

struct my_buffer_type *new_buffer;

k_stack_pop(&buffer_stack, (stack_data_t *)&new_buffer, K_FOREVER);
new_buffer->field1 = ...

 

3. Suggested Uses

当已知存储项的最大数量时,使用堆栈以 “后进先出” 的方式存储和检索整数数据值。

 

4. Configuration Options

相关配置选项:

  • None

 

参考链接

https://docs.zephyrproject.org/latest/reference/kernel/data_passing/stacks.html#

以上是关于Zephyr RTOS -- Stacks的主要内容,如果未能解决你的问题,请参考以下文章

Zephyr RTOS -- Stacks

Zephyr RTOS -- 学习笔记总述

Zephyr RTOS -- 学习笔记总述

Zephyr RTOS -- Polling API

Zephyr RTOS -- Polling API

Zephyr RTOS -- Message Queues