lol轮询模式任务调度和抢占式任务调度有什么区别

转:第14章
任务调度—抢占式,时间片和合作式 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
转:第14章
任务调度—抢占式,时间片和合作式
09:55:28  
本章教程为大家将介绍FreeRTOS操作系统支持的任务调度方式:抢占式,时间片和合作式,这部分算是FreeRTOS操作系统的核心了。对于初学者来说,要一下子就能够理解这些比较困难,需要多花些时间把这些基本概念搞清楚,然后阅读下源码,深入理解实现方法。
& & 本章教程配套的例子含Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407以及F429。
14.1 关于合作式调度器的特别说明
14.2 FreeRTOS支持的调度方式
14.3 什么是调度器
14.4 抢占式调度器
14.5 时间片调度器
14.6 实验例程说明
14.7& && &总结
14.1&&关于合作式调度器的特别说明
& & 关于合作式调度器,官方进行了特别的说明,说明如下:http://www.freertos.org/taskandcr.html
意思是说合作式调度主要用在资源有限的设备上面,现在已经很少使用了。出于这个原因,后面的FreeRTOS版本中不会将合作式调度删除掉,但也不会再进行升级了。
& & 使用STM32F103,F407和F429的资源足够多,所以此次教程不再制作合作式调度相关的说明和例子。
14.2&&FreeRTOS支持的调度方式
& &&&FreeRTOS操作系统支持三种调度方式:抢占式调度,时间片调度和合作式调度。实际应用主要是抢占式调度和时间片调度,合作式调度用到的很少。
(1)抢占式调度
& & 每个任务都有不同的优先级,任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的API函数,比如vTaskDelay。
(2)时间片调度
& & 每个任务都有相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式的API函数,比如vTaskDelay,才会执行同优先级任务之间的任务切换。
09:55:50  
14.3 什么是调度器
& && &简单的说,调度器就是使用相关的调度算法来决定当前需要执行的任务。所有的调度器有一个共同的特性:
A.&&调度器可以区分就绪态任务和挂起任务(由于延迟,信号量等待,邮箱等待,事件组等待等原因而使得任务被挂起)。
B.&&调度器可以选择就绪态中的一个任务,然后激活它(通过执行这个任务)。当前正在执行的任务是运行态的任务。
C.&&不同调度器之间最大的区别就是如何分配就绪态任务间的完成时间。
& && &嵌入式实时操作系统的核心就是调度器和任务切换,调度器的核心就是调度算法。任务切换的实现在不同的嵌入式实时操作系统中区别不大,基本相同的硬件内核架构,任务切换也是相似的。调度算法就有些区别了。下面我们主要了解一下抢占式调度器和时间片调度器。
09:56:05  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
14.4 抢占式调度器
14.4.1 抢占式调度器基本概念
& & 在实际的应用中,不同的任务需要不同的响应时间。例如,我们在一个应用中需要使用电机,键盘和LCD显示。电机比键盘和LCD需要更快速的响应,如果我们使用合作式调度器或者时间片调度,那么电机将无法得到及时的响应,这时抢占式调度是必须的。
& & 如果使用了抢占式调度,最高优先级的任务一旦就绪,总能得到CPU的控制权。比如,当一个运行着的任务被其它高优先级的任务抢占,当前任务的CPU使用权就被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权并运行。又比如,如果中断服务程序使一个高优先级的任务进入就绪态,中断完成时,被中断的低优先级任务被挂起,优先级高的那个任务开始运行。
& & 使用抢占式调度器,使得最高优先级的任务什么时候可以得到CPU的控制权并运行是可知的,同时使得任务级响应时间得以最优化。
& & 总的来说,学习抢占式调度要掌握的最关键一点是:每个任务都被分配了不同的优先级,抢占式调度器会获得就绪列表中优先级最高的任务,并运行这个任务。
09:56:21  
14.4.2 FreeRTOS抢占式调度器的实现
& & 如果用户在FreeRTOS的配置文件FreeRTOSConfig.h中禁止使用时间片调度,那么每个任务必须配置不同的优先级。当FreeRTOS多任务启动执行后,基本会按照如下的方式去执行:
u 首先执行的最高优先级的任务Task1,Task1会一直运行直到遇到系统阻塞式的API函数,比如延迟,事件标志等待,信号量等待,Task1任务会被挂起,也就是释放CPU的执行权,让低优先级的任务得到执行。
u FreeRTOS操作系统继续执行任务就绪列表中下一个最高优先级的任务Task2,Task2执行过程中有两种情况:
& & l Task1由于延迟时间到,接收到信号量消息等方面的原因,使得Task1从挂起状态恢复到就绪态,在抢占式调度器的作用下,Task2的执行会被Task1抢占。
& & l Task2会一直运行直到遇到系统阻塞式的API函数,比如延迟,事件标志等待,信号量等待,Task2任务会被挂起,继而执行就绪列表中下一个最高优先级的任务。
u 如果用户创建了多个任务并且采用抢占式调度器的话,基本都是按照上面两条来执行。根据抢占式调度器,当前的任务要么被高优先级任务抢占,要么通过调用阻塞式API来释放CPU使用权让低优先级任务执行,没有用户任务执行时就执行空闲任务。
下面我们通过如下的框图来说明一下抢占式调度在FreeRTOS中的运行过程,让大家有一个形象的认识。
运行条件:
u&&这里仅对抢占式调度进行说明。
u&&创建3个任务Task1,Task2和Task3。
u&&Task1的优先级为1,Task2的优先级为2,Task3的优先级为3。FreeRTOS操作系统是设置的数值越小任务优先级越低,故Task3的优先级最高,Task1的优先级最低。
u&&此框图是FreeRTOS操作系统运行过程中的一部分。
运行过程描述如下:
u 此时任务Task1在运行中,运行过程中由于Task2就绪,在抢占式调度器的作用下任务Task2抢占Task1的执行。Task2进入到运行态,Task1由运行态进入到就绪态。
u 任务Task2在运行中,运行过程中由于Task3就绪,在抢占式调度器的作用下任务Task3抢占Task2的执行。Task3进入到运行态,Task2由运行态进入到就绪态。
u 任务Task3运行过程中调用了阻塞式API函数,比如vTaskDelay,任务Task3被挂起,在抢占式调度器的作用下查找到下一个要执行的最高优先级任务是Task2,任务Task2由就绪态进入到运行态。
u 任务Task2在运行中,运行过程中由于Task3再次就绪,在抢占式调度器的作用下任务Task3抢占Task2的执行。Task3进入到运行态,Task2由运行态进入到就绪态。
上面就是一个简单的不同优先级任务通过抢占式调度进行任务调度和任务切换的过程。
09:56:37  
14.5 时间片调度器
14.5.1 时间片调度器基本概念
& & 在小型的嵌入式RTOS中,最常用的的时间片调度算法就是Round-robin调度算法。这种调度算法可以用于抢占式或者合作式的多任务中。另外,时间片调度适合用于不要求任务实时响应的情况。
& & 实现Round-robin调度算法需要给同优先级的任务分配一个专门的列表,用于记录当前就绪的任务,并为每个任务分配一个时间片(也就是需要运行的时间长度,时间片用完了就进行任务切换)。
14.5.2 FreeRTOS时间片调度器的实现
& & 在FreeRTOS操作系统中只有同优先级任务才会使用时间片调度,另外还需要用户在FreeRTOSConfig.h文件中使能宏定义:
& && && && &#define configUSE_TIME_SLICING& & 1
& & 默认情况下,此宏定义已经在FreeRTOS.h文件里面使能了,用户可以不用在FreeRTOSConfig.h文件中再单独使能。
下面我们通过如下的框图来说明一下时间片调度在FreeRTOS中的运行过程,让大家有一个形象的认识。
运行条件:
(1)这里仅对时间片调度进行说明。
(2)创建4个同优先级任务Task1,Task2,Task3和Task4。
(3)每个任务分配的时间片大小是5个系统时钟节拍。
运行过程描述如下:
(1)先运行任务Task1,运行够5个系统时钟节拍后,通过时间片调度切换到任务Task2。
(2)任务Task2运行够5个系统时钟节拍后,通过时间片调度切换到任务Task3。
(3)任务Task3在运行期间调用了阻塞式API函数,调用函数时,虽然5个系统时钟节拍的时间片大小还没有用完,此时依然会通过时间片调度切换到下一个任务Task4。(注意,没有用完的时间片不会再使用,下次任务Task3得到执行还是按照5个系统时钟节拍运行)
(4)任务Task4运行够5个系统时钟节拍后,通过时间片调度切换到任务Task1。
上面就是一个简单的同优先级任务通过时间片调度进行任务调度和任务切换的过程。
09:56:55  
14.6 实验例程说明
14.6.1 STM32F103开发板实验
配套例子:
& & V4-308_FreeRTOS实验_时间片调度
实验目的:
& & 1.& &&&学习FreeRTOS的时间片调度。
& & 2.& &&&使用FreeRTOS的时间片调度,仅需在FreeRTOSConfig.h文件中使能如下宏定义:
& && &&&#defineconfigUSE_TIME_SLICING& && &1
& && &&&不配置也没有关系,因为FreeRTOS.h文件中默认已经使能了。
实验内容:
& & 1.& &&&K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
& & 2.& &&&任务vTaskLED和任务vTaskMsgPro具有相同的优先级。
& & 3.& &&&各个任务实现的功能如下:
& && && && &&&vTaskUserIF任务& &:按键消息处理。
& && && && &&&vTaskLED任务& &&&:LED闪烁。
& && && && &&&vTaskMsgPro任务 :消息处理,这里是用作LED闪烁。
& && && && &&&vTaskStart任务& & :启动任务,也是最高优先级任务,这里实现按键扫描。
09:57:19  
FreeRTOS的配置:
& & FreeRTOSConfig.h文件中的配置如下:
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include &stdint.h&
extern volatile uint32_t ulHighFrequencyTimerT
#define configUSE_PREEMPTION
#define configUSE_IDLE_HOOK
#define configUSE_TICK_HOOK
#define configCPU_CLOCK_HZ
( ( unsigned long )
#define configTICK_RATE_HZ
( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES
#define configMINIMAL_STACK_SIZE
( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE
( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN
#define configUSE_TRACE_FACILITY
#define configUSE_16_BIT_TICKS
#define configIDLE_SHOULD_YIELD
#define configUSE_TIME_SLICING
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS
#define configUSE_STATS_FORMATTING_FUNCTIONS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
(ulHighFrequencyTimerTicks = 0ul)
#define portGET_RUN_TIME_COUNTER_VALUE()
ulHighFrequencyTimerTicks
//#define portALT_GET_RUN_TIME_COUNTER_VALUE
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet
#define INCLUDE_uxTaskPriorityGet
#define INCLUDE_vTaskDelete
#define INCLUDE_vTaskCleanUpResources
#define INCLUDE_vTaskSuspend
#define INCLUDE_vTaskDelayUntil
#define INCLUDE_vTaskDelay
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS
__NVIC_PRIO_BITS
#define configPRIO_BITS
/* 15 priority levels */
/* The lowest interrupt priority that can be used in a call to a &set priority&
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.
DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
09:57:46  
几个重要选项说明:
1、#define configUSE_PREEMPTION& && &&&1
& && && & 使能抢占式调度器
2、#define configCPU_CLOCK_HZ& &&&( ( unsigned long )
& && && & 系统主频72MHz。
3、#define configTICK_RATE_HZ& && && && &&&( ( TickType_t ) 1000 )
& && && & 系统时钟节拍1KHz,即1ms。
4、#define configMAX_PRIORITIES& && && & ( 5 )
& && && & 定义可供用户使用的最大优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。
5、#define configTOTAL_HEAP_SIZE& && &&&( ( size_t ) ( 17 * 1024 ) )
& && && & 定义堆大小,FreeRTOS内核,用户动态内存申请,任务栈等都需要用这个空间。
6、#define configUSE_TIME_SLICING& && &1
& && && & 使能时间片调度。
7、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY& && && & 0x01
& && && & 定义受FreeRTOS管理的最高优先级中断。简单的说就是允许用户在这个中断服务程序里面调用FreeRTOS的API的最高优先级。为了进一步说明这个宏定义的的作用,解释如下:
(1)使用CM内核的MCU,官方强烈建议将NVIC的优先级分组配置为全抢占式优先级,全部配置为抢占式优先级的好处就是方便管理。
(2)对于STM32来说,设置NVIC的优先级分组为4时,NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4)就是全部配置为抢占式优先级。又因为STM32的优先级设置仅使用CM内核8bit中的高4bit,即只能区分2^4 = 16种优先级。因此当优先级分组设置为4的时候可供用户选择抢占式优先级为0到15,共16个优先级,配置为0表示最高优先级,配置为15表示最低优先级,不存在子优先级。
(3)这里配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为0x01表示用户可以在抢占式优先级为1到15的中断里面调用FreeRTOS的API函数,抢占式优先级为0的中断里面是不允许调用的。
09:58:03  
FreeRTOS任务调试信息(按K1按键,串口打印):
上面截图中打印出来的任务状态字母B, R, D, S对应如下含义:
& & #definetskBLOCKED_CHAR& && && & ( 'B' )&&任务阻塞
& & #definetskREADY_CHAR& && && &&&( 'R' ) 任务就绪
& & #definetskDELETED_CHAR& && && &&&( 'D' )&&任务删除
& & #definetskSUSPENDED_CHAR& &( 'S' ) 任务挂起
09:58:16  
程序设计:
任务栈大小分配:
& & vTaskUserIF任务& &:2048字节
& & vTaskLED任务& &&&:2048字节
& & vTaskMsgPro任务 :2048字节
& & vTaskStart任务& & :2048字节
& & 任务栈空间是在任务创建的时候从FreeRTOSConfig.h文件中定义的heap空间中申请的
& & #defineconfigTOTAL_HEAP_SIZE& && &&&( ( size_t )( 17 * 1024 ) )
系统栈大小分配:
09:58:34  
FreeROTS初始化:
*********************************************************************************************************
函 数 名: main
功能说明: 标准c程序入口。
返 回 值: 无
*********************************************************************************************************
int main(void)
在启动调度前,为了防止初始化STM32外设时有中断服务程序执行,这里禁止全局中断(除了NMI和HardFault)。
这样做的好处是:
1. 防止执行的中断服务程序中有FreeRTOS的API函数。
2. 保证系统正常启动,不受别的中断影响。
3. 关于是否关闭全局中断,大家根据自己的实际情况设置即可。
在移植文件port.c中的函数prvStartFirstTask中会重新开启全局中断。通过指令cpsie i开启,__set_PRIMASK(1)
和cpsie i是等效的。
__set_PRIMASK(1);
/* 硬件初始化 */
bsp_Init();
/* 1. 初始化一个定时器中断,精度高于滴答定时器中断,这样才可以获得准确的系统信息 仅供调试目的,实际项
目中不要使用,因为这个功能比较影响系统实时性。
2. 为了正确获取FreeRTOS的调试信息,可以考虑将上面的关闭中断指令__set_PRIMASK(1); 注释掉。
vSetupSysInfoTest();
/* 创建任务 */
AppTaskCreate();
/* 启动调度,开始执行任务 */
vTaskStartScheduler();
如果系统正常启动是不会运行到这里的,运行到这里极有可能是用于定时器任务或者空闲任务的
heap空间不足造成创建失败,此要加大FreeRTOSConfig.h文件中定义的heap大小:
#define configTOTAL_HEAP_SIZE
( ( size_t ) ( 17 * 1024 ) )
09:58:51  
硬件外设初始化
& & 硬件外设的初始化是在bsp.c文件实现:
*********************************************************************************************************
函 数 名: bsp_Init
功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
全局变量。
返 回 值: 无
*********************************************************************************************************
void bsp_Init(void)
由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
系统时钟缺省配置为72MHz,如果需要更改,可以修改 system_stm32f10x.c 文件
/* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitUart();
/* 初始化串口 */
bsp_InitLed();
/* 初始LED指示灯端口 */
bsp_InitKey();
/* 初始化按键 */
09:59:16  
硬件外设初始化
& & 硬件外设的初始化是在bsp.c文件实现:
*********************************************************************************************************
函 数 名: bsp_Init
功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
全局变量。
返 回 值: 无
*********************************************************************************************************
void bsp_Init(void)
由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
系统时钟缺省配置为72MHz,如果需要更改,可以修改 system_stm32f10x.c 文件
/* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitUart();
/* 初始化串口 */
bsp_InitLed();
/* 初始LED指示灯端口 */
bsp_InitKey();
/* 初始化按键 */
11:01:09  
FreeRTOS任务创建:
*********************************************************************************************************
函 数 名: AppTaskCreate
功能说明: 创建应用任务
返 回 值: 无
*********************************************************************************************************
static void AppTaskCreate (void)
xTaskCreate( vTaskTaskUserIF,
/* 任务函数
&vTaskUserIF&,
/* 任务栈大小,单位word,也就是4字节 */
/* 任务参数
/* 任务优先级*/
&xHandleTaskUserIF );
/* 任务句柄
xTaskCreate( vTaskLED,
/* 任务函数
&vTaskLED&,
/* 任务栈大小,单位word,也就是4字节 */
/* 任务参数
/* 任务优先级*/
&xHandleTaskLED ); /* 任务句柄
xTaskCreate( vTaskMsgPro,
/* 任务函数
&vTaskMsgPro&,
/* 任务栈大小,单位word,也就是4字节 */
/* 任务参数
/* 任务优先级*/
&xHandleTaskMsgPro );
/* 任务句柄
xTaskCreate( vTaskStart,
/* 任务函数
&vTaskStart&,
/* 任务栈大小,单位word,也就是4字节 */
/* 任务参数
/* 任务优先级*/
&xHandleTaskStart );
/* 任务句柄
11:01:33  
四个FreeRTOS任务的实现:
*********************************************************************************************************
函 数 名: vTaskTaskUserIF
功能说明: 接口消息处理。
参: pvParameters 是在创建该任务时传递的形参
返 回 值: 无
优 先 级: 1
(数值越小优先级越低,这个跟uCOS相反)
*********************************************************************************************************
static void vTaskTaskUserIF(void *pvParameters)
uint8_t ucKeyC
uint8_t pcWriteBuffer[500];
ucKeyCode = bsp_GetKey();
if (ucKeyCode != KEY_NONE)
switch (ucKeyCode)
/* K1键按下 打印任务执行情况 */
case KEY_DOWN_K1:
printf(&=================================================\r\n&);
printf(&任务名
任务状态 优先级
剩余栈 任务序号\r\n&);
vTaskList((char *)&pcWriteBuffer);
printf(&%s\r\n&, pcWriteBuffer);
printf(&\r\n任务名
使用率\r\n&);
vTaskGetRunTimeStats((char *)&pcWriteBuffer);
printf(&%s\r\n&, pcWriteBuffer);
/* 其他的键值不处理 */
vTaskDelay(20);
*********************************************************************************************************
函 数 名: vTaskLED
功能说明: LED闪烁
参: pvParameters 是在创建该任务时传递的形参
返 回 值: 无
优 先 级: 2
*********************************************************************************************************
static void vTaskLED(void *pvParameters)
bsp_LedToggle(2);
vTaskDelay(200);
*********************************************************************************************************
函 数 名: vTaskMsgPro
功能说明: 消息处理,这里是用作LED闪烁
参: pvParameters 是在创建该任务时传递的形参
返 回 值: 无
优 先 级: 3
*********************************************************************************************************
static void vTaskMsgPro(void *pvParameters)
bsp_LedToggle(3);
vTaskDelay(300);
*********************************************************************************************************
函 数 名: vTaskStart
功能说明: 启动任务,也就是最高优先级任务,这里用作按键扫描。
参: pvParameters 是在创建该任务时传递的形参
返 回 值: 无
优 先 级: 4
*********************************************************************************************************
static void vTaskStart(void *pvParameters)
/* 按键扫描 */
bsp_KeyScan();
vTaskDelay(10);
11:01:49  
14.6.2& &STM32F407开发板实验
配套例子:
& & V5-308_FreeRTOS实验_时间片调度
实验目的:
& & 1.& &&&学习FreeRTOS的时间片调度。
& & 2.& &&&使用FreeRTOS的时间片调度,仅需在FreeRTOSConfig.h文件中使能如下宏定义:
& && &&&#defineconfigUSE_TIME_SLICING& && &1
& && &&&不配置也没有关系,因为FreeRTOS.h文件中默认已经使能了。
实验内容:
& & 1.& &&&K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
& & 2.& &&&任务vTaskLED和任务vTaskMsgPro具有相同的优先级。
& & 3.& &&&各个任务实现的功能如下:
& && && && &&&vTaskUserIF任务& &:按键消息处理。
& && && && &&&vTaskLED任务& &&&:LED闪烁。
& && && && &&&vTaskMsgPro任务 :消息处理,这里是用作LED闪烁。
& && && && &&&vTaskStart任务& & :启动任务,也是最高优先级任务,这里实现按键扫描。
11:02:22  
FreeRTOS的配置:
& & FreeRTOSConfig.h文件中的配置如下:
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include &stdint.h&
extern volatile uint32_t ulHighFrequencyTimerT
/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include &stdint.h&
extern volatile uint32_t ulHighFrequencyTimerT
#define configUSE_PREEMPTION
#define configUSE_IDLE_HOOK
#define configUSE_TICK_HOOK
#define configCPU_CLOCK_HZ
( ( unsigned long )
#define configTICK_RATE_HZ
( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES
#define configMINIMAL_STACK_SIZE
( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE
( ( size_t ) ( 30 * 1024 ) )
#define configMAX_TASK_NAME_LEN
#define configUSE_TRACE_FACILITY
#define configUSE_16_BIT_TICKS
#define configIDLE_SHOULD_YIELD
#define configUSE_TIME_SLICING
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS
#define configUSE_STATS_FORMATTING_FUNCTIONS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
(ulHighFrequencyTimerTicks = 0ul)
#define portGET_RUN_TIME_COUNTER_VALUE()
ulHighFrequencyTimerTicks
//#define portALT_GET_RUN_TIME_COUNTER_VALUE
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet
#define INCLUDE_uxTaskPriorityGet
#define INCLUDE_vTaskDelete
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend
#define INCLUDE_vTaskDelayUntil
#define INCLUDE_vTaskDelay
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS
__NVIC_PRIO_BITS
#define configPRIO_BITS
/* 15 priority levels */
/* The lowest interrupt priority that can be used in a call to a &set priority&
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.
DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
11:02:34  
几个重要选项说明:
1、#define configUSE_PREEMPTION& && &&&1
& && && & 使能抢占式调度器
2、#define configCPU_CLOCK_HZ& &&&( ( unsigned long )
& && && & 系统主频168MHz。
3、#define configTICK_RATE_HZ& && && && &&&( ( TickType_t ) 1000 )
& && && & 系统时钟节拍1KHz,即1ms。
4、#define configMAX_PRIORITIES& && && & ( 5 )
& && && & 定义可供用户使用的最大优先级数,如果这个定义的是5,那么用户可以使用的优先级号是0,1,2,3,4,不包含5,对于这一点,初学者要特别的注意。
5、#define configTOTAL_HEAP_SIZE& && &&&( ( size_t ) ( 30 * 1024 ) )
& && && & 定义堆大小,FreeRTOS内核,用户动态内存申请,任务栈等都需要用这个空间。
6、#define configUSE_TIME_SLICING& && &1
& && && & 使能时间片调度。
7、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY& && && & 0x01
& && && & 定义受FreeRTOS管理的最高优先级中断。简单的说就是允许用户在这个中断服务程序里面调用FreeRTOS的API的最高优先级。为了进一步说明这个宏定义的的作用,解释如下:
& && &(1)使用CM内核的MCU,官方强烈建议将NVIC的优先级分组配置为全抢占式优先级,全部配置为抢占式优先级的好处就是方便管理。
& && &(2)对于STM32来说,设置NVIC的优先级分组为4时,NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4)就是全部配置为抢占式优先级。又因为STM32的优先级设置仅使用CM内核8bit中的高4bit,即只能区分2^4 = 16种优先级。因此当优先级分组设置为4的时候可供用户选择抢占式优先级为0到15,共16个优先级,配置为0表示最高优先级,配置为15表示最低优先级,不存在子优先级。
& && &(3)这里配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为0x01表示用户可以在抢占式优先级为1到15的中断里面调用FreeRTOS的API函数,抢占式优先级为0的中断里面是不允许调用的。
11:02:49  
FreeRTOS任务调试信息(按K1按键,串口打印):
上面截图中打印出来的任务状态字母B, R, D, S对应如下含义:
& & #definetskBLOCKED_CHAR& && && & ( 'B' )&&任务阻塞
& & #definetskREADY_CHAR& && && &&&( 'R' ) 任务就绪
& & #definetskDELETED_CHAR& && && &&&( 'D' )&&任务删除
& & #definetskSUSPENDED_CHAR& &( 'S' ) 任务挂起
11:03:11  
程序设计:
任务栈大小分配:
& & vTaskUserIF任务& &:2048字节
& & vTaskLED任务& &&&:2048字节
& & vTaskMsgPro任务 :2048字节
& & vTaskStart任务& & :2048字节
& & 任务栈空间是在任务创建的时候从FreeRTOSConfig.h文件中定义的heap空间中申请的
& & #defineconfigTOTAL_HEAP_SIZE& && &&&( ( size_t )( 30 * 1024 ) )
系统栈大小分配:
Powered by
供应链服务
商务及广告合作
Jeffery Guo
关注我们的微信
供应链服务 PCB/IC/PCBA
版权所有 (C) 深圳华强聚丰电子科技有限公司

我要回帖

更多关于 轮询方式 的文章

 

随机推荐