一些有意思的专用名词解释:
- 饿死(starved):饿死常常出现在多任务执行的情况,一个最简单的例子就是。任务2的优先级比任务1的优先级高,并且总是可运行,因此任务2是唯一一个一直处于运行态的任务。而任务1不可能进入运行态。这种情况就是任务1被任务2饿死了。
一、在应用程序中,FreeRTOS如何为各任务分配处理时间
每个任务的运行时间都以时间片为单位。调度器需要在每个时间片的结束时刻进入心跳中断函数,来决定下一个时间片应该运行什么函数。而心跳中断频率由FreeRTOSConfig.h 中的编译时配置常量 configTICK_RATE_HZ 进行配置。比如说,如果 configTICK_RATE_HZ 设为 100(HZ),则时间片长度为 10ms
二、在任意给定时刻,FreeRTOS如何选择任务投入运行
在任意给定时刻,FreeRTOS执行处于就绪状态的任务,如果有多个就绪状态任务,则根据任务优先级来判断执行哪一个。如果此时没有就绪状态的任务,则执行定义好的空任务函数。
三、任务优先级如何影响系统行为
低优先级号表示任务的优先级低,优先级号0表示最低优先级。有效的优先级号范围从0到(configMAX_PRIORITES – 1) ,当两个任务都可以被执行(ready)时,高优先级的任务会被执行。FreeRTOS也可以设置同优先级任务。
四、任务存在哪些状态
由于只有一个处理器来执行程序,则任意时刻只有一个程序在运行。所有的任务都有基本的两个状态:运行状态和非运行状态(休眠)。为了使不同优先级的任务都能运行,不至于出现谁饿死谁的情况,将“非运行状态”扩充为不同状态,如阻塞、挂起等,以便于实现任务调度。下面来逐一解释各个状态
- 阻塞状态(blocked):任务可以进入阻塞以等待以下另种不同类型的时间
- 定时(时间相关)事件——这类事件可以是延迟到期或是绝对时间到点。比如说某个任务可以进入阻塞态以延迟10ms,可以程序设定等待超时时间。
- 同步事件——源于其他任务或中断的事件。比如说,某个任务可以进入阻塞态以等待队列中有数据到来。同步事件囊括了所有板级范围内的事件类型。
- 挂起状态(suspended):进入挂起状态的唯一办法是调用vTaskSuspend()API函数;唤醒任务的唯一途径是调用vTaskResume()或vTaskResumeFromlSR()API函数。大多数应用程序不会用到挂起状态
- 就绪状态(ready):任务处于非运行态,但是既没有阻塞也没有挂起。处于就绪态的任务能够被运行
完整的状态转移图:
五、基础使用与配置
-
如何实现一个任务
1)调用xTaskCreate()创建任务,主要是对任务的各项属性进行配置portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask );
2)创建任务函数实体,这是代码实际执行的函数
void vTask1( void *pvParameters ) { const char *pcTaskName = "Task 1 is running\r\n"; volatile unsigned long ul; /* 和大多数任务一样,该任务处于一个死循环中。 */ for( ;; ) { /* Print out the name of this task. */ vPrintString( pcTaskName ); /* 延迟,以产生一个周期 */ for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) { /* 这个空循环是最原始的延迟实现方式。在循环中不做任何事情。后面的示例程序将采用 delay/sleep函数代替这个原始空循环。 */ } } }
-
如何创建一个或多个任务的实例
通过void *pvParameters的参数传递,来使功能相同的函数,通过不同参数的传入来实现不同的用户需求 -
如何改变一个已创建任务的优先级
xTaskCreate() API 函数的参数 uxPriority 为创建的任务赋予了一个初始优先级。这
个优先级可以在调度器启动后调用 vTaskPrioritySet() API 函数进行修改。 -
如何删除任务
void vTaskDelete( xTaskHandle pxTaskToDelete );
-
空闲任务何时运行,可以用来干什么
空闲任务拥有最低优先级,以保证其不会妨碍具有更高优先级的应用任务进入运行态。空闲任务通常为延时很小的循环。用来在CPU没有代码运行时,让CPU有事可干