RTOS学习笔记--FreeRTOS相关API

本文介绍了FreeRTOS操作系统中任务创建、删除、挂起和恢复的相关API,包括xTaskCreate()、xTaskCreateStatic()、vTaskDelete()、vTaskSuspend()和vTaskResume()等。任务控制块(TCB)的结构和作用也进行了说明,以及临界区的概念。文章还提供了示例代码以帮助理解这些功能的使用。
摘要由CSDN通过智能技术生成

RTOS学习笔记–FreeRTOS相关API

本文基于正点原子RTOS开发指南,笔记自用,获取详细信息请关注正点原子官方账号

1. 任务创建和删除API
API函数描述说明
xTaskCreate()动态创建任务任务控制块以及任务的栈空间所需的内存,均由RTOS从其管理的堆中分配
xTaskCreateStatic()静态创建任务任务控制块以及任务的栈空间所需的内存,均由用户自行分配
vTaskDelete()删除任务

动态创建任务函数

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 	/* 任务句柄,就是任务的任务控制块 */
)

动态创建任务流程

  1. 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1

  2. 定义函数入口参数

  3. 编写任务函数

  4. 此函数会立刻进入就绪态

    内核流程

    1. 申请堆栈内存&任务控制块内存
    2. 定义函数入口参数
    3. 添加新任务到就绪列表中

任务控制快结构体成员介绍

typedef struct tskTaskControlBlock       
{
    	volatile StackType_t * pxTopOfStack; 	/* 任务栈栈顶,必须为TCB的第一个成员 */
   	ListItem_t 	xStateListItem;           		/* 任务状态列表项 */      
	ListItem_t 	xEventListItem;					/* 任务事件列表项 */     
    UBaseType_t 	uxPriority;                	/* 任务优先级,数值越大,优先级越大 */
    StackType_t 	* pxStack;					/* 任务栈起始地址 */
    char 				pcTaskName[ configMAX_TASK_NAME_LEN ]; 	/* 任务名字 */		
	…
	省略很多条件编译的成员
} tskTCB;

​ 任务控制块描述了任务的信息

**临界区 **

临界区是指,希望这段代码能够完整的执行,不要被中断所打断,所以在代码运行前进入临界区,在代码执行完毕后再退出临界区,常常用于任务的创建,在任务创建时避免被中断所打扰,本质上是关中断

taskENTER_CRITICAL();//进入临界区
taskEXIT_CRITICAL();//退出临界区

启动任务

每一个任务创建时都有优先级,如果想让任务按照优先级去运行,则需要打开调度器vTaskStartScheduler();

同样还有取消调度器

示例

/*宏定义的和任务型相关的信息*/
#define START_TASK_PRIO	1 //优先级
#define START_TASK_STACK_SIZE 128//堆栈大小
void start_task(void *argv); //任务函数

TaskHandle_t start_task_handler; //任务句柄


/*进入临界区*/
taskENTER_CRITICAL();
/*创建任务*/
xTaskCreate((TaskFunction_t )	start_task,
            (char * ) "start_task",		
            (configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,
            (void *  ) NULL,
            (UBaseType_t ) START_TASK_PRIO,
            (TaskHandle_t *) &start_task_handler );
printf("step1\r\n");
/*退出临界区*/
taskEXIT_CRITICAL();
// Start the real time kernel with preemption.
/*开启调度器*/
vTaskStartScheduler();

静态创建任务函数

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用户没有提供相应的内存,任务创建失败
其他值任务句柄,任务创建成功

静态创建任务流程

  1. 需将宏configSUPPORT_STATIC_ALLOCATION 配置为 1
  2. 定义空闲任务&定时器任务的任务堆栈及TCB
  3. 实现两个接口函数
    1. vApplicationGetIdleTaskMemory()
    2. vApplicationGetTimerTaskMemory ( )
  4. 定义函数入口参数
  5. 编写任务函数

静态创建内部实现

  1. TCB结构体成员赋值
  2. 添加新任务到就绪列表中

任务函数的删除

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

注意:

  1. 当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
  2. 空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将导致内存泄露

示例

/*实现空闲任务的函数*/

StaticTask_t idle_task_tcb; /* 空闲任务控制块 */
StackType_t idle_tack_stack[configMINIMAL_STACK_SIZE]; /* 空闲任务任务堆栈 */
/*空闲任务
* void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, 
*												StackType_t **ppxIdleTaskStackBuffer,
*												uint32_t *pulIdleTaskStackSize );
*参数:  ppxIdleTaskTCBBuffer:空闲任务内存控制块
*		ppxIdleTaskStackBuffer::任务堆栈内存
*		pulIdleTaskStackSize:任务堆栈大小
*/
 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, 
												StackType_t **ppxIdleTaskStackBuffer,
												uint32_t *pulIdleTaskStackSize )
 {
	 * ppxIdleTaskTCBBuffer = &idle_task_tcb;
	 * ppxIdleTaskStackBuffer = idle_tack_stack;
	 * pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
	 
 }

 /*软件定时器内存分配*/
 StaticTask_t timer_task_tcb;
 StackType_t timer_task_stack[configMINIMAL_STACK_SIZE];
 /*定时器任务*/
 /*
 获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的
静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该
有用户来提供, FreeRTOS 提供了接口函数 vApplicationGetIdleTaskMemory()
实现此函数即可。
描述:* @brie 获取定时器服务任务的任务堆栈和任务控制块内
* @param ppxTimerTaskTCBBuffer:任务控制块内存
    ppxTimerTaskStackBuffer:任务堆栈内存
    pulTimerTaskStackSize:任务堆栈大小
 */
 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, 
									  StackType_t **ppxTimerTaskStackBuffer,												uint32_t *pulTimerTaskStackSize )
 {
	 * ppxTimerTaskTCBBuffer = &timer_task_tcb;
	 * ppxTimerTaskStackBuffer = timer_task_stack;
	 * pulTimerTaskStackSize = configMINIMAL_STACK_SIZE;
	 
 }

