随着计算机技术和微电子技术的迅速开展,嵌入式系统运行畛域越来越宽泛,尤其是其具有低功耗技术的特点失掉人们的注重。随着工信部提出NB-IoT基站树立详细指标、三大运营商减速树立,行将迎来万物互联的新时代,这是信息产业继移动互联网之后的下一个万亿级市场,这些为实时操作系统的运行提供了宽广的前景。
嵌入式实时操作系统将会部署到越来越多的设施中,这就要求工程师深化地了解嵌入式实时操作系统。本系列文章将和大家一同从零开局构建一个嵌入式实时操作系统,我将用最便捷直白的形式一步一步搭建,我将用一篇文章的形式来总结搭建中的每个节点阶段,并开源软件工程和源代码。
嵌入式实时操作系统是一个不凡的程序,是一个支持多义务的运转环境。嵌入式实时操作系统最大的特点就是“实时性”,假设有一个义务须要口头,实时操作系统会立刻口头该义务,不会有较长的延时。典型的实时操作系统有uCOS,RT-Thread,FreeRTOS ,VxWorks,WinCE等。
嵌入式实时操作系统是一个不凡的程序(通常称为内核),它可以创立和控制一切义务。嵌入式实时操作系统除了蕴含一个内核以外,还提供其余服务,如文件系统,协定栈,图形用户界面等。本文的重点在于了解嵌入式实时操作系统内核的上班原理和结构,因此文中提到的实时操作系统通常指的是操作系统内核。实时操作系统内核通常要占用5%左右的CPU运转期间,另外内核是一个软件代码,须要额外占用ROM空间和RAM空间。
嵌入式实时操作系重要由以下3个子系统组成:
本文解说构建嵌入式实时操作系统的第一个节点阶段:成功便捷的义务切换性能。
代码区的数据是不变的,处置器寄存器的值和栈空间的值选择程序运转形态。让每个义务“独享”一个栈空间,当咱们将义务运转时的处置器寄存器的值保留起来时,这样就成功保留义务的运转形态。雷同的当咱们把保留的义务运转时的处置器寄存器的值装载四处置的寄存器中时,这样就复原了义务的运转形态,义务继续运转起来。
切换义务的原理是:每个义务有一个“独享”栈空间,经过保留和装载义务运转时的处置器寄存器的值,成功义务的暂停和复原运转。暂停一个义务后再复原另外一个义务就成功了一次性义务切换。
义务代码,义务栈空间和处置器形态如下图:
配件是基于意法半导体的STM32F401(ARM公司的Cortex-M4内核),软件开发经常使用的是KEIL V5.2 开发工具。
软件工程如下:
软件工程中蕴含:main.c ,startup_stm32f401xc.s 和readme三个文件。startup_stm32f401xc.s文件为STM32F401的启动文件,main.c文件成功义务切换性能,readme文件用于记载版本修正日志。
切换义务的原理是让每个义务都有一个“独享”栈空间,经过保留和装载义务运转时的处置器寄存器的值,成功义务的暂停和复原运转。暂停一个义务后再复原另外一个义务就成功了一次性义务切换。
因此须要成功:
栈空间代码如下:
为每个义务定义一个静态数组,当义务运转时将处置器的栈指针指向义务“自己的”静态数组,从而成功独立栈空间。栈空间用来寄存部分变量,终止调用和函数调用时的处置器寄存器的值。义务切换时须要将处置器寄存器的值保留到义务的独立栈空间。
在保留义务运转形态时须要保留处置器寄存器值到栈空间,因此须要深化了解处置器寄存器的用途和出入栈顺序,Cortex-M4内核的寄存器和寄存器终止智能入栈的顺序图如下:
初始化栈空间的代码如下:
栈空间初始化后的形态如下:
栈是一中先入后出的数据结构,Cortex-M4内核的栈操作形式倍设置成了向下成长。psp_array用于保留义务栈指针,psp_array[0]义务0栈指针指向task0_stack[112],其中task0_stack[116]保留PC程序指针值,task0_stack[117]保留形态寄存器(合乎Cortex-M4内核寄存器出栈顺序:手动出栈8个寄存器,配件智能出栈8个寄存器)。
代码如下:
cortex-M4内核有一个PendSV(可挂起的系统调用)意外,其意外编号为14并且具有可编程的优先级。当软件将PendSV设置成挂起时,程序将进入PendSV意外(终止)。
将PendSV意外优先级设置为最低,其它终止函数都可以失掉反常照应,不会遭到PendSV意外影响,在PendSV意外中口头义务切换,时序框图如下:
PendSV_Handler为Cortex-M4内核终止服务函数,进入终止函数时处置器智能保留了R0,R1,R2,R3,R12,LR,PC,XPSR,在PendSV_Handler终止程序中成功R4~R11入栈保留上班,从而成功义务保留上班。
/* 读取当行进程栈指针数值 */ ,/* 保留R4-R11八个寄存器的值到义务栈中同时将回写的地址写入R0 */ ,{}
psp_array[0]为义务0的栈指针, psp_array[1]为义务1的栈指针。以下代码成功义务栈指针切换。
, ()/* 将当行进程PSP指针值 写入 相应的 PSP_array 位置*/,[,, ] ,() ,[]/* R1为&curr_task将下个进程序号写入curr_task中 */ ,[]/* psp_array读取降级后的curr_task的PSP指针数值 */ ,[,, ]
在PendSV_Handler终止程序中成功R4~R11寄存器出栈,PendSV_Handler终止程序前往时处置器智能出栈R0,R1,R2,R3,R12,LR,PC,XPSR,从而成功义务恢停上班。
义务调度的代码如下:
SysTick_Handler为定时器终止程序,成功期间片轮番扭转指标义务,并挂起PendSV_Handle终止,分开SysTick_Handler终止程序时进入PendSV_Handle终止程序。
代码仿真运转如下:
运转代码后task_num0和task_num1这两个变量依次自加,代码成功义务轮番切换性能。
本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/7005.html