第二章 第二节 px4的uORB工作原理分析 闫刚


px4中的uorb是px4非常核心的数据通信机制,所有线程的通信都是靠uorb完成,用过的人可能,仅仅知道在想要获取orb数据的时候,先进行订阅,在发送orb消息之前,先公告主题,uorb是如何工作的?可能少于人知道。直接上代码!!

  • 使用方法

1.发送orb消息: 【orb_advertise订阅】 【orb_publisb发布】


2. 获取orb消息 【orb_subscribe订阅】 【orb_check检测】【orb_copy提取】

  •   单元测试代码

  1. 代码架构

  • 2. 编译代码调试代码

我们把这个文件放到nuttx_px4fmu-v2_default.cmake中,px4默认的已经把uorb_tests的单元测试已经放到nuttx_px4fmu-v2_default.cmake中,已经构建完成, 这个就是uorb_test就是px4自己写的uorb单元测试代码,px4的各个模块的代码都会有自己单元测试代码,这个是非常好的让我们理解模块设计者的思想。 下面我们编译下载,px4工程,同时进入nsh控制台输入uorb_tests可以看到下面的输出信息。


3. 查看设备树

我们会发现设备树下出现了很多的orb消息的节点,节点是如何生成的???


4.  分析代码,找到线程入口函数uorb_tests_main, 进入t.test()方法



  •  代码分析

追踪orb公告和订阅的函数,我们可以发现这个,他们最终都调用了node_open的函数,区别在公告的时候传递参数

advertiser 是true, 在订阅的时候advertiser是flase,

函数

当我们知道最核心的代码是node_open的时候,我们查看node_open的实现方法

int uORB::Manager::node_open
(
	Flavor f,
	const struct orb_metadata *meta,
	const void *data,
	bool advertiser,
	int *instance,
	int priority
)
{
	char path[orb_maxpath];
	int fd = -1, ret;

	/*
	 * If meta is null, the object was not defined, i.e. it is not
	 * known to the system.  We can't advertise/subscribe such a thing.
	 */
	if (nullptr == meta) {
		errno = ENOENT;
		return ERROR;
	}

	/*
	 * Advertiser must publish an initial value.
	 */
	if (advertiser && (data == nullptr)) {
		errno = EINVAL;
		return ERROR;
	}

	/* if we have an instance and are an advertiser, we will generate a new node and set the instance,
	 * so we do not need to open here */
	if (!instance || !advertiser) {
		/*
		 * Generate the path to the node and try to open it.
		 */
		ret = uORB::Utils::node_mkpath(path, f, meta, instance);

		if (ret != OK) {
			errno = -ret;
			return ERROR;
		}

		/* open the path as either the advertiser or the subscriber */
		fd = px4_open(path, advertiser ? PX4_F_WRONLY : PX4_F_RDONLY);

	} else {
		*instance = 0;
	}

	/* we may need to advertise the node... */
	

这个代码也很长,我们分析这个代码

1. 首先在公告的时候,会创建路径

ret = uORB::Utils::node_mkpath(path, f, meta, instance);

2. 打开这个路径,作为文件句柄

fd = px4_open(path, advertiser ? PX4_F_WRONLY : PX4_F_RDONLY);

注意:从"advertiser ?PX4_F_WRONLY : PX4_F_RDONLY"这里我们orb最重要的思想是,订阅仅仅是读,发布仅仅是写。

3. 可能很多人都知道,orb的主题的订阅和公告是分开,也就是说没有线程公告主题,订阅也会成功,这是如何实现?

if (fd < 0) {

		/* try to create the node */
		ret = node_advertise(meta, instance, priority);
从这里就可以看出,订阅的时候,打开路径失败,就是公告主题,也就是这个原因,让orb不会限制线程的启动顺序导致orb订阅失败.



猜你喜欢

转载自blog.csdn.net/yangang185/article/details/80235981