PX4模块设计之四十三:icm20689模块

2023-05-16

PX4模块设计之四十三:icm20689模块

  • 1. icm20689模块简介
  • 2. 模块入口函数
    • 2.1 主入口icm20689_main
    • 2.2 自定义子命令custom_command
    • 2.3 模块状态print_status【重载】
  • 3. ICM20689模块重要函数
    • 3.1 模块启动ThisDriver::module_start
    • 3.2 模块停止ThisDriver::module_stop
    • 3.3 模块状态ThisDriver::module_status
    • 3.4 设备实例对象初始化I2CSPIDriver::instantiate_default
    • 3.5 ICM20689设备实例对象初始化ICM20689::init
    • 3.6 设备实例对象任务I2CSPIDriver::Run()
    • 3.7 ICM20689设备实例对象任务ICM20689::RunImpl
  • 4. 总结
  • 5. 参考资料

1. icm20689模块简介

icm20689 <command> [arguments...]
 Commands:
   start
     [-s]        Internal SPI bus(es)
     [-S]        External SPI bus(es)
     [-b <val>]  board-specific bus (default=all) (external SPI: n-th bus
                 (default=1))
     [-c <val>]  chip-select pin (for internal SPI) or index (for external SPI)
     [-m <val>]  SPI mode
     [-f <val>]  bus frequency in kHz
     [-q]        quiet startup (no message if no device found)
     [-R <val>]  Rotation
                 default: 0

   stop

   status        print status info

注1:print_usage函数是具体对应实现。

class ICM20689 : public device::SPI, public I2CSPIDriver<ICM20689>
class I2CSPIDriver : public I2CSPIDriverBase
class I2CSPIDriverBase : public px4::ScheduledWorkItem, public I2CSPIInstance
class ScheduledWorkItem : public WorkItem
class WorkItem : public IntrusiveSortedListNode<WorkItem *>, public IntrusiveQueueNode<WorkItem *>
class I2CSPIInstance : public ListNode<I2CSPIInstance *>


ICM20689  //类继承关系
 ├──> I2CSPIDriver
 │   └──> I2CSPIDriverBase
 │       ├──> px4::ScheduledWorkItem
 │       │   └──> WorkItem
 │       │       ├──> IntrusiveSortedListNode
 │       │       └──> IntrusiveQueueNode
 │       └──> I2CSPIInstance
 │           └──> ListNode
 └──> device::SPI

注2:ICM20689模块就是针对ICM20689硬件芯片进行管理和数据采集的模块。

2. 模块入口函数

2.1 主入口icm20689_main

模块支持start/stop/status命令,除此以外支持BusCLIArguments的I2C/SPI默认参数选项"RXIa:Ssc: m:kb:f:q"。

icm20689_main
 ├──> using ThisDriver = ICM20689
 ├──> BusCLIArguments cli{false, true}
 ├──> cli.default_spi_frequency = SPI_SPEED
 ├──> <while ((ch = cli.getOpt(argc, argv, "R:")) != EOF)>
 │   └──> <case 'R'>
 │       ├──> cli.rotation = (enum Rotation)atoi(cli.optArg())
 │       └──> break
 ├──> const char *verb = cli.optArg()
 ├──> <!verb>
 │   ├──> ThisDriver::print_usage()
 │   └──> return -1
 ├──> BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_ICM20689)
 ├──> <!strcmp(verb, "start")>
 │   └──> return ThisDriver::module_start(cli, iterator)   //模块启动
 ├──> <(!strcmp(verb, "stop")>
 │   └──> return ThisDriver::module_stop(iterator)  //模块停止
 ├──> <!strcmp(verb, "status")>
 │   └──> return ThisDriver::module_status(iterator)  //模块状态
 ├──> ThisDriver::print_usage()
 └──> return -1

2.2 自定义子命令custom_command

注:该模块采用了纯C语言代码实现,在main函数中直接执行命令,无需ModuleBase的custom_command重载实现。

2.3 模块状态print_status【重载】

该模块采用了纯C语言代码实现,在main函数中直接执行ThisDriver::print_usage()函数,无需ModuleBase的模块状态print_status重载实现。

ICM20689::print_usage

void ICM20689::print_usage()
{
	PRINT_MODULE_USAGE_NAME("icm20689", "driver");
	PRINT_MODULE_USAGE_SUBCATEGORY("imu");
	PRINT_MODULE_USAGE_COMMAND("start");
	PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true);
	PRINT_MODULE_USAGE_PARAM_INT('R', 0, 0, 35, "Rotation", true);
	PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
}

