ardupilot线程理解

2023-05-16

对于apm和pixhawk一直存在疑惑,到现在还不是特别清楚。今天在http://dev.ardupilot.com/看到下面的说明,感觉很有用,对于整体理解amp代码很有帮助,所以记下来。

转载请标记出处,我的一下午啊。多谢。

理解ArduPilot的线程

当你开始学习ArduPilot的基础库的时候,你最好能理解ArduPilot是怎样处理线程的。代码里的 setup()/loop() 结构继承自arduino,肯能个看起来更像一个单线程系统,事实上不是这样的。

ArduPilot的线程方法依赖于它运行的硬件平台情况。在一些板子如APM1和APM2上,由于硬件不支持多线程,所以这类硬件上的线程其实是简单的定时器和回调函数。而在另外的硬件,如PX4和运行linux系统的硬件上,支持实时钟优先级的Posix线程模型,所以在ArduPilot中,这种线程模型得到广泛的使用。


ArduPilot的学习中,关于线程的内容,有下面几个关键概念需要理解:

1  定时器回调
2  HAL层特定线程
3  驱动特定线程
4  ardupilot驱动与平台驱动
5  平台特定线程和任务
6  ap_scheduler系统
7  信号灯
8  无锁数据结构


定时器回调

在AP_HAL层任何平台都会提供一个1KHz的定时器。在ArduPilot任何代码都可以注册成一个定时器功能函数,以1KHz的频率调用。所有注册的定时器函数按照一定顺序被调用。执行。这种简单的调用机制非常轻便并且非常有用。注册定时器回调方式如下


  hal.scheduler->register_timer_process(AP_HAL_MEMBERPROC(&AP_Baro_MS5611::_update));  

这个例子来自MS5611气压计的驱动代码。AP_HAL_MEMBERPROC() 宏把一个c++功能函数封装成一个回调参数。,用函数指针将对象上下文捆绑起来。C++我懂的不多,但是这个语句的意思就是把update函数注册到定时器,然后定时器会以1KHz的频率调用update函数。
有时候,你的代码想以小于1KHz的频率执行,你就需要维护一个自己的“last_called”变量,当距离上次调用的时间不够调用周期时,立即返回即可。这个的实现,你可以通过使用hal.scheduler->millis() 和 hal.scheduler->micros()函数获得从系统启动到现在的时间,这两个函数的单位分别是毫秒和微妙。

看了上面的说明,现在你可以修改一个已经存在的例子,或者新建一段实现代码,然后添加到定时器回调里,让定时器每次递增一个计数器,然后在loop函数中每秒把计数值打印出来。然后修改你的代码让计数器每25毫秒递增计数器,来看看结果是不是和预期的一样。

HAL specific threads

在一些支持实时线程的平台上,平台对应的AP_HAL会创建一些列线程支持基本的操作。例如,在PX4平台上,下面的HAL特定线程会被建立:
    A  UART线程,用于读写平台或板子的UART或USB通信口
    B  定时器线程,这个就是上面说的1KHz的定时器
   C  IO线程,这个线程主要是写 microSD card, EEPROM 或 FRAM
每个平台的AP_HAL实现,你都可以看到在Scheduler.cpp文件中都建立了哪些线程,以及这些线程的实时优先级。如PX4平台,这个文件在libraries\ap_hal_px4\目录下。
在init函数中,建立了这三个线程。创建方式就是linux下大家熟悉的pthread_create。

如果你有一个pixhawk的硬件,你可以连接这个硬件按的serial 5端口和你的pc的串口,pc串口设置57600 8N1,等打印出来一堆信息以后,回车,然后输入ps就会看到下面信息:


PID PRI SCHD TYPE NP STATE NAME
 0 0 FIFO TASK READY Idle Task()
 1 192 FIFO KTHREAD WAITSIG hpwork()
 2 50 FIFO KTHREAD WAITSIG lpwork()
 3 100 FIFO TASK RUNNING init()
 37 180 FIFO TASK WAITSEM AHRS_Test()
 38 181 FIFO PTHREAD WAITSEM (20005400)
 39 60 FIFO PTHREAD READY (20005400)
 40 59 FIFO PTHREAD WAITSEM (20005400)
 10 240 FIFO TASK WAITSEM px4io()
 13 100 FIFO TASK WAITSEM fmuservo()
 30 240 FIFO TASK WAITSEM uavcan()  

