在以往学习 STM32
裸机的时候,就了解了
STM32
是如何从上电复位开始,一步一步的进入到 main()
函数中的,这就是
STM32
的启动流程,那
µC/OS-III
的启动流程是怎样的呢?
1,µC/OS-III
屏蔽所有中断
启动 µC/OS-III
的第一步就是调用函数
CPU_IntDis()
,该函数通过操作寄存器
PRIMASK
,实现屏蔽所有的异常和中断,这样是为了保证在 µC/OS-III
的启动过程中,不被异常或中断打断。
2,µC/OS-III
内核初始化
µC/OS-III 内核的初始化是通过调用函数
OSInit()
完成的,函数
OSInit()
必须在函数
OSStart() 调用之前被调用,函数 OSInit()
会初始化
µC/OS-III
内核并检测是否存在错误,如果检测到错误, 就会立即返回。
函数
OSInit()
的函数原型如下所示:
void OSInit(OS_ERR* p_err);
可以看到,函数 OSInit()有一个形参 p_err,是一个指向接收错误代码变量的指针,如果函数 OSInit()在初始化 µC/OS-III 内核的时候,检测到错误,就会立即返回,并将错误代码通过形参 p_err 返回。
函数 OSInit()
就是初始化了各种供
µC/OS-III
内核正常运行的全 局变量和功能。在做好各种初始化后,会将全局变量OSInitialized
标记为
OS_TRUE
,表示
µC/OS-III 内核已经完成初始化。
3,µC/OS-III
创建第一个应用任务
完成 µC/OS-III
内核初始化后,在开启
µC/OS-III
任务调度之前,还必须至少创建一个应用任务,因为,虽然在函数 OSInit()
初始化
µC/OS-III
内核的过程中,创建了空闲任务、任务统计任务和软件定时器任务(其中空闲任务是一定会被创建的,而任务统计任务和软件定时器任务会根据配置文件的配置,进行创建或不创建),但是以上这三个任务都属于内核任务,应用程序是无法访问的,并且在 µC/OS-III
内核开始任务调度之后,就不会返回,
CPU
只会执行已创建的任务,因此在开始任务调度之前,还需要至少创建一个应用任务,这个应用任务来负责初始化应用程序。
使用函数 OSTaskCreate()来创建任务。函数 OSTaskCreate()
在创建一个任务的时候,会初始化任务控 制块中的成员变量,但最重要的还是初始化的任务的任务栈,任务栈中就包含了任务在获得 CPU 使用权时,应该从哪里开始执行、任务函数意外返回,要返回到那里去、任务函数的参数 以及任务执行过程中的 CPU
寄存器的值等信息。
4,µC/OS-III
开始任务调度
开始 µC/OS-III
任务调度是
µC/OS-III
内核开始运行前的最后一步,在此之前需要先调用函数 OSInit()
对
µC/OS-III
内核进行初始化,并至少创建一个应用任务。通过调用函数
OSStart()
就能够开始 µC/OS-III
的任务调度。
函数 OSStart()
的函数原型如下所示:
void OSStart(OS_ERR* p_err)
可以看到,函数 OSStart()
有一个形参
p_err
,是一个指向接收错误代码变量的指针,如果函数 OSStart()
在开启
µC/OS-III
任务调度的过程中,检测到错误,就会返回,并将错误代码通过形参 p_err
返回。如果函数
OSStart()
成功开启了
µC/OS-III
的任务调度,那么函数
OSStart()是不会返回的,会直接开始进行任务调度,并执行任务。
函数 OSStart()
进行完准备工作后,如果不存在错误,最后会通 过调用函数OSStartHighRdy()
进入到第一个任务中去,从此之后就不会在返回了。
在执行完函数 OSStartHighRdy()
后,就跳转到第一个任务中去执行并开始任务调度了,至 此,µC/OS-III
的启动流程也就结束了。