xx、CubeMx FreeRTOS笔记

在这里插入图片描述

1、常用的任务函数

1)、任务挂起函数:

void vTaskSuspend( TaskHandle_t xTaskToSuspend )

挂起指定任务。被挂起的任务绝不会得到 CPU的使用权,不管该任务具有什么优先级。任务可以通过调用 vTaskSuspend()函数都可以将处于任何状态的任务挂起,被挂起的任务得不到 CPU 的使用权,也不会参与调度,它相对于调度器而言是不可见的,除非它从挂起态中除。

void vTaskSuspendAll( void )

挂起所有任务就是挂起任务调度器。调度器被挂起后则不能进行上下文切换,但是中断还是使能的。 当调度器被挂起的时候,如果有中断需要进行上下文切换, 那么这个任务将会被挂起,在调度器恢复之后才执行切换任务。调度器恢复可以调用 xTaskResumeAll()函数,调用了多少次的 vTaskSuspendAll()就要调用多少次xTaskResumeAll()进行恢复

2)、任务恢复函数:

void vTaskResume( TaskHandle_t xTaskToResume )

任务恢复就是让挂起的任务重新进入就绪状态,恢复的任务会保留挂起前的状态信息,在恢复的时候根据挂起时的状态继续运行。如果被复任务在所有就绪态任务中,处于最高优先级列表的第一位,那么系统将进行任务上下文的切换。vTaskResume()函数用于恢复挂起的任务。无论任务在挂起时候调用过多少次这个vTaskSuspend()函数,也只需调用一次 vTaskResume ()函数即可将任务恢复运行,当然,无论调用多少次的 vTaskResume()函数,也只在任务是挂起态的时候才进行恢复。

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

xTaskResumeFromISR()与 vTaskResume()一样都是用于恢复被挂起的任务,不一样的是 xTaskResumeFromISR()专门用在中断 服务程序中。无论通过调用一次或多 次vTaskSuspend()函数而被挂起的任务,也只需调用一次 xTaskResumeFromISR()函数即可解挂 。
在这里插入图片描述

BaseType_t xTaskResumeAll( void )

恢复调度器,调用了多少次vTaskSuspendAll()函数就必须同样调用多少次 xTaskResumeAll()函数

void vTaskDelete( TaskHandle_t xTaskToDelete )

vTaskDelete()用于删除一个任务。当一个任务删除另外一个任务时,形参为要删除任务创建时返回的任务句柄,如果是删除自身, 则形参为 NULL。

3)、任务延时函数

void vTaskDelay( const TickType_t xTicksToDelay )

相对延时函数,vTaskDelay()用于阻塞延时,调用该函数后,任务将进入阻塞状态,进入阻塞态的任务将让出 CPU资源。延时的时长由形参 xTicksToDelay 决定,单位为系统节拍周期, 比如系统的时钟节拍周期为 1ms,那么调用 vTaskDelay(1)的延时时间则为 1ms。
其它任务和中断活动, 也会影响到 vTaskDelay()的调用(比如调用前高优先级任务抢占了当前任务),进而影响到任务的延时时间。

void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )

绝对延时函数 ,常用于较精确的周期运行任务,比如我有一个任务,希望它以固定频率定期执行,而不受外部的影响,任务从上一次运行开始到下一次运行开始的时间间隔是绝对的,而不是相对的。

4)、任务创建

void SystemInitTask(void const * argument);
osThreadId SystemInitHandle;
  osThreadDef(SystemInit, SystemInitTask, osPriorityIdle, 0, 1024*2);
  SystemInitHandle = osThreadCreate(osThread(SystemInit), NULL);
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,	/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
							const configSTACK_DEPTH_TYPE usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif

在这里插入图片描述

2、消息队列在这里插入图片描述

1)、消息队列创建函数

#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
#endif

xQueueCreate()用于创建一个新的队列并返回可用于访问这个队列的队列句柄。队列句柄其实就是一个指向队列数据结构类型的指针。
在这里插入图片描述
在这里插入图片描述

2)、消息队列删除函数

void vQueueDelete( QueueHandle_t xQueue )

**vQueueDelete()也可用于删除信号量。**如果删除消息队列时,有任务正在等待消息,则不应该进行删除操作。

在这里插入图片描述

3)、向消息队列发送消息函数

#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )

xQueueSend() 等 同 于xQueueSendToBack()。xQueueSend()用于向队列尾部发送一个队列消息。消息以拷贝的形式入队,而不是以引用的形式。该函数绝对不能在中断服务程序里面被调用,中断中必须使用带有中断保护功能的 xQueueSendFromISR()来代替。
在这里插入图片描述
在这里插入图片描述

