FreeRTOS使用 — 合理使用内存 “ 任务中创建任务 ”_freertos 任务可以再创建任务吗(2)

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

先看一下下面的图片,对应上面我们说过的最后其实我们想要长期周期运行的任务只有前面3个,最后一个是需要开机初始化时候运行一次的任务(设计的时候因为用到了 FreeRTOS 的任务通信机制,所以不太好直接在初始化还没开始调度前面进行完成)。

在这里插入图片描述

由上图可知,我们是无法直接创建全部的任务的,即便你想先创建,然后运行完了删除来节约内存,是行不通的。

先说明,上面的任务去掉 64 大小的 myTask04 是可以的,就是256 + 192 +128 的任务组合是我们最终需要保留的周期任务。

那么我们来使用上面提到的思路进行,在允许的范围内,先建立一个初始化的任务(其中 KeyTask 任务我写了一些程序,所以此次就保留在这里,这个保留这个任务不影响本次测试):

在这里插入图片描述

上面的 InitTask 就对应一次性任务 Task04,因为会删除,我们可以创建得大一点,但是也得注意大小。

在 STM32CubeMX 的设置到这里就完成了,其他的地方都需要我们在代码中直接修改。

在 KeyTask 任务中,我们还是加入了任务状态查看功能:

在这里插入图片描述

这里额外说明一下,相比我以前的系列文章,这里多加了一个剩余空间的打印:

printf("free space is %d\n",xPortGetFreeHeapSize());

刚开始,在我们的 InitTask 中,我们什么都不做,初始状态如下图:

在这里插入图片描述

在这里插入图片描述

接下来我们要考虑的就是在当前程序中,我们该如何创建新的任务,而不是依靠 STM32CubeMX 初始化创建。

2.2 FreeRTOS 任务 API 复习

我们先来复习一下 FreeRTOS 的创建任务函数原型(示例以动态创建函数来说明),如下图:

在这里插入图片描述

而在 CMSIS 接口下面通过封装后统一使用的是 osThreadCreate , 我们也来复习一下:

在这里插入图片描述
详细的任务 API 解析请参考以前的博文:FreeRTOS记录(二、FreeRTOS任务API认识和源码简析)

我们再来参考一下系统自动的任务创建操作:

在这里插入图片描述

2.3 实际操作

我们参考这种方式,手动的在 Init 任务中创建新的任务,首先手动定义任务句柄以及声明任务函数,如下图:

在这里插入图片描述

然后我们直接在 InitTask 任务中进行任务创建,当然为了更好的查看结果,我还加入了任务状态打印,如下图:

在这里插入图片描述

最后不要忘了实现一下 myTask02 任务函数:

在这里插入图片描述

测试一下看看效果:

在这里插入图片描述

上面可以看到,出问题了,并没有创建新的任务,奇了怪了!

我以为是创建函数出问题了,把下面的创建函数语句:

osThreadDef(myTask02, StartmyTask02Task, osPriorityNormal, 0, 192);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);

改成了

xTaskCreate( StartmyTask02Task, "myTask02", 192, NULL, osPriorityHigh, &myTask02Handle );

还是不行。

其中还以为是前后要加点延时,测试过也不行,难道是不能创建,没有道理啊!

于是我在原本的另外一个 KeyTask 任务中,加上了一个按键操作,按下按键新建一个 myTask02 ,语句是和在 InitTask 中语句一样的,如下图:

在这里插入图片描述

IninTask 中的代码保持不变,再次测试看看:

在这里插入图片描述

这样可以说明,在任务中创建任务是没问题的,使用的程序语句也是没有问题的,但是开始为什么会创建失败呢?

2.4 问题测试

我进行了一些测试排除了一些问题:

测试记录:
和任务优先级无关(把新创建的任务的优先级设置成比自己高,比自己低,和自己相等)
和延时无关(前后加上足够的延时)
和本任务的栈大小无关(怕自己任务栈不够,去掉了打印,还是创建失败,对比 KeyTask 的栈空间一样还是可以成功)

(中间写了一大堆,最后全部删除了,这都怪自己犯二了 !)

前面刚刚用图片说明了,任务大小 256 + 192 + 128 + 64 都已经内存不够了:

在这里插入图片描述

在上面测试中我初始的任务为 256 + 256 ,还想在没删除任务的时候创建一个大小为 192 的任务……

在这里插入图片描述

好吧! 我是傻子!

2.5 最终测试

这次冷静下来发现了这么二的问题,唉 ~

文章开头说过,我们最终需要的任务是 256 + 192 +128 的组合,然后还有一些操作需要在 InitTask 中实现的,实际上我开始把 InitTask 放成 256 当时是为了打印一些数据方便测试,脑子一下子没反应过来……

我们这里把思路理清楚,我们首先创建一个 256 的 KeyTask 和 192 的 InitTask, 然后在 192 的InitTask 中做初始化的工作,然后创建一个 128 的 myTask03 ,然后 InitTask 自己删除,删除完成以后在 myTask03 中循环前面创建一个 192 的 myTask02 ,结束(确实有点绕,但是前面说了只是为了测试)。

那么我们调整一下,IninTask 改成 192 大小,如下图:

在这里插入图片描述

然后我们 Task02 和 Task03 的定义我们这里就直接一起测试了,首先是任务2 和任务 3 句柄定义和函数声明:

在这里插入图片描述

InitTask 还是打印一下状态,新建任务3 ,这次的空间是足够的:

在这里插入图片描述

实现任务2 和任务 3 函数,在任务3 中创建任务 2 ,如下图:

在这里插入图片描述

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值