FreeRTOS教程8 任务通知

这篇具有很好参考价值的文章主要介绍了FreeRTOS教程8 任务通知。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、准备材料

正点原子stm32f407探索者开发板V2.4

STM32CubeMX软件(Version 6.10.0)

Keil µVision5 IDE(MDK-Arm)

野火DAP仿真器

XCOM V2.6串口助手

2、学习目标

本文主要学习 FreeRTOS 任务通知的相关知识,包括FreeRTOS中的通信手段、任务通知的优缺点、任务通知 API 函数等知识

3、前提知识

3.1、FreeRTOS 中的通信手段

一个 FreeRTOS 负责的系统中,总是存在很多任务和中断,这些不同的任务和中断之间往往需要大量的通信来保证整个系统的运行,到本篇文章为止也已经介绍了包括队列、二值/计数信号量、互斥量、递归互斥量和事件组在内的多种通信方式

3.1.1、通过中介对象进行通信

但是目前已经介绍的这些通信方式有一个共同的特点,当使用通信对象时,事件和数据不会直接发送到接收任务或接收 ISR ,而是发送到通信对象。同样,任务和 ISR 从通信对象接收事件和数据,而不是直接从发送事件或数据的任务或 ISR 接收,这个特点可以用下图表示 (注释1)

3.1.2、直接任务通信

本篇文章所介绍的 “任务通知” 允许在不需要额外的中间媒介(通信对象)的情况下,实现任务与其他任务直接交互,并与 ISR 同步。通过使用任务通知,任务或 ISR 可以直接向接收任务发送事件,该特点可以用下图表示

可以在 FreeRTOSConfig.h 文件中设置 configUSE_TASK_NOTIFICATIONS 参数为 1 启动任务通知功能,启动该功能之后,会在每个任务的 TCB (任务控制块)中增加 8 字节空间,此时每个任务都有一个“通知状态”(可以是 “挂起” 或 “未挂起” )和一个 “通知值” (32 位无符号整数)。当任务收到通知时,其通知状态将设置为挂起,当任务读取其通知值时,其通知状态将设置为未挂起

3.2、任务通知的优缺点

3.2.1、优点

任务通知在性能和 RAM 占用上存在优势,具体为以下两点

  1. 使用任务通知向任务发送事件或数据比使用队列、信号量或事件组执行等效操作要快得多
  2. 启用任务通知功能的固定开销仅为每个任务 8 个字节的 RAM ,而队列、信号量、事件组等在使用前都必须创建,占用空间较大

3.2.2、缺点

任务通知比通信对象更快并且使用更少的 RAM ,但任务通知不能在所有场景中使用,如下所示记录了无法使用任务通知的场景

  1. 通信对象可用于将事件和数据从 ISR 发送到任务,以及从任务发送到 ISR;任务通知只能用于将事件和数据从 ISR 发送到任务,不能用于将事件或数据从任务发送到 ISR
  2. 任何知道通信对象句柄的任务和 ISR 都可以访问通信对象,因此多个任务或 ISR 都可以发送或接收消息;任务通知只能将事件和数据发送到某个具体的接收任务中,发送的事件和数据只能由接收任务使用处理
  3. 队列是一种通信对象,一次可以保存多个数据项,已发送到队列但尚未从队列接收的数据将缓冲在队列对象内;任务通知通过更新接收任务的通知值来向任务发送数据,任务的通知值一次只能保存一个值
  4. 事件组是一种通信对象,可用于一次向多个任务发送事件;任务通知直接发送给接收任务,因此只能由接收任务处理
  5. 如果通信对象暂时处于无法向其写入更多数据或事件的状态(例如,当队列已满时,无法向队列发送更多数据),则尝试写入该对象的任务可以选择进入阻塞状态以等待其写操作完成;如果任务尝试向已经有待处理通知的任务发送任务通知,则发送任务不可能在阻塞状态下等待接收任务重置其通知状态

3.3、任务通知 API 概述

