【基于FreeRTOS的STM32F103系统】编写FreeRTOS程序

系列文章目录

【基于FreeRTOS的STM32F103系统】简介及官方文件移植

【基于FreeRTOS的STM32F103系统】编写FreeRTOS程序

【基于FreeRTOS的STM32F103系统】内存管理及任务调度

【基于FreeRTOS的STM32F103系统】队列 

【基于FreeRTOS的STM32F103系统】Heap_4内存管理机制程序详解

【基于FreeRTOS的STM32F103系统】移动底盘程序优化 


前言

前面简单介绍了FreeRTOS和如何将它简单的移植到STM32F1上,这篇介绍移植完成后,我们如何创建任务,并利用FreeRTOS的多任务机制优化我们的程序。

一、创建任务

创建任务时使用的函数如下:

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针,任务函数
const char * const pcName, //任务的名字
const configSTACK_DEPTH_TYPE usStackDepth,//栈大小,单位为word,10表示40字节
void * const pvParameters, //调用任务函数时传入的参数
UBaseType_t uxPriority, //优先级
TaskHandle_t * const pxCreatedTask );//任务句柄,以后使用它来操作这个任务

参数说明:

  • pvTaskCode:函数指针,可以简单地认为任务就是一个C函数。它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)"
  • pcName:任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。长度为:confifigMAX_TASK_NAME_LEN
  • usStackDepth:每个任务都有自己的栈,这里指定栈大小。
    单位是 word ,比如传入 100 ,表示栈大小为 100 word ,也就是 400 字节。
    最大值为 uint16_t 的最大值。
    怎么确定栈的大小,并不容易,很多时候是估计。
    精确的办法是看反汇编码。
  • pvParameters:传入参数,调用 pvTaskCode 函数指针时用到: pvTaskCode(pvParameters)
  • uxPriorit:优先级范围:0~(confifigMAX_PRIORITIES – 1) 数值越小优先级越低, 如果传入过大的值,xTaskCreate会把它调整为(confifigMAX_PRIORITIES – 1)
  • pxCreatedTask: 用来保存 xTaskCreate 的输出结果: task handle 以后如果想操作这个任务,比如修改它的优先级,就需要这个 handle 如果不想使用该 handle ,可以传入 NULL
  • 返回值:
    成功: pdPASS
    失败: errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY( 失败原因只有内存
    不足 )
    注意:文档里都说失败时返回值是 pdFAIL ,这不对。
    pdFAIL 0 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY -1

实例:

void Task1Function(void * param)
{
	while (1)
	{
		printf("1");
	}
}
void Task2Function(void * param)
{
	while (1)
	{
		printf("2");
	}
}
xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);
xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);

开启任务调度:

vTaskStartScheduler();          //开启任务调度

结果:

二、删除任务

删除任务使用的函数如下:

void vTaskDelete( TaskHandle_t xTaskToDelete );

参数说明:

  • xTaskToDelete:任务句柄,使用 xTaskCreate 创建任务时可以得到一个句柄,也可传入NULL ,这表示删除自己。
  • 句柄的实质就是这个任务结构体的指针,在FreeRTOS中任务的创建利用面向对象的思想,创建的一个个任务都是结构体,删除任务的实质就类似于C语言中的free释放内存

实例:

void vTask1( void *pvParameters )
{
const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );
BaseType_t ret; 
/* 任务函数的主体一般都是无限循环 */
for( ;; ) 
{ 
/* 打印任务的信息 */ 
printf("Task1 is running\r\n");
ret = xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle ); 
if (ret != pdPASS) printf("Create Task2 Failed\r\n");
// 如果不休眠的话, Idle任务无法得到执行 
// Idel任务会清理任务2使用的内存
// 如果不休眠则Idle任务无法执行, 最后内存耗尽
vTaskDelay( xDelay100ms ); 
}

三、任务状态

  • 当前正在进行的任务,是running状态;其他所有任务都处于not running状态
  • "not running"状态还可以细分为:
    ready :就绪,随时可以运行
    blocked :阻塞,该任务在等待某一事件发生
    suspended :挂起,该任务暂停休息

 当创建任务并开始任务调度后,所有任务都处于Ready就绪状态,系统随机挑选一个任务Running,正在执行的任务可以使用vTaskSuspend函数使自己进入挂起状态(传入参数NULL或自己的句柄),也可以使其他任务进入挂起状态(传入参数为需要挂起任务的句柄),进入暂停状态后,需要在别的任务执行过程中调用vTaskResume函数该任务才会重新进入Ready状态;

在任务执行过程中,需要等待某个函数或事件的发生,则进入挂起状态(Baocked),当等待的事件(可能是中断或某个任务)发生后该任务才会恢复Ready状态。


总结

关于任务简单写这些,后面进行内存管理、堆栈、队列等的介绍

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值