堆栈是一个内核对象,它实现传统的后进先出 (LIFO) 队列,允许线程和 ISR 添加和删除有限数量的整数数据值

概念

可以定义任意数量的堆栈(仅受可用 RAM 的限制)。每个堆栈都由其内存地址引用。
堆栈具有以下关键属性:

  • 已添加但尚未删除的整数数据值的队列。队列是使用stack_data_t数组实现的,并且必须是字对齐的。stack_data_t类型对应于芯片的字大小,即32位或64位,具体取决于CPU体系结构和编译模式。
  • 可在数组中排队的最大数据值数。

堆栈必须先初始化,然后才能使用。这会将其队列设置为空。
数据值可以通过线程或 ISR 添加到堆栈。如果等待线程存在,则该值直接提供给等待线程;否则,该值将添加到后进先出的队列中。

如果启用了CONFIG_NO_RUNTIME_CHECKS选项,则队列将不会检查队列是否已经满了。

线程可以从堆栈中删除数据值。如果堆栈的队列为空,则线程可以选择等待。任意数量的线程可以同时在空堆栈上等待。添加数据项时,会将其提供给等待时间最长的优先级最高的线程。

定义堆栈

堆栈是使用k_stack类型定义变量的。然后必须通过调用k_stack_init()k_stack_alloc_init()来初始化它。在后一种情况下,不提供缓冲区,而是从调用线程的资源池中分配缓冲区。

  1. #define MAX_ITEMS 10
  2. stack_data_t my_stack_array[MAX_ITEMS];
  3. struct k_stack my_stack;
  4. k_stack_init(&my_stack, my_stack_array, MAX_ITEMS);

也可以通过调用K_STACK_DEFINE在编译时定义和初始化堆栈

  1. K_STACK_DEFINE(my_stack, MAX_ITEMS);

堆栈入栈操作

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

  1. /* define array of data structures */
  2. struct my_buffer_type {
  3. int field1;
  4. ...
  5. };
  6. struct my_buffer_type my_buffers[MAX_ITEMS];
  7. /* save address of each data structure in a stack */
  8. for (int i = 0; i < MAX_ITEMS; i++) {
  9. k_stack_push(&my_stack, (stack_data_t)&my_buffers[i]);
  10. }

堆栈的出栈操作

通过调用k_stack_pop()从堆栈中获取数据项。

  1. struct my_buffer_type *new_buffer;
  2. k_stack_pop(&buffer_stack, (stack_data_t *)&new_buffer, K_FOREVER);
  3. new_buffer->field1 = ...

堆栈的Kconfig

Kconfig 描述
CONFIG_NO_RUNTIME_CHECKS 不进行运行时错误检查