慢慢从源码来理解FreeRTOS的工作原理
版本信息
#define tskKERNEL_VERSION_NUMBER "V10.0.1"
#define tskKERNEL_VERSION_MAJOR 10
#define tskKERNEL_VERSION_MINOR 0
#define tskKERNEL_VERSION_BUILD 1
两个引用的函数原型
typedef void * TaskHandle_t;
typedef BaseType_t (*TaskHookFunction_t)( void * );
由 eTaskGetState() 这个函数返回的任务状态(用一个结构体来管理)
typedef enum
{
eRunning = 0,
eReady,
eBlocked,
eSuspended,
eDeleted,
eInvalid
} eTaskState;
调用 vTaskNotify() 时可以执行的操作
typedef enum
{
eNoAction = 0,
eSetBits,
eIncrement,
eSetValueWithOverwrite,
eSetValueWithoutOverwrite
} eNotifyAction;
超时时间(仅在内部使用)
typedef struct xTIME_OUT
{
BaseType_t xOverflowCount;
TickType_t xTimeOnEntering;
} TimeOut_t;
定义使用MPU时分配给任务的内存范围(设备要支持MPU功能)
typedef struct xMEMORY_REGION
{
void *pvBaseAddress;
uint32_t ulLengthInBytes;
uint32_t ulParameters;
} MemoryRegion_t;
创建MPU保护任务所需参数
typedef struct xTASK_PARAMETERS
{
TaskFunction_t pvTaskCode;
const char * const pcName; /* 非限定的char类型只允许用于字符串和单个字符 */
uint16_t usStackDepth; /* 栈深度 */
void *pvParameters;
UBaseType_t uxPriority; /* 优先级 */
StackType_t *puxStackBuffer; /* 栈顶指针 */
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
StaticTask_t * const pxTaskBuffer;
#endif
} TaskParameters_t;
返回每个任务的状态到系统中
(与uxTaskGetSystemState()函数一起使用)
typedef struct xTASK_STATUS
{
TaskHandle_t xHandle;
const char *pcTaskName;
UBaseType_t xTaskNumber;
eTaskState eCurrentState;
UBaseType_t uxCurrentPriority;
UBaseType_t uxBasePriority;
uint32_t ulRunTimeCounter;
StackType_t *pxStackBase;
uint16_t usStackHighWaterMark;
} TaskStatus_t;
eTaskConfirmSleepModeStatus() 可能返回的值
typedef enum
{
eAbortSleep = 0,
eStandardSleep,
eNoTasksWaitingTimeout
} eSleepModeStatus;
定义空闲任务使用的优先级。
禁止修改
#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U )
强制上下文切换的宏
#define taskYIELD() portYIELD()
进入临界段的函数宏定义
#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
退出临界段的函数宏定义
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
禁用所有可屏蔽中断的宏
#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
使能所有可屏蔽中断的宏
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
宏定义函数 xTaskGetSchedulerState() 的返回值
#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 )
#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 )
#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 )
动态创建任务函数声明
#if( configSUPPORT_DYNAMIC_ALLOCATION == 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
)
#endif
静态创建任务函数声明
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t xTaskCreateStatic(
TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer
)
#endif
与MPU功能相关的函数声明
#if( portUSING_MPU_WRAPPERS == 1 )
BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif
#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif
void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION;
删除任务函数声明
void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
任务中使用的绝对延时函数声明
void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;
任务中使用的相对延时函数声明
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION;
Abort 函数
(强制任务离开阻塞态,并进入准备态,即使任务处于阻塞态等待的事件没有发生,并且任何指定的超时时间也没有过期)
BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
获取任务优先级函数声明
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
获取任务状态
eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
获取任务信息
(此函数仅用于调试使用,因为它的使用将导致调度器在一段较长的时间内保持挂起。 )
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION;
设置任务优先级
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;
任务挂起
void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION;
任务恢复
void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
开启任务调度器
void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;
关闭任务调度器
void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;
挂起所有任务
void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;
恢复所有任务
BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION;
返回调度器开启后的计数值
TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;
TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;
返回内核当前管理的任务数
(包括所有就绪、阻塞和挂起的任务。 已删除但尚未被空闲任务释放的任务也将包含在计数中。 )
UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;
获取任务名字
(返回TCB结构体中的pcTaskName[0],可用一个 char* 型指针接收)
char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;
获取任务句柄
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION
返回剩余堆栈空间
(返回自任务开始执行以来可用的最小剩余堆栈空间量,即当任务堆栈处于最大(最深)值时剩余的堆栈空间量)
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
与应用程序任务标签相关函数
#ifdef configUSE_APPLICATION_TASK_TAG
#if configUSE_APPLICATION_TASK_TAG == 1
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION;
TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
#endif
#endif
与线程相关函数
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION;
void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION;
#endif
应用程序任务钩子函数
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION;
获取空闲任务的句柄
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
获取系统状态
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION;
任务列表函数
void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION;
获取任务运行时间
void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
任务通知相关函数
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
uint32_t ulValue, eNotifyAction eAction,
uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;
#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )
BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotificationValue,
BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )
#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t *pulNotificationValue,
TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL )
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify,
BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
任务放置相关函数
(将调用任务从就绪列表中移除,并将其放在等待特定事件的任务列表和延迟任务列表中。 如果事件发生(并且没有更高优先级的任务在同一事件上等待)或延迟时间到期,任务将从两个列表中删除,并在就绪列表中被替换。 )
void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
从事件列表中移除任务
(从指定的事件列表和阻塞的任务列表中删除任务,并将其放在就绪队列中。)
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;
void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION;
切换任务上下文信息
void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;
重置事件列表项
( 将事件列表项重置为正常值,这样它就可以使用队列和信号量 )
TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION;
获取当前任务的任务句柄
TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
任务检查超时相关参数配置
(配置前面提到的超时时间结构体)
void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
队列实现使用的快捷方式
以防止对 taskYIELD() 不必要的调用
void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;
获取调度器的状态
BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;
继承任务优先级
BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
不继承任务优先级
BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;
void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder,
UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION;
任务标号相关函数
UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION;
配置低功耗时用到的时钟补偿
(此函数在使用 FreeRTOS 的低功耗 tickless 模式的时候会用到,即宏 configUSE_TICKLESS_IDLE 为 1。当使能低功耗 tickless 模式以后在执行空闲任务的时候系统时钟节拍中断就会停止运行,系统时钟中断停止运行的这段时间必须得补上, 这个工作就是由这个函数来完成的。)
void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;
配置任务低功耗模式状态
eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
增加互斥对象计数函数
(只能内部使用)
(当一个互斥对象被获取时,增加被持有的互斥对象计数,并返回已获取该互斥对象的任务句柄。 )
void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
设置超时时间
(只能内部使用)
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
|