十三 FreeRTOS 的时间相关函数
FreeRTOS 时间相关的函数主要有以下 4 个:
vTaskDelay () vTaskDelayUntil () xTaskGetTickCount() xTaskGetTickCountFromISR()
1 函数 vTaskDelay
函数原型:
void vTaskDelay( const TickType_t xTicksToDelay ); /* 延迟时间长度 >*/
函数描述:
函数 vTaskDelay 用于任务的延迟
参数 xTicksToDelay 用于设置延迟的时钟节拍个数,范围 1- 0xFFFFFFFF。 延迟时间>的最大值在 portmacro.h 文件里面有定义:typedef uint32_t TickType_t; #define portMAX_DELAY ( TickType_t )0xffffffffUL 即延迟时间的范围是:1~ 0xFFFFFFFF
2 函数 vTaskDelayUntil
函数原型:
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, /* 存储任务>上次处于非阻塞状态时刻的变量地址 */ const TickType_t xTimeIncrement ); /* 周期性延>迟时间 */
(1)函数描述:
函数 vTaskDelayUntil 用于周期性延迟。
第 1 个参数,存储任务上次处于非阻塞状态时刻的变量地址。
第 2 个参数,周期性延迟时间。
(2)使用这个函数要注意以下问题:
1. 在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1才有效
#define INCLUDE_vTaskDelayUntil 1
3 函数 xTaskGetTickCount
函数原型:
volatile TickType_t xTaskGetTickCount( void );
函数描述:
函数 xTaskGetTickCount 用于获取系统当前运行的时钟节拍数。
(1) 此函数用于在任务代码里面调用,如果在中断服务程序里面调用的话,需要使用函数xTaskGetTickCountFromISR,这两个函数切不可混用。
4 函数 xTaskGetTickCountFromISR
函数原型:
volatile TickType_t xTaskGetTickCountFromISR( void );函数描述:
函数 xTaskGetTickCountFromISR 用于获取系统当前运行的时钟节拍数。(1). 此函数用于在中断服务程序里面调用, 如果在任务里面调用的话, 需要使用函数 xTaskGetTickCount,这两个函数切不可混用。
系统节拍和时间管理
#include <stdio.h>
#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;
TickType_t xLastWakeTime;
const TickType_t xFrequency = 500;
/* 获取当前的系统时间 */
xLastWakeTime = xTaskGetTickCount();
while (1) {
LedState = (bool) !LedState;
Board_LED_Set(0, LedState);
// vTaskDelay(500);
/* vTaskDelayUntil 是绝对延迟, vTaskDelay 是相对延迟。 */
vTaskDelayUntil(&xLastWakeTime, xFrequency);
}
}
/******
任务栈测试
*****/
static void vUART_Task (void *pvParameters)
{
//栈剩余检测
printf("vUART_Task 任务栈开始:%d\n",(int)uxTaskGetStackHighWaterMark(NULL));
while (1) {
Board_UARTPutSTR("FreeRTOS 动态创建任务\n");
printf("userKey 按下挂起任务, userKey按下恢复任务\n");
printf("vUART_Task 任务栈剩余:%d\n",(int)uxTaskGetStackHighWaterMark(NULL));
vTaskDelay(1000);
}
}
static void vKEY_task(void* pvParameters)
{
bool KeyState = false;
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:
{
KeyState=!KeyState;
if(KeyState)
{
printf("KEY1挂起任务LED\r\n");
vTaskSuspend(LED1_Task_Handle);
vTaskSuspend(UART_Task_Handle);
}
else
{
printf("KEY1恢复任务LED\r\n");
vTaskResume(LED1_Task_Handle);
vTaskResume(UART_Task_Handle);
}
}break;
case 2:
{
/* 打印系统时钟节拍数 */
printf("当前的系统时钟节拍数 = %d\r\n", xTaskGetTickCount());
}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;
}
}
}
static void vTaskMsgPro(void *pvParameters)
{
bool LedState = false;
TickType_t xDelay, xNextTime;
const TickType_t xFrequency = 200;
/* 获取 xFrequency 个时钟节拍后的时间 */
xNextTime = xTaskGetTickCount() + xFrequency;
while(1)
{
LedState = (bool) !LedState;
Board_LED_Set(1, LedState);
/* 用 vTaskDelay 实现 vTaskDelayUntil() */
xDelay = xNextTime - xTaskGetTickCount();
xNextTime += xFrequency;
if(xDelay <= xFrequency)
{
vTaskDelay(xDelay);
}
}
}
/***********************************************************************
* @ 函数名 : AppTaskCreate
* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
* @ 参数 : 无
* @ 返回值 : 无
**********************************************************************/
static void AppTaskCreate()
{
BaseType_t xReturn=pdPASS;/*定义任务返回值*/
taskENTER_CRITICAL();//进入临界区,禁止中断打断
//
xReturn=xTaskCreate(vLED1_Task,
"vLED1_Task",
TASK_STACK_SIZE*2,
NULL,
(tskIDLE_PRIORITY + 1UL),
(TaskHandle_t *) &LED1_Task_Handle);
xReturn=xTaskCreate(vUART_Task,
"vUART_Task",
TASK_STACK_SIZE*2,
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);
xReturn=xTaskCreate(vTaskMsgPro,
"vTaskMsgPro",
TASK_STACK_SIZE*4,
NULL,
(tskIDLE_PRIORITY + 1UL),
NULL);
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中的时间管理函数,包括vTaskDelay、vTaskDelayUntil、xTaskGetTickCount和xTaskGetTickCountFromISR的使用方法和注意事项。通过实例展示了如何在任务中实现周期性延迟,并探讨了系统时钟节拍数的获取。同时,还涵盖了任务栈的检测以及任务创建和管理。

3958

被折叠的 条评论
为什么被折叠?



