uCOS/FreeRTOS任务创建的两种模式

在我们使用uCOS/FreeRTOS编写代码时,首先要面临的一个问题是怎样创建任务并启动整个系统。一般来说,我们会有两种不同的方式。这两种方式不仅适用于uCOS/FreeRTOS,同时也适用于其它RTOS。

创建任务的两种方式

这两种方式各有优缺点。如果用一幅图来表示的话,见下方。

RTOS启动流程

下面将分别说明这两种方式的具体应用方法。

方式一:先创建启动任务,启动任务初始化软硬件并创建其它任务

这种方式是这样的:在启动启动前创建一个初始任务,然后在该任务跑起来后,再完成其它软硬件初始化、创建启动任务。

int main () {
    OSInit();
    CreateFirstTask();      // 创建初始任务
    OSStart();
}

void FirstTask () {
    DataInit();         // 初始化应用相关的数据
    HardwareInit();     // 初始化硬件模块
    CreateTask1();      // 创建任务1
    CreateTask2();      // 创建任务2
}

相于接下来讲到的方式二而言,这种方式的一大优点是:所有的初始化及任务创建都是在整个跑起来之后进行。如果这些是在系统跑起来之前进行的话,则有可能存在潜在的隐患。具体可以看下面的方式二。

在完成所有初始化操作之后,该初始任务可以继续完成一些其它的功能。当然,也有的人直接让任务自行删除。不过我认为自行删除并不必要,因为在任务任务时,我们可能是通过全局变量定义任务的Task结构和堆栈空间。删除之后,这些空间肯定还要用的吧?如果是分配给别的任务,那么还得再创建一个任务。既然如此,那么为什么不直接不删除呢?

要特别注意一点:初始任务的优先级应尽可能的高。因为有些RTOS的任务创建接口中,创建任务之后可能会立即启动该任务,如果新任务的优先级比初始任务的优先级更高,则会切换至新任务运行。而这与我们所期望的流程就不一致。

方式二:在main中完成所有软硬初始化及所有任务创建

这是最简单也是最常用的方式。简单来说是这样:在main()中调用RTOS的初始化函数,中间初始化软硬件、创建其它任务,然后再调用启动os的API。以uCOS为例,如果采用这种方式,其初始化流程可能是这样的。

int main() {
    OSInit();
    DataInit();         // 初始化应用相关的数据
    HardwareInit();     // 初始化硬件模块
    CreateTask1();      // 创建任务1
    CreateTask2();      // 创建任务2
    OSStart();    
    return 0;
}

可以看到采用这种方式,在整个系统跑起来之前已经完成了所有任务的初始化,系统跑起来之后,各个任务就可以专注实现其要实现的功能。

但是这种方式有一个隐藏的缺陷:如果在初始化硬件模块时产生中断,且在中断服务函数中又调用了RTOS相关的API,则有可能导致系统崩溃。

原因是什么呢?

这是因为当前RTOS还没有跑起来,甚至于有些内核数据还没初始化好。此时如果发生中断,在中断中调用的RTOS的API可能访问这些内核数据,或者尝试执行只能在RTOS跑起来后执行的操作。

举个实际的例子,假设当前正在配置GPIO外部上沿升输入中断,刚刚开启中断配置使能后恰恰外部输入了一个上升沿信号(外部往往不可控),则立即进入GPIO中断处理函数中。在中断处理函数中,简单快速处理后向Task 1发送消息。发送完消息后,退出中断时会执行任务切换,尝试切换至Task 1,而此时当前还没有任务运行,那么此时应该怎样完成切换呢?

当然,不排除RTOS在设计时有考虑这种情况。但是你能确定所用的RTOS一定能正确处理这种异常问题吗?

所以,如果你的应用中可能会遇到这种问题,与其花时间研究是否能正确处理这种问题,倒不如直接采用方式一,这是最稳妥也最简单的方式。

总结

总结以上内容,可以看出方式一相对于方式二有着明显的优点:即系统启动之前不会受外部事件干扰的影响。

正是因为这样,我个人比较推荐第一种。目前,在有些RTOS的实现中,默认采用了方式一。其内部已经自动帮我们创建了一个初始任务,我们只需要额外实现一个其定义好的接口函数,然后在函数中添加软硬件初始化及其它任务的创建即可。

当然,实际在写代码时,采用的具体方式可能并不完全同上述两种方式,但基本流程差不太多。

该文章同时发布在:http://01ketang.cc/rtos/rtos-init.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李述铜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值