写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。
标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。
点击此处进入学习日记的总目录
2024.03.01
- 七、UCOSIII:文件结构与解释
- 八、UCOSIII:函数指针
- 函数指针的形式
- 1. 形式1:返回类型(*函数名)(参数表)
- 2. 形式2:typedef 返回类型(*新类型)(参数表)
七、UCOSIII:文件结构与解释
由于后面会用到各种宏与函数,为了给它们分类,我提前把UCOSIII系统各文件的功能整理出来,后面遇到各种文件就知道什么功能了。
父文件目录 | 子文件目录 | 孙文件目录 | 文件名 | 功能 |
---|---|---|---|---|
User | uCOS-III | Source | os.h | 包含主要的μC/ OS-III头文件,该文件声明常量,宏,μC/ OS-III全局变量(仅供μC/ OS-III使用),函数原型等。 |
- | - | Source | os_type.h | 包含μC/ OS-III数据类型的声明,端口设计人员可以更改这些声明以更好地利用CPU体系结构。 与OS相关的数据类型则在os_type.h定义。 在这种情况下,通常会将文件复制到端口目录,然后进行修改。 |
- | - | Source | os_var.c | 包含μC/ OS-III全局变量。 这些变量供μC/ OS-III管理,不应由应用程序代码访问。 |
- | - | Source | os_task.c | 包含用于使用OSTaskCreate(),OSTaskDel(),OSTaskChangePrio()等管理任务的代码。 与任务的操作密切相关,包括任务的建立、删除、挂起、恢复等等。 |
- | - | Source | os_time.c | uC/OS-II中最小时钟单位是timetick(时钟节拍),其中包含时间延迟、时钟设置及时钟恢复等与时钟相关的函数。 |
- | - | Source | os_cfg.h | 定义优先级数量 |
- | - | Source | os_cfg_app.c | 根据os_cfg_app.h中的值声明变量和数组。 |
- | - | Source | os_core.c | 操作系统的处理核心。包括操作系统初始化、操作系统运行、中断进出的前导、时钟节拍、任务调度、事件处理等多部分。能够维持系统基本工作的部分都在这里 |
- | - | Source | os_dbg.c | 包含由内核感知的调试器或μC/ Probe使用的常量变量的声明。 |
- | - | Source | os_flag.c | 包含事件标志管理的代码。 |
- | - | Source | os_int.c | 包含用于中断处理程序任务的代码,当OS_CFG_ISR_POST_DEFERRED_EN(请参见os_cfg.h)设置为1时使用。 |
- | - | Source | os_mem.c | 包含μC/ OS-III固定大小内存管理器的代码。 |
- | - | Source | os_msg.c | 包含处理消息的代码。μC/OS-III提供消息队列和任务特定的消息队列。 |
- | - | Source | os_mutex.c | 包含用于管理互斥信号量的代码。 |
- | - | Source | os_pend_multi.c | 包含允许代码插入多个信号量或消息队列的代码。 |
- | - | Source | os_prio.c | 包含用于管理位图表的代码,用于跟踪准备就绪的任务。如果使用的CPU提供了位设置,清除和测试指令以及计数前导零指令,则可以用等效于汇编语言的该文件代替该汇编语言以提高性能。 |
- | - | Source | os_q.c | 管理信号量。 |
- | - | Source | os_sem.c | 包含用于管理用于资源管理和/或同步的信号量的代码。 |
- | - | Source | os_stat.c | 包含用于统计任务的代码,该代码用于计算全局CPU使用率和每个任务的CPU使用率。 |
- | - | Source | os_tick.c | 包含用于管理已延迟自身的任务或因超时而在内核对象上暂挂的任务的代码。 |
- | - | Source | os_tmr.c | 包含用于管理软件计时器的代码。 |
User | uCOS-III | Ports | os_cpu.h | 进行数据类型定义,处理器相关代码和几个函数原型。 |
- | - | Ports | os_cpu_c.c | 定义一些用户 hook 函数。 |
- | - | Ports | os_cpu_a.asm | 移植需要用汇编代码完成的函数,主要就是任务切换函数。 |
- | - | Ports | os_dbg.c | 内核调试相关数据和函数,可以不改 |
User | uC-CPU | cpu.h | 凡是与CPU类型相关的数据类型则统一在cpu.h中定义,包含用于使μC/OS-III和其他模块独立于CPU和编译器字长的类型定义。 具体来说,将找到CPU_INT16U,CPU_INT32U,CPU_FP32和许多其他数据类型的声明。 该文件还指定CPU是大端机还是小端机,定义μC/ OS-III使用的CPU_STK数据类型,定义宏CPU_CRITICAL_ENTER()和CPU_CRITICAL_EXIT(),并包含特定于CPU体系结构的函数的函数原型等。 | |
- | uC-CPU | cpu_core.c | 包含所有CPU体系结构通用的C代码。 具体来说,该文件包含用于测量CPU_CRITICAL_ENTER()和CPU_CRITICAL_EXIT()宏的中断禁用时间的函数,一个在CPU不提供指令的情况下模拟计数前导零指令的函数以及一些其他函数。 | |
- | uC-CPU | cpu_core.h | 包含cpu_core.c中提供的功能的功能原型以及模块用来测量中断禁用时间的变量的分配。 | |
- | uC-CPU | cpu_def.h | 包含μC/ CPU模块使用的其他#define常数。 |
八、UCOSIII:函数指针
在os.h里,对于任务函数的数据类型是这么定义的:
typedef void (*OS_TASK_PTR)(void *p_arg);
这就用到了一种之前不怎么常用的用法:函数指针
函数指针的形式
1. 形式1:返回类型(*函数名)(参数表)
#include <iostream>
using namespace std;
//定义一个函数指针pFUN,它指向一个返回类型为char,有一个整型的参数的函数
char (*pFun)(int);
//定义一个返回类型为char,参数为int的函数
//从指针层面上理解该函数,即函数的函数名实际上是一个指针,
//该指针指向函数在内存中的首地址
char glFun(int a)
{
cout << a;
}
int main()
{
//将函数glFun的地址赋值给变量pFun
pFun = glFun;
//*pFun”显然是取pFun所指向地址的内容,当然也就是取出了函数glFun()的内容,然后给定参数为2。
(*pFun)(2);
return 0;
}
通过上面的一个小例子,我们知道了函数指针的用法,
而typedef可以让函数指针更直观方便
2. 形式2:typedef 返回类型(*新类型)(参数表)
typedef char (*PTRFUN)(int);
//定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回char类型。后面就可以像使用int,char一样使用PTRFUN了。
PTRFUN pFun;
//使用这个新类型定义了变量pFun,此时就可以像使用形式1一样使用这个变量了。
char glFun(int a){ return;}
void main()
{
pFun = glFun;
//将函数指针指向定义的函数
(*pFun)(2);
//类似于变量指针的用法(使用*),只不过需要输入实参
}
参考资料:
typedef void (*Fun) (void) 的理解——函数指针——typedef函数指针