PX4模块设计之十三:WorkQueue设计

2023-05-16

PX4模块设计之十三:WorkQueue设计

  • 1. WorkQueue启动
  • 2. WorkQueue接口
    • 2.1 基本接口
    • 2.2 辅助接口
    • 2.3 WorkQueue任务函数
      • 2.3.1 Flat Build
      • 2.3.2 Protected Build
    • 2.4 重点接口分析
      • 2.4.1 WorkQueueManagerStart
      • 2.4.2 WorkQueueManagerRun
      • 2.4.3 WorkQueueRunner
      • 2.4.4 WorkQueue::Run
      • 2.4.5 WorkQueueFindOrCreate
  • 3. 总结
  • 4. 参考资料

1. WorkQueue启动

WorkQueue是PX4飞控软件的Common(公共)组件,通过函数px4::WorkQueueManagerStart开始启动的,这之前请参考PX4模块设计之十:PX4启动过程。

board_app_initialize
 └──> px4_platform_init
     └──> px4::WorkQueueManagerStart

注1:Nuttx系统是支持WorkQueue的。但是PX4在common(公共)组件层实现了类似的WorkQueue的功能,而没有直接采用Nuttx系统的WorkQueue。这里初步怀疑还是历史时间上导致的这个结果。
注2:Nuttx第一版本是在2007年发布,开始支持2-3个MCU((i.e. 8051 and ARM7);PX4-AutoPilot是2009年开始的项目,2013年ETH Zurich (苏黎世联邦理工大学)的计算机视觉与几何实验室 Lorenz Meier ,发布了第一代实验版本: 双飞控处理器PX4FMU/PX4IO硬件。

所以综上所述,鉴于以下原因
1)其历史原因,PX4-AutoPilot的公共组件WorkQueue独立实现;
2)飞控模式采用C++类继承进行开发和管理;
3)uORB消息组件采用C++类进行管理;
4)HRT高精度定时采集触发管理;

WorkQueue的整体管理上结合了上述历史原因,将C/C++设计,类,继承,以及内核态/用户态。整体感觉异常复杂,这部分内容实在不太敢恭维!!!(—AnyWay, 历史原因吧!!!—)

2. WorkQueue接口

2.1 基本接口

最为基本的WorkQueue管理接口并不负责,主要就是Start/Stop/Status三个。

int WorkQueueManagerStart() //WorkQueue管理启动任务

int WorkQueueManagerStop() //作为基础组件这个基本不需要Stop,至少目前代码上没有看到有Stop的地方。

int WorkQueueManagerStatus() //WorkQueue状态查询

2.2 辅助接口

const wq_config_t & device_bus_to_wq(uint32_t device_id_int)  //device_bus 转 wq配置

const wq_config_t & serial_port_to_wq(const char *serial)     //serial_port 转 wq配置

const wq_config_t & ins_instance_to_wq(uint8_t instance)      //instance 转 wq配置

static WorkQueue * FindWorkQueueByName(const char *name)      //通过名字查WorkQueue

WorkQueue * WorkQueueFindOrCreate(const wq_config_t &new_wq)   //查找或者创建WorkQueue

2.3 WorkQueue任务函数

WorkQueue目前是支持Flat和Protected Build两种编译模式,不同编译模式下最显著的差异就是Flat Build下采用pthread_create建立任务,而Protected Build下采用px4_task_spawn_cmd建立任务。

2.3.1 Flat Build

static void * WorkQueueRunner(void *context)

2.3.2 Protected Build

该函数内部实现会再次调用Flat Build的函数(此时运行的代码空间将会是内核态)。

inline static int WorkQueueRunner(int argc, char *argv[])

2.4 重点接口分析

2.4.1 WorkQueueManagerStart

WorkQueueManagerStart
 ├──> <_wq_manager_should_exit.load() && (_wq_manager_create_queue == nullptr)>
 │   ├──> _wq_manager_should_exit.store(false);
 │   ├──> int task_id = px4_task_spawn_cmd("wq:manager",SCHED_DEFAULT,SCHED_PRIORITY_MAX,PX4_STACK_ADJUSTED(1280),(px4_main_t)&WorkQueueManagerRun,nullptr);
 │   └──> <task_id < 0>
 │       ├──> _wq_manager_should_exit.store(true);
 │       ├──> PX4_ERR("task start failed (%i)", task_id);
 │       └──> return -errno;
 ├──> else
 │   ├──> PX4_WARN("already running");
 │   └──> return PX4_ERROR;
 └──> return PX4_OK;