在任务通知这一部分,FreeRTOS 为使用者提供了三组 API 函数,三组 API 的特点如下所述

  1. 强大通用但较复杂的 xTaskNotify() 和 xTaskNotifyWait() API 函数
  2. 用作二进制或计数信号量的更轻量级且更快的替代方案的 xTaskNotifyGive() 和 ulTaskNotifyTake() API 函数
  3. 在序号 1 的基础上增加 pulPreviousNotifyValue 参数值的 xTaskNotifyAndQuery() API函数

上面三组不同类型 API 还拥有其对应的中断安全版本函数, 任务通知可以用来代替二进制信号量、计数信号量、事件组,有时甚至可以代替队列, 但是在大多数情况下使用者可能不需要使用如上述序号 1 中所述 API 函数提供的完全灵活性,一组更简单的函数就足够了

因此开发者提供了 xTaskNotifyGive() API 函数以允许将任务通知用作二值或计数信号量的更轻量级且更快的替代方案,并且提供 ulTaskNotifyTake() API 函数作为 xTaskNotifyWait() 的更简单但灵活性较差的替代方案,所以具体使用哪一组 API 函数可以根据使用者的需要按需使用

3.4、xTaskNotifyGive() 和 ulTaskNotifyTake() API 函数

xTaskNotifyGive() 直接向任务发送通知,并对接收任务的通知值进行递增(加一,因为是模拟信号量),如果接收任务尚未挂起,则调用 xTaskNotifyGive() 会将接收任务的通知状态设置为挂起,该 API 实际上是作为宏实现的,而不是函数,其具体声明如下所述

/**
  * @brief  任务通知用作轻量级且更快的二进制或计数信号量替代方案时所使用的通知发送函数
  * @param  xTaskToNotify:通知发送到的任务的句柄
  * @retval 只会返回pdPASS
  */
BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify);

/**
  * @brief  上述函数的的中断安全版本函数
  * @param  xTaskToNotify:通知发送到的任务的句柄
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval None
  */
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
							BaseType_t *pxHigherPriorityTaskWoken);

当一个任务使用 xTaskNotifyGive() API 函数将通知值用作二值或等效计数信号量时, 则被通知的任务应使用 ulTaskNotifyTake() API 函数来接收或等待通知值

ulTaskNotifyTake() 允许任务在阻塞状态下等待其通知值大于零,并在返回之前递减(减一)或清除任务的通知值,其具体函数声明如下所述

/**
  * @brief  任务通知被用作更快、更轻的二进制或计数信号量替代时使用通知接收函数
  * @param  xClearCountOnExit:设置为pdTRUE,则该函数返回之前,调用任务的通知值将被清零;设置为pdFASLE,并且通知值大于0,则调用任务的通知值将在该函数返回之前递减
  * @param  xTicksToWait:调用任务应保持阻塞状态以等待其通知值大于零的最长时间
  * @retval 阻塞时间到期也没能等到消息则返回 0 ,阻塞时间到期前等到消息则返回之前的通知值
  */
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait);

3.5、xTaskNotify() API 函数

xTaskNotify() 是 xTaskNotifyGive() 的功能更强大的版本,可用于通过以下任意方式更新接收任务的通知值

  1. 接收任务的通知值递增(加一),在这种情况下 xTaskNotify() 相当于 xTaskNotifyGive()
  2. 接收任务的通知值中设置一位或多位,这允许任务的通知值用作事件组的更轻量级和更快的替代方案
  3. 将一个全新的数字写入接收任务的通知值,但前提是接收任务自上次更新以来已读取其通知值,这允许任务的通知值提供与长度为 1 的队列提供的功能类似的功能
  4. 将一个全新的数字写入接收任务的通知值,即使接收任务自上次更新以来尚未读取其通知值,这允许任务的通知值提供与 xQueueOverwrite() API 函数提供的功能类似的功能,由此产生的行为有时被称为“邮箱”