静态创建任务

//创建任务
#define START_TASK_PRIO	1
#define START_TASK_STACK_SIZE 128
void start_task(void *argv);

/*静态创建任务的TCB 控制块和堆栈大小*/
StaticTask_t start_task_tcb;
StackType_t start_task_stack[configMINIMAL_STACK_SIZE];
TaskHandle_t start_task_handler;
/*进入临界区*/
taskENTER_CRITICAL();
/*静态创建*/
start_task_handler = xTaskCreateStatic((TaskFunction_t)start_task,
									(char * )"start_task",		
									(uint32_t )START_TASK_STACK_SIZE,
									(void * ) NULL,
									(UBaseType_t) START_TASK_PRIO,
									(StackType_t *) start_task_stack,
									(StaticTask_t *) &start_task_tcb );
	printf("step1\r\n");
/*退出临界区*/
taskEXIT_CRITICAL();
	// Start the real time kernel with preemption.
	/*开启调度器*/
	vTaskStartScheduler();
2. 任务挂起和恢复API

RTOS有关于挂起和恢复任务的相关的API

函数说明
vTaskSuspend()挂起任务
vTaskResume()恢复被挂起的任务
xTaskResumeFromISR()在中断中恢复被挂起的任务

挂起任务xTaskToSuspend

  1. 此函数用于挂起任务,使用时需将宏 INCLUDE_vTaskSuspend 配置为 1
  2. 无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复 。
  3. 注意:当传入的参数为NULL,则代表挂起任务自身(当前正在运行的任务)

任务中恢复被挂起函数:void vTaskResume

形参描述
xTaskToResume待恢复任务的任务句柄
  1. 使用该函数注意宏:INCLUDE_vTaskSuspend必须定义为 1
  2. 注意:任务无论被 vTaskSuspend() 挂起多少次,只需在任务中调用 vTakResume() 恢复一次,就可以继续运行。且被恢复的任务会进入就绪态!

任务恢复函数介绍(中断中恢复)xTaskResumeFromISR

形参描述
xTaskToResume待恢复任务的任务句柄

函数:xTaskResumeFromISR返回值描述如下:

返回值描述说明
pdTRUE任务恢复后需要进行任务切换如果恢复的这个任务的优先级的任务最高,则恢复后需要切换到该任务
pdFALSE任务恢复后不需要进行任务切换如果恢复的这个任务优先级不是最高的,则不用切换,等到下一个抢占
  1. 使用该函数注意宏:INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1
  2. 该函数专用于中断服务函数中,用于解挂被挂起任务
  3. 注意:中断服务程序中要调用freeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级

示例

if( eTaskGetState(task2_handler) != eDeleted){
    /*任务存在则挂起*/
    vTaskSuspend(task2_handler);
}

if( eTaskGetState(task2_handler) == eSuspended){
    /*查询任务状态为挂起时,则拉起*/
    vTaskResume(task2_handler);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值