队列:实用程序服务和数据结构

Queues: utility services and data structures

队列实用程序服务

Nucleus RTOS有四个API调用,它们提供与队列相关的实用函数:重置队列、返回有关队列的信息、返回应用程序中的队列数量以及返回指向应用程序中所有队列的指针。前三个在Nucleus SE中实现。

重置队列

此API调用将队列恢复到其未使用的初始状态。队列中存储的所有消息都将丢失。队列上挂起的所有任务都将恢复,并收到返回代码NUSE_queue_WAS_RESET。

Nucleus RTOS API Call for Resetting a Queue

Service call prototype:

STATUS NU_Reset_Queue(NU_QUEUE *queue;

Parameters:

queue – pointer to user-define queue control block

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_QUEUE – the queue
pointer is not valid

Nucleus SE API Call for Resetting a Queue

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

STATUS NUSE_Queue_Reset(NUSE_QUEUE queue);

Parameters:

queue – the index (ID) of the queue to be reset

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_QUEUE – the queue index is not valid

Nucleus SE Implementation of Queue Reset

在参数检查之后,NUSE_Queue_Reset()API函数的最初部分代码非常简单。头和尾索引以及队列的消息计数都设置为零。

启用阻塞时,其他代码负责唤醒任何挂起的任务,因此:

while (NUSE_Queue_Blocking_Count[queue] != 0){ U8 index; /* check whether any tasks are blocked / / on this queue */ for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { NUSE_Task_Blocking_Return[index] = NUSE_QUEUE_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Queue_Blocking_Count[queue]–;}#if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK);#endif

队列上挂起的每个任务都标记为“就绪”,挂起返回代码NUSE_queue_WAS_RESET。此过程完成后,如果正在使用优先级调度程序,则会调用NUSE_Reschedule(),因为一个或多个优先级较高的任务可能已准备就绪,需要允许其运行。

队列信息

此服务调用获取有关队列的信息选择。Nucleus SE实现与Nucleus RTOS的不同之处在于,它返回的信息较少,因为不支持对象命名、可变消息大小和挂起顺序,并且可能无法启用任务挂起。

Nucleus RTOS API Call for Queue Information

Service call prototype:

STATUS NU_Queue_Information(NU_QUEUE *queue, CHAR *name,
VOID **start_address,UNSIGNED *queue_size, UNSIGNED
*available,
UNSIGNED *messages, OPTION *message_type,
UNSIGNED *message_size, OPTION *suspend_type,
UNSIGNED *tasks_waiting, NU_TASK **first_task);

Parameters:

queue – pointer to the user-supplied queue control block
name – pointer to an 8-character
destination area for the message-queue’s name
start_address – a pointer to a
pointer, which will receive the address of the start of the queue’s data area
queue_size – a pointer to a
variable for holding the total number of UNSIGNED data
elements in the queue
available – a pointer to a
variable for holding the number of available UNSIGNED data
elements in the queue
messages – a pointer to a
variable for holding the number of messages currently in the queue
message_type – pointer to a
variable for holding the type of messages supported by the queue; valid message
types are NU_FIXED_SIZE and NU_ VARIABLE_SIZE
message_size – pointer to a
variable for holding the number of UNSIGNED data
elements in each queue message; if the queue supports variable-length messages,
this number is the maximum message size
suspend_type – pointer to a
variable for holding the task suspend type. Valid task suspend types are NU_FIFO and NU_PRIORITY
tasks_waiting – a pointer to a
variable which will receive the number of tasks suspended on this queue
first_task – a pointer to a task
pointer; the pointer of the first suspended task is placed in this task pointer

Returns:

NU_SUCCESS – the call was completed successfully
NU_INVALID_QUEUE – the queue
pointer is not valid

Nucleus
SE API Call for Queue Information

This API call supports the key functionality of the Nucleus RTOS
API.

Service call prototype:

STATUS
NUSE_Queue_Information(NUSE_QUEUE queue,
ADDR *start_address, U8 *queue_size, U8 *available, U8
*messages, U8 *tasks_waiting, NUSE_TASK *first_task);

Parameters:

queue – the index of the queue about which information is being
requested
start_address – a pointer to a
variable of type ADDR ,
which will receive the address of the start of the queue’s data area
queue_size – a pointer to a
variable of type U8 ,
which will receive the total number of messages for which the queue has capacity
available – a pointer to a
variable of type U8 ,
which will receive the number of messages for which the queue has currently
remaining capacity
messages – a pointer to a
variable of type U8 ,
which will receive the number of messages currently in the queue
tasks_waiting – a pointer to a
variable which will receive the number of tasks suspended on this queue
(nothing returned if task suspend is disabled)
first_task – a pointer to a
variable of type NUSE_TASK which
will receive the index of the first suspended task (nothing returned if task
suspend is disabled)

Returns:

NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_QUEUE – the queue
index is not valid
NUSE_INVALID_POINTER – one or
more of the pointer parameters is invalid

Nucleus
SE Implementation of Queue Information

The implementation of this API call is quite straightforward:

*start_address = NUSE_Queue_Data[queue];*queue_size = NUSE_Queue_Size[queue];*available = NUSE_Queue_Size[queue] - NUSE_Queue_Items[queue];*messages = NUSE_Queue_Items[queue];#if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Queue_Blocking_Count[queue]; if (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif

函数返回队列状态。然后,如果启用了阻塞API调用,则返回等待的任务数和第一个任务的索引(否则这两个参数设置为0)。

获取队列数

此服务调用返回应用程序中配置的队列数。在Nucleus RTOS中,这将随时间而变化,返回的值将表示当前的队列数,而在Nucleus SE中,返回的值在构建时设置,不能更改。

Nucleus RTOS API Call for Queue Count

Service call prototype:

UNSIGNED NU_Established_Queues(VOID);

Parameters:

None

Returns:

The number of created queues in the system.

Nucleus SE API Call for Queue Count

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

U8 NUSE_Queue_Count(void);

Parameters:

None

Returns:

The number of configured queues in the application

队列计数的Nucleus SE实现

这个API调用的实现非常简单:返回#define symbol NUSE_QUEUE_NUMBER的值。

数据结构

队列使用五到六个数据结构—全部在RAM和ROM中—与其他Nucleus SE对象一样,这些数据结构是一系列表,根据配置的队列数量和选择的选项进行包含和标注。

我强烈建议应用程序代码不要直接访问这些数据结构,而是使用提供的API函数。这避免了与Nucleus SE未来版本的不兼容和不必要的副作用,并简化了将应用程序移植到Nucleus RTOS的过程。这里包含数据结构的详细信息,以便更容易地理解服务调用代码的工作方式和调试。

内核RAM数据

这些数据结构包括:

NUSE_Queue_Head[]–这是一个U8类型的数组,每个配置的队列有一个条目,它表示指向消息队列前面的指针。它用作NUSE_Queue_Data[]中地址的索引(见下文)。

NUSE_Queue_Tail[]–这是一个U8类型的数组,每个配置的队列有一个条目,它表示指向消息队列末尾的指针。它用作NUSE_Queue_Data[]中地址的索引(见下文)。

NUSE_Queue_Items[]–这是一个U8类型的数组,每个配置的队列有一个条目,表示队列中当前消息数的计数。这个数据可以说是多余的,因为它的值可以从head和tail索引中派生出来,但是存储计数可以简化代码。

NUSE_Queue_Blocking_Count[]–此类型的U8数组包含每个队列上阻塞的任务数。此数组仅在启用阻止API调用支持时存在。

当Nucleus SE启动时,这些数据结构都由NUSE_Init_Queue()初始化为零。这是合乎逻辑的,因为它将每个队列呈现为空(未使用)。未来的文章将全面描述Nucleus SE的启动过程。
以下是nuse_init.c文件中这些数据结构的定义:

RAM U8 NUSE_Queue_Head[NUSE_QUEUE_NUMBER];RAM U8 NUSE_Queue_Tail[NUSE_QUEUE_NUMBER];RAM U8 NUSE_Queue_Items[NUSE_QUEUE_NUMBER];#if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Queue_Blocking_Count[NUSE_QUEUE_NUMBER];#endif

用户RAM

用户负责为每个配置的队列提供一个RAM区域用于数据存储。这个RAM区域的大小必须容纳ADDR类型的数组,队列中的每条消息都有一个条目。

ROM数据

这些数据结构包括:

NUSE_Queue_Data[]–这是一个ADDR类型的数组,每个配置的队列有一个条目,它表示每个队列的数据区指针(在上面的用户RAM中讨论过)。

NUSE_Queue_Size[]–这是一个U8类型的数组,每个配置的队列有一个条目,表示每个队列可以容纳的消息数。

这些数据结构都在nuse_config.c中声明和初始化(当然是静态的),因此:

ROM ADDR NUSE_Queue_Data[NUSE_QUEUE_NUMBER] ={ / addresses of queue data areas ------ /};ROM U8 NUSE_Queue_Size[NUSE_QUEUE_NUMBER] ={ / queue sizes ------ */};

Queue Data Footprint

Like all kernel objects in Nucleus SE, the amount of data memory
required for queues is readily predictable.

The ROM data footprint (in bytes) for all the queues in an
application may be computed thus:

NUSE_QUEUE_NUMBER * (sizeof(ADDR) + 1)

The kernel RAM data footprint (in bytes) for all the queues in
an application, when blocking API calls is enabled, may be computed thus:

NUSE_QUEUE_NUMBER* 3

Otherwise it is:

NUSE_QUEUE_NUMBER* 4

The amount of user RAM (in bytes) required for the queue with
index queue is:

NUSE_Queue_Size[queue]* sizeof(ADDR)

Unimplemented API Calls

Four queue API calls found in Nucleus RTOS are not implemented
in Nucleus SE:

Create Queue

This API call creates a queue. It is not needed with Nucleus SE,
as queues are created statically.

Service call prototype:

STATUS NU_Create_Queue(NU_QUEUE *queue, char *name,
VOID *start_address, UNSIGNED queue_size, OPTION
message_type, UNSIGNED message_size, OPTION suspend_type);

Parameters:

queue – pointer to a user-supplied queue control block; this
will be used as a “handle” for the queue in other API calls
name – pointers to a 7-character, null-terminated name for the queue
start_address – starting address for the queue
message_type – type of message
supported by the queue; may be NU_FIXED_SIZE or NU_VARIABLE_SIZE
message_size – if the queue supports fixed size messages, this parameter specifies the exact size of each message; otherwise, if the queue supports variable sized messages, this is the maximum message size suspend_type – specifies how
tasks suspend on the queue. Valid options for this parameter are NU_FIFOand NU_PRIORITY , which represent
First-In-First-Out (FIFO) and priority-order task suspension, respectively

Returns:

NU_SUCCESS – indicates successful completion of the service
NU_INVALID_QUEUE – indicates the
queue control block pointer is NULL or already in use
NU_INVALID_MEMORY – indicates the
memory area specified by the start_address is invalid
NU_INVALID_MESSAGE – indicates
that the message_type parameter is invalid
NU_INVALID_SIZE – indicates that
either the message size is greater than the queue size, or that the queue size or message size is zero
NU_INVALID_SUSPEND – indicates
that the suspend_type parameter is invalid

Delete Queue

This API call deletes a previously created queue. It is not needed with Nucleus SE, as queues are created statically and cannot be deleted.

Service call prototype:

STATUS NU_Delete_Queue(NU_QUEUE *queue);

Parameters:

queue – pointer to queue control block

Returns:

NU_SUCCESS – indicates successful completion of the service
NU_INVALID_QUEUE – indicates the
queue pointer is invalid

Queue Pointers

This API call builds a sequential list of pointers to all queues
in the system. It is not needed with Nucleus SE, as queues are identified by a simple index, not a pointer, and it would be redundant.

Service call prototype:

UNSIGNED NU_Queue_Pointers(NU_QUEUE **pointer_list,
UNSIGNED maximum_pointers);

Parameters:

pointer_list – pointer to an array of NU_QUEUE pointers;
this array will be filled with pointers to established queues in the system
maximum_pointers – the maximum
number of pointers to place in the array

Returns:

The number of NU_QUEUE pointers placed into the array

Broadcast to Queue

This API call broadcasts a message to all tasks waiting for a message from the specified queue. It is not implemented with Nucleus SE, as it would have added excessive complexity.

Service call prototype:

STATUS NU_Broadcast_To_Queue(NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend);

Parameters:

queue – pointer to queue control block
message – pointer to the broadcast message
size – the number of UNSIGNED data elements in the message. If the queue supports variable-length messages, this parameter must be
equal to or less than the message size supported by the queue. If the queue supports fixed-size messages, this parameter must be exactly the same as the message size supported by the queue
suspend – specifies whether or not to suspend the calling task if the queue is already full; valid options for this parameter are NU_NO_SUSPEND , NU_SUSPEND or a timeout value.

Returns:

NU_SUCCESS – indicates successful completion of the service
NU_INVALID_QUEUE – indicates the queue pointer is invalid
NU_INVALID_POINTER – indicates
that the message pointer is NULL
NU_INVALID_SIZE – Indicates that the message size specified is not compatible with the size specified when the queue was created
NU_INVALID_SUSPEND – indicates
that suspend attempted from a non-task thread
NU_QUEUE_FULL – indicates that
there is insufficient space in the queue for the message
NU_TIMEOUT – indicates the queue
is still full after the timeout has expired
NU_QUEUE_DELETED – queue was
deleted while task was suspended
NU_QUEUE_RESET – queue was reset
while the task was suspended

与Nucleus RTOS的兼容性

对于Nucleus SE的各个方面,我的目标是尽可能保持与Nucleus RTOS的高级别应用程序代码兼容性。队列也不例外,从用户的角度来看,它们的实现方式与Nucleus RTOS中的方式大致相同。有一些不兼容的地方,我认为这样的不兼容是可以接受的,因为生成的代码更容易理解,或者更有可能提高内存效率。否则,Nucleus RTOS API调用几乎可以直接映射到Nucleus SE调用上。未来的一篇文章将包括关于为Nucleus RTOS用户使用Nucleus SE的更多信息。

对象标识符

在Nucleus RTOS中,所有对象都由具有特定数据类型的数据结构(控制块)来描述。指向此控制块的指针用作队列的标识符。在Nucleus SE中,我决定需要一种不同的方法来提高内存效率,所有的内核对象都由RAM和/或ROM中的许多表来描述,这些表的大小由配置的每个对象类型的数量决定。特定对象的标识符只是这些表的索引。因此,我将NUSE_QUEUE定义为等同于U8;此类型的变量(而不是指针)将用作队列标识符。这是一个小的不兼容性,如果代码被移植到Nucleus RTOS或从Nucleus RTOS移植过来,就很容易处理这个问题。对象标识符通常只是存储和传递,而不是以任何方式操作。

Nucleus RTOS还支持队列命名。这些名称仅用于基于目标的调试工具。为了节省内存,我把它们从Nucleus SE中省略了。

消息大小和可变性

在Nucleus RTOS中,队列可以配置为处理由任意数量的无符号数据元素组成的消息。在Nucleus SE中,队列被简化,只支持单个ADDR消息。管道在Nucleus SE中更为灵活,可能为某些应用程序提供了替代队列的有用方法;本系列的下两篇文章将介绍管道。

Nucleus RTOS还支持具有可变大小消息的队列,其中仅在创建时指定最大大小。Nucleus SE不支持可变大小的消息。

队列大小

Nucleus SE中队列中的消息数被限制为256条,因为所有索引变量和常量都是U8类型。Nucleus RTOS不受此限制。

未实现的API调用

Nucleus RTOS支持10个服务调用来处理队列。其中4个在Nucleus SE中没有实现。

队列:实用程序服务和数据结构相关推荐

  1. 管道:实用程序服务和数据结构

    管道:实用程序服务和数据结构 Pipes: utility services and data structures 管道公用设施 Nucleus RTOS有四个API调用,它们提供与管道相关的实用程 ...

  2. 从“消息队列”到“服务总线”和“流处理平台”

    作者简介 Gavin,程序员.软件架构师.企业架构师,关注智能制造. 本文是专栏<智能制造系统架构>中的文章,其它文章请参阅入坑智能制造系统架构. 消息队列是分布式系统中重要的组件,也是企 ...

  3. 循环队列–C语言实现–数据结构

    循环队列–C语言实现–数据结构 目录 循环队列C语言实现数据结构 目录 一 要求 二 循环队列 三 循环队列的算法设计 1 建立循环队列 2 置空队列 3 入队 4 出队 5 打印队 四 程序 1 程 ...

  4. python线性表和队列_[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列...

    python数据结构之线性表 python内置了很多高级数据结构,list,dict,tuple,string,set等,在使用的时候十分舒心.但是,如果从一个初学者的角度利用python学习数据结构 ...

  5. Java实现自定义队列和树结构_Java数据结构之链表、栈、队列、树的实现方法示例...

    本文实例讲述了java数据结构之链表.栈.队列.树的实现方法.分享给大家供大家参考,具体如下: 最近无意中翻到一本书,闲来无事写几行代码,实现几种常用的数据结构,以备后查. 一.线性表(链表) 1.节 ...

  6. c语言编写队列元素逆置,数据结构与算法实验—利用栈逆置队列元素.doc

    数据结构与算法实验-利用栈逆置队列元素 利用栈逆置队列元素实验报告 通信1204班 谢崇赟 实验名称 利用堆栈将队列中的元素逆置 实验目的 会定义顺序栈和链栈的结点类型. 掌握栈的插入和删除结点在操作 ...

  7. c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...

    第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...

  8. 环形队列的输出_Java数据结构:使用数组实现环形队列详解

    队列 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除 ...

  9. 宝塔部署Yii框架多个商城项目,队列问题“服务测试失败,请检查服务是否正常运行”

    原因:队列起了相同的编号,导致运行队列冲突 Centos7.8 多个商城在同一个宝塔内,必须要设置\config\local.php,给不同队列起不同编号,那么多个商城运行队列不冲突 'queue' ...

最新文章

  1. Overfull \hbox或Underfull \hbox错误提示 基于LaTex+VSCode+MAC
  2. java 提供的排序方法_请给出java几种排序方法
  3. Matlab错误:Y must be a vector or a character array
  4. kaggle数据集命令行下载
  5. 视图中::text_新CalendarFX视图:MonthGridView!
  6. 在MacOSX上重新安装Python (10.8) python 自然语言处理的前戏
  7. nginx 监听非标准端口80,重定向端口丢失问题解决
  8. TensorFlow中的Keras用法和自定义模型和层
  9. UVA 12300 Smallest Regular Polygon(正多边形)
  10. Linux学习笔记之查看Linux版本信息
  11. Linux之Redhat7如何破解密码
  12. 大数据分析的好帮手 Excel函数应用的顶级实战 Excel数据分析应用+VBA实战 24G课程
  13. 巴菲特的获利秘诀——“5+12+8+2”
  14. 9.3 开发经验和屁股的关系——《逆袭大学》连载
  15. 苹果手机 jquery点击无效
  16. 嵌入式计算机是专用计算机吗,什么是嵌入式计算机?
  17. 微信小程序文件目录介绍
  18. python3.7安装keras教程_keras教程-02-tensorflow和keras安装
  19. Java下载Excel兼容性问题
  20. 计算机桌面转换打字图标不见了,电脑输入法不见了,详细教您电脑输入法图标不见了怎么办...

热门文章

  1. RPC 笔记(07)— socket 通信(多进程服务器)
  2. 【Docker】Ubuntu18.04国内源安装Docker-准备工作(一)
  3. pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法
  4. python yield 和 return 对比分析
  5. MindSpore循环神经网络
  6. MindSpore张量mindspore::tensor
  7. h265webplayer
  8. 英特尔® 至强® 平台集成 AI 加速构建数据中心智慧网络
  9. Python:爬虫框架Scrapy的安装与基本使用
  10. python 中 is 与 == 的区别