日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2、FreeRTOS任务相关API函数

發(fā)布時間:2025/4/16 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2、FreeRTOS任务相关API函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.任務(wù)相關(guān)的API函數(shù)

函數(shù)存在于task.c中,主要的函數(shù)有:

  • xTaskCreate():使用動態(tài)的方法創(chuàng)建一個任務(wù);
  • xTaskCreatStatic():使用靜態(tài)的方法創(chuàng)建一個任務(wù)(用的非常少);
  • xTaskCreateRestricted():創(chuàng)建一個使用MPU進(jìn)行限制的任務(wù);
  • vTaskDelete():刪除一個任務(wù);
  • vTaskSuspend():掛起一個任務(wù);
  • vTaskResume():恢復(fù)一個任務(wù)的運(yùn)行;
  • vTaskResumeFromISR():中斷服務(wù)函數(shù)中恢復(fù)一個任務(wù)的運(yùn)行;
  • portENABLE_INTERRUPTS():打開FreeRTOS中斷;
  • portDISABLE_INTERRUPTS():關(guān)閉freeRTOS中斷;

2.動態(tài)創(chuàng)建任務(wù)

  • xTaskCreate()函數(shù)原型: BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,const char * const pcName,uint16_t usStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pvCreatedTask);
  • 動態(tài)創(chuàng)建任務(wù):使用前先判斷?#if( configSUPPORT_STATIC_ALLOCATION == 1 ) 是否成立,如果不成立需要在FreeRTOSConfig.h 文件中添加;
    #include "FreeRTOS.h" #include "task.h"//start_task 任務(wù) void start_task(void *pvParameters); // 任務(wù)函數(shù) #define start_task_zise 50 // 任務(wù)堆棧的大小 #define start_task_prio 1 // 任務(wù)優(yōu)先級 TaskHandle_t start_task_handler; // 任務(wù)句柄//led1_task 任務(wù) void led1_task(void *pvParameters); // 任務(wù)函數(shù) #define led1_task_zise 50 // 任務(wù)堆棧的大小 #define led1_task_prio 2 // 任務(wù)優(yōu)先級 TaskHandle_t led1_task_handler; // 任務(wù)句柄
    int main(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);delay_init();LED_Init();// 創(chuàng)建一個任務(wù) xTaskCreate(任務(wù)函數(shù), 任務(wù)名, 任務(wù)堆棧的大小, 傳遞給任務(wù)函數(shù)的參數(shù), 任務(wù)優(yōu)先級, 任務(wù)句柄);xTaskCreate( start_task, "start_stask", start_task_zise, NULL, start_task_prio, &start_task_handler); vTaskStartScheduler(); // 開啟任務(wù)調(diào)度return 0; }void start_task( void * pvParameters ) {taskENTER_CRITICAL(); // 創(chuàng)建臨界區(qū)// 創(chuàng)建led1任務(wù)xTaskCreate(led1_task, "led1_task", start_task_zise, NULL, led1_task_prio, &led1_task_handler); vTaskDelete(start_task_handler); //刪除開始任務(wù)taskEXIT_CRITICAL(); // 退出臨界區(qū) } //LED1任務(wù)函數(shù) void led1_task( void * pvParameters ) {for( ;; ){LED0 = ~LED0;vTaskDelay(1000);} }

