FreeRTOS 常用 API 手册

FreeRTOS 常用 API 速查手册:任务创建删除、挂起恢复、临界段、调度器、列表与列表项、消息队列,含参数说明与完整例程。

任务内核

portDISABLE_INTERRUPTS() portENABLE_INTERRUPTS()

关闭FreeRTOS可管理的5-15优先级的中断

开启FreeRTOS可管理的5-15优先级的中断

taskENTER_CRITICAL() taskEXIT_CRITICAL()

任务中进入临界段

任务中退出临界段

taskENTER_CRITICAL() ;
{
… … /* 临界区 */
}
taskEXIT_CRITICAL() ;

taskENTER_CRITICAL_FROM_ISR() taskEXIT_CRITICAL_FROM_ISR()

中断中进入临界段

中断中退出临界段

uint32_t save_status;
save_status = taskENTER_CRITICAL_FROM_ISR() ;
{
… … /* 临界区 */
}
taskEXIT_CRITICAL_FROM_ISR(save_status );

vTaskSuspendAll() xTaskResumeAll()

实现任务调度器挂起与恢复

vTaskSuspendAll() ;
{
… … /* 内容 */
}
xTaskResumeAll();

void vTaskStartScheduler()

vTaskStartScheduler();

任务创建与删除

1.xTaskCreate

参数和返回值

BaseType_t xTaskCreate
(
	TaskFunction_t pxTaskCode, 					/* 指向任务函数的指针 */
	const char * const pcName, 					/* 任务名字,最大长度 configMAX_TASK_NAME_LEN */
	const configSTACK_DEPTH_TYPE usStackDepth, 	/* 任务堆栈大小,注意字为单位 */
	void * const pvParameters, 					/* 传递给任务函数的参数 */
	UBaseType_t uxPriority, 					/* 任务优先级,范围: 0 ~ configMAX_PRIORITIES - 1 */
	TaskHandle_t * const pxCreatedTask 			/* 任务句柄,就是任务的任务控制块 */
)

返回:
pdPASS 任务创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 任务创建失败

实现例程

#define START_TASK_STACK_SIZE 	128					//栈大小
#define START_TASK_PRIO 	  	1					//优先级
TaskHandle_t 					start_task_handle;	//句柄
void startTask(void* pvParamenters);

#define TASK1_STACK_SIZE 		128
#define TASK1_PRIO 	  			2
TaskHandle_t 					task1_handle;
void task1(void* pvParamenters);

void freertos_demo(void)
{
	xTaskCreate( (TaskFunction_t	    ) startTask,
	 			 (char *		        ) "startTask", 
				 (configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,
				 (void * 			    ) NULL,
				 (UBaseType_t           ) START_TASK_PRIO,
				 (TaskHandle_t * 	    ) &start_task_handle );

	vTaskStartScheduler();
}

void startTask(void* pvParamenters)
{
	taskENTER_CRITICAL();
	xTaskCreate( (TaskFunction_t  	    ) task1,			//任务函数
				 (char *		   	    ) "task1", 			//任务名
			 	 (configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,	//任务堆栈
				 (void * 		  	    ) NULL,				//任务函数参数
				 (UBaseType_t           ) TASK1_PRIO,		//优先级
				 (TaskHandle_t * 	    ) &task1_handle );	//任务句柄(就是指向任务控制块头的指针)

	vTaskDelete(start_task_handle);
	taskEXIT_CRITICAL();
}

void task1(void* pvParamenters){
	while(1){
	}
}

2.xTaskCreateStatic

参数和返回值

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 	/* 任务控制块指针,由用户分配 */
);

返回:
NULL 用户没有提供相应的内存,任务创建失败
其他值 任务句柄,任务创建成功

实现例程

#define START_TASK_STACK_SIZE 	128
#define START_TASK_PRIO 	  	1
TaskHandle_t 					start_task_handle;
StackType_t						start_task_stack[START_TASK_STACK_SIZE];
StaticTask_t					start_task_buffer;
void startTask(void* pvParamenters);

#define TASK1_STACK_SIZE 		128
#define TASK1_PRIO 	  			2
TaskHandle_t 					task1_handle;
StackType_t						task1_stack[TASK1_STACK_SIZE];
StaticTask_t					task1_buffer;
void task1(void* pvParamenters);

/*空闲任务配置*/
StaticTask_t idle_task_tcb;
StackType_t idle_task_stack[configMINIMAL_STACK_SIZE];

/*软件定时器任务配置*/
StaticTask_t timer_task_tcb;
StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH];

