【STM32CubeIDE】STM32裸板多任务实现

前言

对于大部分的项目来讲,STM32基本都是处于“裸奔”的状态,将程序全部放在一个while(1)中顺序执行,但也会有部分任务要求几个任务“同时进行”,这个时候就需要一个RTOS了,但是有的时候就是这样,总会感觉为了一个小小的目的而在小容量的单片机中放一个OS,有些小题大做,我们需要的无非就是OS中的一个任务调度的功能,所以我只需要把这个功能给提取出来。

多任务

单片机只有一个处理核心,所以并不能同多核的PC机一样几个核心同时处理多个线程,我叫它“线程并行”。而单片机中所谓的多任务就是“线程并发”,就是多个线程看似一起发生,实际上还是单核心的顺序执行,只不过是每个线程都被分成了不同的时间片轮转执行。有关单片机多任务实现原理可以百度搜索一番,我在这里就不过多叭叭了,直接搞核心东西。

扩展知识

首先我们要知道,STM32有两个栈指针:MSP(主栈指针)和PSP(进程栈指针)有两种处理器模式:Thread ModeHandler Mode,有两种特权等级:特权模式非特权模式

STM32共有两个栈,主栈和进程栈,在裸机开发中全程使用主栈,而如果涉及到了多任务,就会用到进程栈,每个任务(其实就是函数)都会有一个属于任务本身的栈,这就是进程栈,这个栈的指针就要使用PSP,而这个时候到底是使用MSP还是PSP则是由 CONTROL 寄存器决定的, CONTROL[bit1] 若为0,则使用MSP,为 1 则使用PSP。中断或是异常的服务函数(例如 Systick_Handler 和 PendSV_Handler )一定是使用MSP(不需要人为控制,进入中断函数后 CONTROL[bit1] 位自动清零,函数退出后自动置 1 ),否则HardFault。

在 Thread Mode 中通过 CONTROL[bit0] 位可以选择处于特权模式或是非特权模式(0 特权模式,1 非特权模式),Handler Mode 一定是特权模式。(详情请自行搜索:任务运行在特权级或非特权级模式

功能实现

关于实现方式主要参考于《ARM Cortex-M3 Cortex-M4权威指南》第八章和第十章,主要用到了 PendSV 异常Systick 定时器中断,以及一些汇编语言的知识。

其中PendSV用于在PendSV_Handler中实现上下文切换(所谓上下文切换就是在多个线程之间反复横跳),Systick定时器则是将多个任务切分成时间片,每次进入 Systick_Handler 就会挂起一个PendSV异常,在 Systick_Handler以及其他高优先级异常任务处理完成之后 再进入PendSV_Handler。

在PendSV_Handler中其实只是做了两件工作:保存现场进程栈指针重定向。(这里需要用到汇编语言和寄存器的知识,如r0-r12,sp,lr,pc,msp,psp等,请自行搜索)

接下来分析代码。
这是使用STM32CubeIDE写的F407的代码,基于HAL库函数。

//宏定义 直接访问某个地址空间(1个字大小)
#define HW32_REG(ADDRESS) (*((volatile unsigned int *)(ADDRESS)))
//定义任务栈,每个2KB
long long task0Stack[256], task1Stack[256];

uint32_t currTask = 0;	//当前任务号
uint32_t nextTask = 1;	//下一个任务号
uint32_t PSP_Array[2];	//存放 进程栈指针 的数组

uint8_t initStatus = 0;	//初始化完成标志,
//HAL库的Systick初始化在HAL_Init()中就完成了,不想更改,只能加一个status

void Task0()
{
   
	initStatus = 1;	//进入Task0之后,任务调度开始
	while(1)
	{
   
		HAL_GPIO_TogglePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin);
		HAL_Delay(300);
	}
}

void Task1()
{
   
	while
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值