3. ICM20689模块重要函数

3.1 模块启动ThisDriver::module_start

启动过程会将以下驱动信息关联到设备实例上:

  1. static I2CSPIDriverBase *I2CSPIDriver::instantiate_default(const I2CSPIDriverConfig &config, int runtime_instance)
  2. int ICM20689::init()
  3. void ICM20689::RunImpl()
  4. void I2CSPIDriver::Run() final
ThisDriver::module_start(ICM20689::module_start)
 └──> I2CSPIDriver::module_start
     └──> I2CSPIDriverBase::module_start

注:I2CSPIDriverBase::module_start会进行第一次的Run激活(px4::WorkItemSingleShot)。

3.2 模块停止ThisDriver::module_stop

ThisDriver::module_stop(ICM20689::module_stop)
 └──> I2CSPIDriverBase::module_stop

注:I2CSPIDriverBase类的通用方法,不在这里展开。

3.3 模块状态ThisDriver::module_status

ThisDriver::module_status(ICM20689::module_status)
 └──> I2CSPIDriverBase::module_status

注:I2CSPIDriverBase类的通用方法,不在这里展开。

3.4 设备实例对象初始化I2CSPIDriver::instantiate_default

该方法在I2CSPIDriverBase::module_start函数里面调用,其目的是新建一个设备对象实例,并进行初始化。

I2CSPIDriver::instantiate_default
 ├──> instance = new T(config)   // 新建一个ICM20689设备对象实例
 ├──> <!instance>
 │   ├──> PX4_ERR("alloc failed")
 │   └──> return nullptr
 ├──> <OK != instance->init()>  // ICM20689设备对象实例初始化
 │   ├──> delete instance
 │   └──> return nullptr
 └──> return instance

3.5 ICM20689设备实例对象初始化ICM20689::init

ICM20689设备实例对象初始化

ICM20689::init
 ├──> int ret = SPI::init()  // SPI总线初始化
 ├──> <ret != PX4_OK>
 │   ├──> DEVICE_DEBUG("SPI::init failed (%i)", ret)
 │   └──> return ret
 └──> return Reset() ? 0 : -1  // 重置模块,然后触发ScheduleNow

3.6 设备实例对象任务I2CSPIDriver::Run()

ICM20689设备初始化时以及设置定时时间,定时轮询Run过程,并调用业务实现方法RunImpl。

I2CSPIDriver::Run
 ├──> static_cast<T *>(this)->RunImpl()
 └──> <should_exit()>
     └──> exit_and_cleanup()  //优雅退出处理

3.7 ICM20689设备实例对象任务ICM20689::RunImpl

根据ICM20689模块业务状态机变化,进行业务操作,发布gyro, accel, temperature消息

