浅析LiteOS启动过程(基于STM32L431)-0x01

举报
Jasonchenbj 发表于 2020/07/02 17:44:13 2020/07/02
【摘要】 摘要:本文简要的分析了基于STM32L431的智慧农业案例程序中的LiteOS的启动过程。从经典的main函数开始,到LiteOS正常启动,实现任务的调度。通过这种分析,可以很好的理解LiteOS的一些运行原理过程,有助于LiteOS移植过程中的问题排查,有助于在其他芯片上顺利移植LiteOS。1.从主函数main()进入在嵌入式C语言程序中,程序通常从main函数开始执行。在没有操作系统的...

摘要:本文简要的分析了基于STM32L431的智慧农业案例程序中的LiteOS的启动过程。从经典的main函数开始,到LiteOS正常启动,实现任务的调度。通过这种分析,可以很好的理解LiteOS的一些运行原理过程,有助于LiteOS移植过程中的问题排查,有助于在其他芯片上顺利移植LiteOS

1.从主函数main()进入

在嵌入式C语言程序中,程序通常从main函数开始执行。在没有操作系统的时候,通常在主程序中会有一个无限循环。例如下面的这一段程序。

image.png


在无限循环中,不断控制两个LED灯的亮灭控制。但是,当程序有了操作系统后,这个主函数还有吗?这个无限循环还会有吗,它的运行逻辑是什么?

   下面是智慧农业的程序的main函数

image.png


在这个main函数中

62行,调用Hardware_Init进行硬件初始化。主要是时钟、GPIOUARTLCD等的初始配置。

63行,调用LOS_Kernelinit( )Lite OS的内核进行初始化。

70行,调用create_work_tasks(void) 创建了一个工作任务。

77行,调用LOS_Start( )启动LiteOS系统。

可以看出,在上面的程序中,没有出现while(1)这样的无限循环。那么77行,调用LOS_Start()后,接下来的要执行的程序代码去哪里了?难道就这样return0了吗?不应该。

从哪里消失,从哪里找起。从LOS_Start( )“消失”,继续从LOS_Start( )看起。

2. 进入LOS_Start( )

LOS_Start( )函数在los_init.c文件中,代码如下

image.png

99行,调用osTickStart(); 配置Lite OS系统的时钟。Lite OS系统的时钟配置和刚开始的时钟的初始化配置不同。刚开始的时钟配置是基于STM32L431的系统进行的时钟配置。这里的时钟配置,是Lite OS系统中时钟配置。这里Lite OS系统时钟,类似于大家常用的桌面操作系统的时钟概念。

   121行,调用LOS_StartToRun( );启动Lite OS 运行。 LOS_StartToRun()函数,在Keil 环境中,通过右键->转到定义 的方法,找不到函数的实现文件。通过在整个项目中,查找LOS_StartToRun发现LOS原来的los_dispatch_keil.S文件中。

3. 进入los_dispatch_keil.S

 los_dispatch_keil.S使用汇编语言编写的,主要实现了下面几个重要的函数及全局变量。

image.png

其中有LOS_StartToRun 函数。这个LOS_StartToRun函数就应该是在LOS_Start()函数最后调用的那个LOS_StartToRun( )。 LOS_StartToRun函数代码如下

image.png

image.png

image.png

这个代码用汇编语言写的。很难看懂,但是76-80行的注释,简要的说明了这个函数的调用形式以及功能:这个函数是没有返回值,没有参数的,它主要实现了 启动第一个任务,这个任务具有最高的优先级。其他的任务都是由任务调度来启动。任务调度在哪里?下面一会会说。

这个函数中最后一行 BX R6 上面的注释说,直接跳转到了g_stLosTask.pstRunTask中存储的PC指针处了,这样main函数的相关新就丢失了,程序就不会返回到main函数中了。

通常在嵌入式汇编程序中,调用子程序时,通常会保存号当前函数相关的信息,等调用完后,在恢复到调用的函数中。而这里的 BX R6 并没有让LOS_StartToRun函数返回到调用它的函数中,这样程序就不会在返回到main函数中了。至此,main函数结束了。整个系统的运行就全部依靠Lite OS系统了。

不返回main函数了,那么程序从哪里开始执行了?从 PC of g_stLosTask.pstRunTask,开始执行了。这里的PC是程序计数器,里面存储着CPU下一次要执行的程序指令的地址。执行完BX R6后,CPU就取到了g_stLosTask.pstRunTask地址中存储的指令,开始执行了。这个g_stLosTask.pstRunTask里面存储的是什么?在整个项目中查找g_stLosTask.pstRunTask,发现有如下代码

image.png

osTaskInit()函数中,对g_stLosTask.pstRunTask进行了赋值。从分析赋值过程语句,可发现在g_stLosTask.pstRunTask中存储了要执行的任务相关的信息存储在里面了,即任务控制块(task control block structureLOS_TASK_CB中的内容)的内容存储在g_stLosTask.pstRunTask中了。

在汇编语言中,将g_stLosTask.pstRunTask中的相关信息存储到STM32L431的相关的工作寄存器中,例如R6 工作寄存器。这样程序就可以执行任务了。而任务的相关信息、入口函数等都可以用C语言来编写。至此,程序可以绕道执行任务相关的代码了。“绕道”,这里绕道可以理解为,终于绕开了那个main函数了,可以执行操作系统中的多个任务了!

多个任务的调度,主要由LOS_IntLock,LOS_IntUnlock,LOS_IntRestore,osTaskScheldule,PendSV_Handler这些函数实现。这些函数也是用汇编语言写的。那么这里可以看出,针对不同芯片移植LiteOS的时候,由于不同的汇编语言可能需要不同的类似los_dipatch_keil.S这样的汇编语言编写程序文件。

4.综述

通过以上的分析,可以看出,在Lite OS在启动的时候,是从main函数中被调用开始,而在被调用的过程中,没有让PC指针再次跳转回main函数中,而是直接跳转到执行任务的命令的地址上去,从而开启了具有多任务执行能力的操作系统功能。






【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。