12 freertos任务-任务栈调度锁

十二 freertos任务-任务栈调度锁

FreeRTOS 打开调度锁

使用如下函数可以实现 FreeRTOS 的调度锁开启:

vTaskSuspendAll ()

函数原型:

	void vTaskSuspendAll( void );

函数描述:

	函数 vTaskSuspendAll 用于实现 FreeRTOS 调度锁开启。

使用这个函数要注意以下问题:

	1. 调度锁函数只是禁止了任务调度,并没有关闭任何中断。
	2. 调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 一定要成对使用。
	3. 切不可在调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 之间调用任何会引起任务切换的 API,比如 vTaskDelayUntil、 vTaskDelay、 xQueueSend 等。

FreeRTOS 调度锁关闭

使用如下函数可以实现 FreeRTOS 的调度锁关闭:

xTaskResumeAll ()

函数原型:

BaseType_t xTaskResumeAll(void)

函数描述:

函数 xTaskResumeAll 用于实现 FreeRTOS 调度锁关闭

调度锁关闭后,如果需要任务切换,此函数返回 pdTRUE,否则返回 pdFALSE。
使用这个函数要注意以下问题:

1. 调度锁函数只是禁止了任务调度,并没有关闭任何中断。
2. 调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 一定要成对使用。
3. 切不可在调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 之间调用任何会引	起任务切换的 API,比如 vTaskDelayUntil、 vTaskDelay、 xQueueSend 等。
#include 
#include "board.h"
#include "led.h"
#include "key.h"

#include "uart.h"


/*** System oscillator rate and clock rate on the CLKIN pin  ****/
/**/const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ;		 /**/
/**/const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ;		 /**/
 //系统复位
#define	System_restart	(LPC_SWM->PINENABLE0 = 0xffffffffUL) /**/
/***************************************************************/


#include "FreeRTOSConfig.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
/**************************** 任务句柄 ********************************/
/* 
 * 任务句柄是一个指针,用于指向一个任务。
 */

/* LED任务句柄 */	
static TaskHandle_t LED1_Task_Handle= NULL;	
static TaskHandle_t UART_Task_Handle= NULL;	
static TaskHandle_t KEY_Task_Handle = NULL;	
//static xTaskHandle  pv_handle = NULL;

#define TASK_STACK_SIZE 32


/* Sets up system hardware 
**********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
*********************************************************************/
static void prvSetupHardware(void)
{

	SystemCoreClockUpdate();

	DEBUGINIT();
	led_Init() ;	
	Key_INIT();


	Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "\n");

}


/**********************************************************************
  * @ 函数名  : vLED_Task0
  * @ 功能说明: LED_Task任务主体
  * @ 参数    :   
  * @ 返回值  : 无
  ********************************************************************/

static void vLED1_Task (void *pvParameters)
{
	bool LedState = false;
	u8 i=0;
	while (1) {
		
		LedState = (bool) !LedState;
		for(i=0;i<8;i++)
		{
			Board_LED_Set(i, LedState);
			
		}
		vTaskDelay(500);
		
	}
}

/******
任务栈测试
*****/
static void vUART_Task (void *pvParameters)
{

	//栈剩余检测
	printf("vUART_Task 任务栈开始:%d\n",(int)uxTaskGetStackHighWaterMark(NULL));
	while (1) {

		Board_UARTPutSTR("FreeRTOS 动态创建任务\n");
		printf("userKey 按下挂起任务, upKey按下恢复任务\n");
		printf("vUART_Task 任务栈剩余:%d\n",(int)uxTaskGetStackHighWaterMark(NULL));
		vTaskDelay(1000);


	}
}

static void vKEY_task(void* pvParameters)
{
	uint8_t pcWriteBuffer[200];
	u8 key2=0;
	while(1)
	{
		u8 key=0;
		if(Scan_Key())
			vTaskDelay(20);
		else continue;
		if(!Scan_Key())continue;
		else
		{
			key=Scan_Key();
			key2=key;
		}
		
		vTaskSuspendAll(); /* 开启调度锁 */
		while(Scan_Key()){};//等按键抬起
		/* 关闭调度锁,如果需要任务切换,此函数返回 pdTRUE,否则返回 pdFALSE */
		if(!xTaskResumeAll())
		{
			taskYIELD ();
		}
		
		if(key2)
		{

			switch(key2)
			{
				case 1:
				{
					printf("KEY1挂起任务LED\r\n");
					vTaskSuspend(LED1_Task_Handle);
					vTaskSuspend(UART_Task_Handle);
				}break;
				case 2:
				{
					printf("KEY2恢复任务LED\r\n");
					vTaskResume(LED1_Task_Handle);
					vTaskResume(UART_Task_Handle);
				}break;
				case 3:
				{
					/*为了获取FreeRTOS任务的执行情况,需要执行如下操作
					* a在FreeRTOSConfig.h文件中使能如下宏
					* #define configUSE_TRACE_FACILITY	                1
					* #define configGENERATE_RUN_TIME_STATS               1
					*/
					printf("=================================================\r\n");
					printf("任务名      任务状态 优先级   剩余栈 任务序号\r\n");
					vTaskList((char *)&pcWriteBuffer);
					printf("%s\r\n", pcWriteBuffer);
 					
				}break;
				default:break;
			}
			key2=0;
		}
		

			
	}
}


/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate()
{
	BaseType_t xReturn=pdPASS;/*定义任务返回值*/
	
	taskENTER_CRITICAL();//进入临界区,禁止中断打断
//	
 
	xReturn=xTaskCreate(vLED1_Task, 
						"vLED1_Task",
						TASK_STACK_SIZE, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						(TaskHandle_t *) &LED1_Task_Handle);

	xReturn=xTaskCreate(vUART_Task, 
						"vUART_Task",
						TASK_STACK_SIZE+32, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						&UART_Task_Handle);
	
	xReturn=xTaskCreate(vKEY_task, 
						"vKEY_Task",
						TASK_STACK_SIZE*4, 
						NULL, 
						(tskIDLE_PRIORITY + 1UL),
						(TaskHandle_t *) &KEY_Task_Handle);
				
	if(pdPASS==xReturn)
	{
		printf("创建LED_Task任务成功\r\n");
	}	

	
	
	
	
//	 vTaskDelete(LED1_Task_Handle);//删除AppTaskCreate任务
//	 vTaskDelete(UART_Task_Handle);//删除AppTaskCreate任务

	
	taskEXIT_CRITICAL(); //退出临界区
	

}

/**
 * @brief	main routine for blinky example
 * @return	Function should not exit.
 */
int main(void)
{
	
	prvSetupHardware();
	Board_UARTPutSTR("LPC824 FreeRTOS 任务管理\n\r");
	printf("Key按下挂起任务,Key按下恢复任务\r\n");

	AppTaskCreate();
	vTaskStartScheduler();//任务调度

	
	
	/* Loop forever */
	while (1) {
			printf("FreeRTOS 运行失败\n\r");
 	}
	
	
}


你可能感兴趣的:(FreeRTOS,单片机)