从0到1写嵌入式操作系统---------------------------5.双任务时间片切换

本文针对双任务切换中需多次调用umTaskSched()函数的问题,提出基于时间片切换的方式,利用Systick定时器定时溢出产生中断触发。介绍了Systick定时器初始化及中断函数代码,还提及修改系统时钟频率,最后完成双任务时间片切换并展示效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上次我们使用任务调度器实现了双任务的切换,在任务1和任务2函数中需要对 umTaskSched()函数进行多次调用,针对这个问题,下面提出关于是否可以自动周期调用umTaskSched()函数的方法。提出了一种基于时间片切换的方式,该方式如何触发?由谁来触发?使用定时器定时溢出产生中断来触发,该定时器就是Systick定时器,它是一个24位倒计数定时器,当计数到 0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。

初始化Systick定时器,让该定时器在n*ms时触发Systick中断,具体代码如下:

// Systick定时器初始化函数

void SetSysTickperiod(uint32_t ms)

{

  SysTick->LOAD = ms*SystemCoreClock/1000-1; //Ô¤×°ÔØÖµ

         NVIC_SetPriority(SysTick_IRQn,(1<<__NVIC_PRIO_BITS)-1);

         SysTick->VAL = 0;

         SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk|

                         SysTick_CTRL_TICKINT_Msk|

                         SysTick_CTRL_ENABLE_Msk;

}

将任务中umTaskSched()函数转移到Systick中断函数中Systick_Hander() 具体代码如下:

//Systick中断函数

void Systick_Hander()

{

  umTaskSched();

}

暂且将Systick定时器初始化函数,放置在第一个任务函数中,且将任务1和任务2函数中的  umTaskSched()函数移除,具体如下

最后需要修改下系统的时钟频率,将SystemCoreClock配置为12M,即是将__XTAL 配置为12000000u   分频系数__SYSTEM_CLOCK设置为1.

趁着媳妇睡着了,撩一下PendSV异常,本人在调试基于这个实验的时候死活进不去Task2中,花了几个小时一直找,一直找,最后发现是这个原因:在FirstTask()中,我之前没有在意,先是触发PendSV异常,然后再设置优先级,这样的操作导致我后面检查了好久才发现是这个原因,所以这里告诫大家,一些设备的初始化我们尽可能按着顺序来,避免不必要的时间浪费在这无休止的检查中。

最后我们来一起看一下效果吧!编译代码,Debug仿真运行,直接全速运行代码,下面是逻辑分析的波形,可以看到任务1和任务2执行的时间是相等的,即是Systick中断触发的时间,本次我们就完成了双任务时间片切换。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值