xTaskNotify() 比 xTaskNotifyGive() 更灵活、更强大,并且由于额外的灵活性和强大功能,它的使用也稍微复杂一些,使用 xTaskNotify() 函数时,如果接收任务尚未挂起,则调用 xTaskNotify() 将始终将其设置为挂起状态,如下所示为其具体函数声明

/**
  * @brief  任务通知函数
  * @param  xTaskToNotify:通知发送到的任务的句柄
  * @param  ulValue:ulValue的使用方式取决于eAction值,参考 “3.5.1、eAction 参数” 小节
  * @param  eAction:一个枚举类型,指定如何更新接收任务的通知值,参考 “3.5.1、eAction 参数” 小节
  * @retval 除 “3.5.1、eAction 参数” 小节提到的一种情况外,均返回pdPASS
  */
BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify,
					   uint32_t ulValue,
					   eNotifyAction eAction);

/**
  * @brief  任务通知的中断安全版本函数
  * @param  xTaskToNotify:通知发送到的任务的句柄
  * @param  ulValue:ulValue的使用方式取决于eAction值,参考 “3.5.1、eAction 参数” 小节
  * @param  eAction:一个枚举类型,指定如何更新接收任务的通知值,参考 “3.5.1、eAction 参数” 小节
  * @param  pxHigherPriorityTaskWoken:用于通知应用程序编写者是否应该执行上下文切换
  * @retval 除 “3.5.1、eAction 参数” 小节提到的一种情况外,均返回pdPASS
  */
BaseType_t xTaskNotifyFromISR(TaskHandle_t xTaskToNotify,
							  uint32_t ulValue,
							  eNotifyAction eAction
							  BaseType_t *pxHigherPriorityTaskWoken);

3.5.1、eAction 参数

eAction 参数是一个 eNotifyAction 枚举类型,其定义了 5 中不同枚举类型,用于模拟二值信号量、计数信号量、队列、事件组和 ”邮箱“ 等功能,其具体定义如下所述

eNotifyAction 值 对接收任务的最终影响
eNoAction 接收任务的通知状态设置为待处理,而不更新其通知值,未使用 xTaskNotify() 中 ulValue 参数
eSetBits 接收任务的通知值与 xTaskNotify() 中 ulValue 参数中传递的值进行按位或运算,例如:如果 ulValue 设置为 0x01,则接收任务的通知值中将置位第 0 位
eIncrement 接收任务的通知值递增,未使用 xTaskNotify() 中 ulValue 参数
eSetValueWithoutOverwrite 如果接收任务在调用 xTaskNotify() 之前有待处理的通知,则不执行任何操作,并且 xTaskNotify() 将返回 pdFAIL;如果在调用 xTaskNotify() 之前接收任务没有待处理的通知,则接收任务的通知值将设置为 xTaskNotify() 中 ulValue 参数中传递的值
eSetValueWithOverwrite 接收任务的通知值设置为 xTaskNotify() ulValue 参数中传递的值,无论接收任务在调用 xTaskNotify() 之前是否有待处理的通知

3.6、xTaskNotifyWait() API 函数

xTaskNotifyWait() 是 ulTaskNotifyTake() 的功能更强大的版本,它允许任务以可选的超时等待调用任务的通知状态变为待处理(如果它尚未处于待处理状态),xTaskNotifyWait() 提供了在进入函数和退出函数时清除调用任务的通知值中的位的参数 ulBitsToClearOnEntryulBitsToClearOnExit

/**
  * @brief  任务通知的中断安全版本函数
  * @param  ulBitsToClearOnEntry:参考 “3.6.1、ulBitsToClearOnEntry 参数” 小节
  * @param  ulBitsToClearOnExit:参考 “3.6.2、_ulBitsToClearOnExit_ 参数” 小节
  * @param  pulNotificationValue:用于传递任务的通知值,因为等待通知的函数可能由于 ulBitsToClearOnExit 参数在函数退出时收到的消息值已被更改
  * @param  xTicksToWait:调用任务应保持阻塞状态以等待其通知状态变为挂起状态的最长时间
  * @retval 参考 “3.6.2、xTaskNotifyWait() 函数返回值” 小节
  */
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,
						   uint32_t ulBitsToClearOnExit,
						   uint32_t *pulNotificationValue,
						   TickType_t xTicksToWait);

