FreeRTOS应用(参数,优先级,延时,钩子,任务,删除函数)

发布时间:2026/7/23 23:51:25
FreeRTOS应用(参数,优先级,延时,钩子,任务,删除函数) 1.任务参数使用2.任务的优先级3.相对延时函数4.绝对延时函数5.空闲钩子函数6.任务句柄7.删除任务函数一.任务参数使用1.void指针可以指向任意类型的数据既可以用任意类型的指针对void指针赋值。例如int *a; void *p; pa;如果将void指针p赋给其它类型的指针则需要强制转换例如a(int*)p2.在不同的标准中ANSI c标准中void不能进行算数运算因为void是无类型每次算数运算就不知道该操作几个字节。而在GNU中可以因为GNU认为void*和char*一样。sizeof(void*)sizeof(char*);3.应用①CubeMX的配置代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT ;ul) { //延时 } char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); //对比pcTaskName与cSectionStr1是否一样 if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }二.任务的优先级1.优先级的介绍①调度器始终确保可以运行的最高优先级任务是被选中进入运行状态的任务。具有相同优先级的任务会依次进入和退出运行状态。② 用于创建任务的 xTaskCreate() API函数的uxPriority 参数为任务分配其初始优先级。vTaskPrioritySet() API函数在任务创建后改变其优先级。③ 最大优先级数量由FreeRTOSConfig.h 中定义的configMAX_PRIORITIES 编译时配置常量设置。较低的数值优先级表示低优先级任务其中优先级0是最低优先级。可以使用的优先级范围是从0到(configMAX_PRIORITIES – 1)。【建议configMAX_PRIORITIES的值保持在最小值减少RAM的开销和减少执行时间】扩展若将FreeRTOSConfig.h中的configUSE_PORT_OPTIMISED_TASK_SELECTION设置为 0 。如果没有定义configUSE_PORT_OPTIMISED_TASK_SELECTION 或者通用方法是为正在使用的FreeRTOS移植提供的唯一方法就会使用通用方法。在FreeRTOSConfig.h中将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1时就会使用架构优化的方法。注意并非所有的FreeRTOS移植都提供了架构优化方法。2.测量与滴答中断3.应用CubeMX的配置略代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT ;ul) { } char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果三.相对延时函数1.事件驱动型任务到目前为止创建的任务总是需要执行处理操作并且从未需要等待任何东西因此总是能够进入运行状态。 “连续处理”类型的任务用途有限任务只能在最低优先级下创建。如果这些任务以其他优先级运行就会阻止优先级更低的任务运行。必须将任务重新编写成事件驱动型的任务。事件驱动型的任务具有的不同优先级只有在触发事件发生后才有工作要执行在事件发生前不会进入运行状态。调度器始终选择可以运行的最高优先级任务。如果无法选择高优先级任务例如正在等待某个事件则调度器必须选择可以运行的优先级较低的任务。2.任务的阻塞状态正在等待事件的任务称为处于“阻塞”状态这是“非运行”状态的一个子状态。任务可以进入阻塞状态以等待两种不同类型的事件• 时间性事件这些事件发生在延迟期到期或达到绝对时间时。例如任务可能会进入阻塞状态以等待10毫秒过去。• 同步事件这些事件来自另一个任务或中断。例如任务可能会进入阻塞状态等待队列中的数据到达。同步事件涵盖了广泛的事件类型。队列、二进制/计数信号量、互斥量、递归互斥量、事件组、流缓冲区、消息缓冲区和直接任务通知都可以创建同步事件。任务也可以在同步事件上设置超时从而有效地同时阻塞两种类型的事件。3.挂起和就绪状态①挂起状态挂起状态也是非运行状态的一个子状态。处于挂起状态的任务对调度器不可用。进入挂起状态的唯一方法是调用vTaskSuspend() API函数。退出挂起状态的唯一方法是调用vTaskResume()或xTaskResumeFromISR() API函数。大多数应用程序不使用挂起状态。②就绪状态处于非运行状态且未阻塞或挂起的任务被称为处于就绪状态。它们可以运行因此准备运行但当前不在运行状态。4.vTaskDelay()函数5.应用CubeMX配置代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; const TickType_t xDelay250mspdMS_TO_TICKS (250); //注意把250ms转换为滴答数 pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); vTaskDelay (xDelay250ms ); char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果四.绝对延时函数CubeMX配置略代码在FreeRTOS.c与main.c中加#include user_app.h在FreeRTOS.c中user_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vContinuousProcessingTask(void *pvParameters); void vprintfString(const char *pcString); void vPeriodicTask(void* pvParameters); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vContinuousProcessingTask(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters ; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT;ul) { } char*pcRetPtrstrstr(pcTaskName ,task1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } } void vPeriodicTask(void* pvParameters) { TickType_t xLastWakeTime; const TickType_t xDelay250mspdMS_TO_TICKS (250UL); const char *a(char*) pvParameters; xLastWakeTime xTaskGetTickCount (); for(;;) { vprintfString(a); vTaskDelayUntil (xLastWakeTime ,xDelay250ms ); } }效果五.空闲钩子函数应用CubeMX的配置代码在FreeRTOS.c与main.c中加#include user_app.h在FreeRTOS中user_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vContinuousProcessingTask(void *pvParameters); void vprintfString(const char *pcString,uint32_t ulValue); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff uint32_t ulIdleCycleCount0; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString,uint32_t ulValue) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); printf(ulIdleCycleCount%d\n\r,ulValue); } taskEXIT_CRITICAL(); } void vContinuousProcessingTask(void *pvParameters) { char *pcTaskName; //volatile uint32_t ul; pcTaskName(char*)pvParameters ; const TickType_t xDelay250mspdMS_TO_TICKS (250); for(;;) { vprintfString(pcTaskName,ulIdleCycleCount); vTaskDelay (xDelay250ms ); char*pcRetPtrstrstr(pcTaskName ,task1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果六.任务句柄应用CubeMX的配置略代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTask1(void *pvParameters); void vprintfString(const char *pcString); void vTask2(void* pvParameters); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff extern osThreadId_t Task1Handle; extern osThreadId_t Task2Handle; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); // printf(ulIdleCycleCount%d\n\r,ulValue); } taskEXIT_CRITICAL(); } void vTask1(void *pvParameters) { UBaseType_t uxPriorityuxTaskPriorityGet(NULL); for(;;) { vprintfString(Task1 is Running\n\r); vprintfString (About to raise the Task2 priority\n\r); vTaskPrioritySet (Task2Handle,(uxPriority1)); //注意 HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } } void vTask2(void* pvParameters) { UBaseType_t uxPriorityuxTaskPriorityGet(NULL); for(;;) { vprintfString(Task2 is Running\n\r); vprintfString (About to lower the Task2 priority\n\r); vTaskPrioritySet(NULL,(uxPriority -2)); //注意 HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } }效果七.删除任务函数应用在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTask1(void *pvParameters); void vprintfString(const char *pcString); void vTask2(void* pvParameters); #endifuser_app.c #include user_app.h TaskHandle_t xTask2Handle; extern osThreadId_t Task1Handle; extern osThreadId_t Task2Handle; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTask1(void *pvParameters) { const TickType_t xDelay100mspdMS_TO_TICKS (100UL); for(;;) { vprintfString(Task1 is Running\n\r); xTaskCreate(vTask2,Task 2,1000,NULL,osPriorityLow1,xTask2Handle); } } void vTask2(void* pvParameters) { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); vprintfString (Task2 is running and abut to delete itself\n\r); vTaskDelete (xTask2Handle ); }效果