#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )

在这里插入图片描述
在这里插入图片描述

#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )

在这里插入图片描述

4)、从消息队列读取消息函数

BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )

在这里插入图片描述
在这里插入图片描述
**如果不想删除消息的话,就调用 xQueuePeek()函数。**其实这个函数与 xQueueReceive()函数的实现方式一样,连使用方法都一样,只不过xQueuePeek()函数接收消息完毕不会删除消息队列中的消息而已

BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer )
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken )

在这里插入图片描述

5)、消息队列清空

/*
 * Reset a queue back to its original empty state.  The return value is now
 * obsolete and is always set to pdPASS.
 */
#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )

3、信号量

1)、创建信号量函数

a、创建二值信号量
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
#endif

二值信号量和互斥量都共同使用一个类型 SemaphoreHandle_t 的句柄,该句柄的原型是一个 void 型的指针。使用该函数创建的二值信号量是空的,在使用函数xSemaphoreTake()获取之前必须先调用函数 xSemaphoreGive()释放后才可以获取。

b、创建计数信号量
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
#endif

在这里插入图片描述
在这里插入图片描述

2)、信号量删除函数

#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )

vSemaphoreDelete()用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递
归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。
在这里插入图片描述

3)、信号量释放函数

#define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )

xSemaphoreGive()是一个用于释放信号量的宏,真正的实现过程是调用消息队列通用发送函数,xSemaphoreGive()函数原型具体见代码清单 18-8。释放的信号量对象必须是已经被创建的,可以用于二值信号量、计数信号量、互斥量的释放,但不能释放由函数xSemaphoreCreateRecursiveMutex()创建的递归互斥量。此外该函数不能在中断中使用。
在这里插入图片描述

#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )

用于释放一个信号量,带中断保护。被释放的信号量可以是二进制信号量和计数信号量。和普通版本的释放信号量 API 函数有些许不同,它不能释放互斥量,这是因为互斥量不可以在中断中使用,互斥量的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
在这里插入图片描述

4)、信号量获取函数

#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )

xSemaphoreTake()函数用于获取信号量,不带中断保护。获取的信号量对象可以是二值信号量、计数信号量和互斥量,但是递归互斥量并不能使用这个 API 函数获取。
在这里插入图片描述
在这里插入图片描述

#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )

用于获取信号量,是一个不带阻塞机制获取信号量的函数,获取对象必须由是已经创建的信号量,信号量类型可以是二值信号量和计数信号量,它与xSemaphoreTake()函数不同,它不能用于获取互斥量,因为互斥量不可以在中断中使用,并且互斥量特有的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
在这里插入图片描述

4、互斥量

1)、互斥量创建函数

	#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )

在这里插入图片描述

#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
	#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
#endif

xSemaphoreCreateRecursiveMutex()用于创建一个递归互斥量,不是递归的互斥量由函数 xSemaphoreCreateMutex() 或 xSemaphoreCreateMutexStatic()创建,且只能被同一个任务获取一次,如果同一个任务想再次获取则会失败。
在这里插入图片描述

2)、互斥量删除函数 vSemaphoreDelete()

3)、互斥量获取函数 xSemaphoreTake()

在这里插入图片描述

4)、递归互斥量获取函数

#if( configUSE_RECURSIVE_MUTEXES == 1 )
	#define xSemaphoreTakeRecursive( xMutex, xBlockTime )	xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
#endif

在这里插入图片描述

5)、互斥量释放函数

#define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )

任务想要访问某个资源的时候,需要先获取互斥量,然后进行资源访问,在任务使用完该资源的时候,必须要及时归还互斥量,这样别的任务才能对资源进行访问。**互斥量的释放只能在任务中,不允许在中断中释放互斥量。**使用该函数接口时,只有已持有互斥量所有权的任务才能释放它,**当任务调用xSemaphoreGive()函数时会将互斥量变为开锁状态,**等待获取该互斥量的任务将被唤醒。如果任务的优先级被互斥量的优先级翻转机制临时提升,那么当互斥量被释放后,任务的优先级将恢复为原本设定的优先级。
在这里插入图片描述

6)、递归互斥量释放函数

#if( configUSE_RECURSIVE_MUTEXES == 1 )
	#define xSemaphoreGiveRecursive( xMutex )	xQueueGiveMutexRecursive( ( xMutex ) )
#endif

释放递归互斥量,获取了多少次就要释放多少次

本文来自[野火®]《FreeRTOS 内核实现与应用开发实战—基于STM32》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值