自学内容网 自学内容网

400行程序写一个实时操作系统(十一):arm cortex m3架构

前言

通过上一篇文章,我们已经知道了一个RTOS的基本框架,寄存器这个概念已然跃出水面,摆在我们面前的难题是对arm架构的理解。

封装与接口思想

由于c语言的操作尺度不足,我们只能使用汇编语言完成任务切换,同时很多中断的配置需要对芯片内部的一个又一个的角落进行编程。请读者必须明白,你并不是芯片厂商,你也不需要从门电路开始搭建CPU。我们需要的是查找手册中的信息并使用它,在arm手册中寻找实现RTOS的指导,而不是关注arm架构的本质。**我们的重点是关注实现的功能,而不是芯片手册的本质理解。**如果读者没有arm架构和汇编基础,你大可直接跳过,只要知道我们使用的汇编和二进制程序实现了什么功能即可。换而言之,请使用封装与接口思想

arm架构

简单介绍一下我们要在汇编尺度下完成的事情:产生SVC中断调用->开启第一个任务->任务执行 ->systick中断触发Pendsv中断 ->pendsv中断->保存原先任务状态 ->切换下一个任务状态->任务执行->systick中断触发Pendsv中断 ->pendsv中断->保存原先任务状态 ->切换下一个任务状态-------循环---------

img

以最常用的stm32f10系列为例,它的架构是arm cortex m3。在arm架构中,有七种工作模式,37个寄存器。

了解以下模式即可:

1.正常情况下是usr模式

2.用于高速数据传输和通道处理时切换为FIQ模式

3.执行外部中断时是irq模式

4.最高权限是管理模式svc

5.系统模式sys

除了系统模式和用户模式,其他模式都被称之为异常。

在arm汇编中。我们使用寄存器进行编程,对数据的操控都要通过寄存器进行。寄存器分为31个通用寄存器和6个状态寄存器,在不同的状态下,我们能使用的寄存器可能会不同。

查找手册

为了让我们的框架落到实处,我们必须寻求arm架构手册的指导。

顺便一提,笔者很早就想喷一些翻译了,为什么要将stack翻译成堆栈?为什么要将stack翻译成堆栈?为什么要将stack翻译成堆栈?不知道到底是谁开的头,导致国内很多书籍全都这么干,不管是有名的书籍还是无名的,全是清一色的堆栈。谁能告诉我这么干的理由?

有翻译总比没翻译好,凑合着看,只能说还是尽量看英文手册。

让我们看看 arm cortex m3官方手册是如何指导写出一个os的,这是关于栈的部分:

img
​ 简单来说,就是使用双栈机制。关键性的代码使用MSP指针,此时处于特权模式。应用程序代码使用PSP指针,此时处于用户态。

​ 我们知道栈要初始化,初始化的理论依据可以参考arm cortex m3官方手册对os栈初始化的介绍:

img

中断与上下文切换

笔者在前面的博客讲过一点中断在arm架构中是完成任务切换实现多线程的关键因素,然后引出了systick中断和Pendsv中断的概念,它们都属于arm cm3的硬件资源。

让我们看看arm cortex m3官方手册:

笔者在之前调试sparrow时已经说过,systick中断会触发pendsv中断完成上下文切换,这与图中是一样的。

任务的启动

显然,我们开启RTOS第一个任务,肯定要保证第一个任务马上执行,不会受到干扰,所以,

为了能够启动RTOS,sparrow利用了svc中断,也就是系统中断,下图是中断向量表。

中断向量表是一种数据结构,它用于存储中断服务程序(ISR)的入口地址。当硬件设备触发中断时,CPU会根据中断号查找中断向量表,以获取对应ISR的地址,并跳转到该地址执行相应的中断处理程序。:

img编辑

于是,在SVC中断中,我们将把第一个任务的内容加载到了寄存器中,sparrow开始执行任务。随后,来到PendSV函数,在这里,我们将会保存前一个任务的状态,并且切换到下一个任务。

PendSV(可悬起的系统调用),它和 SVC 协同使用。一方面,SVC 异常是必须立即得到响应的,应用程序执行 SVC 时都是希望所需的请求立即得到响 应。

另一方面,PendSV 则不同,它是可以像普通的中断一样被悬起的(不像 SVC 那样会上访。OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。悬起 PendSV 的方法是:手工往 NVIC 的 PendSV 悬起寄存器中写 1。悬起后,如果优先级不够高,则将缓期等待执行。

PendSV 的典型使用场合是在上下文切换时(在不同任务之间切换)。例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是:

1.执行一个系统调用

2.系统滴答定时器(SYSTICK)中断

系统调用是提供给用户的接口,可以触发优先级抢占,滴答计时器中断时可以发生时间片轮转。

顺便一提,在sparrow中,如果创建任务时没有延时,任务的优先级又非常高,那么任务就会一直执行。这是因为没有产生系统调用,优先级太高又导致没有相同优先级的任务在产生滴答计时器时过来抢占。

任务的保存与切换

关于任务是如何被保存的,读者可以参考下文,知道如何保存,也就知道了如何切换:

img

从arm架构的角度看,RTOS通过SVC中断开启了第一个任务,随后Systick中断定时触发PendSV中断进行任务的保存与切换,这就是sparrow中的任务切换调度部分。

总结

以上就是本文要探讨的重点,即arm cm3中的栈、中断与上下文切换,笔者将会结合sparrow源码来理解官方手册。

链接:skaiui2/SKRTOS_sparrow at manual (github.com)

这是arm cortex m3和arm cortex m4的参考手册,有需要的读者自取,加上cm4的手册是考虑cm3的手册不详细。


原文地址:https://blog.csdn.net/2301_77061352/article/details/143082132

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!