王超的小站
认证:VIP会员
所在专题目录 查看专题
FreeRTOS移植详解2-滴答定时器实现(基于Microchip dsPIC33C系列芯片)
FreeRTOS移植详解3-内核裁剪(基于Microchip dsPIC33C系列芯片)
FreeRTOS移植详解4-中断配置(基于Microchip dsPIC33C系列芯片)
FreeRTOS移植详解5-临界段处理(基于Microchip dsPIC33C系列芯片)
FreeRTOS移植详解6-任务堆栈初始化和启动(基于Microchip dsPIC33C系列芯片)
FreeRTOS移植详解7-任务切换(基于Microchip dsPIC33C系列芯片)
作者动态 更多
PIC24 & dsPIC33 MCU Bootloader开发
2021-11-08 15:12
PIC16 & PIC18 MCU Bootloader开发
2021-11-08 15:00
Python开发环境搭建(for Bootloader)
2021-11-08 14:58
Python开发环境搭建 (for Control)
2021-01-27 18:43
MCU扩展CAN/CAN FD接口方案-MCU软件动手实验
2020-11-25 14:11

FreeRTOS移植详解7-任务切换(基于Microchip dsPIC33C系列芯片)

      经过上一节的介绍,我们已经清晰了任务堆栈初始化后任务堆栈的内容,及启动任务时如何将堆栈内容恢复并跳转到任务函数。那么本节接着介绍任务切换,任务切换决定了任务的执行顺序,包括如优先级高的任务打断优先级低的任务和同等优先级任务的时间片调度等。

      任务切换可以在两种情况下进行,一种是执行一个系统调用,如直接调用引起任务切换的API函数,比如任务切换函数taskYIELD()。另一种是在滴答定时器Timer1中断中执行任务切换。无论哪种方法,最终实际都是调用portYIELD()函数来实现的。为了深刻理解这个切换过程,我们有必要再一次回顾涉及到的基本汇编语法。

      我们首先看下portmacro.h中portYIELD()的宏定义,可以看出这里有个CALL语句,所以当前任务下一PC 执行地址将自动压栈。

      接着我们看一下CALL调用的子函数vPortYield的内容,可以很容易的看出其首先按照堆栈初始化的方式进行压栈,直到压完uxCriticalNesting后将栈顶赋值给当前任务的TCB第一个成员变量pxTopOfStack;然受调用vTaskSwitchContext()来获取下一个要运行的任务(如存在高优先级的任务),明确该任务堆栈的栈顶指针,先出栈uxCriticalNesting,然后接着顺序出栈直到出栈SR,最后借助return汇编语句跳转到下一个要运行任务的任务函数。

      最后在介绍一下时间片调度。FreeRTOS支持多个任务同时拥有一个优先级,同时允许一个任务运行一个时间片(一个时钟节拍的长度)后让出CPU的使用权,让拥有同一个优先级的下一个任务运行。任务是否切换这是通过滴答定时器中断中的xTaskIncrementTick()来判断的,并且只有当configUSE_PREEMPTION和configUSE_TIME_SLICING都为1的时候才允许进行时间片调度。在xTaskIncrementTick()中会判断当前任务的优先级下是否还有其他任务,如果有则返回pdTRUE,执行一次任务切换。


      至此已经讲完了FreeRTOS在dsPIC33C系列芯片移植的所有内容,已经可以跑起来FreeRTOS的开发环境了,剩下的就是找一本讲解FreeRTOS的书,逐步了解FreeRTOS自身的知识点,边动手边思考,相信大家一定可以将FreeRTOS熟练应用到后续的项目中去。

      额外的,还需要注意的是在例程中我定义了三个宏,通过这些宏可以区分port.c、portasm_dsPIC.S是针对dsPIC33C还是针对PIC24等。换句话说这个移植不仅针对于dsPIC33CK系列芯片,它更适用于Microchip全系16位MCU芯片。

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 4
收藏 4
关注 40
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