rtos最小任务切换的实现 keil软件仿真 stm32 PendSV

最小任务切换的实现

本例子实现了一个 rtos 最小的任务切换功能,使用 keil 仿真功能,在模拟的 stm32f103 的器件上实现了使用 PendSV 中断切换线程的效果。
git 源码仓库:https://github.com/yutianos/rtos-little
本文链接:csdn@LeiCoder 将持续更新
https://blog.csdn.net/qq_29832469/article/details/139330311

环境基础

  • win11
  • keil v5.39
  • ArmClang.exe V6.21

技术基础

  • cortex-m3 架构中,在中断模式下(Handler)使用 MSP,在用户模式(Thread)模式下使用 PSP 作为栈指针。使用 msr msp, r0 指令来设置 MSP 寄存器,寄存器的值为栈的高地址。
  • cortex-m3 架构中,栈的增长方向为递减,向栈内压入数据,栈指针的地址的数值减小,并且栈的指针指向最新的数据。
  • cortex-m3 架构中,在进入中断模式时,硬件会自动将 [r0 r1 r2 r3 r12 r14(LR) r15(pc) xpsr] 一共 8 个寄存器压入栈内,且压入顺序固定
  • cortex-m3 架构中,从中断模式返回时,Cortex-M3 处理器支持不同的异常返回方式,这些方式由 LR 寄存器中的特定值指示。当处理器从异常(例如中断或系统调用)返回时,它会检查 LR 寄存器的值以确定返回方式和堆栈指针。常见的异常返回值包括:
0xFFFFFFF1:返回到特权模式,使用 MSP(Main Stack Pointer)。
0xFFFFFFF9:返回到特权模式,使用 MSP(这是硬件自动保存的值)。
0xFFFFFFFD:返回到线程模式,使用 PSP(Process Stack Pointer)。
  • cortex-m3 架构中,通常使用 PendSV 中断来切换线程,由于它可以方便通过软件触发,是一个系统级中断,而且使用中我们将其优先级配置为最低,保证其他中断事务处理完成之后才进行任务切换。
  • cortex-m3 架构中,有一个 systick 定时器,用它作为系统的时基。

实现步骤

  1. 设计使用 systick 作为时基。设置成为一个周期触发的事件,用来检查是否需要切换任务,并触发 PendSV 中断。代码如下,这个配置是来自 freertos,详细内容见 systick.c 文件。
#define configKERNEL_INTERRUPT_PRIORITY    255
/* Constants required to manipulate the core.  Registers first... */
#define portNVIC_SYSTICK_CTRL_REG             ( *( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG             ( *( ( volatile uint32_t * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG    ( *( ( volatile uint32_t * ) 0xe000e018 ) )
#define portNVIC_SHPR3_REG                    ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
/* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT              ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT              ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT           ( 1UL << 0UL )
#define portNVIC_SYSTICK_COUNT_FLAG_BIT       ( 1UL << 16UL )
#define portNVIC_PENDSVCLEAR_BIT              ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_SET_BIT         ( 1UL << 26UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT       ( 1UL << 25UL )

#define portNVIC_PENDSV_PRI                   ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值