freeRTOS任务挂起与恢复

任务的挂起与恢复

一、API函数介绍

二、编程实现

实验目的:学会使用 vTaskSuspend()、vTaskResume()、xTaskResumeFromISR()

实验设计内容:设计四个任务:start_task、task1、task2、task3

task1:实现LED0每500ms闪烁一次

task2:实现LED1每500ms闪烁一次

task3:判断按键按下逻辑,KEY0被按下,挂起task1,按下KEY1在任务中恢复task1,按下KEY_WK_UP,在中断中恢复task1(外部中断线实现)

freertos_demo.c


#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_PRIO 	1
#define START_TASK_STACK_SIZE 128
TaskHandle_t	start_task_handler;
void start_task( void * pvParameters );
/******************************************************************************************************/

/* task1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO 	2
#define TASK1_STACK_SIZE 128
TaskHandle_t	task1_handler;
void task1( void * pvParameters );
/******************************************************************************************************/
/* task2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO 	3
#define TASK2_STACK_SIZE 128
TaskHandle_t	task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/
/* task3 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK3_PRIO 	4
#define TASK3_STACK_SIZE 128
TaskHandle_t	task3_handler;
void task3( void * pvParameters );
/******************************************************************************************************/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
		xTaskCreate( (TaskFunction_t				)		start_task,
                 (char * 								)		"start_task", 
                 (configSTACK_DEPTH_TYPE) 	START_TASK_STACK_SIZE,
                 (void * 								) 	NULL,
                 (UBaseType_t						)		START_TASK_PRIO,
                 (TaskHandle_t * 				) 	&start_task_handler );
    
    vTaskStartScheduler();
}
 // Task to be created.
 void start_task( void * pvParameters )
 {
	  taskENTER_CRITICAL();
		xTaskCreate( (TaskFunction_t				)		task1,
                 (char * 								)		"task1", 
                 (configSTACK_DEPTH_TYPE) 	TASK1_STACK_SIZE,
                 (void * 								) 	NULL,
                 (UBaseType_t						)		TASK1_PRIO,
                 (TaskHandle_t * 				) 	&task1_handler );
								 
		xTaskCreate( (TaskFunction_t				)		task2,
                 (char * 								)		"task2",
                 (configSTACK_DEPTH_TYPE) 	TASK2_STACK_SIZE,
                 (void * 								) 	NULL,
                 (UBaseType_t						)		TASK2_PRIO,
                 (TaskHandle_t * 				) 	&task2_handler );
								 
		xTaskCreate( (TaskFunction_t				)		task3,
                 (char * 								)		"task3",
                 (configSTACK_DEPTH_TYPE) 	TASK3_STACK_SIZE,
                 (void * 								) 	NULL,
                 (UBaseType_t						)		TASK3_PRIO,
                 (TaskHandle_t * 				) 	&task3_handler );
		vTaskDelete(start_task_handler);
		taskEXIT_CRITICAL();
 }
//实现LED0 每500ms翻转一次
void task1( void * pvParameters )
 {
	 while(1)
	 {
		 printf ("task1正在运行!!!\r\n");
		 LED0_TOGGLE();
		 vTaskDelay(500);
	 }
 }
//实现LED1 每500ms翻转一次
void task2( void * pvParameters )
 {
	 while(1)
	 {
		 printf ("task2正在运行!!!\r\n");
		 LED1_TOGGLE();
		 vTaskDelay(500);
	 }
 }
 //判断按键key0是否按下,按下则删除task1
void task3( void * pvParameters )
 {
	 uint8_t key = 0;
	 while(1)
	 {
			printf ("task3正在运行!!!\r\n");
			key = key_scan(0);
			if(key == KEY0_PRES)
			{
						vTaskSuspend(task1_handler);
			}
			else if(key == KEY1_PRES)
			{
						vTaskResume(task1_handler);
			}
			vTaskDelay(10);
	 }
 }
 
 
 

exti.c 

/**
 ****************************************************************************************************
 * @file        exti.c
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.0
 * @date        2020-04-19
 * @brief       外部中断 驱动代码
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 MiniSTM32 V4开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 * 修改说明
 * V1.0 20200420
 * 第一次发布
 *
 ****************************************************************************************************
 */

#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_demo.h"
#include "FreeRTOS.h"
#include "task.h"
/**
 * @brief       KEY0 外部中断服务程序
 * @param       无
 * @retval      无
 */

extern TaskHandle_t	task1_handler;
/**
 * @brief       KEY1 外部中断服务程序
 * @param       无
 * @retval      无
 */


/**
 * @brief       WK_UP 外部中断服务程序
 * @param       无
 * @retval      无
 */
void WKUP_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);        /* 调用中断处理公用函数 清除KEY1所在中断线 的中断标志位,中断下半部在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 xYiedRequired ;
      
        case WKUP_INT_GPIO_PIN:
            if (WK_UP == 1)
            {
               xYiedRequired = xTaskResumeFromISR(task1_handler);
							if(xYiedRequired == pdTRUE)
							{
									portYIELD_FROM_ISR(xYiedRequired);
							}
            }
            break;
    }
}

/**
 * @brief       外部中断初始化程序
 * @param       无
 * @retval      无
 */
void extix_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;


    WKUP_GPIO_CLK_ENABLE();                                  /* WKUP时钟使能 */


    gpio_init_struct.Pin = WKUP_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;             /* 上升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct);        /* WKUP配置为下降沿触发中断 */



    HAL_NVIC_SetPriority(WKUP_INT_IRQn, 5, 0);               /* 抢占2,子优先级2 */
    HAL_NVIC_EnableIRQ(WKUP_INT_IRQn);                       /* 使能中断线0 */

}












  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值