ICM20689::RunImpl
 ├──> const hrt_abstime now = hrt_absolute_time()
 └──> switch (_state) {
     ├──> <case STATE::RESET>
     │   ├──> [PWR_MGMT_1: Device Reset	]
     │   └──> ScheduleDelayed(100_ms)
     ├──> <case STATE::WAIT_FOR_RESET>
     │   ├──> <Reset OK??? (RegisterRead(Register::WHO_AM_I) == WHOAMI)  && (RegisterRead(Register::PWR_MGMT_1) == 0x40)>
     │   │   ├──> [offset registers (factory calibration) should not change during normal operation]
     │   │   ├──> [Wakeup and reset digital signal path		
     │   │   ├──> [_state = STATE::CONFIGURE  // if reset succeeded then configure
     │   │   └──> ScheduleDelayed(35_ms) // max 35 ms start-up time from sleep
     │   └──> <else Reset failed>  // RESET not complete
     │       ├──> <hrt_elapsed_time(&_reset_timestamp) > 1000_ms>  // Reset failed, retrying
     │       │   ├──> _state = STATE::RESET
     │       │   └──> ScheduleDelayed(100_ms)
     │       └──> <else>  // Reset not complete, check again in 10 ms
     │           └──> ScheduleDelayed(10_ms)
     ├──> <case STATE::CONFIGURE>
     │   ├──> <Configure()> // if configure succeeded then start reading from FIFO
     │   │   ├──> _state = STATE::FIFO_READ
     │   │   │   ├──> <DataReadyInterruptConfigure()>
     │   │   │   │   ├──> _data_ready_interrupt_enabled = true
     │   │   │   │   └──> ScheduleDelayed(100_ms)  // backup schedule as a watchdog timeout
     │   │   │   └──> <else>
     │   │   │       ├──> _data_ready_interrupt_enabled = false
     │   │   │       └──> ScheduleOnInterval(_fifo_empty_interval_us, _fifo_empty_interval_us)
     │   │   └──> FIFOReset()
     │   └──> <else > // CONFIGURE not complete
     │       ├──> <hrt_elapsed_time(&_reset_timestamp) > 1000_ms>  // Configure failed, resetting
     │       │   └──> _state = STATE::RESET
     │       ├──> <else>   // Configure failed, retrying
     │       └──> ScheduleDelayed(100_ms)
     └──> <case STATE::FIFO_READ>
         ├──> [Execption handling procedures]
         ├──> [Update temperature readings]
         └──> [Update gyro and accel]  //FIFORead function and ProcessGyro/ProcessAccel

4. 总结

具体逻辑业务后续再做深入,从模块代码角度:

  • 输入: 芯片(硬件)

  • 输出: 修改OSD显示内容

uORB::PublicationMulti<sensor_gyro_s> _sensor_pub{ORB_ID(sensor_gyro)};
uORB::PublicationMulti<sensor_gyro_fifo_s>  _sensor_fifo_pub{ORB_ID(sensor_gyro_fifo)};

uORB::PublicationMulti<sensor_accel_s> _sensor_pub{ORB_ID(sensor_accel)};
uORB::PublicationMulti<sensor_accel_fifo_s>  _sensor_fifo_pub{ORB_ID(sensor_accel_fifo)};

注1:参考class PX4Accelerometer和class PX4Gyroscope。

注2:参考ICM 20689芯片规格书: DS-000143-ICM-20689-TYP-v1.1.pdf

5. 参考资料

【1】PX4开源软件框架简明简介
【2】PX4模块设计之十一:Built-In框架
【3】PX4模块设计之十二:High Resolution Timer设计
【4】PX4模块设计之十三:WorkQueue设计
【5】PX4模块设计之十七:ModuleBase模块
【6】PX4模块设计之三十:Hysteresis类
【7】PX4 modules_main
【8】PX4模块设计之四十一:I2C/SPI Bus Instance基础知识

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

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

  • 下载并构建PX4

    根据官方的文档 xff0c PX4下载和构建的方式有两种 xff1a Linux系列的Console模式 xff08 当然也支持Windows下的MINGW32 xff09 和Windows模式 在Windows平台下 xff0c 我们习惯
  • PX4二次开发中查无资料的踩坑总结

    写在前 xff1a 2021年9月下旬开始摸索px4飞控的二次开发 xff0c 从C 43 43 零基础到第一个修改算法后的版本稳定运行 xff0c 大概用了2个月 xff0c 从12月初改用新版本px4源码到现在又过去了约1个月 xff0
  • PX4使用I2C方式添加自定义传感器(1)

    PX4使用I2C方式添加自定义传感器 xff08 1 xff09 前言 毕业设计就是要在PX4上添加一个传感器 xff08 角度传感器 xff09 xff0c 由于板子上的接口数量很少 xff0c 很是宝贵 最后只能选择通过I2C通信方式
  • PX4通过I2C方式添加自定义传感器(3)

    添加自定义传感器并实现数据的发送和订阅 1 前期准备 1 1 建立文件夹和相关文件配置 我是在src drivers distance sensor文件夹下操作的 xff0c 当然其他文件夹下都类似 首先建立了两个文件夹angle sour
  • px4: v2的主板刷写v2的固件

    v2的主板刷写v2的固件 fengxuewei 64 fengxuewei Legion Y7000 2019 PG0 src Firmware changwei rc span class token function make span
  • PX4/Pixhawk---uORB深入理解和应用

    The Instructions of uORB PX4 Pixhawk 软件体系结构 uORB 主题发布 主题订阅 1 简介 1 1 PX4 Pixhawk的软件体系结构 PX4 Pixhawk的软件体系结构主要被分为四个层次 xff0c
  • PX4位置控制offboard模式说明

    offboard模式的开发及应用 一 px4固件的模式 px4固件支持10几种飞行模式 xff0c 从代码结构上分析 xff0c 分为基本模式 自定义模式和自定义子模式 1 基本模式 基本模式又分为 xff0c 位置控制模式 自稳模式 手动
  • PX4 GAZEBO无人机添加相机并进行图像识别

    PX4 GAZEBO无人机添加摄像头并进行图像识别 在之前完成了ROS的安装和PX4的安装 xff0c 并可以通过roslaunch启动软件仿真 接下来为无人及添加相机 xff0c 并将图像用python函数读取 xff0c 用于后续操作
  • 初学PX4之环境搭建

    文章转自 xff1a http www jianshu com p 36dac548106b 前言 前段时间linux崩溃了 xff0c 桌面进去后只有背景 xff0c 折腾好久没搞定 xff0c 为了节省时间索性重装了系统 xff0c 同
  • PX4 ---- Mixer

    文章目录 Mixer 混合控制 作用输入输出装载混控文件MAVROS代码解析总结示例MAINAUX Mixer 混合控制 作用 经过位置控制和姿态控制后 xff0c 控制量通过 actuator controls发布 xff0c 其中 co
  • 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模块设计之十三:WorkQueue设计

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

    PX4模块设计之十六 xff1a Hardfault模块 1 Hardfault模块初始化2 Hardfault模块主程序3 Hardfault命令3 1 hardfault check status3 2 hardfault rearm3
  • PX4模块设计之二十六:BatteryStatus模块

    PX4模块设计之二十六 xff1a BatteryStatus模块 1 BatteryStatus模块简介2 模块入口函数2 1 主入口battery status main2 2 自定义子命令custom command 3 Batter
  • PX4模块设计之三十一:ManualControl模块

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

    PX4模块设计之三十四 xff1a ControlAllocator模块 1 ControlAllocator模块简介2 模块入口函数2 1 主入口control allocator main2 2 自定义子命令custom command
  • PX4模块设计之四十六:dataman模块

    PX4模块设计之四十六 xff1a dataman模块 1 dataman模块简介2 模块入口函数dataman main3 dataman模块重要函数3 1 start3 2 stop3 3 status3 4 task main 4 A
  • 【px4】运行mavsdk中的offboard example

    运行MAVSDK中的offboard例子时无人机不执行 想控制无人机前后左右移动 xff0c 在按照官方教程实现offboard 插件的时候 发现用action插件能正常起飞和降落 但是一旦执行到offboard的插件代码的时候就会自动降落
  • PX4飞控之自主返航(RTL)控制逻辑

    本文基于PX4飞控1 5 5版本 xff0c 分析导航模块中自护返航模式的控制逻辑和算法 自主返航模式和导航中的其他模式一样 xff0c 在Navigator main函数中一旦触发case vehicle status s NAVIGAT
  • 步骤三:PX4,Mavros的下载安装及代码测试

    1 安装Mavros sudo apt install ros melodic mavros ros melodic mavros extras 2 安装Mavros相关的 geographiclib dataset 此处已经加了ghpro

随机推荐