在上面的现实中你可以看到三个线程:
定时器线程(优先级181), uart线程(优先级60)和io线程(优先级59).
线程的一个常见用途
是提供驱动程序的方式来安排慢任务
线程的一个常见用途
是提供驱动程序的方式来安排慢任务
线程的一个常见用途
是提供驱动程序的方式来安排慢任务
线程的常见用途是给驱动提供一种慢速任务调度的方式。这样不会中断主飞行代码的执行。例如,AP_Terrain库需要操作文件IO,如读写microSD卡,就是放到io线程来做的:


hal.scheduler->register_io_process(AP_HAL_MEMBERPROC(&AP_Terrain::io_timer));

在板级IO线程中,AP_Terrain::io_timer代码定期执行,这意味着这是个低实时优先级,比较适合IO存储操作的任务。像这样的低速IO任务不能在定时器线程调用,因为在处理高速传感器数据的过程中会引起延时,而传感器数据的处理更重要,所以这类IO函数不能放到定时器线程,只能放在IO线程。



Driver specific threads

 

有时候,需要建立驱动特定线程,支持与一个驱动的特定方式的异步处理。目前你只能以平台相关的方式建立驱动特定线程,所以只有你打算你的驱动之适用于一种autopilot板子时,这种方式才适用。如果你打算让你的驱动运行在多个AP_HAL抽象目标上,通常你有两个做法:
    A    
你可以使用register_io_process() 和 register_timer_process() 调度器来调用已经存在的定时器或IO线程。
   B     你可以添加一个新创建线程的HAL层接口,在多AP_HAL目标上提供一个通用的调用方式(需要发布补丁)
一个驱动特定线程的例子是ToneAlarm线程,  AP_HAL_Linux/ToneAlarmDriver.cpp这个文件,我没有在这个目录下找到这个文件,但是在其它目录找到这个文件了,其实就是在Firmware有一个驱动在和硬件交互,读取数据,然后其它驱动为了省事,直接open设备路径,然后从firmware层读取数据。这种方式其实挺简单,对于临时想替换个驱动,或者减少代码一类的操作,比较快捷,但是有一个最大的不足就是这个代码只能是特定目的的使用。firmware层需要提供这个驱动,并且还需要提供open或者ioctl函数来获取或者设置数据。这属于不按照常理出牌的套路。因为这对于系统整体的维护不利。如果你现在看apm代码是怎么用在pixhawk硬件上的可以明显看到这一点,apm好多代码调用了firmware的接口。

今天先到这里吧,星期6,到公司以下午,就完成这么点东西。都是自己的理解,有不对的地方,欢迎大家一起来讨论。

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

ardupilot线程理解 的相关文章

