之前的章节都是针对某个或某些知识点进行的专项讲解,重点在功能和代码解释。
回到最初开始学μC/OS-III系统时,当时就定下了一个目标,不仅要读懂,还要读透,改造成更适合中国宝宝体质的使用方式。在学完野火的教程后,经过几经思考,最后决定自己锦上添花,再续上几章。
这几章想达成目的如下:
- 能够快速的上手
- 能够控制系统的功能
- 明白移植的过程
- 能够根据需要的功能来裁剪源码
从第六十一章开始的章节都是熟读源码后,根据笔者的整理方法,按照某种逻辑从系统源码中抽出来的专项解释。
笔者整理方法如下
- 各文件夹功能介绍(每个文件夹放什么文件,哪些是移植的,哪些不需要改,哪些需要修改)
- 各文件功能概览(每个文件都明白有哪些东西,是系统的哪一部分)
- 各文件函数概览(每个文件的有什么函数,函数的作用是什么,形参是什么)
- 移植的本质与移植的顺序(哪些文件需要了解,哪些文件是移植的时候需要更换的)
- 添加与裁剪源码(添功能与删功能怎么上手)
- 常用的结构体列表
- 常用宏介绍(如何用宏来控制整个系统,启用或关闭某个功能)
- main函数常用的结构顺序
- 创建任务的流程
- 任务在几种队列的变化
每个整理方法会用一章或多章的篇幅来解释。
2024.05.10:UCOSIII第六十四节:常用的结构体(os.h文件)第三部分
六十八、UCOSIII:常用的结构体(os.h文件)第三部分
OS_RDY_LIST
typedef struct os_rdy_list OS_RDY_LIST;
/*
------------------------------------------------------------------------------------------------------------------------
* READY LIST
------------------------------------------------------------------------------------------------------------------------
*/
struct os_rdy_list {
OS_TCB *HeadPtr; /* Pointer to task that will run at selected priority */
OS_TCB *TailPtr; /* Pointer to last task at selected priority */
OS_OBJ_QTY NbrEntries; /* Number of entries at selected priority */
};
这个结构体定义描述了就绪列表(Ready List)。下面是结构体中各个字段的详细解释:
HeadPtr
: 指向就绪列表中具有最高优先级的任务的指针。在多任务系统中,任务的优先级决定了其在就绪列表中的位置,HeadPtr指向具有最高优先级的任务。TailPtr
: 指向就绪列表中具有最低优先级的任务的指针。在多任务系统中,任务的优先级决定了其在就绪列表中的位置,TailPtr指向具有最低优先级的任务。NbrEntries
: 表示在就绪列表中的任务数量,即就绪列表的长度。
就绪列表是操作系统内核中用于管理处于就绪状态的任务的数据结构。在多任务系统中,操作系统需要维护一个就绪列表,以便能够快速地确定下一个应该运行的任务。就绪列表根据任务的优先级进行排序,因此具有最高优先级的任务将成为下一个执行的任务。通过维护就绪列表,操作系统可以实现任务的优先级调度,从而合理地分配处理器时间,提高系统的响应性和效率。
OS_TICK_SPOKE
typedef struct os_tick_spoke OS_TICK_SPOKE;
/*
------------------------------------------------------------------------------------------------------------------------
* TICK DATA TYPE
------------------------------------------------------------------------------------------------------------------------
*/
struct os_tick_spoke {
OS_TCB *FirstPtr; /* Pointer to list of tasks in tick spoke */
OS_OBJ_QTY NbrEntries; /* Current number of entries in the tick spoke */
OS_OBJ_QTY NbrEntriesMax; /* Peak number of entries in the tick spoke */
};
这个结构体定义描述了一个时钟节(Tick Spoke)。下面是结构体中各个字段的详细解释:
FirstPtr
: 指向时钟节中第一个任务的指针,即位于该时钟节中的第一个任务的控制块(TCB)。NbrEntries
: 当前时钟节中的任务数量,即时钟节的长度。NbrEntriesMax
: 时钟节中同时存在的最大任务数量,表示时钟节在任何时间点上达到的最大负载。
时钟节是操作系统内核中用于实现时钟节拍机制的数据结构。在实时操作系统中,时钟节拍是指定时间间隔内发生的一次系统时钟脉冲。时钟节用于分割系统时钟周期,将任务按照其定时要求组织到不同的时钟节中。通过维护时钟节,操作系统可以轻松地管理任务的定时要求,并在适当的时候唤醒这些任务。时钟节通常被实现为一个链表或数组结构,其中包含了当前时钟节中的所有任务,并记录了时钟节的状态信息。
OS_TMR
typedef struct os_tmr OS_TMR;
/*
------------------------------------------------------------------------------------------------------------------------
* TIMER DATA TYPES
------------------------------------------------------------------------------------------------------------------------
*/
struct os_tmr {
OS_OBJ_TYPE Type;
CPU_CHAR *NamePtr; /* Name to give the timer */
OS_TMR_CALLBACK_PTR CallbackPtr; /* Function to call when timer expires */
void *CallbackPtrArg; /* Argument to pass to function when timer expires */
OS_TMR *NextPtr; /* Double link list pointers */
OS_TMR *PrevPtr;
OS_TICK Match; /* Timer expires when OSTmrTickCtr matches this value */
OS_TICK Remain; /* Amount of time remaining before timer expires */
OS_TICK Dly; /* Delay before start of repeat */
OS_TICK Period; /* Period to repeat timer */
OS_OPT Opt; /* Options (see OS_OPT_TMR_xxx) */
OS_STATE State;
#if OS_CFG_DBG_EN > 0u
OS_TMR *DbgPrevPtr;
OS_TMR *DbgNextPtr;
#endif
};
这个结构体定义描述了一个定时器(Timer)。下面是结构体中各个字段的详细解释:
Type
: 对象类型,应设置为OS_OBJ_TYPE_TMR
,表示这是一个定时器对象。NamePtr
: 定时器的名称,用于标识定时器。CallbackPtr
: 定时器到期时要调用的回调函数的指针。CallbackPtrArg
: 传递给回调函数的参数指针,即在定时器到期时要传递给回调函数的参数。NextPtr
、PrevPtr
: 双向链表指针,用于将定时器链接到定时器列表中的下一个和上一个定时器。Match
: 定时器到期的匹配值,表示当系统时钟计数器(OSTmrTickCtr)达到该值时,定时器将到期。Remain
: 定时器到期前剩余的时间,表示从当前系统时钟计数器的值到定时器到期时剩余的时间。Dly
: 定时器启动前的延迟时间,表示定时器启动之前要等待的时间。Period
: 定时器重复周期,表示定时器到期后要重启的时间间隔。Opt
: 定时器的选项,用于指定定时器的行为,例如单次触发还是重复触发。State
: 定时器的状态,表示定时器当前的状态,如启动、停止等。
定时器是一种用于在指定时间间隔内执行特定操作的机制。通过设置定时器的到期时间和回调函数,可以在定时器到期时执行特定的任务或操作。定时器通常用于实现任务调度、超时处理、周期性任务等功能,在实时系统中具有广泛的应用。
OS_TMR_SPOKE
typedef struct os_tmr_spoke OS_TMR_SPOKE;
struct os_tmr_spoke {
OS_TMR *FirstPtr; /* Pointer to first timer in linked list */
OS_OBJ_QTY NbrEntries;
OS_OBJ_QTY NbrEntriesMax;
};
这个结构体定义描述了一个定时器节(Timer Spoke)。下面是结构体中各个字段的详细解释:
FirstPtr
: 指向定时器链表中第一个定时器的指针,即位于该定时器节中的第一个定时器。NbrEntries
: 当前定时器节中的定时器数量,即定时器节的长度。NbrEntriesMax
: 定时器节中同时存在的最大定时器数量,表示定时器节在任何时间点上达到的最大负载。
定时器节是操作系统内核中用于实现定时器管理的数据结构之一。在实时操作系统中,定时器通常会根据其到期时间被组织到不同的定时器节中,以便更快速地查询和处理到期的定时器。定时器节通常被实现为一个链表或数组结构,其中包含了当前定时器节中的所有定时器,并记录了定时器节的状态信息。
OS_PEND_DATA
typedef struct os_pend_data OS_PEND_DATA;
/*
------------------------------------------------------------------------------------------------------------------------
* PEND DATA and PEND LIST
------------------------------------------------------------------------------------------------------------------------
*/
struct os_pend_data {
OS_PEND_DATA *PrevPtr;
OS_PEND_DATA *NextPtr;
OS_TCB *TCBPtr;
OS_PEND_OBJ *PendObjPtr;
OS_PEND_OBJ *RdyObjPtr;
void *RdyMsgPtr;
OS_MSG_SIZE RdyMsgSize;
CPU_TS RdyTS;
};
这个结构体定义描述了挂起数据(Pend Data),以及挂起列表(Pend List)中的一个条目。下面是结构体中各个字段的详细解释:
PrevPtr
: 指向挂起列表中前一个条目的指针,用于在挂起列表中链接前一个条目。NextPtr
: 指向挂起列表中下一个条目的指针,用于在挂起列表中链接下一个条目。TCBPtr
: 指向挂起的任务控制块(TCB)的指针,表示与此挂起数据相关联的任务。PendObjPtr
: 指向挂起的对象(如信号量、消息队列等)的指针,表示导致任务挂起的对象。RdyObjPtr
: 指向就绪的对象(通常是与PendObjPtr
相同的对象)的指针,表示导致任务从挂起状态转换为就绪状态的对象。RdyMsgPtr
: 如果任务挂起于消息队列,该字段指向就绪消息的指针。RdyMsgSize
: 如果任务挂起于消息队列,该字段表示就绪消息的大小。RdyTS
: 就绪时间戳,表示任务从挂起状态转换为就绪状态的时间。
挂起数据和挂起列表通常用于实现任务挂起和恢复的机制。当任务等待某个条件的发生时,它可以被挂起,并将相关信息存储在挂起数据中。一旦条件满足,任务将从挂起状态转换为就绪状态,并通过挂起列表中的挂起数据恢复执行。这种机制允许任务在等待外部事件发生时释放CPU资源,从而提高系统的效率和响应性。
OS_PEND_LIST
typedef struct os_pend_list OS_PEND_LIST;
struct os_pend_list {
OS_PEND_DATA *HeadPtr;
OS_PEND_DATA *TailPtr;
OS_OBJ_QTY NbrEntries;
};
这个结构体定义描述了挂起列表(Pend List)。下面是结构体中各个字段的详细解释:
HeadPtr
: 指向挂起列表中第一个挂起数据的指针,即位于该挂起列表中的第一个挂起数据的指针。TailPtr
: 指向挂起列表中最后一个挂起数据的指针,即位于该挂起列表中的最后一个挂起数据的指针。NbrEntries
: 挂起列表中的挂起数据数量,即挂起列表的长度。
挂起列表通常用于在操作系统中管理任务的挂起状态。当任务等待某个事件发生时,它将被挂起,并将相关信息存储在挂起列表中。挂起列表可以是一个队列、链表或其他数据结构,用于存储和管理所有挂起的任务。通过挂起列表,操作系统可以轻松地管理挂起的任务,并在适当的时候恢复它们的执行。
OS_PEND_OBJ
typedef struct os_pend_obj OS_PEND_OBJ;
/*
------------------------------------------------------------------------------------------------------------------------
* PEND OBJ
*
* Note(s) : (1) The 'os_pend_obj' structure data type is a template/subset for specific kernel objects' data types:
* 'os_flag_grp', 'os_mutex', 'os_q', and 'os_sem'. Each specific kernel object data type MUST define
* ALL generic OS pend object parameters, synchronized in both the sequential order & data type of each
* parameter.
*
* Thus, ANY modification to the sequential order or data types of OS pend object parameters MUST be
* appropriately synchronized between the generic OS pend object data type & ALL specific kernel objects'
* data types.
------------------------------------------------------------------------------------------------------------------------
*/
struct os_pend_obj {
OS_OBJ_TYPE Type;
CPU_CHAR *NamePtr;
OS_PEND_LIST PendList; /* List of tasks pending on object */
#if OS_CFG_DBG_EN > 0u
void *DbgPrevPtr;
void *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
};
这个结构体定义描述了挂起对象(Pend Object)。下面是结构体中各个字段的详细解释:
Type
: 对象类型,表示该挂起对象所属的对象类型。不同的对象类型(如事件标志组、互斥量、消息队列、信号量等)都有不同的类型。NamePtr
: 指向对象的名称的指针,通常是一个以NUL终止的ASCII字符串,用于标识该挂起对象。PendList
: 挂起列表,用于存储等待该对象的任务的挂起数据。DbgPrevPtr
、DbgNextPtr
和DbgNamePtr
: 调试目的的前一个和后一个挂起对象指针以及挂起对象名称的指针。
挂起对象是操作系统内核中用于实现任务挂起和恢复的机制。不同类型的内核对象(如事件标志组、互斥量、消息队列、信号量等)都有自己的挂起对象。当任务等待某个内核对象时,它将被挂起,并将相关信息存储在该内核对象的挂起列表中。挂起列表可以是一个队列、链表或其他数据结构,用于存储和管理所有挂起的任务。通过挂起对象和挂起列表,操作系统可以轻松地管理挂起的任务,并在适当的时候恢复它们的执行。