芯片启动后转向用户程序、操作系统的过程
上一章介绍了芯片启动后的过程,芯片上电后开始启动执行到无操作系统主函数main(07_NosPrg\main.cpp)前。那么针对于BIOS最小系统和mbedOS的跳转过程如下:
1. BIOS最小系统的跳转
BIOS的main函数如下:
1 | int main(void) |
那么,在上述代码中,有两处关键代码 pin_reset_judge(); 和 user_reset(GEC_USERBASE);
pin_reset_judge();
代码进行的是复位引脚被触碰了几次,本例子中以6次为限,触碰6次则程序返回BIOS中。
那么上一章所提的BSS段被注释掉就是希望芯片启动后不清楚某些全局变量的状态,如果芯片复位标志被置位,说明已触碰6次,那么就不会跳转到GEC_USERBASE用户区。反之,芯片启动后会直接跳转到用户区。具体流程见后续章节。
user_reset(GEC_USERBASE);
这段代码会让芯片直接跳转到用户区,GEC_USERBASE是用户区的首地址。
2. mbedOS的跳转
main 函数开始 mbedOS 的启动,我们把 mbedOS 启动过程梳理到一个函数中运行,由 main 函数来调用,这个函数原型为:
1 | mbedOS_start(osThreadId_t &thd, void (*func)(void))。 |
mbedOS 进入 main 函数之后,调用 mbedOS 的启动函数,mbedOS 就开始启动,并无休无止地开始运行,进行任务调度。
mbedOS_start 函数是 mbedOS 启动过程函数
其主要任务是:
1.设置 mbedOS 堆栈区
2.重定向中断向量表
3.完成内核初始化
4.建立互斥信号
5.创建主线程和启动内核
类似于BIOS,在main函数中会直接调用mbedOS_start这个函数跳转到mbedOS的首地址处。
当内核启动成功后,函数 svcRtxKernelStart 执行完成返回到 SVC 中断中,进行上下文切换,返回到定时器线程中执行。定时器线程 osRtxInfo.timer.thread 运行后会进入阻塞状态,此时 mbedOS 会选择就绪队列中优先级最高的线程,即主线程 main_thread,使其进入激活态。
主线程被调度运行时,其执行函数 app_init主要负责完成初始化外设模块、初始化全局变量、使能中断模块、创建并启动其他用户线程、阻塞主线程的功能,之后的线程运行和切换都由 mbedOS 调度完成