04_FreeRTOS的任務掛起與恢復

爱吃冰激凌的黄某某發表於2024-03-21

FreeRTOS的任務掛起與恢復

任務的掛起與恢復的API函式

image-20240319224723994

任務掛起函式介紹

image-20240319224740395

任務恢復函式介紹

image-20240319224754186

image-20240319224814296

任務優先順序:數值越大,優先順序越高

中斷優先順序:數值越小,優先順序越高

使用中斷任務恢復時要確保在啟動 RTOS 之前呼叫 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); 所有優先順序位都指定為搶佔優先順序位。

任務掛起與恢復實驗

image-20240319224835074

任務掛起函式內部實現

image-20240319224902831

任務恢復函式內部實現

image-20240319224914912

程式碼

freertos_demo.c

/**
 ****************************************************************************************************
 * @file        freertos.c
 * @author      正點原子團隊(ALIENTEK)
 * @version     V1.4
 * @date        2022-01-04
 * @brief       FreeRTOS 移植實驗
 * @license     Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 實驗平臺:正點原子 探索者F407開發板
 * 線上影片:www.yuanzige.com
 * 技術論壇:www.openedv.com
 * 公司網址:www.alientek.com
 * 購買地址:openedv.taobao.com
 *
 ****************************************************************************************************
 */

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任務 配置
 * 包括: 任務控制代碼 任務優先順序 堆疊大小 建立任務
 */
 #define START_TASK_STACK_SIZE 	128
 #define START_TASK_PRIO		1
 TaskHandle_t start_task_handler;
 
 #define TASK1_STACK_SIZE 	128
 #define TASK1_PRIO		2
 TaskHandle_t task1_handler;
 
 #define TASK2_STACK_SIZE 	128
 #define TASK2_PRIO		3
 TaskHandle_t task2_handler;
 
  #define TASK3_STACK_SIZE 	128
 #define TASK3_PRIO		4
 TaskHandle_t task3_handler;
void start_task( void * pvParameters );

void task1( void * pvParameters )
{
	uint32_t task1_num = 0;
	while(1)
	{
		printf("task1_num:%d!!!\r\n", ++task1_num);
		LED0_TOGGLE();
		vTaskDelay(500);
	}
}

void task2( void * pvParameters )
{
	uint32_t task2_num = 0;
	while(1)
	{
		printf("task2_num:%d!!!\r\n", ++task2_num);
		LED1_TOGGLE();
		vTaskDelay(500);
	}
}

/* 
 *	按鍵0:任務1掛起
 *	按鍵1:任務1恢復
 */
void task3( void * pvParameters )
{
	uint8_t key = 0;
	while(1)
	{
		key=key_scan(0);
		if(key == KEY0_PRES)
		{
			if(task1_handler!=NULL)
			{
				vTaskSuspend(task1_handler);
				printf("掛起task1\r\n");
			}
			
		}
		else if(key == KEY1_PRES)
		{
			vTaskResume(task1_handler);
			printf("在任務中恢復task1\r\n");
		}
		vTaskDelay(10);
	}
}
/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函式
 * @param       無
 * @retval      無
 */
void freertos_demo(void)
{
    xTaskCreate(start_task, "start_task", START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);
    vTaskStartScheduler();
}

void start_task( void * pvParameters )
{
	taskENTER_CRITICAL(); //進入臨界區
	xTaskCreate(task1, "task1", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &task1_handler);
	xTaskCreate(task2, "task2", TASK2_STACK_SIZE, NULL, TASK2_PRIO, &task2_handler);
	xTaskCreate(task3, "task3", TASK3_STACK_SIZE, NULL, TASK3_PRIO, &task3_handler);
    vTaskDelete(NULL);
	taskEXIT_CRITICAL(); //退出臨界區
}


exti.c

/**
 ****************************************************************************************************
 * @file        exti.c
 * @author      正點原子團隊(ALIENTEK)
 * @version     V1.0
 * @date        2021-10-14
 * @brief       外部中斷 驅動程式碼
 * @license     Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 實驗平臺:正點原子 探索者 F407開發板
 * 線上影片:www.yuanzige.com
 * 技術論壇:www.openedv.com
 * 公司網址:www.alientek.com
 * 購買地址:openedv.taobao.com
 *
 * 修改說明
 * V1.0 20211014
 * 第一次釋出
 *
 ****************************************************************************************************
 */

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/EXTI/exti.h"

#include "FreeRTOS.h"
#include "task.h"

 extern TaskHandle_t task1_handler;

/**
 * @brief       KEY2 外部中斷服務程式
 * @param       無
 * @retval      無
 */
void KEY2_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(KEY2_INT_GPIO_PIN);        /* 呼叫中斷處理公用函式 清除KEY2所在中斷線 的中斷標誌位,中斷下半部在HAL_GPIO_EXTI_Callback執行 */
    __HAL_GPIO_EXTI_CLEAR_IT(KEY2_INT_GPIO_PIN);        /* HAL庫預設先清中斷再處理回撥,退出時再清一次中斷,避免按鍵抖動誤觸發 */
}

/**
 * @brief       WK_UP 外部中斷服務程式
 * @param       無
 * @retval      無
 */
void WKUP_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);        /* 呼叫中斷處理公用函式 清除KEY_UP所在中斷線 的中斷標誌位,中斷下半部在HAL_GPIO_EXTI_Callback執行 */
    __HAL_GPIO_EXTI_CLEAR_IT(WKUP_INT_GPIO_PIN);        /* HAL庫預設先清中斷再處理回撥,退出時再清一次中斷,避免按鍵抖動誤觸發 */
}

/**
 * @brief       中斷服務程式中需要做的事情
 *              在HAL庫中所有的外部中斷服務函式都會呼叫此函式
 * @param       GPIO_Pin:中斷引腳號
 * @retval      無
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20);      /* 消抖 */
    switch(GPIO_Pin)
    {
		BaseType_t xYieldRequired;
        case KEY2_INT_GPIO_PIN:
            if (KEY2 == 0)
            {
                xYieldRequired = xTaskResumeFromISR(task1_handler);
				printf("在中斷中恢復task1\r\n");
				if(xYieldRequired == pdTRUE)
				{
					portYIELD_FROM_ISR( xYieldRequired );
				}
            }
            break;
        default : break;
    }
}

/**
 * @brief       外部中斷初始化程式
 * @param       無
 * @retval      無
 */
void extix_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    key_init();
	
    gpio_init_struct.Pin = KEY2_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下降沿觸發 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY2_INT_GPIO_PORT, &gpio_init_struct);    /* KEY2配置為下降沿觸發中斷 */
    
    HAL_NVIC_SetPriority(KEY2_INT_IRQn, 5, 0);               /* 搶佔5,子優先順序0 */
    HAL_NVIC_EnableIRQ(KEY2_INT_IRQn);                       /* 使能中斷線2 */

}

函式解析

image-20240321160740075

image-20240321160755796

image-20240321160813987

相關文章