FreeRTOS学习笔记(二)

优先级抢占式调度
先上图
在这里插入图片描述
任务的四个状态
运行:在就绪态里优先级最高的任务
阻塞:等待触发条件(时间,中断或其他任务触发),触发后进入就绪态
就绪:就绪后,由优先级决定是否运行
挂起:在运行,阻塞和就绪态时都可以将任务挂起,挂起后系统不会去管这些任务

系统永远让最高优先级运行,当不止一个任务是最高优先级时,系统让这些任务轮流执行,执行的时间都一样,而这个时间的确定是由configTICK_RATE_HZ设置
例如

configTICK_RATE_HZ = 10Hz;	//那么TICK就是100ms

TICK周期的精度依赖于系统的时钟频率

空闲任务
当所有任务都阻塞时,没任务运行了咋办?系统会创建一个空闲任务(优先级最低),来保证一直有一个任务在运行,优先级最低保证了其他任务就绪后能进入运行态,

空闲任务钩子函数(hook)

void vApplicationIdleHook( void ); 

通过FreeRTOSConfig.h 中的配置常量configUSE_IDLE_HOOK 定义为1,启用函数
在这里插入图片描述
它在空闲任务中循环执行,可以在函数内添加计时来查看系统的空闲时间,判断系统利用率,或者将系统设置为低功耗,可以根据你自己的需要去设置,但是有条件的:
它不能被阻塞和挂起
在任务被vTaskDelete() API删除后,空闲任务要去回收资源,所以要求它能快速返回

例:

/* 定义一个变量去计数*/
unsigned long ulIdleCycleCount = 0UL;  
/* 空闲钩子函数必须命名为vApplicationIdleHook(),无参数也无返回值 */
 void vApplicationIdleHook( void ) 
 { 
 	ulIdleCycleCount++; 
 } 

延时函数

vTaskDelay() API

 void vTaskDelay( portTickType xTicksToDelay ); 
 //xTicksToDelay  :就是TICK周期

利用这个延时来让任务进入阻塞,让出运行位置,来执行其他任务,这个延时时间段是从调用vTaskDelay()开始到切出阻塞态的时间;相对延时
在这里插入图片描述
借用大佬图片

vTaskDelayUntil() API

void vTaskDelayUntil( portTickType * pxPreviousWakeTime, portTickType xTimeIncrement ); 

也是阻塞延时,但时间段不一样,任务开始到执行到下一次任务执行的时间
这样任务就可以按固定周期执行,在任务中执行中断,任务的执行时间也不会变,增加的中断处理时间,延时时间就减小,整体的时间还是没变
在这里插入图片描述
借用大佬图片

vTaskPrioritySet() API

void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority ); 
// xTaskHandle pxTask:任务句柄
//unsigned portBASE_TYPE uxNewPriority :优先级
//任务修改自己本身的优先级时,句柄为NULL

在调度器启动后去更改任务的优先级

uxTaskPriorityGet() API

unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ); 

查询任务的优先级

vTaskDelete() API

void vTaskDelete( xTaskHandle pxTaskToDelete ); 
//xTaskHandle pxTaskToDelete:句柄
//删自己还是NULL

任务创建
创建两个简单的任务

int main( void ) 
{
	xTaskCreate(	Task1,		//看作函数名就好
					"Task 1",	//任务名
					1000,		//设定任务的栈空间
					NULL,		//传入函数的指针(void*),这里没用
					2,			//优先级
					NULL );		//句柄,这里没用
	xTaskCreate( Task2, "Task 2", 1000, NULL, 1, NULL );	//0的优先级最低
	vTaskStartScheduler();	//开启调度器					
	
	while(1);
}
void task1(void *pvParameters)  //LED0亮灭
{ 
	while(1) 
	{ 
	       LED0=~LED0; 
	       vTaskDelay(500); 
	} 
}       
 
//LED1 任务函数 
void task2(void *pvParameters) 	//LED1亮灭
{ 
	while(1) 
	 { 
        LED1=0; 
         vTaskDelay(200); 
         LED1=1; 
         vTaskDelay(800); 
	 } 
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mapoplus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值