PX4模块设计之四十四: bmp280模块

int bmp280_main(int argc, char *argv[]);

1. bmp280模块简介

bmp280 <command> [arguments...]
 Commands:
   start
     [-I]        Internal I2C bus(es)
     [-X]        External I2C bus(es)
     [-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)
     [-a <val>]  I2C address
                 default: 118
     [-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)

   stop

   status        print status info

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

class BMP280 : public I2CSPIDriver<BMP280>
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 *>


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

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

2. 模块入口函数

2.1 主入口bmp280_main

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

bmp280_main
 ├──> using ThisDriver = BMP280;
 ├──> BusCLIArguments cli{true, true};
 ├──> <CONFIG_I2C>
 │   ├──> cli.i2c_address = 0x76;
 │   └──> cli.default_i2c_frequency = 100 * 1000;
 ├──> <CONFIG_SPI>
 │   └──> cli.default_spi_frequency = 10 * 1000 * 1000;
 ├──> const char *verb = cli.parseDefaultArguments(argc, argv)
 ├──> <!verb>
 │   ├──> ThisDriver::print_usage()
 │   └──> return -1
 ├──> BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_BMP280)
 ├──> <!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重载实现。

BMP280::print_usage

void
BMP280::print_usage()
{
	PRINT_MODULE_USAGE_NAME("bmp280", "driver");
	PRINT_MODULE_USAGE_SUBCATEGORY("baro");
	PRINT_MODULE_USAGE_COMMAND("start");
#if defined(CONFIG_I2C)
	PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, true);
	PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x76);
#else
	PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true);
#endif
	PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
}

3. bmp280模块重要函数

3.1 模块启动ThisDriver::module_start

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

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

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

3.2 模块停止ThisDriver::module_stop

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

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

3.3 模块状态ThisDriver::module_status

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

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

3.4 设备实例对象初始化BMP280::instantiate

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

BMP280::instantiate
 ├──> bmp280::IBMP280 *interface = nullptr;
 ├──> <CONFIG_I2C><config.bus_type == BOARD_I2C_BUS>
 │   └──> interface = bmp280_i2c_interface(config.bus, config.i2c_address, config.bus_frequency);
 ├──> <CONFIG_SPI><config.bus_type == BOARD_SPI_BUS>
 │   └──> interface = bmp280_spi_interface(config.bus, config.spi_devid, config.bus_frequency, config.spi_mode);
 ├──> <interface == nullptr>
 │   ├──> PX4_ERR("failed creating interface for bus %i", config.bus);
 │   └──> return nullptr;
 ├──> <interface->init() != OK>  // I2C/SPI总线初始化
 │   ├──> delete interface;
 │   ├──> PX4_DEBUG("no device on bus %i", config.bus);
 │   └──> return nullptr;
 ├──> BMP280 *dev = new BMP280(config, interface);   // 新建一个BMP280设备对象实例
 ├──> <dev == nullptr>
 │   ├──> delete interface;
 │   └──> return nullptr;
 ├──> <OK != dev->init()>   // BMP280设备对象实例初始化
 │   ├──> delete dev;
 │   └──> return nullptr;
 └──> return dev;

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

BMP280设备实例对象初始化

BMP280::init
 ├──> [reset sensor]
 ├──> [check id]
 ├──> [set config, recommended settings]
 ├──> [get calibration and pre process them]
 ├──> Start()   // 重置模块状态机,然后触发ScheduleNow
 └──> return OK

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

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

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

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

根据BMP280模块业务状态机变化,进行业务操作,发布sensor_baro消息。

BMP280::RunImpl
 ├──> <_collect_phase>
 │   └──> collect();  // 获取测试数据,并发布sensor_baro消息
 ├──> <else>
 │   └──> measure();  // 触发一次测试
 └──> ScheduleDelayed(_measure_interval);

4. 总结

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

  • 输入: 芯片(硬件:bmp280)

  • 输出: sensor_baro消息

uORB::PublicationMulti<sensor_baro_s> _sensor_baro_pub{ORB_ID(sensor_baro)};

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基础知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值