| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 【OpenHarmony】LiteOS-M内核启动流程 -> 正文阅读 |
|
[嵌入式]【OpenHarmony】LiteOS-M内核启动流程 |
文章目录【OpenHarmony】LiteOS-M内核启动流程
一、LiteOS 内核框架首先先看一下 LiteOS 的内核框架,如下: 最底层是芯片的硬件架构适配,使用汇编代码适配各种芯片架构,比如 Cortex-M3、Cortex-M4、Risc-V等等 中间层是系统的内核,左边是基础内核是系统运行所具备的基础特性,一般一个 RTOS 都会有这些特性,右边是扩展的特性 最上层是抽象层,提供了 CMSIS 和 POSIX 接口,用于提供对外的接口,这套接口的 API是固定的,但 API 的底层则是调用 LiteOS 的内核函数,我们开发使用 CMSIS 的 API 进行开发,如果需要换 RTOS 开发,直接换 CMSIS 的底层接口就行,这样方便我们将代码从一个 RTOS 移植到另外一个 RTOS 一般常用的是 CMSIS-RTOS 接口,这套接口 Mculover666 写过详细的文章,我们不重复造轮子,请参考他的文章来使用 CMSIS 接口:RTOS内功修炼记(八)——CMSIS RTOS API,内核通用API接口 之前我们移植了 LiteOS-M 到 STM32F407ZGT6 单片机上,移植链接:【OpenHarmony】移植 3.1 版本系统到 STM32 移植的工程创建了一个简单的串口任务用于任务调度,本章将基于上一节移植的工程,简单的分析一下 STM32 单片机上电后,是如何运行到 LiteOS-M 任务调度内核那一块代码的 二、程序运行环境准备(上电执行)当我们按下 STM32 的单片机后,第一时间,单片机执行的不是我们写的 C 语言代码,而是一段汇编代码,我们一般叫他启动文件,我们上一节工程的代码启动文件是 单片机上电首先执行的就是这个汇编文件,可能你会有疑问为什么单片机上电先执行这段汇编,其他汇编文件不行嘛?这个是因为单片机上电后,执行的程序地址是固定的,由单片机的 PC 指针决定,而PC指针刚上的是由硬件复位,指向了固定地址,而工程文件中有一个链接文件,将汇编文件中的 Reset_Handler 函数放在了 PC 第一个执行地址,所以单片机上电后硬件初始化完 PC 和 SP 后,就会执行 Reset_Handler 了,Reset_Handler 再启动文件的位置如下: 他设置的 SP 堆栈指针的值,然后将数据段的起始地址传给 R0-2 寄存器,用于传参数给下一个调用函数,也就是 LoopCopyDataInit 函数,用来拷贝具有非 0 初始化值的变量到 SRAM,因为代码中的变量一开始全在 Flash 中,我们需要拷贝到 SRAM 运行,之后再清除未初始化数据段(.bss),初始化完成后,调用 SystemInit 来初始化单片机的 FPU 和时钟: 初始化完成后调用 __libc_init_array 来初始化 lib 库,初始化完成后就会跳转到 main 函数了,就可以愉快的运行 C 语言代码了! 可能有同学会问为什么这个启动文件和我再 MDK 里面看到的启动文件有差别,MDK 的还调用了 __main 函数,其实 __main 函数和上面时钟初始化前做的内容都差不多,只不过我这编译器是 GCC,MDK 是 ARMCC,有些许差别正常,如果一样就见鬼了! 好了,下面分析一下 main 函数做了啥! 三、外设复位及关键外设初始化首先是一个 HAL_Init 函数,复位所有的外设,对 Flash 读写进行初始化以及配置内核定时器: 函数内容如下: 四、时钟树及片上外设配置在上面的的复位和初始化完成后,下面我们又要对时钟进行一次初始化,这次时钟初始化较为完整,将整个 MCU 的时钟树进行初始化,这里的初始化代码由 CubeMX 生成,配置完成的时钟树如下: 时钟树初始化完成后就算对片上外设的初始化,比如这里我初始化了串口、DMA以及两个GPIO口: 这里单片机初始化部分基本上完成了,下面就是进入到 LiteOS-M 的内核初始化 五、内核初始化5.1 基本内核功能初始化内核我使用的 CMSIS-RTOS 接口进行配置,我按照 CMSIS 接口里面的代码逻辑顺序分析,先看一下内核基本初始化函数 先调用内核初始化函数进行初始化: 初始化函数判断当前如果系统没激活,且调用的位置不在中断中,就会调用 LiteOS-M 的初始化函数: 我们好好看一下 LOS_KernelInit 这个初始化函数 先打印一段提示:
调用 OsRegister 函数设置最大的任务数量:
下面的代码就是调用内存初始化函数初始化堆,OsMemSystemInit 初始化内容就是获取堆的首地址,然后根据设置的大小分配内存:
之后的初始化是跟底层架构相关的初始化函数,该函数调用了硬件中断初始化,如果我们使能了内核中断接管,则会在这个函数进行初始化,架构相关初始化函数:
芯片架构初始化完成后,下面的代码就是系统时基任务初始化,因为系统的正常运行离不开由内核定时器提供的时间基准,时间基准的维护由其相关时基任务进行,时基初始化就是配置相关任务,设置时基的一些相关参数:
之后调用 OsTaskInit 初始化任务列表,复位相关结构体的参数,调用的函数如下:
任务初始化完成后,接着初始化 IPC 通信的相关内容,分别初始化信号量、互斥量、队列:
之后初始化软件定时器,OsSwtmrInit 内容就是将软件定时器列表初始化,同时创建一个软件定时器守护线程,用于维护软件定时器
最后创建空闲任务:
LiteOS-M 内核的基础功能初始化流程图如下: 5.2 其他系统功能初始化以上就是系统运行的几个关键初始化函数,除此之外还有一些其他的可裁剪功能: 下面代码判断栈回溯宏定义有没有开启,开启了就初始化栈回溯,将回溯的hook关联上去,这样就会执行相关函数,这里我把这个功能裁剪了:
下面一段代码则是用于 LMS 模块裁剪控制,该模块可以检测memcpy、memmove、strcat、strcpy、memcpy_s、memmove_s、strcat_s、strcpy_s 这些函数的使用是否会引入内存问题,这里我没有开启: LMS 的初始化就是初始化控制句柄,为它分配好内存,然后指向对应的函数实体:
还有一些其他的功能,这里不具体展开,这些功能没有使用到,都裁剪了 六、启动系统(开始调度)在内核初始化完成后,下面我们创建我们需要的内核对象,比如创建一个串口任务
创建完任务后,开启启动内核,运行任务,启动接口如下
该函数调用的底层函数为 LOS_Start()
该函数就是,查找任务就绪列表最高优先级任务,然后立即进行任务调度,之后内核就开启运行了
代码工程仓库:Gitee |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 5:51:06- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |