一、前言

最近项目使用到 CPU2 与 CPU0 之间的通信, 使用定时器传递消息到 CPU0 后, CPU0 需要将消息分发到不同的应用程序里面. PX4 里面使用的是 uORB 多线程/进程通信机制.

uORB 相关介绍参考: 官方 uORB 介绍 以及 无人机中级篇:第三讲:uORB原理与使用, 下文中的代码细节也不做过多解释。

目前使用的是 Firmware 的 1.82 版本 . 下文使用到的文件夹地址如下:

  • uORB 库文件位于 Firmware/src/modules/uORB.

  • configs 文件位于 Firmware/cmake/configs

  • drivers 文件位于 Firmware/src/drivers

  • msg 文件位于 Firmware/msg

二、Coding

主要的步骤为:

  1. 新建 msg
  2. 新建 publish 和 subscriber
  3. 将publish 和 subscriber 添加到 configs 目录下对应的板子里面去
  4. 编译上传。

2.1 新建 msg

在 msg 目录下面新建一个 cpu2.msg, 并将 cpu2 添加到 msg/CMakeLists.txt 文件中

cpu2 简单定义一个变量: length

uint32 length  

2.2 新建 publish 和 subscriber

在 drivers 目录下面新建 uorb_publish 目录 以及 uorb_subscriber 目录, 并新建对应的文件, 结构如下

├── uorb_publish
│ ├── CMakeLists.txt
│ └── uorb_publish.cpp
├── uorb_subscriber
│ ├── CMakeLists.txt
│ └── uorb_subscriber.cpp

uorb_publish/CMakeLists.txt

px4_add_module(
MODULE drivers__uorb_publish
MAIN uorb_publish
STACK_MAIN 1200
COMPILE_FLAGS
SRCS
uorb_publish.cpp
DEPENDS
)

uorb_publish/uorb_publish.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include <px4_log.h>
#include <uORB/uORB.h>
#include <uORB/topics/cpu2.h> #include <px4_workqueue.h> extern "C" __EXPORT int uorb_publish_main(int argc, char *argv[]); static orb_advert_t cpu2_topic; static uint8_t cnt = 0; static struct work_s work; static struct cpu2_s att; static void cycle_trampoline(void *arg)
{
PX4_INFO("publish \n"); if (cpu2_topic == NULL)
{
cpu2_topic = orb_advertise(ORB_ID(cpu2), &att); } att.length = cnt;
cnt++; if (cnt == 255) {
cnt = 0;
} orb_publish(ORB_ID(cpu2), cpu2_topic, &att); (void)work_queue(HPWORK, &work, (worker_t)&cycle_trampoline, nullptr, USEC2TICK(1000 * 1000)); } int uorb_publish_main(int argc, char *argv[])
{
PX4_INFO(" uorb_publish \n"); work = {}; cpu2_topic = NULL; memset(&att, 0 , sizeof(att)); (void)work_queue(HPWORK, &work, (worker_t)&cycle_trampoline, nullptr, 0); return 0;
}

uorb_subscriber/CMakeLists.txt

px4_add_module(
MODULE drivers__uorb_subscriber
MAIN uorb_subscriber
STACK_MAIN 1200
COMPILE_FLAGS
SRCS
uorb_subscriber.cpp
DEPENDS
)

uorb_subscriber/uorb_subscriber.cpp

#include <poll.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <px4_log.h> #include <uORB/topics/cpu2.h> #include <uORB/uORB.h>
#include <px4_workqueue.h>
#include <drivers/device/device.h> extern "C" __EXPORT int uorb_subscriber_main(int argc, char *argv[]); static struct work_s work; static int cpu2_fd = 0; static struct cpu2_s att; static void cycle_trampoline(void *arg)
{
// PX4_INFO("subscriber \n");
if (cpu2_fd == 0)
{
cpu2_fd = orb_subscribe(ORB_ID(cpu2));
} bool updated = false; updated = false; if (orb_check(cpu2_fd, &updated) != PX4_OK)
{
return;
} if (updated)
{
orb_copy(ORB_ID(cpu2), cpu2_fd, &att); PX4_INFO("%d \n", att.length);
} work_queue(HPWORK,
&work,
(worker_t)&cycle_trampoline,
nullptr,
USEC2TICK(1000 * 1000));
} int uorb_subscriber_main(int argc, char *argv[])
{ work = {};
cpu2_fd = 0;
memset(&att, 0 , sizeof(att)); PX4_INFO("uorb_subscriber "); (void)work_queue(HPWORK, &work, (worker_t)&cycle_trampoline, nullptr, 0); return 0;
}

2.3 将publish 和 subscriber 添加到 configs 目录下对应的板子里面去 以及 编译运行

三、运行结果以及常见问题

  1. 编译烧录到板子后,在 nsh 键入 ? , 会显示如下

        nsh> ?
    help usage: help [-v] [<cmd>] [ dirname false mkfatfs pwd true
    ? date free mkfifo rm uname
    basename dd help mkrd rmdir umount
    break df hexdump mh set unset
    cat echo kill mount sh usleep
    cd printf ls mv sleep xd
    cp exec mb mw test
    cmp exit mkdir ps time Builtin Apps: ...
    uorb
    uorb_publish
    uorb_subscriber
    ...
    nsh>

    如果未出现 uorb_publishuorb_subscriber, 原因在于 未将publish 和 subscriber 添加到 configs 目录下对应的板子里面去;

  2. 先启动 uorb_subscriber , 再启动 uorb_publish


    nsh> uorb_subscriber
    INFO [uorb_subscriber] uorb_subscriber
    nsh> uorb_publish
    INFO [uorb_publish] uorb_publish INFO [uorb_publish] publish nsh> INFO [uorb_subscriber] 0 INFO [uorb_publish] publish INFO [uorb_subscriber] 1 INFO [uorb_publish] publish INFO [uorb_subscriber] 2 INFO [uorb_publish] publish INFO [uorb_subscriber] 3 INFO [uorb_publish] publish INFO [uorb_subscriber] 4 INFO [uorb_publish] publish INFO [uorb_subscriber] 5 INFO [uorb_publish] publish INFO [uorb_subscriber] 6 INFO [uorb_publish] publish
    .....

PX4学习之-uORB简单体验的更多相关文章

  1. PX4学习之-uORB msg 自动生成模板解读

    最后更新日期 2019-06-22 一.前言 在 PX4学习之-uORB简单体验 中指出, 使用 uORB 进行通信的第一步是新建 msg.在实际编译过程中,新建的 msg 会转换成对应的 .h..c ...

  2. Linux入门学习教程:虚拟机体验之KVM篇

    本文中可以学习到的命令: 1. aptitude 是apt-get 不会产生垃圾的版本 2.       dpkg -L virtualbox 显示属于该包的文件 lsmod | grep kvmfi ...

  3. 第三次随笔--安装虚拟机及学习linux系统初体验

    第三次随笔--安装虚拟机及学习linux系统初体验 ·学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 首先按照老师的提示步骤进行VirtualBox虚拟 ...

  4. 【Cardboard】 体验 - Google Cardboard DIY及完成后简单体验

    体验 - Google Cardboard DIY及完成后简单体验 今年的Google I/O最让我感兴趣的除了Material Design以外就是这个Google Cardboard了.据说是Go ...

  5. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  6. Hibernate二次学习一----------Hibernate简单搭建

    因为博客园自带的markdown不太好用,因此所有markdown笔记都使用cmd_markdown发布 Hibernate二次学习一----------Hibernate简单搭建: https:// ...

  7. JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  8. oracle学习 第一章 简单的查询语句 ——03

    1.1最简单的查询语句 例 1-1 SQL> select * from emp; 例 1-1 结果 这里的 * 号表示全部的列.它与在select 之后列出全部的列名是一样的.查询语句以分号( ...

  9. Spark学习笔记0——简单了解和技术架构

    目录 Spark学习笔记0--简单了解和技术架构 什么是Spark 技术架构和软件栈 Spark Core Spark SQL Spark Streaming MLlib GraphX 集群管理器 受 ...

随机推荐

  1. js 如何生成一个不重复的ID的函数

    在MongoDB中的ObjectID,可以理解为是一个不会重复的ID,这里有个链接http://www.jb51.net/article/101164.htm感兴趣可以去研究一下. 我今天要做的就是做 ...

  2. case when then else 详解

    原文发布时间为:2008-10-15 -- 来源于本人的百度文章 [由搬家工具导入] sql语句判断方法之一 Case具有两种格式。简单Case函数和Case搜索函数。 --简单Case函数 CASE ...

  3. 一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子

    一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子 最近,由于云计算的发展,数据库技术也从结构式数据库发展到NoSQL数据库,存储模式从结构化的关系存储到现在如火如荼的key/val ...

  4. 《手把手教你学C语言》学习笔记(8)--- 运算符和表达式

    C语言编程的核心是指针和库,而库的核心就是函数,函数的基本组成部分就是语句. C语言合法表达式加上分号(语句结束符)构成C函数的基本部分语句.如果只有分号没有表达式就构成空语句,空语句常常用来形成占位 ...

  5. 用python获取服务器硬件信息[转]

    #!/usr/bin/env python # -*- coding: utf-8 -*- import rlcompleter, readline readline.parse_and_bind(' ...

  6. 吉首大学 问题 L: 小李子的老年生活

    时间限制: 1 Sec  内存限制: 128 MB提交: 719  解决: 27 题目描述 小李子有n-1个朋友,分别编号为1..n-1,小李子的编号是n ,小李子的表面朋友的编号会与小李子编号互质 ...

  7. python接口自动化(四十)- logger 日志 - 下(超详解)

    简介 按照上一篇的计划,这一篇给小伙伴们讲解一下:(1)多模块使用logging,(2)通过文件配置logging模块,(3)自己封装一个日志(logging)类.可能有的小伙伴在这里会有个疑问一个l ...

  8. C++面向对象程序设计_Part1

    目录 C++历史 C++的组成 C++ 与 C 的数据和函数区别 基于对象与面向对象的区别 C++类的两个经典分类 头文件防卫式声明 头文件的布局 类的声明 类模板简介 内联(inline)函数 访问 ...

  9. POJ 3264 Balanced Lineup RMQ ST算法

    题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...

  10. UICollectionView专题

    什么是UICollectionView UICollectionView是一种新的数据展示方式,简单来说可以把他理解成多列的UITableView(请一定注意这是UICollectionView的最最 ...