2.4.2 WorkQueueManagerRun

WorkQueueManagerRun
 ├──> _wq_manager_wqs_list = new BlockingList<WorkQueue *>();
 ├──> _wq_manager_create_queue = new BlockingQueue<const wq_config_t *, 1>();
 ├──> <while (!_wq_manager_should_exit.load())>
 │   ├──> const wq_config_t *wq = _wq_manager_create_queue->pop();  //当没有work queue的时候,管理任务始终阻塞在这里。
 │   └──> <wq != nullptr> //不应该是空,容错以防段错误,里面是建立新的work queue
 │       ├──> [stack, priority, etc]  //略。。。。
 │       ├──> [Flat Build, pthread_create WorkQueueRunner]
 │       ├──> [Protected Build, px4_task_spawn_cmd WorkQueueRunner]
 │       ├──> <pid > 0>
 │       │   └──> PX4_DEBUG("starting: %s, priority: %d, stack: %zu bytes", wq->name, sched_priority, stacksize);
 │       └──> <else>
 │           └──> PX4_ERR("failed to create thread for %s (%i): %s", wq->name, pid, strerror(pid));
 └──> return 0;

2.4.3 WorkQueueRunner

WorkQueueRunner
 ├──> wq_config_t *config = static_cast<wq_config_t *>(context);
 ├──> WorkQueue wq(*config);
 ├──> _wq_manager_wqs_list->add(&wq);    // add to work queue list
 ├──> wq.Run();                          // 这里就是启动任务队列WorkQueue::Run()
 ├──> _wq_manager_wqs_list->remove(&wq); // remove from work queue list
 └──> return nullptr;

2.4.4 WorkQueue::Run

WorkQueue::Run
 ├──> <while (!should_exit())>
 │   ├──> do {} while (px4_sem_wait(&_process_lock) != 0); // loop as the wait may be interrupted by a signal
 │   ├──> work_lock();
 │   └──> <while (!_q.empty())>
 │       ├──> WorkItem *work = _q.pop();
 │       ├──> work_unlock();         // unlock work queue to run (item may requeue itself)
 │       ├──> work->RunPreamble();
 │       ├──> work->Run();           // 真实需要执行的Run函数,通常是继承WorkItem的对象
 │       ├──> work_lock();           // re-lock
 │       └──> work_unlock();
 └──> PX4_DEBUG("%s: exiting", _config.name);

2.4.5 WorkQueueFindOrCreate

WorkQueueFindOrCreate
 ├──> <_wq_manager_create_queue == nullptr>
 │   ├──> PX4_ERR("not running");
 │   └──> return nullptr;
 ├──> WorkQueue *wq = FindWorkQueueByName(new_wq.name); // search list for existing work queue
 ├──> <wq == nullptr>
 │   ├──> _wq_manager_create_queue->push(&new_wq);  //这里很重要,只有push了,WorkQueueManagerRun里面才能执行下去。
 │   ├──> _uint64_t t = 0;
 │   └──> _<while (wq == nullptr && t < 10_s)>  // we wait until new wq is created, then return
 │       ├──> t += 1_ms;
 │       ├──> px4_usleep(1_ms);
 │       ├──> wq = FindWorkQueueByName(new_wq.name);
 │       └──> <wq == nullptr>
 │           └──> PX4_ERR("failed to create %s", new_wq.name);
 └──> return wq;

3. 总结

工作队列,理解起来其实并不复杂。而PX4的工作队列为什么看起来复杂,主要是工作队列和实际的业务耦合。这里我们还没有将uORB的订阅内容放到里面,如果结合这部分,再加上多个继承业务的相互切换等内容,就看似更加复杂了。

所以我们尤其强调设计需要松耦合,尽量模块化,明确接口设计,明确框架设计。