3.靜態(tài)創(chuàng)建任務(wù)

  • xTaskCreatStatic()函數(shù)原型: TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,const char * const pcName,const uint32_t ulStackDepth,void * const pvParameters,UBaseType_t uxPriority,StackType_t * const puxStackBuffer,StaticTask_t * const pxTaskBuffer )
  • 靜態(tài)創(chuàng)建任務(wù):使用前先判斷?#if( configSUPPORT_STATIC_ALLOCATION== 1 ) 是否成立,如果不成立需要在FreeRTOSConfig.h 文件中添加;
  • 在FreeRTOSConfig.h 文件中添加中添加宏后,編譯報錯: .\Objects\freeRTOS_sCreate_task.axf: Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory(referred from tasks.o). .\Objects\freeRTOS_sCreate_task.axf: Error: L6218E: Undefined symbol vApplicationGetTimerTaskMemory (referred from timers.o).
  • 由于把靜態(tài)創(chuàng)建的宏給打開了,所以這兩個數(shù)需要我們自己去實(shí)現(xiàn) // 空閑任務(wù) static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE]; static StaticTask_t IdleTaskTCB; // 定時器任務(wù) static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH]; static StaticTask_t TimerTaskTCB;// 空閑任務(wù)所需內(nèi)存 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) {*ppxIdleTaskTCBBuffer = &IdleTaskTCB;*ppxIdleTaskStackBuffer = IdleTaskStack;*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } // 定時器任務(wù)所需內(nèi)存 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) {*ppxTimerTaskTCBBuffer = &TimerTaskTCB;*ppxTimerTaskStackBuffer = TimerTaskStack;*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; }
  • 靜態(tài)創(chuàng)建任務(wù) //start_task 任務(wù) void start_task(void *pvParameters); // 任務(wù)函數(shù) #define start_task_zise 50 // 任務(wù)堆棧的大小 #define start_task_prio 1 // 任務(wù)優(yōu)先級 StackType_t start_task_stack[start_task_zise]; // 任務(wù)控制塊大小 StaticTask_t start_task_TCB; // 任務(wù)堆棧大小 TaskHandle_t start_task_handler; // 任務(wù)句柄//led1_task 任務(wù) void led1_task(void *pvParameters); // 任務(wù)函數(shù) #define led1_task_zise 50 // 任務(wù)堆棧的大小 #define led1_task_prio 2 // 任務(wù)優(yōu)先級 StackType_t led1_task_stack[start_task_zise]; // 任務(wù)控制塊大小 StaticTask_t led1_task_TCB; // 任務(wù)堆棧大小 TaskHandle_t led1_task_handler; // 任務(wù)句柄//led2_task 任務(wù) void led2_task(void *pvParameters); // 任務(wù)函數(shù) #define led2_task_zise 50 // 任務(wù)堆棧的大小 #define led2_task_prio 3 // 任務(wù)優(yōu)先級 StackType_t led2_task_stack[start_task_zise]; // 任務(wù)控制塊大小 StaticTask_t led2_task_TCB; // 任務(wù)堆棧大小 TaskHandle_t led2_task_handler; // 任務(wù)句柄int main(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);delay_init();LED_Init();// 創(chuàng)建一個開始任務(wù)start_task_handler = xTaskCreateStatic( (TaskFunction_t )start_task,(char *)"start_task",(uint32_t )start_task_zise,(void * )NULL,(UBaseType_t )start_task_prio,(StackType_t * )start_task_stack, // 任務(wù)控制塊大小(StaticTask_t * )&start_task_TCB ); // 任務(wù)堆棧大小 vTaskStartScheduler(); // 開啟任務(wù)調(diào)度return 0; }void start_task( void * pvParameters ) {led1_task_handler = xTaskCreateStatic( (TaskFunction_t )led1_task,(char *)"led1_task",(uint32_t )led1_task_zise,(void * )NULL,(UBaseType_t )led1_task_prio,(StackType_t * )led1_task_stack, // 任務(wù)控制塊大小(StaticTask_t * )&led1_task_TCB ); // 任務(wù)堆棧大小 led2_task_handler = xTaskCreateStatic( (TaskFunction_t )led2_task,(char *)"led2_task",(uint32_t )led2_task_zise,(void * )NULL,(UBaseType_t )led2_task_prio,(StackType_t * )led2_task_stack, // 任務(wù)控制塊大小(StaticTask_t * )&led2_task_TCB ); // 任務(wù)堆棧大小 vTaskDelete(start_task_handler); } void led1_task( void * pvParameters ) {for( ;; ){LED0 = ~LED0;vTaskDelay(200);} } void led2_task( void * pvParameters ) {for( ;; ){LED1 = ~LED1;vTaskDelay(1000);} }

4.刪除任務(wù)

  • void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;

5.任務(wù)掛起

  • ?void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION;