3.6.1、ulBitsToClearOnEntry 参数

如果调用任务在调用 xTaskNotifyWait() 之前没有待处理的通知,则在进入该函数时,将在任务的通知值中清除参数 ulBitsToClearOnEntry 中设置的任何位

例如,如果参数 ulBitsToClearOnEntry 为 0x01,则任务通知值的位 0 将被清除,再举一个例子,将参数 ulBitsToClearOnEntry 设置为 0xffffffff(ULONG_MAX)将清除任务通知值中的所有位,从而有效地将值清除为 0

3.6.2、ulBitsToClearOnExit 参数

如果调用任务因为收到通知而退出 xTaskNotifyWait() ,或者因为在调用 xTaskNotifyWait() 时已经有通知挂起,那么在参数 ulBitsToClearOnExit 中设置的任何位将在任务退出 xTaskNotifyWait() 函数之前在任务的通知值中被清除

例如,如果参数 ulBitsToClearOnExit 为 0x03 ,则任务通知值的位 0 和位 1 将在函数退出之前被清除,再举个例子,将参数 ulBitsToClearOnExit 为 0xffffffff(ULONG_MAX)将清除任务通知值中的所有位,从而有效地将值清除为 0

3.6.2、xTaskNotifyWait() 函数返回值

有两种可能的返回值,分别为 pdPASS 和 pdFALSE ,具体如下所述

① pdPASS

  1. 调用 xTaskNotifyWait() 时调用任务已经有待处理的通知
  2. 调用 xTaskNotifyWait() 时调用任务没有待处理的通知,由于设置了阻塞时间因此进入阻塞状态等待消息挂起,在阻塞时间到期之前成功等到消息挂起

② pdFALSE

  1. 调用 xTaskNotifyWait() 时调用任务没有待处理的通知,由于设置了阻塞时间因此进入阻塞状态等待消息挂起,但是直到阻塞时间到期都没有等到消息挂起

3.7、其他 API 函数

除了上面的一些常用 API 之外,还有一些工具或不常用的 API 函数,因为启用任务通知后会在任务控制块中增加一个任务状态和一个任务通知值,因此 FreeRTOS 提供了清除任务状态的 xTaskNotifyStateClear() API 函数和 清除任务通知值的 ulTaskNotifyValueClear() API 函数

另外增加了 "3.3、任务通知 API 概述" 小节中提到的在 xTaskNotify() API 函数上增加了 pulPreviousNotifyValue 参数的 xTaskNotifyAndQuery() API函数和其中断安全版本函数,上述提到的四个函数声明具体如下所述

/**
  * @brief  清除任务通知状态
  * @param  xTask:要操作的任务句柄
  * @retval 如果要操作的任务有待处理的通知,并且该通知已清除,则返回pdTRUE;如果该任务没有待处理的通知,则返回pdFALSE
  */
BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask);

/**
  * @brief  清除任务通知值
  * @param  xTask:要操作的任务句柄
  * @param  ulBitsToClear:xTask的通知值中要清除的位的位掩码,比如设置为0x01表示将通知值的第0位清除
  * @retval ulBitsToClear指定的位被清除之前目标任务的通知值的值
  */
uint32_t ulTaskNotifyValueClear(TaskHandle_t xTask,
								uint32_t ulBitsToClear);