4. 参考资料

【1】PX4开源软件框架简明简介
【2】Nuttx WorkQueue

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4模块设计之十三:WorkQueue设计 的相关文章

  • PX4通过I2C方式添加自定义传感器(3)

    添加自定义传感器并实现数据的发送和订阅 1 前期准备 1 1 建立文件夹和相关文件配置 我是在src drivers distance sensor文件夹下操作的 xff0c 当然其他文件夹下都类似 首先建立了两个文件夹angle sour
  • PX4 Offboard Control with MAVROS--Takeoff(一键起飞)

    警告 xff1a 请先在仿真环境下进行测试 xff0c 能达到预期效果后在进行实际飞行测试 xff0c 以免发生意外 本篇文章只是用作学习交流 xff0c 实际飞行时如出现意外情况作者不予以负责 所需材料 1 PIXhawk或者Pixrac
  • 编译PX4固件

    PX4编译 文章目录 PX4编译疑难杂症bug1bug2catkin build isolated 官方脚本Step1Step2 安装常用依赖Step3 创建并运行脚本Step4 补全代码子模块Step5 验证仿真 官方offboard 例
  • PX4 GAZEBO无人机添加相机并进行图像识别

    PX4 GAZEBO无人机添加摄像头并进行图像识别 在之前完成了ROS的安装和PX4的安装 xff0c 并可以通过roslaunch启动软件仿真 接下来为无人及添加相机 xff0c 并将图像用python函数读取 xff0c 用于后续操作
  • Ubuntu20.04+MAVROS+PX4+Gazebo保姆级安装教程

    Ubuntu20 04 43 MAVROS 43 PX4 43 Gazebo 安装PX4步骤安装MAVROS安装QGCPX4仿真 安装PX4步骤 从github上clone源码 span class token function git s
  • PX4无人机 - 键盘控制飞行代码

    PX4无人机 键盘控制飞行代码 仿真效果 实机效果 由于图片限制5M以内 xff0c 只能上传一小段了 xff0c 整段视频请点击链接 Pixhawk 6c 无人机 键盘控制无人机 Offboard模式 核心 xff1a 发布 mavros
  • 基于F4/F7/H7飞控硬件和px4飞控固件的廉价自主无人机系统(1)-飞控

    前言 穿越机F4 F7 H7飞控是一系列采用stm32系列F4xx和F7xx处理器的飞控的统称 xff0c 是目前穿越机爱好者非常喜欢使用的飞控硬件 xff0c 其价格也非常便宜180 xff5e 410 而px4则是一款常见的开源飞控固件
  • PX4代码学习系列博客(6)——offboard模式位置控制代码分析

    分析offboard模式的代码需要用到以下几个模块 local position estimator mavlink mc pos control mc att control mixer 程序数据走向 mavlink 一般的offboar
  • PX4源代码下载编译

    sudo git clone https github com PX4 PX4 Autopilot git recursivegit submodule update init recursivegit submodule update r
  • PX4进入系统控制台以及运行程序

    这里提供进入控制台两种办法 1 运行 Tools mavlink shell py dev ttyACM0 是我进入Px4系统控制台的命令 xff0c 进入之后应该是这样 Pixhawk src Firmware Tools mavlink
  • PX4模块设计之一:SITL & HITL模拟框架

    PX4模块设计之一 xff1a SITL amp HITL模拟框架 1 模拟框架1 1 SITL模拟框架1 2 HITL模拟框架 2 模拟器类型3 MAVLink API4 总结 基于PX4开源软件框架简明简介的框架设计 xff0c 逐步分
  • PX4模块设计之十八:Logger模块

    PX4模块设计之十八 xff1a Logger模块 1 Logger模块简介2 模块入口函数2 1 主入口logger main2 2 自定义子命令Logger custom command2 3 日志主题uORB注册 3 重要实现函数3
  • PX4模块设计之二十一:uORB消息管理模块

    PX4模块设计之二十一 xff1a uORB消息管理模块 1 uORB模块构建模式2 uORB消息管理函数2 1 状态查询2 2 资源利用2 3 模块启动2 4 模块停止3 uORB消息接口3 1 消息主题注册3 2 消息主题去注册3 3
  • PX4模块设计之二十四:内部ADC模块

    PX4模块设计之二十四 xff1a 内部ADC模块 1 内部ADC模块简介2 模块入口函数2 1 主入口board adc main2 2 自定义子命令custom command 3 内部ADC模块重要函数3 1 task spawn3
  • PX4模块设计之三十一:ManualControl模块

    PX4模块设计之三十一 xff1a ManualControl模块 1 ManualControl模块简介2 模块入口函数2 1 主入口manual control main2 2 自定义子命令custom command 3 Manual
  • PX4模块设计之三十六:MulticopterPositionControl模块

    PX4模块设计之三十六 xff1a MulticopterPositionControl模块 1 MulticopterPositionControl模块简介2 模块入口函数2 1 主入口mc pos control main2 2 自定义
  • PX4模块设计之四十五:param模块

    PX4模块设计之四十五 xff1a param模块 1 param模块简介2 模块入口函数param main3 重要函数列表4 总结5 参考资料 1 param模块简介 Description Command to access and
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • px4无人机常识介绍(固件,px4等)

    专业名词解释 aircraft 任何可以飞或者可以携带物品还是搭载旅客的飞行器统称为飞机 航空器 uav 无人驾驶飞机 vehicle 飞行器 airplane plane aero plane 有机翼和一个或多个引擎的飞行器统称为飞机 D
  • 飞行姿态解算(三)

    继之前研究了一些飞行姿态理论方面的问题后 又找到了之前很流行的一段外国大神写的代码 来分析分析 第二篇文章的最后 讲到了文章中的算法在实际使用中有重大缺陷 大家都知道 分析算法理论的时候很多情况下我们没有考虑太多外界干扰的情况 原因是很多情

