当前位置: 首页 > article >正文

STM32F1+HAL库+FreeTOTS学习11——延时函数API

STM32F1+HAL库+FreeTOTS学习11——延时函数API

  • 延时函数API
    • 1. vTaskDelay()
    • 2. vTaskDelayUntil()
    • 3. xTaskDelayUntil()
    • 相对延时和绝对延时的区别
    • 4. xTaskAbortDelay()

上一期,我们学习了任务相关API使用,这一期我们开始学习FreeRTOS延时函数的API使用

延时函数API

在FreeRTOS官方提供的技术文档中,一共提供了三种延时的函数,他们的功能都只有一种:延时,但是又存在一定的差异,让我们来看一下:
在这里插入图片描述

1. vTaskDelay()

函数 vTaskDelay()用于对任务进行延时,延时的时间单位为系统时钟节拍,使用此函数,需要将宏 INCLUDE_vTaskDelay 配置为 1。其函数原型如下:

/**
 * @brief       vTaskDelay
 * @param       xTicksToDelay : 需要延时的时间,延时单位为系统节拍
 * @retval      无
 */
void vTaskDelay( const TickType_t xTicksToDelay );

//使用示例如下:
/**
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task1(void *pvParameters)
{
    
    while(1)
    {
        HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);  
		 /* LED0闪烁 */
        vTaskDelay(500);                                               /* 延时1000ticks */
    }
}	

需要注意以下两点

  1. vTaskDelay延时的单位是系统节拍,具体长度由宏 configTICK_RATE_HZ 决定,在FreeRTOS默认的源码里面,该值为1000 HZ,那么一个系统节拍对应的时间就是1/1000s = 1ms ,500个系统节拍就是500ms。
  2. vTaskDelay函数的延时时间,是从调用该函数开始的,由于vTaskDelay前面的代码运行时间不确定,所以实际上下一次运行任务1的时间并不是准确的500ms,只能是大概500ms。

2. vTaskDelayUntil()

函数vTaskDelayUntil()用于以一个绝对的时间阻塞任务,适用于需要按照一定频率运行的任务,函数vTaskDelayUntil()实际上是一个宏,在task.h文件中有定义,具体的代码如下所示:

#define vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ) \
{ \
 ( void ) xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); \
}

通过观察代码,我们发现vTaskDelayUntil内部是直接调用了 xTaskDelayUntil() 函数,所以我们直接来介绍xTaskDelayUntil() 函数

3. xTaskDelayUntil()

和vTaskDelayUntil() 函数相同,xTaskDelayUntil()也是用于一个绝对的时间阻塞任务,适用于需要按照一定频率运行的任务,其函数原型如下:

/**
 * @brief       xTaskDelayUntil
 * @param       pxPreviousWakeTime: 用于记录上一次任务解除阻塞的系统节拍数(系统时间),改变量首次使用前必须初始化,
 * 				后续会在xTaskDelayUntil()中自动更新。
 * @param       xTimeIncrement : 周期时间段。任务将在 (*pxPreviousWakeTime + xTimeIncrement) 时间取消阻塞。
 * 				使用 相同的 xTimeIncrement 	参数值调用 xTaskDelayUntil 将导致任务以固定的间隔周期执行 。
 * @retval      返回值为pdTRUE表示任务实际延时,如果为pdFALSE表示下一个预计唤醒的时间已过,无法执行延时,任务将不延时。
 */
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
                                const TickType_t xTimeIncrement );

//使用示例如下:
/**
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task2(void *pvParameters)	
{	
	
	TickType_t xLastWakeTime;										/*定义上一次解除阻塞的时间*/
	const TickType_t xFrequency = 500;								/*定义周期时间段*/
	BaseType_t xWasDelayed;
	
	xLastWakeTime = xTaskGetTickCount ();
	
	
while(1)
    {
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);   					/* LED0闪烁 */

		xWasDelayed = xTaskDelayUntil(&xLastWakeTime,xFrequency);

    }
}