/**
  * @brief  执行与xTaskNotify()相同的操作,此外它还在附加的pulPreviousNotifyValue中返回目标任务的先前通知值(调用函数时的通知值,而不是函数返回时的通知值)
  * @param  xTaskToNotify:被通知任务的句柄
  * @param  ulValue:通知值,ulValue的使用方式取决于eAction值,参考 “3.5.1、eAction 参数” 小节
  * @param  eAction:一个枚举类型,指定如何更新接收任务的通知值,参考 “3.5.1、eAction 参数” 
  * @param  pulPreviousNotifyValue:返回目标任务的先前通知值
  * @retval 除 “3.5.1、eAction 参数” 小节提到的一种情况外,均返回pdPASS
  */
BaseType_t xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify,
							   uint32_t ulValue,
							   eNotifyAction eAction,
							   uint32_t *pulPreviousNotifyValue);
							   

/**
  * @brief  上述函数的中断安全版本
  * @param  pxHigherPriorityTaskWoken:通知应用程序编程者是否需要进行上下文切换
  */
BaseType_t xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,
									  uint32_t ulValue,
									  NotifyAction eAction,
									  uint32_t *pulPreviousNotifyValue,
									  BaseType_t *pxHigherPriorityTaskWoken);

4、实验一:使用任务通知替代信号量

4.1、实验目标

既然本实验目的是使用任务通知替代信号量,那么我们可以使用任务通知重新实现一下 "FreeRTOS教程5 信号量" 文章中 “4、实验一:二值信号量的应用” 小节内容

4.2、CubeMX相关配置

复制 “FreeRTOS教程5 信号量” 文章中 “4、实验一:二值信号量的应用”小节所描述的实验工程,然后通过 “.ioc” 后缀的文件打开该工程的 STM32CubeMX 软件配置界面,单击 Middleware and Software Packs/FREERTOS ,在 Configuration 中找到 Timers and Semaphores ,删除原来创建好名为 BinarySem_ADC 的二值信号量,然后直接重新生成工程代码即可

4.3、添加其他必要代码

重新实现 ADC 采集转换完成中断回调函数和任务函数 TASK_ADC ,主要是将原来使用二值信号量同步 ISR 和 TASK_ADC 的程序修改为使用任务通知,具体如下所示

/*ADC数据处理任务*/
void TASK_ADC(void *argument)
{
  /* USER CODE BEGIN TASK_ADC */
	//定义一个变量用于表示任务待处理的事件数量
	uint32_t ulEventsToProcess;
  /* Infinite loop */
  for(;;)
  {
		//等待任务通知
		ulEventsToProcess = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(500));
		//如果等到事件
		if(ulEventsToProcess != 0)
		{
			//当待处理的事件不为0就一直处理,处理一次待处理的事件减少1
			while(ulEventsToProcess > 0)
			{
				uint32_t Volt = (3300 * adc_value)>>12;
				printf("val:%d, Volt:%d\r\n", adc_value, Volt);
				ulEventsToProcess --;
			}
		}
  }
  /* USER CODE END TASK_ADC */
}


/*转换完成中断回调*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	/*定时器中断启动单通道转换*/
	if(hadc->Instance == ADC1)
	{
		//获取原始ADC采集值
		adc_value = HAL_ADC_GetValue(hadc);
		BaseType_t highTaskWoken = pdFALSE;
		if(task_ADCHandle != NULL)
		{
			//采集完毕给TASK_ADC任务发送采集完毕的通知
			vTaskNotifyGiveFromISR(task_ADCHandle, &highTaskWoken);
			portYIELD_FROM_ISR(highTaskWoken);
		}
	}
}

4.4、烧录验证

实验现象与 “FreeRTOS教程5 信号量” 文章 “4.4、烧录验证” 小节内容一样,如下图所示

5、实验二:使用任务通知传递数据

5.1、实验目标

“4、实验一:使用任务通知替代信号量” 小节的实验流程如下所述

  1. TASK_ADC 等待消息的到来
  2. ADC_ISR 获取原始 ADC 采集值,然后将采集值写入全局变量 adc_value 中,并且发送消息给 TASK_ADC 表示采集完成
  3. TASK_ADC 消息挂起,退出阻塞状态,然后对存入全局变量 adc_value 中的采集值进行处理,最后通过串口将信息输出