6.任務(wù)恢復(fù)

  • ?void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
  • 掛起、恢復(fù)代碼如下: //key_task 任務(wù) void key_task(void *pvParameters); // 任務(wù)函數(shù) #define key_task_zise 50 // 任務(wù)堆棧的大小 #define key_task_prio 4 // 任務(wù)優(yōu)先級 TaskHandle_t key_task_handler; // 任務(wù)句柄void start_task( void * pvParameters ) {taskENTER_CRITICAL(); // 創(chuàng)建臨界區(qū)// 創(chuàng)建按鍵檢查任務(wù) xTaskCreate((TaskFunction_t )key_task,(const char * )"key_task",(uint16_t )key_task_zise,(void * )NULL,(UBaseType_t )key_task_prio,(TaskHandle_t * )&key_task_handler);......vTaskDelete(start_task_handler); //刪除開始任務(wù)taskEXIT_CRITICAL(); // 退出臨界區(qū) }//key任務(wù)函數(shù) void key_task( void * pvParameters ) {char key;for( ;; ){key = KEY_Scan(0);switch(key){case KEY0_PRES:vTaskSuspend(led1_task_handler);printf("led1_task Suspended.\n");break;case KEY1_PRES:vTaskResume(led1_task_handler);printf("led1_task Resumed.\n");break;case KEY2_PRES:vTaskSuspend(led2_task_handler);printf("led2_task Suspended.\n");break;case WKUP_PRES:vTaskResume(led2_task_handler);printf("led2_task Resumed.\n");break;}vTaskDelay(10); //延時10ms } }

7.FreeRTOS開關(guān)中斷

  • freeRTOS管理的中斷優(yōu)先級為 5~15,這是在freeRTOSConfig.h中設(shè)置的。 #ifdef __NVIC_PRIO_BITS#define configPRIO_BITS __NVIC_PRIO_BITS #else#define configPRIO_BITS 4 #endif#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中斷最低優(yōu)先級 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系統(tǒng)可管理的最高中斷優(yōu)先級 #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)
  • 設(shè)置好宏后,低于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY優(yōu)先級的中斷可以安全的調(diào)用FreeRTOS的API函數(shù)(xxFromISR()函數(shù));
  • 高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY優(yōu)先級的中斷不能被FreeRTOS禁止,中斷服務(wù)函數(shù)也不能調(diào)用FreeRTOS的API函數(shù)。
  • 由于高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的優(yōu)先級不會被FreeRTOS內(nèi)核屏蔽,因此那些對實(shí)時性要求嚴(yán)格的任務(wù)可以使用這些優(yōu)先級(0~4),比如四軸飛行器中的避障檢測; //start_task 任務(wù) void start_task(void *pvParameters); // 任務(wù)函數(shù) #define start_task_zise 50 // 任務(wù)堆棧的大小 #define start_task_prio 1 // 任務(wù)優(yōu)先級 TaskHandle_t start_task_handler; // 任務(wù)句柄//interrupt_task 任務(wù) void interrupt_task(void *pvParameters); // 任務(wù)函數(shù) #define interrupt_task_zise 50 // 任務(wù)堆棧的大小 #define interrupt_task_prio 2 // 任務(wù)優(yōu)先級 TaskHandle_t interrupt_task_handler; // 任務(wù)句柄int main(void) {NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);uart_init(115200);delay_init();LED_Init();TIM3_Int_Init(10000-1,7200-1); //設(shè)置定時器3的搶占優(yōu)先級為 4TIM5_Int_Init(10000-1,7200-1); //設(shè)置定時器5的搶占優(yōu)先級為 5// 創(chuàng)建一個任務(wù)xTaskCreate((TaskFunction_t )start_task, // 任務(wù)函數(shù) (const char * )"start_stask", // 任務(wù)名 (uint16_t )start_task_zise, // 任務(wù)堆棧的大小(void * )NULL, // 傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )start_task_prio, // 任務(wù)優(yōu)先級(TaskHandle_t * )&start_task_handler); // 任務(wù)句柄 vTaskStartScheduler(); // 開啟任務(wù)調(diào)度return 0; }void start_task( void * pvParameters ) {taskENTER_CRITICAL(); // 創(chuàng)建臨界區(qū)// 創(chuàng)建led1任務(wù) xTaskCreate((TaskFunction_t )interrupt_task,(const char * )"interrupt_task",(uint16_t )interrupt_task_zise,(void * )NULL,(UBaseType_t )interrupt_task_prio,(TaskHandle_t * )&interrupt_task_handler);// 創(chuàng)建led2任務(wù) vTaskDelete(start_task_handler); //刪除開始任務(wù)taskEXIT_CRITICAL(); // 退出臨界區(qū) } //interrupt任務(wù)函數(shù) void interrupt_task( void * pvParameters ) {int i = 0;for( ;; ){if(i == 5){printf("關(guān)閉中斷!!!.\n");portDISABLE_INTERRUPTS();delay_xms(5000); // delay_xms執(zhí)行的時候不會執(zhí)行任何任務(wù)調(diào)度printf("開中斷!!!.\n");portENABLE_INTERRUPTS();}printf("interrupt task is %d runing.\n", i);LED0 = ~LED0;vTaskDelay(1000);i++;} }