随机推荐

  • Linux串口(serial、uart)驱动程序设计

    一 核心数据结构 串口驱动有3个核心数据结构 xff0c 它们都定义在 lt include linux serial core h gt 1 uart driver uart driver包含了串口设备名 串口驱动名 主次设备号 串口控制
  • Xshell 5 评估过期,需要采购,不能使用的解决办法

    Xshell 5 当然 xff0c 现在我们可以直接撸 Xshell 6 了 卸载原来的 Xshell 5进入 Xshell 5 官网 xff1a https www netsarang com页面上点导航栏的 Free Licence x
  • mapreduce编程(一)-二次排序

    mr自带的例子中的源码SecondarySort xff0c 我重新写了一下 xff0c 基本没变 这个例子中定义的map和reduce如下 xff0c 关键是它对输入输出类型的定义 xff1a xff08 java泛型编程 xff09 p
  • Android apk执行shell脚本 工具类

    在做Android应用时 xff0c 经常需要执行shell脚本 xff0c 以快速实现某些功能 xff1b 在Android应用程序中执行shell脚本可以省去一大堆繁琐的代码 xff0c 还可以避免不必要的错误 xff1b 比如 xff
  • Python最强装逼神技!微信远程控制电脑,想让你电脑关机就关机!

    今天带给大家一个非常有意思的 python 程序 xff0c 基于 itchat 实现微信控制电脑 你可以通过在微信发送命令 xff0c 来拍摄当前电脑的使用者 xff0c 然后图片会发送到你的微信上 甚至你可以发送命令来远程关闭电脑 程序
  • 基于ESKF的IMU姿态融合【附MATLAB代码】

    目录 0 前言1 什么是ESKF2 系统方程2 1 状态变量2 2 imu的测量值2 3 预测方程及雅克比矩阵2 4 测量方程及雅克比矩阵 3 kalman filter loop计算4 Show me the code5 代码下载链接 0
  • 【笔记】自适应卡尔曼滤波 Adaptive Extended Kalman Filter

    0 阅读文章 Adaptive Adjustment of Noise Covariance in Kalman Filter for Dynamic State Estimation 1 主要内容 一般情况下 xff0c kalman中的
  • 二、Docker:Dockerfile的使用、指令详解和示例

    什么是 Dockerfile xff1f Dockerfile 是一个用来构建镜像的文本文件 xff0c 文本内容包含了一条条构建镜像所需的指令和说明 使用 Dockerfile 定制镜像 1 使用 dockerfile 定制 nginx
  • # STM32中断方式实现串口通信(标准库)

    STM32中断方式实现串口通信 xff08 标准库 xff09 文章目录 STM32中断方式实现串口通信 xff08 标准库 xff09 一 串口通信原理以及中断原理一 问题分析1 涉及外设2 状态机实现 二 创建MDK xff08 kei
  • 一张图看懂阿里云网络产品[一]网络产品概览

    一张图看懂网络产品系列文章 xff0c 让用户用最少的时间了解网络产品 xff0c 本文章是第一篇 网络产品概览 系列文章持续更新中 xff0c 敬请关注 xff3b 一 xff3d 网络产品概览 xff3b 二 xff3d VPC xff
  • MapReduce原理及编程实现

    文章目录 MapReduce原理及编程实现MapReduce基本概念MapReduce执行过程Mapper阶段Reducer阶段Combiner类Partitioner类 MapReduce实现WordCountKey amp Value类
  • 2020-10-20 学习日志(Crazepony控制环)

    2020年10月20日 学习任务 xff1a 完成Crazepony控制环的理解 之前是通过姿态解算获得了 四元数 旋转矩阵 欧拉角 CtrlAttiRate void CtrlAttiRate void float yawRateTarg
  • STL学习笔记之迭代器--iterator

    STL设计的精髓在于 xff0c 把容器 xff08 Containers xff09 和算法 xff08 Algorithms xff09 分开 xff0c 彼此独立设计 xff0c 最后再用迭代器 xff08 Iterator xff0
  • 提升工作效率之PCB设计软件“立创EDA”

    文章目录 前言一 立创EDA二 PCB生产三 团队功能总结 前言 由于工作需要设计一款硬件调试小工具 xff0c 考虑到器件采购和PCB制版都在立创商城上进行 xff0c 索性就试用立创EDA进行PCB设计 结论在前 xff1a 立创线上E
  • nvidia显卡,驱动以及cuda版本对应查询

    实验室新买了一块rtx 2080和titan rtx xff0c 需要分别配置驱动和cuda xff0c 但是一直也找不到显卡和cuda的官方对照表 xff0c 每次都是百度 谷歌 必应 xff0c 参考别人安装之旅 今天突然发现了驱动和c
  • LoRa 信噪比和接收灵敏度

    文章目录 前言一 信噪比极限 xff08 SNR LIMIT xff09 二 接收灵敏度 前言 介绍信噪比极限和如何计算接收灵敏度 参考资料 xff1a LoRa信噪比和接收灵敏度 一 信噪比极限 xff08 SNR LIMIT xff09
  • C在字符串后面加/0和0

    使用复制字符串时 xff0c 经常会遇到字符串后面跟着一大堆莫名其妙的字符串 xff0c 例如屯屯屯 之类的东西 xff0c 这是因为在使用字符串时没有在字符串结尾加 0或0 通常分配一块内存到堆上或栈上时 xff0c 内存区域可能会有之前
  • 基于k8s+prometheus实现双vip可监控Web高可用集群

    目录 一 规划整个项目的拓扑结构和项目的思维导图 二 修改好各个主机的主机名 xff0c 并配置好每台机器的ip地址 网关和dns等 2 1修改每个主机的ip地址和主机名 2 2 关闭firewalld和selinux 三 使用k8s实现W
  • PX4源码开发人员文档(一)——软件架构

    软件架构 PX4 在广播消息网络内 xff0c 按照一组节点 xff08 nodes xff09 的形式进行组织 xff0c 网络之间使用像如 姿态 和 位置 之类的语义通道来传递系统状态 软件的堆栈结构主要分为四层 应用程序接口 提供给a
  • ardupilot线程理解

    对于apm和pixhawk一直存在疑惑 xff0c 到现在还不是特别清楚 今天在http dev ardupilot com 看到下面的说明 xff0c 感觉很有用 xff0c 对于整体理解amp代码很有帮助 xff0c 所以记下来 转载请