PX4代码结构分析

        PX4代码是基于nuttx操作系统开发的,不是单片机程序,以至于新手在看代码的时候,理不清代码的结构,不知道每个函数对应的功能。后台也有人私信我,问应用的初始化在哪,run函数是在哪调用的。这篇博客,我就整理下PX4的代码结构。

        程序的启动分为两种类型,一种是将自身添加到运行队列里,由队列统一管理;另一种是在应用中创建新进程,将程序启动。下面分别介绍两种。

一、在运行队列中运行

        在介绍该方式时候,先介绍一下队列管理器。队列管理器管理处于队列中的应用。在文件px4_init.cpp中有一个函数WorkQueueManagerStart();在该函数中调用px4_task_spawn_cmd函数启动一条进程来管理队列中的应用。在队列中,调用wq.Run();来执行应用本身的逻辑。

        也就是说,这种方式运行的应用,只要将自身添加到队列中,并实现Run()就可以了。

        采用队列方式运行的应用,必须要继承两个类,一个是ModuleBase<T>另一个是WorkItem。

        ModuleBase封装了应用常用的功能,包含对start,stop,help等指令的处理。在接收到启动命令后,会调用start_command_base()函数。在该函数中调用T::task_spawn(argc, argv)(也就是说具体的应用要重写task_spawn函数)。在task_spawn(argc, argv)会new一个应用自身的对象,如new MulticopterAttitudeControl()来完成资源分配和变量的初始化。

        WorkItem类完成了加入进程队列需要的一些配置,是在初始化时完成的,不要要相关的调用。

        前面介绍说在队列中,调用wq.Run();来执行应用本身的逻辑,因此具体的应用要实现Run()这个虚函数。

二、应用自身启动新进程

        不同于上一种方式,通过新进程的方式启动的应用,只要继承ModuleBase类就可以了。

        在接收到start指令后,调用父类的start_command_base()函数。在该函数中,调用子类重写的task_spawn函数。子类的task_spawn函数通过px4_task_spawn_cmd函数新建一条进程,入口是父类的run_trampoline。在该函数中,统一进行类的初始化及运行run()逻辑处理函数。

        相比于上一种启动方式,这里的run函数以小写字母开头,上面一种则是Run()。

三、总结

        总结一下,这两种方式是将一些共用的功能通过modleBase进行了提炼,封装成了公共的,减少了代码量。

        说一下他们的使用场景。在姿态控制控制、姿态估计这种底层的,必须要的应用时候,一般采用第一种启动方式。对于navigator这种上层的应用,有时候进程挂了,不产生严重影响的应用,则可以采用第二种方式。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值