随机推荐

  • 四轴FPV无人机手动操作简明介绍

    四轴FPV无人机手动操作简明介绍 通常航拍机都是有自稳算法 43 GPS导航 43 辅助功能 避障 的支持 xff0c 从而保证飞手能够相对容易且稳定的操作模型飞机 xff0c 通常通过阅读说明书都能很快上手 xff0c 这里就不在赘述 本
  • BetaFlight开源代码框架简介

    BetaFlight开源代码框架简介 1 框架设计分析考量2 框架分析前提条件3 主程序框架4 调度框架5 模块方法6 典型任务 amp 模块6 1 典型任务6 2 典型模块6 3 传感模块 7 回顾 amp 分析8 分析模板 1 框架设计
  • 四轴飞控DIY集成FPV功能

    四轴飞控DIY集成FPV功能 1 功能需求2 概念介绍2 1 制式2 2 显示分辨率2 3 摄像头线数高于700线低于700线 3 需求分析4 组件选择5 接线组装5 1 摄像头接线5 2 图传接线 6 组装位置7 FPV功能调试7 1 摄
  • MFC拷贝文件及进度条显示

    参考 xff1a 封装CopyFileEx函数 xff0c 实现文件复制中的暂停 xff0c 控速 xff0c 获取进度 http blog csdn net career2011 article details 6844513 实例讲解C
  • BetaFlight模块设计之三十二:MSP协议模块分析

    BetaFlight模块设计之三十二 xff1a MSP协议模块分析 1 MSP协议模块1 1 MSP描述1 2 MSP版本优缺点1 3 MSP代码资源 2 MSP报文解析2 1 MSP收包状态机2 2 MSP报文格式 3 MSP报文处理3
  • BetaFlight模块设计之三十三:Pid模块分析

    BetaFlight模块设计之三十三 xff1a Pid模块分析 Pid模块1 Pid audio子模块2 Pid init子模块3 Pid算法子模块3 1 TPA模式3 2 飞行模式3 3 Launch模式3 4 AcroTrainer模
  • BetaFlight模块设计之三十四:OSD模块分析

    BetaFlight模块设计之三十四 xff1a OSD模块分析 1 OSD模块1 1 osd状态机子模块1 2 osd warnings检查子模块1 3 osd elements子模块 2 OSD设备 驱动及适配框架2 1 OSD设备2
  • ssh无法远程登陆问题汇总

    ssh无法远程登陆问题汇总 1 ssh服务是否已经启动1 1 sshd服务是否已经安装1 2 sshd是否已经启动 2 检查sshd配置3 检查路由情况4 检查hosts许可文件5 检查防火墙问题5 1 检查防火墙是否启动5 2 修改防火墙
  • traceroute命令结果分析

    traceroute命令结果分析 1 基本原理2 IP地址种类2 1 A类IP地址2 2 B类IP地址2 3 C类IP地址2 4 D类地址用于多点广播 Multicast 2 5 E类IP地址 3 测试3 1 第一次3 2 第二次 4 总结
  • bash脚本返回值应用

    bash脚本返回值应用 应该说bash脚本对于linux系统来说具有举足轻重的意义 这里不做展开 xff0c 也不做bash脚本介绍 更多的是做一个例子 xff0c 应用了bash脚本的以下特性 xff1a 输入参数函数定义调用可执行命令脚
  • 如何理解printf变参函数的实现

    如何理解printf变参函数的实现 1 printf函数变参的问题2 printf函数定义和解释2 1 printf函数定义2 2 Linux Man page解释 https man7 org linux man pages man3 s
  • BetaFlight模块设计之三十五:RSSI信号强度&链路稳定性分析

    BetaFlight模块设计之三十五 xff1a RSSI信号强度 amp 链路稳定性分析 1 RSSI信号强度1 1 RSSI Value1 2 RSSI dBm Value 2 链路稳定性3 RSSI amp LinkQuality来源
  • Linux的so组件设计框架及逻辑

    Linux的so组件设计框架及逻辑 1 组件关注点1 1 组件定义关注点1 2 组件业务关注点 2 so特性3 so组件设计逻辑4 so组件设计框架4 1 so组件范例4 2 so隐式调用范例4 3 so显式调用范例 5 so组件设计建议
  • PX4模块设计之八:Ubuntu 20.04搭建FlightGear模拟器

    PX4模块设计之八 xff1a Ubuntu 20 04搭建FlightGear模拟器 1 使用FlightGear的源由2 FlightGear模拟器简介3 Ubuntu 20 04搭建FlightGear步骤3 1 设置flightge
  • 封装CopyFileEx函数,实现文件复制中的暂停,控速,获取进度

    封装CopyFileEx函数 xff0c 实现文件复制中的暂停 xff0c 控速 xff0c 获取进度等 前段时间无意间想到如何控制文件复制过程的复制速度 xff0c 并且能实时获得复制进度 对于一个几兆甚至更小的文件 xff0c 调用AP
  • PX4模块设计之九:PX4飞行模式简介

    PX4模块设计之九 xff1a PX4飞行模式简介 关于模式的探讨1 需求角度1 1 多旋翼 MC multi copter 1 1 1 RC控制模式1 1 1 1 Position Mode1 1 1 2 Altitude Mode1 1
  • PX4模块设计之十:PX4启动过程

    PX4模块设计之十 xff1a PX4启动过程 1 硬件 飞控硬件上电2 硬件 飞控硬件初始化3 硬件 43 软件 飞控bootloader初始化4 硬件 43 软件 飞控系统初始化5 软件 飞控应用初始化6 配置 SD卡配置文件6 1 e
  • PX4模块设计之十一:Built-In框架

    PX4模块设计之十一 xff1a Built In框架 1 Nuttx Built In框架2 PX4 Built In框架2 1 NSH Built In关联文件2 2 NSH Built In关联文件生成2 3 NSH Built In
  • PX4模块设计之十二:High Resolution Timer设计

    PX4模块设计之十二 xff1a High Resolution Timer设计 1 HRT模块特性2 HRT模块基本功能2 1 循环触发接口2 2 延迟触发接口2 3 定时触发接口2 4 其他功能 3 HRT模块精度3 1 精度粒度3 2
  • PX4模块设计之十三:WorkQueue设计

    PX4模块设计之十三 xff1a WorkQueue设计 1 WorkQueue启动2 WorkQueue接口2 1 基本接口2 2 辅助接口2 3 WorkQueue任务函数2 3 1 Flat Build2 3 2 Protected