本实验要实现的目的仍然为单通道的 ADC 采集,只不过不需要定义全局变量 adc_value 来存储采集到的原始 ADC 的值,之前提到过启用任务通知后,任务会有一个 32 位的通知值,当我们需要传递的数据为 32 位或更低位的数据时我们可以用这个通知值来直接传递数据

但是注意不是所有情况下都可以用来传递数据的,这要根据 eAction 参数来决定,具体可以参考 “3.5.1 eAction 参数” 小节内容,这里我们将其选择为 eSetValueWithOverwrite ,但是要注意这时只能传递一个数据,传递完毕如果接收端不处理下次该数据就会被覆盖掉,本实验流程如下所述

  1. TASK_ADC 等待消息的到来
  2. ADC_ISR 获取原始 ADC 采集值,将原始 ADC 采集值作为通知值传递给 TASK_ADC
  3. TASK_ADC 消息挂起,然后退出阻塞状态,取出通知值进行处理,最后通过串口将信息输出

5.2、CubeMX相关配置

复制 “4、实验一:使用任务通知替代信号量” 小节配置好的工程即可

5.3、添加其他必要代码

打开工程代码,修改 TASK_ADC 任务函数体和 ADC 采集完毕中断回调函数,具体如下所述

/*ADC处理任务*/
void TASK_ADC(void *argument)
{
	/* USER CODE BEGIN TASK_ADC */
	//定义一个变量用于表示任务待处理的事件数量
	uint32_t notifyValue;
	/* Infinite loop */
	for(;;)
	{
		//进入xTaskNotifyWait函数时不清除任何位
		uint32_t ulBitsToClearOnEntry = 0x00;
		//退出xTaskNotifyWait函数时清除所有位
		uint32_t ulBitsToClearOnExit = 0xFFFFFFFF;
		//等待任务通知
		BaseType_t result = xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, &notifyValue, portMAX_DELAY);
		//如果等到事件
		if(result == pdTRUE)
		{
			//对采集值处理并通过串口输出
			uint32_t Volt = (3300 * notifyValue)>>12;
			printf("val:%d, Volt:%d\r\n", notifyValue, Volt);
		}
	}
  /* USER CODE END TASK_ADC */
}

