CORTEX-M4知识点总结 联系客服

发布时间 : 星期一 文章CORTEX-M4知识点总结更新完毕开始阅读

使用CMSIS-Core中的函数就能方便地使用Systick,主要作用就是产生定时中断,如下,产生1HZ的定时中断

配置正确的始终频率数,产生1khz的定时中断 Sys_Config(SystemCoreClock/1000); SystemCoreClock为对应芯片的时钟频率 SysTick定时器的寄存器只能在特权状态下访问。

8OS支持特性

8.1 OS支持特性简介

上下文切换是OS中很重要的一点,经过前面的学习,我们知道一个OS的运行就是在不同任务间频繁的切换,而在切换时,就需要对上一个任务的一些数据进行保存,然后进入下一个任务,并取出这个任务保存的数据。可以手动的实现一个系统的上下文切换。

处理器架构实现了多个特性,保证了OS设计的方便和高效:

· 影子栈指针。有两个栈指针,MSP用于OS内核以及中断处理,PSP用于应用任务。 · Systick定时器。处理器内部的简单的定时器。可实现任务的定时器切换 · SVC和PendSV异常。这两种异常对于嵌入式OS的操作非常重要,如上下文的切换的实现等等。 · 非特权等级执行,可以利用其实现一种基本安全模型

8.2 SVC和PendSV

SVC称作请求管理调用,它既是一条指令,也是一种异常。SVC指令就可以进入SVC异常中,之前说道过从非特权转换到特权模式就可以使用SVC异常的方法。并且SVC异常通常是不能被打断的,如果打断就会出现硬件错误。 PendSV异常是为完成OS的上下文切换,并且PendSV的异常等级要设置为最低。这是因为如果PendSV的异常等级比较高的话,当其他异常来临或正在执行时,上下文切换就会打断其他异常,上下文的切换较为复杂,就造成中断延迟。这在实时系统中是不可以的。所以要把PendSV异常等级设置为最低,等待所有中断执行完毕后,再进行上下文切换。下图是两种方式的对比。

任务切换一般有两种方式,一种可以通过systick中断触发PendSV异常,比如在时间片式的任务中;对于手动方式,可以通过SVC触发PendSV异常,完成上下文切换。这里要说明一下的是,下面两幅图中省略了触发PendSV的过程,Systick异常优先级是比较高的,它的作用简单,只是触发PendSV异常,它对IRQ的抢占影响很小。

优先级上下文切换PendSVOSOSIRQIRQIRQ线程任务A任务B时间优先级

IRQIRQ上下文切换PendSVOSOS线程任务A异常到来任务B时间

8.3 实际的上下文切换

上下文切换操作由PendSV异常执行处理,由于异常流程已经保存了寄存器的R0-R3、R12、LR、xPSR和返回地址,PendSV只需将R4-R11保存到栈中。

进入PendSV存储器任务A的栈任务A的异常栈帧(R0-R3、R12、LR、PC和xPSR)保存任务A的上下文存储器任务A的栈任务A的异常栈帧(R0-R3、R12、LR、PC和xPSR)任务A的R4-R11PSP存储器指向任务B的上下文任务B的栈任务B的异常栈帧(R0-R3、R12、LR、PC和xPSR)任务B的R4-R11任务B的上下文恢复存储器任务B的栈任务B的异常栈帧(R0-R3、R12、LR、PC和xPSR)PSPPSPPSP array[]STDMBLDMIA???任务B的SP任务A的SP加载下一个任务的PSP

具有四个任务的多任务系统实例: /*字访问的宏定义*/

#define HW32_REG(ADDRESS) (*(volatile unsigned long *)ADDRESS) /*以上宏定义相当于 Int *p;

p = (int*)0x60000000; *p = 0x01;

就是可以对ADDRESS地址处赋值,也就是访问这个字地址处的数据。*/ Void task0(void); Void task1(void); Void task2(void);

Void task3(void); //任务事件

Volatile uint32_t systick_count=0; //每个任务用的栈 8KB

long long

task0_stack[1024],task1_stack[1024],task2_stack[1024],task3_stack[1024];

//OS使用的数据