/*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize )
{
	*ppxIdleTaskTCBBuffer = &idle_task_tcb;
	*ppxIdleTaskStackBuffer = idle_task_stack;
	*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

/*软件定时器内存分配*/
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
                                     StackType_t ** ppxTimerTaskStackBuffer,
                                     uint32_t * pulTimerTaskStackSize )
{
	*ppxTimerTaskTCBBuffer = &timer_task_tcb;
	*ppxTimerTaskStackBuffer = timer_task_stack;
	*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

void freertos_demo(void)
{
	
	start_task_handle = xTaskCreateStatic( (TaskFunction_t) startTask,
										   (char* 		  ) "startTask", 
										   (uint32_t	  ) START_TASK_STACK_SIZE,
										   (void*		  ) NULL,
										   (UBaseType_t	  ) START_TASK_PRIO,
										   (StackType_t*  ) start_task_stack,
										   (StaticTask_t* ) &start_task_buffer );
	vTaskStartScheduler();
}

void startTask(void* pvParamenters)
{
	taskENTER_CRITICAL();
	task1_handle  = xTaskCreateStatic( (TaskFunction_t) task1,
									   (char* 		  ) "task1", 
									   (uint32_t	  ) TASK1_STACK_SIZE,
									   (void*		  ) NULL,
									   (UBaseType_t	  ) TASK1_PRIO,
									   (StackType_t*  ) task1_stack,
									   (StaticTask_t* ) &task1_buffer );
	vTaskDelete(start_task_handle);
	taskEXIT_CRITICAL();
}

void task1(void* pvParamenters)
{
	while(1)
	{
	}
}

3.vTaskDelete

void vTaskDelete(TaskHandle_t xTaskToDelete);//xTaskToDelete 待删除任务的任务句柄

任务挂起与恢复

1.vTaskSuspend

void vTaskSuspend( TaskHandle_t xTaskToSuspend );
vTaskSuspend(任务句柄);
vTaskSuspend(NULL);//挂起本任务

2.vTaskResume

void vTaskResume( TaskHandle_t xTaskToResume );
vTaskResume(任务句柄);

3.xTaskResumeFromISR

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	BaseType_t xYieldRequired;
	switch(GPIO_Pin)
	{
	case GPIO_PIN_0:
		delay_ms(20);      /* 消抖 */
		flag2_suspend++;
		if(flag2_suspend%2==1) vTaskSuspend(task2_handle);
		else xYieldRequired = xTaskResumeFromISR(task2_handle);
		portYIELD_FROM_ISR( xYieldRequired );		//任务恢复后需要进行任务切换
		
		break;
	}
}

列表与列表项

1.vListInitialise

初始化列表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
/*pxList 是待初始化列表*/
void vListInitialise( List_t * const pxList )
{
    //初始化时,列表只有xListEnd,pxIndex指向xListEnd
    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); 
	//末尾列表项默认最大值,升序排序在最后
	pxList->xListEnd.xItemValue = portMAX_DELAY;
	//初始化时,列表中只有xListEnd,因此上下都是本身
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );    
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); 
	//初始化时列表项数量为0(不包含xListEnd)
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
	//初始化校验
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}

2.vListInitialiseItem

初始化列表项

1
2
3
4
5
6
7
8
9
/*pxItem是待初始化列表项*/
void vListInitialiseItem( ListItem_t * const pxItem )
{
	//初始化时,列表项所在列表为空
    pxItem->pxContainer = NULL;

    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

3.vListInsertEnd

列表末尾插入列表项

1
2
//目标列表,目标列表项
void vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem);

4.vListInsert

列表插入列表项

1
2
//目标列表,目标列表项
void vListInsert(List_t * const pxList,ListItem_t * const pxNewListItem); 

5.uxListRemove

列表移除列表项

1
2
3
//pxItemToRemove 待移除的列表项
UBaseType_t uxListRemove ( ListItem_t * const pxItemToRemove );
//返回值,移除后所剩列表项

插入删除实验

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/*创建列表*/
List_t 	   TestList;
ListItem_t ListItem1;
/*初始化列表,列表项*/
vListInitialise(&TestList);
vListInitialiseItem(&ListItem1);
ListItem1.xItemValue = 40;
/*插入列表项*/
vListInsert((List_t*    )&TestList,         /* 列表 */
            (ListItem_t*)&ListItem1);       /* 列表项 */

任务相关API

image-20250805151211347

1.uxTaskPriorityGet

获取任务优先级

打开宏INCLUDE_uxTaskPriorityGet

//xTask要查找的任务句柄, NULL 代表任务自身
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )
//返回无符号整数,为任务优先级

2.vTaskPrioritySet

改变任务优先级

宏 INCLUDE_vTaskPrioritySet 为 1

//xTask任务句柄 uxNewPriority优先级
void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority )

3.uxTaskGetNumberOfTasks

此函数用于获取系统中任务的任务数量

UBaseType_t uxTaskGetNumberOfTasks( void )

4.uxTaskGetSystemState

获取系统中所有任务的任务状态信息

消息队列API

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
QueueHandle_t key_quque;     /*小数据句柄*/
QueueHandle_t big_date_queue;/*大数据句柄*/
char buff[100] = {"This is a big data queue"};

key_quque = xQueueCreate(2,sizeof(uint8_t));
    if(key_quque != NULL)
    {
        printf("key_queue队列创建成功\r\n");
    }else printf("key_queue队列创建失败\r\n");

big_date_queue = xQueueCreate(1,sizeof(char *));
    if(key_quque != NULL)
    {
        printf("big_date_queue队列创建成功\r\n");
    }else printf("big_date_queue队列创建失败\r\n");
/*入队,发送*/
void task1()
{
    key_val = key_scan(0);
        if(key_val == KEY0_PRES || key_val ==  KEY1_PRES)
        {
            err = xQueueSend(key_quque,&key_val,portMAX_DELAY);
            if(err!=pdTRUE)
            {
                printf("key_queue队列发送失败\r\n");
            }
        }
}

/*出队,读取*/
void task2()
{
    if(xQueueReceive(big_date_queue,&buf,portMAX_DELAY)!=pdTRUE)
        {
            printf("big_date_queue队列接收失败\r\n");  
        }
        else 
        {
            printf("big_date_queue读取队列成功,数据%s\r\n",buf);
        }
}
使用 Hugo 构建
主题 Stack 由 Jimmy 设计