介绍FreeRTOS常用API函数
任务相关
1. 创建任务
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask );
*返回值:成功:pdPASS;失败:errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(失败原因只有内存不足)
************************************************************************************************************
2. 任务删除
void vTaskDelete( TaskHandle_t xTaskToDelete );
例:*自我删除: vTaskDelete(NULL) ;
*被其他任务删除:vTaskDelete(pvTaskCode);
************************************************************************************************************
3. 修改任务优先级
在任务创建时设置了优先级,可以使用下面两个函数获取和修改优先级
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
*使用参数xTask来指定任务,设置为NULL表示获取自己的优先级
void vTaskPrioritySet( TaskHandle_t xTask,UBaseType_t uxNewPriority );
*使用参数xTask来指定任务,设置为NULL表示设置自己的优先级;
*参数uxNewPriority表示新的优先级,取值范围是0~(configMAX_PRIORITIES – 1)。
************************************************************************************************************
4.修改任务状态
挂起任务
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
*参数xTaskToSuspend表示要暂停的任务,如果为NULL,表示暂停自己
恢复任务
要退出暂停状态,只能由别人来操作
void vTaskResume( TaskHandle_t xTaskToResume )
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
TICK相关
1.把ms转换为tick
pdMS_TO_TICKS(xTimeInMs)
************************************************************************************************************
2.获取当前tick时间
TickType_t xTaskGetTickCount( void );
Delay函数
void vTaskDelay( const TickType_t xTicksToDelay )
*至少等待指定个数的Tick Interrupt才能变为就绪状态
例:vTaskDelay(50);
************************************************************************************************************
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,const TickType_t xTimeIncrement );
*等待到指定的绝对时刻,才能变为就绪态
例:xLastWakeTime = xTaskGetTickCount();
vTaskDelayUntil(&xLastWakeTime, 50);
队列
1.创建队列
创建队列动态
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
*uxQueueLength 队列长度,最多能存放多少个数据(item)
*uxItemSize 每个数据(item)的大小:以字节为单位
*返回值 非0:成功,返回句柄 NULL:失败,因为内存不足
创建队列静态
QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,
UBaseType_t uxItemSize,
uint8_t *pucQueueStorageBuffer,
StaticQueue_t *pxQueueBuffer);
*uxQueueLength 队列长度,最多能存放多少个数据(item)
*uxItemSize 每个数据(item)的大小:以字节为单位
*pucQueueStorageBuffer 此数组大小至少为"uxQueueLength * uxItemSize"
*pxQueueBuffer 必须执行一个StaticQueue_t结构体,用来保存队列的数据结构
*返回值:非0:成功,返回句柄,以后使用句柄来操作队列 NULL:失败,因为pxQueueBuffer为NULL
************************************************************************************************************
2.复位
BaseType_t xQueueReset( QueueHandle_t pxQueue);
************************************************************************************************************
3.删除队列
void vQueueDelete( QueueHandle_t xQueue );
*只能删除使用动态方法创建的队列
************************************************************************************************************
4.写队列
BaseType_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
*往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait
BaseType_t xQueueSendToBack(QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait);
*往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait
BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken);
* 往队列尾部写入数据,此函数可以在中断函数中使用,不可阻塞
BaseType_t xQueueSendToFront(QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait);
* 往队列头部写入数据,阻塞时间为xTicksToWait
BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue,
const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken);
*往队列头部写入数据,此函数可以在中断函数中使用,不可阻塞
************************************************************************************************************
5.读队列
BaseType_t xQueueReceive( QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait );
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxTaskWoken);
************************************************************************************************************
6.查询
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
* 返回队列中可用数据的个数
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
* 返回队列中可用空间的个数
************************************************************************************************************
7.覆盖/偷看
当队列长度为1时
覆盖队列
BaseType_t xQueueOverwrite(QueueHandle_t xQueue,const void * pvItemToQueue);
BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken);
偷看队列
BaseType_t xQueuePeek(QueueHandle_t xQueue,void * const pvBuffer,TickType_t xTicksToWait);
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue,void *pvBuffer);
信号量(semaphore)
1.二值信号量
SemaphoreHandle_t xSemaphoreCreateBinary( void );
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer );
2.计数值信号量
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount,
StaticSemaphore_t
*pxSemaphoreBuffer );
3.删除
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
4.获取/释放
释放
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken);
获取
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait);
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken);
互斥量(mutex)
##define configUSE_MUTEXES 1
1.创建
SemaphoreHandle_t xSemaphoreCreateMutex( void );
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer);
2.删除
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
3.释放/获取
同信号量
释放
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken);
获取
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait);
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken);
递归锁
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );
BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t xSemaphore );
BaseType_t xSemaphoreTakeRecursive(SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait);
事件组(event group)
1.创建
EventGroupHandle_t xEventGroupCreate( void );
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer );
2.删除
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
3.设置事件
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t * pxHigherPriorityTaskWoken );
4.等待事件
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait );
*xEventGroup 等待哪个事件组?
*uxBitsToWaitFor 等待哪些位?哪些位要被测试?
*xWaitForAllBits pdTRUE:等待的位,全部为1; pdFALSE: 等待的位,某一个为1即可
*xClearOnExit pdTRUE: 清除uxBitsToWaitFor指定的位 pdFALSE: 不清除
*xTicksToWait 等待数据
*返回值 返回的是事件值,如果期待的事件发生了,返回的是"非阻塞条件成立"时的事件值;如果是超时退出,返回的是超时时刻的事件值。
5.同步事件
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
const EventBits_t uxBitsToWaitFor,
TickType_t xTicksToWait );
*xEventGroup 哪个事件组?
*uxBitsToSet 要设置哪些事件?
*uxBitsToWaitFor 等待那个位、哪些位?
*xTicksToWait 阻塞时间
*返回值 返回的是事件值,如果期待的事件发生了,返回的是"非阻塞条件成立"时的事件值;如果是超时退出,返回的是超时时刻的事件值。
任务通知(Task Notifications)
1.发出通知
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t*pxHigherPriorityTaskWoken );
2.获取通知
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait);
xClearCountOnExit 函数返回前是否清零:pdTRUE:把通知值清零 pdFALSE:如果通知值大于0,则把通知值减一
xTicksToWait 任务进入阻塞态的超时时间,它在等待通知值大于0。 portMAX_DELAY:一直等待,直到通知值大于0;
返回值
函数返回之前,在清零或减一之前的通知值。
如果xTicksToWait非0,则返回值有2种情况:
1. 大于0:在超时前,通知值被增加了
2. 等于0:一直没有其他任务增加通知值,最后超时返回0
************************************************************************************************************
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue,eNotifyAction eAction );
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
BaseType_t *pxHigherPriorityTaskWoken );
*xTaskToNotify 任务句柄(创建任务时得到),给哪个任务发通知
*ulValue 怎么使用ulValue,由eAction参数决定
*eAction :
1.eNoAction 仅仅是更新通知状态为"pending",未使用ulValue。这个选项相当于轻量级的、更高效的二进制信号量。
2.eSetBits 通知值 = 原来的通知值 | ulValue,按位或。相当于轻量级的、更高效的事件组
3.eIncrement 通知值 = 原来的通知值 + 1,未使用ulValue。相当于轻量级的、更高效的二进制信号量、计数型信号量。相当于 xTaskNotifyGive() 函数。
4.eSetValueWithoutOverwrite 不覆盖。如果通知状态为"pending"(表示有数据未读),则此次调用xTaskNotify不做任何事,返回pdFAIL 如果通知状态不是"pending"(表示没有新数据),则:通知值 = ulValue。
5.eSetValueWithOverwrite 覆盖。无论如何,不管通知状态是否为"pendng",通知值 = ulValue。
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t *pulNotificationValue,
TickType_t xTicksToWait );
ulBitsToClearOnEntry :
在xTaskNotifyWait入口处,要清除通知值的哪些位?通知状态不是"pending"的情况下,才会清除。
它的本意是:我想等待某些事件发生,所以先把"旧数据"的某些位清零。
能清零的话:通知值 = 通知值 & ~(ulBitsToClearOnEntry)。
比如传入0x01,表示清除通知值的bit0;传入0xffffffff即ULONG_MAX,表示清除所有位,即把值设置为0
ulBitsToClearOnExit :
在xTaskNotifyWait出口处,如果不是因为超时推出,而是因为得到了数据而退出时:
通知值 = 通知值 & ~(ulBitsToClearOnExit)。
在清除某些位之前,通知值先被赋给"*pulNotificationValue"。
比如入0x03,表示清除通知值的bit0、bit1;
传入0xffffffff即ULONG_MAX,表示清除所有位,即把值设置为0
pulNotificationValue :
用来取出通知值。
在函数退出时,使用ulBitsToClearOnExit清除之前,把通知值赋
给"*pulNotificationValue"。
如果不需要取出通知值,可以设为NULL。
xTicksToWait:
任务进入阻塞态的超时时间,它在等待通知状态变为"pending"。
0:不等待,即刻返回;
portMAX_DELAY:一直等待,直到通知状态变为"pending";
其他值:Tick Count,可以用 pdMS_TO_TICKS() 把ms转换为TickCount
返回值
1. pdPASS:成功
这表示xTaskNotifyWait成功获得了通知:
可能是调用函数之前,通知状态就是"pending";
也可能是在阻塞期间,通知状态变为了"pending"。
2. pdFAIL:没有得到通知。
软件定时器
#define configUSE_TIMERS 1
configTIMER_TASK_PRIORITY
configTIMER_QUEUE_LENGTH
TimerHandle_t xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );
TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
TickType_t xTimerPeriodInTicks,
UBaseType_t uxAutoReload,
void * pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t *pxTimerBuffer );
BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait );
BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,TickType_t xNewPeriod,BaseType_t *pxHigherPriorityTaskWoken );
void *pvTimerGetTimerID( TimerHandle_t xTimer );
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
回调函数 void ATimerCallback( TimerHandle_t xTimer );
关中断/关调度
屏蔽中断
taskENTER_CRITICAL();
taskEXIT_CRITICAL();
taskENTER_CRITICA_FROM_ISR()
taskEXIT_CRITICAL_FROM_ISR()
暂停调度器
void vTaskSuspendAll( void );
BaseType_t xTaskResumeAll( void );