8.臨界段

  • ?臨界段是指:那些必須完整運(yùn)行,不能被打斷的代碼段,比如有的外設(shè)的初始化需要嚴(yán)格的時序,初始化過程中不能被打斷。FreeRTOS在進(jìn)入臨界段代碼的時候需要關(guān)閉中斷,當(dāng)處理完臨界段代碼以后再打開中斷。
  • FreeRTOS中與臨界段有關(guān)的函數(shù)有4個,定義于task.h中: #define taskENTER_CRITICAL() portENTER_CRITICAL() #define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()#define taskEXIT_CRITICAL() portEXIT_CRITICAL() #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
  • taskENTER_CRITICAL():進(jìn)入任務(wù)級的臨界區(qū);  ? ?
  • taskEXIT_CRITICAL():退出任務(wù)級的臨界區(qū); void start_task( void * pvParameters ) {taskENTER_CRITICAL(); // 進(jìn)入臨界區(qū)// 創(chuàng)建led1任務(wù) xTaskCreate((TaskFunction_t )interrupt_task,(const char * )"interrupt_task",(uint16_t )interrupt_task_zise,(void * )NULL,(UBaseType_t )interrupt_task_prio,(TaskHandle_t * )&interrupt_task_handler);// 創(chuàng)建led2任務(wù) vTaskDelete(start_task_handler); //刪除開始任務(wù)taskEXIT_CRITICAL(); // 退出臨界區(qū) }
  • taskEXIT_CRITICAL_FROM_ISR():進(jìn)入中斷級臨界區(qū);
  • taskENTER_CRITICAL_FROM_ISR():退出中斷級臨界區(qū); //定時器3中斷服務(wù)程序 void TIM3_IRQHandler(void) //TIM3中斷 {int status_value;if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查TIM3更新中斷發(fā)生與否 {status_value = taskENTER_CRITICAL_FROM_ISR(); //進(jìn)入臨界區(qū)printf("定時器3發(fā)生中斷.\n");LED1=!LED1;TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中斷標(biāo)志 taskEXIT_CRITICAL_FROM_ISR(status_value); //退出臨界區(qū) } }//定時器3中斷服務(wù)程序 void TIM5_IRQHandler(void) //TIM3中斷 {int status_value;if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //檢查TIM5更新中斷發(fā)生與否 { status_value = taskENTER_CRITICAL_FROM_ISR(); //進(jìn)入臨界區(qū)printf("定時器5發(fā)生中斷.\n");LED1=!LED1;TIM_ClearITPendingBit(TIM5, TIM_IT_Update ); //清除TIMx更新中斷標(biāo)志 taskEXIT_CRITICAL_FROM_ISR(status_value); //退出臨界區(qū) } }

    ?

    ?

?

轉(zhuǎn)載于:https://www.cnblogs.com/icefree/p/8684859.html

總結(jié)

以上是生活随笔為你收集整理的2、FreeRTOS任务相关API函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。