如何查看freertos任务切换解析调度各个任务状态

如果将所有任务都设置在相同的优先级,那么在系统跑起来之后,所有任务将进行轮盘式的调度。如果任务仅仅具有不同的优先级而没有经过其他处理时。高优先级的任务将一直重复运行,将低优先级的任务“饿死(starved))”。
事件驱动:
为了使我们的任务切实有用,我们需要通过某种方式来进行事件驱动。一个事件驱动任务只会在事件发生后触发工作(处理),而在事件没有发生时是不能进入运行态的。调度器总是选择所有能够进入运行态的任务中具有最高优先级的任务。一个高优先级但不能够运行的任务意味着不会被调度器选中,而代之以另一个优先级虽然更低但能够运行的任务。因此,采用事件驱动任务的意义就在于任务可以被创建在许多不同的优先级上,并且最高优先级任务不会把所有的低优先级任务饿死。
任务有两种大的运行状态:运行态和非运行态。非运行态有较多类型,以下一一解释:
1 阻塞态 blocked:
任务可以进入阻塞态以等待以下两种不同类型的事件:1. 定时(时间相关)事件——这类事件可以是延迟到期或是绝对时间到点。比如说某个任务可以进入阻塞态以延迟10ms。2. 同步事件——源于其它任务或中断的事件。比如说,某个任务可以进入阻塞态以等待队列中有数据到来。同步事件囊括了所有板级范围内的事件类型。
任务可以在进入阻塞态以等待同步事件时指定一个等待超时时间,这样可以有效地实现阻塞状态下同时等待两种类型的事件。
我们可以利用阻塞态进行相应的延时操作提高系统的效率,原来使用for循环或者while循环进行延时,处理器进行的都是很多无用的操作。使用阻塞态进行延时时,处理器可以处理其他任务。从而提高了系统的效率。调用vTaskDelay() API 函数来代替空循环即可。
void vTaskDelay( portTickType xTicksToDelay );
xTicksToDelay 延迟多少个心跳周期。调用该延迟函数的任务将进入阻塞态,经延迟指定的心跳周期数后,再转移到就绪态。
举个例子,当某个任务调用vTaskDelay( 100 )时,心跳计数值为10,000,则该任务将保持在阻塞态,直到心跳计数计到10,100。常数 portTICK_RATE_MS 可以用来将以毫秒为单位的时间值转换为以心跳周期为单位的时间值。
<span style="color: #&挂起状态&(suspended))
。让一个任务进入挂起状态的唯一办法就是调用vTaskSuspend() API 函数;而把一个挂起状态的任务唤醒的唯一途径就是调用vTaskResume() 或vTaskResumeFromISR() API 函数。大部分应用程序都不需要进入挂起状态。不在详细赘述。
<span style="color: #&就绪状态&(ready)
任务处于非运行状态,但既没有阻塞也没有挂起,则这个任务处于就绪(ready,准备或就绪)状态。处于就绪态的任务能够被运行,但是没有运行。当前状态的任务已经具有了所有可执行的条件,只等待处理器将他进行调度。
其他延时函数:
vTaskDelayUntil() API 函数的参数就是用来指定任务离开阻塞态进入就绪态那一刻的精确心跳计数值。API 函数vTaskDelayUntil()可以用于实现一个固定执行周期的需求(当你需要让你的任务以固定频率周期性执行的时候)。由于调用此函数的任务解除阻塞的时间是绝对时刻,比起相对于调用时刻的相对时间更精确(即比调用vTaskDelay()可以实现更精确的周期性)。
阅读(...) 评论()FreeRTOS调度器是如何执行的,SysTick中断中又干了啥 - 嵌入式系统编程 -
电子工程世界-论坛
后使用快捷导航没有帐号?
请完成以下验证码
查看: 1685|回复: 3
FreeRTOS调度器是如何执行的,SysTick中断中又干了啥
在线时间353 小时
E金币729枚
TA的帖子TA的资源
一粒金砂(高级), 积分 303, 距离下一级还需 197 积分
一粒金砂(高级), 积分 303, 距离下一级还需 197 积分
最近入门RTOS,首先看书了解了合作式调度器的应用,其基本思想是在主循环中不断执行调度函数,在SysTick中断中更新任务状态,程序我也大致看懂了。之后到了入门FreeRTOS遇到了困难,利用了stm32的官方例程,原理上的东西大致懂了,可在程序中是如何实现的呢,C语言障碍,没看懂。
首先是调度函数,函数函数是如何执行的呢?如下图,新建任务后执行调度函数,为什么没用循环,调度函数是一直运行的吗?在其C语言程序中哪里可见执行任务的代码?
SysTick中断中主要更新了任务状态,它是怎么轮询每个任务的呢,在中断中决定了下一个执行的任务吗?
可能我问的任务比较繁琐,大侠们如果有空回答重点即可,程序我还是慢慢凿吧,谢谢
在线时间267 小时
芯币3315枚
TA的帖子TA的资源
纯净的硅(初级), 积分 598, 距离下一级还需 202 积分
纯净的硅(初级), 积分 598, 距离下一级还需 202 积分
对于绝大多数人来说,学习rtos主要是学习例子和应用,而不是开始就纠缠细节。
在线时间523 小时
TA的帖子TA的资源
纯净的硅(初级), 积分 796, 距离下一级还需 4 积分
纯净的硅(初级), 积分 796, 距离下一级还需 4 积分
你没看到每个任务里while循环最后有个延时的函数吗,在那个函数里,系统就要查找所有已就绪的任务里优先级最高的那个,然后就通过调度器把任务切换到那个任务里了
这个C语言没看太懂,延时函数中调度函数就直接切换任务了吗,任务函数难道不总是在SysTick中断中切换的吗
我昨天大致理解了在不用delay函数的任务切换,与合作式调度器基本相似,只是不需要在main函数中不断查询&
在线时间353 小时
E金币729枚
TA的帖子TA的资源
一粒金砂(高级), 积分 303, 距离下一级还需 197 积分
一粒金砂(高级), 积分 303, 距离下一级还需 197 积分
你没看到每个任务里while循环最后有个延时的函数吗,在那个函数里,系统就要查找所有已就绪的任务里优先级 ...
这个C语言没看太懂,延时函数中调度函数就直接切换任务了吗,任务函数难道不总是在SysTick中断中切换的吗
我昨天大致理解了在不用delay函数的任务切换,与合作式调度器基本相似,只是不需要在main函数中不断查询调度器然后执行函数
荣誉会员勋章
曾经的版主且威望大于2000,或对EEWORLD论坛有突出贡献的坛友
EEWORLD 官方微信
EE福利 唾手可得
Powered byFreeRTOS串口打印任务状态的疑问|FreeRTOS - 安富莱电子论坛 - Powered by phpwind
查看完整版本: [--
FreeRTOS串口打印任务状态的疑问
&&&&&&&&&&老大的教程看了,都能看懂,测试也都通过。但是我尝试将定时器的初始化放在了启动任务调度器或者创建任务之前,则定时器中断无法进入。后来我又单开了一个任务专门打印任务信息。只要优先级设置比其余两个任务低,则定时器同样无法进入中断。&&&&&&&&&&请问老大,OS在使用定时器中断时要特别注意些啥?
这个是什么定时器,是用于统计任务执行情况的那个高分辨率定时器么。
:这个是什么定时器,是用于统计任务执行情况的那个高分辨率定时器么。&#160;( 00:53)&#160;我用的是TIM2
:我用的是TIM2&#160;( 11:49)&#160;没什么要特别注意的,是不是你的定时器配置有问题,
:没什么要特别注意的,是不是你的定时器配置有问题,&#160;( 13:38)&#160;配置没问题啊,逻辑测试正常。放系统初始化的位置非得注意下才行
:这个是什么定时器,是用于统计任务执行情况的那个高分辨率定时器么。 &&&&&&&&&&老大的教程看了,都能看懂,测试也都通过。但是我尝试将定时器的初始化放在了启动任务调度器或者创建任务之前,则定时器中断无法进入。后来我又单开了一个任务专门打印任务信息。只要优先级设置比其余两个任务低,则定时器同样无法进入中断。&&&&&&&&&&请问老大,OS在使用定时器中断时要特别注意些啥?
:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;老大的教程看了,都能看懂,测试也都通过。但是我尝试将定时器的初始化放在了启动任务调度器或者创建任务之前,则定时器中断无法进入。后来我又单开了一个任务专门打印任务信息。只要优先级设置比其余两个任务低, ..&#160;( 19:38)&#160;老大,工程文件已经上传,你帮忙测试看看。打印调试信息任务的优先级如果设置高于其他任务就有影响了。
:没什么要特别注意的,是不是你的定时器配置有问题,&#160;( 13:38)&#160;老大工程文件我已经上传了,还得麻烦你看下
:老大工程文件我已经上传了,还得麻烦你看下&#160;( 22:14)&#160;注意这个优先级分组,一定要在main函数中优先设置,且使用优先级分组4,在教程中的很多地方我都着重强调了这个问题,这个问题要注意下。=================================================================你在进入到打印任务时,设置了优先级分组为0,默认优先级分组就是0,其实不用再设置。&&&&NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);&&修改你的工程,在main函数中优先设置。
:注意这个优先级分组,一定要在main函数中优先设置,且使用优先级分组4,在教程中的很多地方我都着重强调了这个问题,这个问题要注意下。=================================================================你在进入到打印任务时,设置了优先级分组为0,默认优先级分组就是0, ..&#160;( 01:06)&#160;为什么要最先配置分组,而且是否是Group4又有什么关系呢?如果都为4,那不就是全都为抢占优先级了!
:为什么要最先配置分组,而且是否是Group4又有什么关系呢?如果都为4,那不就是全都为抢占优先级了!&#160;( 09:04)&#160;教程里面对于这些问题有详细讲解,看一下。我写的这个教程有好多细节问题,都在教程上面进行了说明,看的时候可能没有太注意,使用的时候问题就出来了。
:教程里面对于这些问题有详细讲解,看一下。我写的这个教程有好多细节问题,都在教程上面进行了说明,看的时候可能没有太注意,使用的时候问题就出来了。&#160;( 09:07)&#160;教程我看了,在12.2这一节中写了:强烈推荐用户将 Cortex-M3 内核的 STM32F103 和 Cortex-M4 内核的 STM32F407 以及STM32F429 的 NVIC 优先级分组设置为 4,即:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);这样中断优先级的管理将非常方便。 这个也是官方强烈建议的。 此函数在 bsp_Init 中第一个被调用。只有讲到这些,但并没有讲出原因呀,老大!
:教程我看了,在12.2这一节中写了:强烈推荐用户将 Cortex-M3 内核的 STM32F103 和 Cortex-M4 内核的 STM32F407 以及STM32F429 的 NVIC 优先级分组设置为 4,即:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);这样中断优先级的管理将非常方便。 这个也是官方强烈建议的。 此函 .. ( 09:22) 1. 配置为0,你的中断服务程序将没有实时性可言,重要中断服务程序由于非重要中断程序的阻塞无法及时响应。把这些中断的抢占式优先级区分出来才有实时性。 2.中断优先级管理方便。 3. 保证PendSV中断是最低优先级的。这样才能保证发生中断嵌套的时候,正确执行任务切换,这一点非常非常重要。 等等方面的原因。就讨论这么多吧,剩下你检查下你程序的问题。
:1. 配置为0,你的中断服务程序将没有实时性可言,重要中断服务程序由于非重要中断程序的阻塞无法及时响应。把这些中断的抢占式优先级区分出来才有实时性。2.中断优先级管理方便。.......&#160;( 09:58)&#160;好的
:1. 配置为0,你的中断服务程序将没有实时性可言,重要中断服务程序由于非重要中断程序的阻塞无法及时响应。把这些中断的抢占式优先级区分出来才有实时性。2.中断优先级管理方便。.......&#160;( 09:58)&#160;老大,已经按你说的修改了,实际测试一个样儿!优先级调试时也看过了。都没问题。
:1. 配置为0,你的中断服务程序将没有实时性可言,重要中断服务程序由于非重要中断程序的阻塞无法及时响应。把这些中断的抢占式优先级区分出来才有实时性。2.中断优先级管理方便。.......&#160;( 09:58)&#160;郁闷了&&&&&&&&&&&&&&&&&&&&&&&&
:1. 配置为0,你的中断服务程序将没有实时性可言,重要中断服务程序由于非重要中断程序的阻塞无法及时响应。把这些中断的抢占式优先级区分出来才有实时性。2.中断优先级管理方便。.......&#160;( 09:58)&#160;老大,调试了下,我知道问题了!低级错误,我把打印调试任务的优先级设置成了最高,但是串口的初始化却在串口任务的while(1)外面,所以一直死在等待USART_FLAG上。太低级了,以后跑系统有个好习惯,封装个BSP_Init放在main函数的第一句。吃亏了!
:老大,调试了下,我知道问题了!低级错误,我把打印调试任务的优先级设置成了最高,但是串口的初始化却在串口任务的while(1)外面,所以一直死在等待USART_FLAG上。太低级了,以后跑系统有个好习惯,封装个BSP_Init放在main函数的第一句。吃亏了!&#160;( 21:17)&#160;别看这个小错误,找到问题了还是有些成就感的
:[表情]别看这个小错误,找到问题了还是有些成就感的&#160;( 00:56)&#160;哈哈
查看完整版本: [--
Powered by
Time 0.130007 second(s),query:2 Gzip enabled查看: 2185|回复: 16
FreeRTOS使用delay_ms()作为系统延时、任务调度
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
请教一个问题,最近在学习使用FreeRTOS,想像原子一样在delay.c里添加RTOS的系统支持,即使用tick时钟作延时。现在有几个问题:
1、在启动任务调度器前,如果调用了delay_ms()或者printf()(LCD_Init函数会用到这两个函数),系统就会进入HardFault_Handler状态
2、但当启动了vTaskStartScheduler()调度器后,延时和串口函数都能正常工作
3、相比ucosii,在初始化os前,调用了延时和串口打印却等正常运转。。。
以上初步怀疑是FreeRTOS的中断处理没配置好,系统的源代码、某开发板的FreeRTOS教程也看过好几遍,没找到办法。。
支招!!!
附:自己移植的工程代码,使用的是f103
22:33 上传
点击文件名下载附件
337.08 KB, 下载次数: 104
这是你没移植好延时。跟FreeRTOS没关系。给你发一份我们自己F429的的FreeRTOS版本的SYSTEM文件夹,你可以参考一下。F429用的HAL库。
主题帖子精华
在线时间1171 小时
这是你没移植好延时。跟FreeRTOS没关系。给你发一份我们自己F429的的FreeRTOS版本的SYSTEM文件夹,你可以参考一下。F429用的HAL库。
10:16 上传
点击文件名下载附件
8.88 KB, 下载次数: 188
主题帖子精华
在线时间939 小时
调度器没启动前是不能调用系统延时的,因为调度器在启动时才开始初始化SysTick,也就是说系统定时器在调度器启动后才开始运行
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
调度器没启动前是不能调用系统延时的,因为调度器在启动时才开始初始化SysTick,也就是说系统定时器在调度 ...
这样说来,串口中断处理等操作也是要调度器启动了才能开始运行?
主题帖子精华
在线时间939 小时
这样说来,串口中断处理等操作也是要调度器启动了才能开始运行?
根据FreeRTOS的设计,几乎可以认为系统没开跑前系统API都不能用
因为不管是信号量、队列、互斥锁还是任务结构体,使用前必须要创建,创建时一定会调用系统自带的内存管理,例如 heap_4只要调用了内存分配,必然会调用 vTaskSuspendAll(); 跟 xTaskResumeAll();
xTaskResumeAll() 最后调用了 taskEXIT_CRITICAL();
[AppleScript] 纯文本查看 复制代码void vPortExitCritical( void )
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
portENABLE_INTERRUPTS();
}仔细看有一个操作系统的嵌套层数计数器进行了自减操作:uxCriticalNesting--;
这个变量在操作系统没开跑前的初始值并不是0: static UBaseType_t uxCriticalNesting = 0
问题就出在这了,因为初始值并不是0,所以 portENABLE_INTERRUPTS(); 是不会被执行的!!!
portENABLE_INTERRUPTS() 是啥?这是使能系统中断的接口,内存分配前系统屏蔽了中断,在操作系统启动后,内存分配完毕会重新开启中断
反之,在FreeRTOS的调度器没启动前,只要你调用了系统的内存管理,中断就会被关闭,而且关闭之后不会被打开!
我们一般都在串口中断里面调用了信号量API来通知APP,但信号量创建后中断就被关闭了,如果串口中断也在操作系统的管辖范围内
那么意味着串口中断也被屏蔽了,你说还能正常使用么?
生活不只有眼前的苟且,还有你看不懂的诗和永远到不了的远方!
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
这是你没移植好延时。跟FreeRTOS没关系。给你发一份我们自己F429的的FreeRTOS版本的SYSTEM文件夹,你可以参 ...
十分感谢,还没看过F429的资料,想不到已经做出来了
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
根据FreeRTOS的设计,几乎可以认为系统没开跑前系统API都不能用
因为不管是信号量、队列、互斥锁还是任 ...
原来是自己没有深入理解FreeRTOS,感谢版主耐心回答
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
的提示和解答,今天再修改了一下delay.c函数,在SysTick_Handler()里加入系统启动判断:
[AppleScript] 纯文本查看 复制代码//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
#ifdef OS_CRITICAL_METHOD
//如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
OSIntEnter();
//进入中断
OSTimeTick();
//调用ucos的时钟服务程序
OSIntExit();
//触发任务切换软中断
#ifdef FreeRTOS
if(OSRunning==1) //系统在运行
xPortSysTickHandler();
这样系统就能在没有启动调度器的情况下,调用延时和串口打印函数也能正常运行。
新的问题又来了:
USART1_IRQHandler()里模仿ucos调用了taskENTER_CRITICAL_FROM_ISR(),taskEXIT_CRITICAL_FROM_ISR()作为中断屏蔽,追踪源码,是一段汇编,,,
[AppleScript] 纯文本查看 复制代码//taskENTER_CRITICAL_FROM_ISR()
__asm uint32_t ulPortSetInterruptMask( void )
mrs r0, basepri
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r1
/*-----------------------------------------------------------*/
//portCLEAR_INTERRUPT_MASK_FROM_ISR()
__asm void vPortClearInterruptMask( uint32_t ulNewMask )
msr basepri, r0
/*-----------------------------
能指点迷津?
附:修正后的工程
19:32 上传
点击文件名下载附件
337.33 KB, 下载次数: 230
主题帖子精华
在线时间939 小时
感谢@zuozhongkai @FreeRTOS 的提示和解答,今天再修改了一下delay.c函数,在SysTick_Handler()里加入系统 ...
关于 configMAX_SYSCALL_INTERRUPT_PRIORITY 和 BASEPRI 寄存器的用法请参考我的另一个帖子:
帖子中间部分对这两者进行了一个比较详细的解释
生活不只有眼前的苟且,还有你看不懂的诗和永远到不了的远方!
主题帖子精华
中级会员, 积分 278, 距离下一级还需 222 积分
在线时间91 小时
请问楼主问题解决了吗?
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
请问楼主问题解决了吗?
嗯?是指哪方面问题?
主题帖子精华
中级会员, 积分 278, 距离下一级还需 222 积分
在线时间91 小时
嗯?是指哪方面问题?
没启用调度前delay_ms和串口不能打印的问题。
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
没启用调度前delay_ms和串口不能打印的问题。
解决了,工程代码已共享。代码在第8楼
不过启动任务调度前的delay_ms()可能会不太准
主题帖子精华
中级会员, 积分 278, 距离下一级还需 222 积分
在线时间91 小时
本帖最后由 wangjun110 于
18:03 编辑
解决了,工程代码已共享。代码在第8楼
不过启动任务调度前的delay_ms()可能会不太准
嗯。看到了,我很喜欢你的代码风格。
你说的延时可能不太准,能否解释下原因呢?呵呵
(27.98 KB, 下载次数: 2)
17:48 上传
(53.57 KB, 下载次数: 2)
18:03 上传
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
嗯。看到了,我很喜欢你的代码风格。
你说的延时可能不太准,能否解释下原因呢?呵呵
1、delay_ms 函数里有一个 OSRunning==1 的判断,它是启用了任务调度函数才为真。在调度使用前,延时都用 delay_us 来实现。比如说 delay_ms(2) 实际就是 delay_us(2000) 。
2、中断使用的4组,4位抢占优先级,0位响应优先级。然后抢占优先级的范围是0~2^4-1,就是0~15。数值越小越优先,所以设一个15
主题帖子精华
中级会员, 积分 278, 距离下一级还需 222 积分
在线时间91 小时
1、delay_ms 函数里有一个 OSRunning==1 的判断,它是启用了任务调度函数才为真。在调度使用前,延时都用 ...
多谢谢指教,从回贴的时间不难看出你是8点上班然后5:30下班,我猜的没错吧。
主题帖子精华
高级会员, 积分 991, 距离下一级还需 9 积分
在线时间374 小时
多谢谢指教,从回贴的时间不难看出你是8点上班然后5:30下班,我猜的没错吧。
哈哈,这都可以看出来。
Powered byFreeRTOS的任务优先级配置原来这么简单
FreeRTOS的任务优先级配置原来这么简单
IT生活论坛
上一篇文章说到了中断优先级的配置,这里针对stm32cubemx+freertos中任务优先级的配置进行说明。由于这里freertos使用的是CMSIS-OS的封装而不是原版的freertos。这里对优先级的封装进行了控制只有7个选择。cmsis-os.h中优先级的定义Freertos任务配置页面的参数设置项但是要注意在ARM后期发布的cmsis-os2中对封装的优先级进行了修改,在原来每级的基础上有细分了7个优先级,这样就可以避免在系统任务超过7个时有多个任务使用相同的优先级。在软件里默认配置freertos为抢占式调度,学习抢占式调度要掌握的最关键一点是:每个任务都被分配了不同的优先级,抢占式调度器会获得就绪列表中优先级最高的任务,并运行这个任务。当不同的任务有这相同的优先级时,只有在系统滴答定时器(SysTick)中断发生时,对相同优先级的任务轮转执行。对于中断优先级和任务优先级,简单的说,这两个之间没有任何关系,不管中断的优先级是多少,中断的优先级永远高于任何任务的优先级,即任务在执行的过程中,中断来了就开始执行中断服务程序。看完这些你是不是感觉都懵逼了,这就对了,我当初看的时候也是这样。加油多看看就明白了。
本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。
IT生活论坛
百家号 最近更新:
简介: 谈生活 谈理想 谈人生什么都谈 来这里看我
作者最新文章}

我要回帖

更多关于 freertos任务切换解析 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信