/*ADC转换完成中断回调*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	//定时器中断启动单通道转换
	if(hadc->Instance == ADC1)
	{
		//获取原始ADC采集值
		uint32_t adc_value = HAL_ADC_GetValue(hadc);
		BaseType_t highTaskWoken = pdFALSE;
		if(task_ADCHandle != NULL)
		{
			//采集完毕后将采集值作为消息数据发送给TASK_ADC任务
			xTaskNotifyFromISR(task_ADCHandle, adc_value, eSetValueWithOverwrite, &highTaskWoken);
			portYIELD_FROM_ISR(highTaskWoken);
		}
	}
}

5.4、烧录验证

实验现象与 “FreeRTOS教程5 信号量” 文章 “4.4、烧录验证” 小节内容一样,此处不再赘述

6、注释详解

注释1:图片来源于 Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf

参考资料

STM32Cube高效开发教程(基础篇)

Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf文章来源地址https://www.toymoban.com/news/detail-841643.html

到了这里,关于FreeRTOS教程8 任务通知的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 CubeMX (第二步Freertos任务通信:队列、信号量、互斥量,事件组,任务通知)

    学习使用Freertos第二步 在 FreeRTOS 中,任务通信可以通过以下函数来实现: xQueueCreate() :用于创建一个消息队列。可以设置队列长度和每个消息的大小。 xQueueSend() :将一条消息发送到队列中。可以选择阻塞或非阻塞发送。 xQueueReceive() :从队列中接收一条消息。可以选择阻塞

    2024年02月11日
    浏览(42)
  • 正点原子STM32嵌入式学习-keil5安装教程

    前言:本人没有什么嵌入式的经验,但是看到硬件的同事做开发板比较好玩,比较感兴趣。刚好有这样一个机会,可以跟随《原子教你玩STM32(库函数版)》课程线下学习,在此,将本次课程的学习做一个记录。相信对我这样一个小白来说,帮助还是会非常大的。 目录 一.下

    2024年03月10日
    浏览(71)
  • (第48-59讲)STM32F4单片机,FreeRTOS【事件标志、任务通知、软件定时器、Tickless低功耗】【纯文字讲解】【】

    【吐血总结】FreeRTOS难点、Systick中断-滴答定时器、PendSV中断-任务切换、SVC中断-系统底层、时间片调度-时钟节拍【已完结】 (第1-8讲)STM32F4单片机,FreeRTOS基础知识总结【视频笔记、代码讲解】【正点原子】【原创】 (第9-10讲)STM32F4单片机,FreeRTOS任务创建和删除(动态方

    2024年02月01日
    浏览(61)
  • 用正点原子STM32F103ZET6精英板控制舵机转动实验保姆教程

    正点原子精英板一块 Jlink4线SWD下载线一根 精英板usb供电/下载线一根(负责给开发板供电) SG90舵机一个(三线:其中红线接5V电压,棕线接GED,橙黄色为信号线接开发板PB5引脚,舵机所给为3pin杜邦线母头,可用单根杜邦线(一头子一头母)将舵机线飞开接到精英板上)。 以

    2023年04月15日
    浏览(57)
  • FreeRTOS教程2 任务管理

    正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCOM V2.6串口助手 一个滑动变阻器 逻辑分析仪nanoDLA 本文主要学习FreeRTOS任务管理的相关知识, 包括FreeRTOS创建/删除任务、任务状态、任务优先级、延时函数、空闲任务和任务

    2024年03月12日
    浏览(40)
  • 【Freertos基础教程】任务管理之基本使用

    本freertos是以 stm32 系列为操作的 任务管理是实时操作系统(RTOS)的核心功能之一,它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS,它提供了强大的任务管理功能,让开发者能够轻松创建和控制任务。本文将介绍 FreeRTOS 的任务管理功能,包括任

    2024年02月13日
    浏览(38)
  • 【正点原子Linux连载】第五章 RKMedia编译和使用 摘自【正点原子】ATK-DLRV1126系统开发手册

    5.1 RKMedia编译 Rkmedia是RK官方封装一层简易的API,把RGA、MPP、RKNN等等这些接口封装成高级的接口。在SDK官方的源码目录下,运行以下命令进行跳转: cd external/rkmedia/examples/ ls 运行命令结果如下所示: 图4.12.1.1 rkmedia官方的demo 里面有很多C文件的代码,可以结合Rockchip_Developer_G

    2024年02月08日
    浏览(85)
  • 正点原子LoRa模块的使用

    所用单片机为STM32F407,此篇为当时做电赛时未记录,但是现在忘了所以重新记录一下,防止自己忘记。总的来说就是用串口给LoRa模块发送AT指令来配置模块,然后单片机想要发数据也是使用串口发送出去。 MD0引脚配置为推挽输出模式,并配置为下拉, AUX引脚配置为输入模式

    2024年02月08日
    浏览(37)
  • 【正点原子Linux连载】第三章 RV1126开发环境搭建 摘自【正点原子】ATK-DLRV1126系统开发手册

    1)实验平台:正点原子RV1126 Linux开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692176265749 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html 3.1 rv1126的环境配置 在上章节里面我们已经安装好Ubuntu,此时的Ubuntu还是不能做开发的,因为还有很多环

    2024年02月04日
    浏览(49)
  • 【正点原子STM32连载】 第四十章 IIC实验 摘自【正点原子】APM32E103最小系统板使用指南

    1)实验平台:正点原子APM32E103最小系统板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban 本章将介绍使用APM32E103驱动板载的EEPROM进行读写操作。通过本章的学习,读者将学习到使用GPIO模拟

    2024年02月21日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包