相对延时和绝对延时的区别

  1. vTaskDelay() 函数是相对延时,指每次延时都是从执行函数vTaskDelay()开始,直到延时指定的时间结束。在这个过程中,如果vTaskDelay() 函数前面的内容执行了一段时间(我们这里举个栗子:50ms) ,并且我们通过vTaskDelay() 函数延时了500个系统节拍,那么这个任务实际运行的间隔就是550ms。
  2. vTaskDelayUntil() 和 xTaskDelayUntil() 函数是绝对延时,指将整个任务的运行周期看成一个整体,适用于需要按照一定频率运行的任务,比如我们这里使用xTaskDelayUntil()函数延时500ms,那么整个任务的运行间隔就是500ms(前提是任务里面的代码整体运行实际不能超过500ms)。
    在这里插入图片描述

下面我简单的看一段代码,深入了解以下:

void task1(void *pvParameters)
{
    
    while(1)
    {
        HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);   				/* LED0闪烁 */
		HAL_Delay(250);												/*强制延时250ms,模拟代码运行*/
																	/*在freeRTSO的任务里面本不应该出现整个延时函数*/
																	/*这里出现时为了做演示,让效果更明显*/
        vTaskDelay(500);                                           /* 延时500没事、*/
    }
}	
/**
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task2(void *pvParameters)	
{	
	
	TickType_t xLastWakeTime;										/*定义上一次解除阻塞的时间*/
	const TickType_t xFrequency = 500;								/*定义周期时间段*/
	BaseType_t xWasDelayed;
	
	xLastWakeTime = xTaskGetTickCount ();
	
	
while(1)
    {
		HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);   					/* LED0闪烁 */
		HAL_Delay(250);												/*强制延时250ms,模拟代码运行*/
																	/*在freeRTSO的任务里面本不应该出现整个延时函数*/
																	/*这里出现时为了做演示,让效果更明显*/
		
		xWasDelayed = xTaskDelayUntil(&xLastWakeTime,xFrequency);		/*绝对延时500ms*/

    }
}
  • 在任务1当中,我们先调用HAL_Delay() 进行强制延时,模拟代码正在运行,如何调用vTaskDelay(500)执行了时长为500ms的相对延时,那么任务1的执行周期应该就是750ms
  • 在任务2当中,我们先调用HAL_Delay() 进行强制延时,模拟代码正在运行,如何调用xTaskDelayUntil(500)执行了时长为500ms的绝对延时,那么任务1的执行周期应该就是500ms

以上是我们分析得到的,下面我们来看一下实际情况:

在这里插入图片描述

和理论一致,没有问题!

4. xTaskAbortDelay()

函数 xTaskAbortDelay()用于终止处于阻塞态任务的阻塞,此函数在 task.c 文件中有定义。函数原型如下:

/**
 * @brief       xTaskAbortDelay
 * @param       xTask : 将被强制退出阻塞状态的任务的句柄。
 * @retval      如果 xTask 引用的任务不在“阻塞”状态,则返回 pdFAIL。否则返回 pdPASS。
 */
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );

http://www.kler.cn/a/312640.html

相关文章:

  • 软件工程的基础和核心理论概念
  • vite构建的react程序放置图片
  • Linux系统的网络设置
  • 全球碳循环数据集(2000-2023)包括总初级生产力、生态系统净碳交换和生态系统呼吸变量
  • el-dialog 设置 水平垂直居中 高度不固定
  • 【算法速刷(9/100)】LeetCode —— 42.接雨水
  • QT的dropEvent函数进入不了
  • 平滑损失对生成图像的影响和使用场景
  • 跟着DAMA学数据管理--数据管理框架
  • 身份证实名认证的应用场景-身份证识别api
  • 人工智能安全治理新篇章:《2024人工智能安全治理框架1.0版》深度解读@附20页PDF文件下载
  • cas 5.3服务器搭建
  • 【busybox记录】【shell指令】stdbuf
  • MySQL —— 索引
  • C++ | Leetcode C++题解之第407题接雨水II
  • Windows下SDL2创建最简单的一个窗口
  • 华为昇腾服务器+Atlas300IPro*2 部署Dify+MindIE+Embedding+Rerank实现Qwen2.5-7B全国产化的大模型推理平台
  • stm32f411ceu6芯片学习
  • CSP-J 算法基础 归并排序
  • VideoPlayer插件的用法
  • 初体验《SpringCloud 核心组件Eureka》
  • 栈的各种接口的实现(C)
  • 软设9.20
  • 828华为云征文|基于华为云Flexus X实例快速搭建Halo博客平台
  • 后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0916)
  • 基于SSM+Vue+MySQL的家教服务管理系统