apps/system/uorb: c interfaces.
refer to: https://docs.px4.io/v1.12/en/middleware/uorb.html - orb_open: do real work for advertise() and subscribe(), if thre is no user, register topic first, then save meta in driver; only first user can successfully set buffer number. - orb_exists: check topic state, if topic only has subscribers, return "not exists". Signed-off-by: jihandong <jihandong@xiaomi.com>
This commit is contained in:
parent
beb9188cee
commit
3528b5515f
41
system/uorb/Kconfig
Normal file
41
system/uorb/Kconfig
Normal file
@ -0,0 +1,41 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
menuconfig UORB
|
||||
tristate "uorb(micro object request broker)"
|
||||
depends on SENSORS && USENSOR
|
||||
default n
|
||||
|
||||
if UORB
|
||||
|
||||
config DEBUG_UORB
|
||||
bool "uorb debug output"
|
||||
default n
|
||||
|
||||
if DEBUG_UORB
|
||||
|
||||
config UORB_ALERT
|
||||
bool "uorb panic output"
|
||||
default n
|
||||
depends on DEBUG_ALERT
|
||||
|
||||
config UORB_ERROR
|
||||
bool "uorb error output"
|
||||
default n
|
||||
depends on DEBUG_ERROR
|
||||
|
||||
config UORB_WARN
|
||||
bool "uorb warn output"
|
||||
default n
|
||||
depends on DEBUG_WARN
|
||||
|
||||
config UORB_INFO
|
||||
bool "uorb info output"
|
||||
default n
|
||||
depends on DEBUG_INFO
|
||||
|
||||
endif # DEBUG_UORB
|
||||
|
||||
endif # UORB
|
25
system/uorb/Make.defs
Normal file
25
system/uorb/Make.defs
Normal file
@ -0,0 +1,25 @@
|
||||
############################################################################
|
||||
# apps/system/uorb/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifneq ($(CONFIG_UORB),)
|
||||
CONFIGURED_APPS += $(APPDIR)/system/uorb
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \
|
||||
$(APPDIR)/system/uorb/}
|
||||
endif
|
25
system/uorb/Makefile
Normal file
25
system/uorb/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
############################################################################
|
||||
# apps/system/uorb/uORB/Makefile
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
CSRCS += uORB/uORB.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
314
system/uorb/uORB/uORB.c
Normal file
314
system/uorb/uORB/uORB.c
Normal file
@ -0,0 +1,314 @@
|
||||
/****************************************************************************
|
||||
* apps/system/uorb/uORB/uORB.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <uORB/uORB.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_open
|
||||
*
|
||||
* Description:
|
||||
* Open device node as advertiser / subscriber, regist node and save meta
|
||||
* in driver for first user, set buffer number for advertisers.
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta The uORB metadata (usually from the ORB_ID() macro)
|
||||
* advertiser Whether advertiser or subscriber.
|
||||
* instance Instance number to open.
|
||||
* queue_size Maximum number of buffered elements.
|
||||
*
|
||||
* Returned Value:
|
||||
* fd on success, otherwise returns negative value and set errno.
|
||||
****************************************************************************/
|
||||
|
||||
static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
|
||||
int instance, unsigned int queue_size)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
bool first_open = false;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
snprintf(path, PATH_MAX, ORB_SENSOR_PATH"%s%d", meta->o_name, instance);
|
||||
|
||||
/* Check existance before open */
|
||||
|
||||
ret = access(path, F_OK);
|
||||
if (ret < 0)
|
||||
{
|
||||
struct sensor_reginfo_s reginfo;
|
||||
|
||||
reginfo.path = path;
|
||||
reginfo.esize = meta->o_size;
|
||||
reginfo.nbuffer = queue_size;
|
||||
|
||||
fd = open(ORB_USENSOR_PATH, O_WRONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Register new device node */
|
||||
|
||||
ret = ioctl(fd, SNIOC_REGISTER, (unsigned long)(uintptr_t)®info);
|
||||
close(fd);
|
||||
if (ret < 0 && ret != -EEXIST)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
first_open = true;
|
||||
}
|
||||
|
||||
fd = open(path, O_CLOEXEC | (advertiser ? O_WRONLY : O_RDONLY));
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (first_open)
|
||||
{
|
||||
ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
|
||||
}
|
||||
|
||||
/* Only first advertiser can successfully set buffer number */
|
||||
|
||||
if (queue_size)
|
||||
{
|
||||
ioctl(fd, SNIOC_SET_BUFFER_NUMBER, (unsigned long)queue_size);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data, FAR int *instance,
|
||||
unsigned int queue_size)
|
||||
{
|
||||
int inst;
|
||||
int fd;
|
||||
|
||||
/* Open the node as an advertiser */
|
||||
|
||||
inst = instance ? *instance : orb_group_count(meta);
|
||||
|
||||
fd = orb_open(meta, true, inst, queue_size);
|
||||
if (fd < 0)
|
||||
{
|
||||
uorberr("%s advertise failed (%i)", meta->o_name, fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The advertiser may perform an initial publish to initialise the object */
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = orb_publish_multi(fd, data, meta->o_size);
|
||||
if (ret != meta->o_size)
|
||||
{
|
||||
uorberr("%s publish %d, expect %d",
|
||||
meta->o_name, ret, meta->o_size);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int orb_unadvertise(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
ssize_t orb_publish_multi(int fd, const void *data, size_t len)
|
||||
{
|
||||
return write(fd, data, len);
|
||||
}
|
||||
|
||||
int orb_subscribe_multi(FAR const struct orb_metadata *meta,
|
||||
unsigned instance)
|
||||
{
|
||||
return orb_open(meta, false, instance, 0);
|
||||
}
|
||||
|
||||
int orb_unsubscribe(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len)
|
||||
{
|
||||
return read(fd, buffer, len);
|
||||
}
|
||||
|
||||
int orb_get_state(int fd, FAR struct orb_state *state)
|
||||
{
|
||||
struct sensor_state_s tmp;
|
||||
int ret;
|
||||
|
||||
if (!state)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, SNIOC_GET_STATE, (unsigned long)(uintptr_t)&tmp);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
state->max_frequency = tmp.min_interval ?
|
||||
1000000 / tmp.min_interval : 0;
|
||||
state->min_batch_interval = tmp.min_latency;
|
||||
state->queue_size = tmp.nbuffer;
|
||||
state->enable = tmp.nsubscribers > 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int orb_check(int fd, FAR bool *updated)
|
||||
{
|
||||
struct pollfd fds[1];
|
||||
int ret;
|
||||
|
||||
fds[0].fd = fd;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
ret = poll(fds, 1, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*updated = (fds[0].revents & POLLIN) > 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int orb_ioctl(int handle, int cmd, unsigned long arg)
|
||||
{
|
||||
return ioctl(handle, cmd, arg);
|
||||
}
|
||||
|
||||
int orb_set_interval(int fd, unsigned interval)
|
||||
{
|
||||
return ioctl(fd, SNIOC_SET_INTERVAL, (unsigned long)interval);
|
||||
}
|
||||
|
||||
int orb_get_interval(int fd, FAR unsigned *interval)
|
||||
{
|
||||
struct sensor_state_s tmp;
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, SNIOC_GET_STATE, (unsigned long)(uintptr_t)&tmp);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*interval = tmp.min_interval;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int orb_set_batch_interval(int fd, unsigned batch_interval)
|
||||
{
|
||||
return ioctl(fd, SNIOC_BATCH, (unsigned long)batch_interval);
|
||||
}
|
||||
|
||||
int orb_get_batch_interval(int fd, FAR unsigned *batch_interval)
|
||||
{
|
||||
struct sensor_state_s tmp;
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, SNIOC_GET_STATE, (unsigned long)(uintptr_t)&tmp);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*batch_interval = tmp.min_latency;
|
||||
return ret;
|
||||
}
|
||||
|
||||
orb_abstime orb_absolute_time(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
return 1000000ull * ts.tv_sec + ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
int orb_exists(FAR const struct orb_metadata *meta, int instance)
|
||||
{
|
||||
struct sensor_state_s state;
|
||||
char path[PATH_MAX];
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
snprintf(path, PATH_MAX, ORB_SENSOR_PATH"%s%d", meta->o_name, instance);
|
||||
fd = open(path, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, SNIOC_GET_STATE, (unsigned long)(uintptr_t)&state);
|
||||
close(fd);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return state.nadvertisers > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int orb_group_count(FAR const struct orb_metadata *meta)
|
||||
{
|
||||
unsigned instance = 0;
|
||||
|
||||
while (orb_exists(meta, instance) == 0)
|
||||
{
|
||||
++instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
645
system/uorb/uORB/uORB.h
Normal file
645
system/uorb/uORB/uORB.h
Normal file
@ -0,0 +1,645 @@
|
||||
/****************************************************************************
|
||||
* apps/system/uorb/uORB/uORB.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APP_SYSTEM_UORB_UORB_UORB_H
|
||||
#define __APP_SYSTEM_UORB_UORB_UORB_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/sensors/ioctl.h>
|
||||
#include <nuttx/sensors/sensor.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <debug.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <syslog.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct orb_metadata;
|
||||
typedef void (*orb_print_message)(FAR const struct orb_metadata *meta,
|
||||
FAR const void *buffer);
|
||||
|
||||
struct orb_metadata
|
||||
{
|
||||
FAR const char *o_name; /* Unique object name */
|
||||
uint16_t o_size; /* Object size */
|
||||
#ifdef CONFIG_DEBUG_UORB
|
||||
orb_print_message o_cb; /* Function pointer of output topic message */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef FAR const struct orb_metadata *orb_id_t;
|
||||
|
||||
struct orb_state
|
||||
{
|
||||
uint32_t max_frequency; /* Object maximum frequency, Hz */
|
||||
uint32_t min_batch_interval; /* Object minimum batch interval, us */
|
||||
uint32_t queue_size; /* The maximum number of buffered elements,
|
||||
* if 1, no queuing is is used
|
||||
*/
|
||||
bool enable; /* Indicates whether the current node is
|
||||
* subscribed or activated
|
||||
*/
|
||||
};
|
||||
|
||||
struct orb_object
|
||||
{
|
||||
orb_id_t meta; /* The metadata of topic object */
|
||||
int instance; /* The instance of topic object */
|
||||
};
|
||||
|
||||
typedef uint64_t orb_abstime;
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ORB_SENSOR_PATH "/dev/sensor/"
|
||||
#define ORB_USENSOR_PATH "/dev/usensor"
|
||||
|
||||
#ifdef CONFIG_UORB_ALERT
|
||||
# define uorbpanic(fmt, ...) _alert(fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
# define uorbpanic _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_UORB_ERROR
|
||||
# define uorberr(fmt, ...) _err(fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
# define uorberr _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_UORB_WARN
|
||||
# define uorbwarn(fmt, ...) _warn(fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
# define uorbwarn _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_UORB_INFO
|
||||
# define uorbinfo(fmt, ...) _info(fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
# define uorbinfo _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_UORB
|
||||
# define uorbdebug(fmt, ...) syslog(LOG_INFO, fmt "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
# define uorbdebug _none
|
||||
#endif
|
||||
|
||||
#define uorbinfo_raw(fmt, ...) syslog(LOG_INFO, fmt "\n", ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Generates a pointer to the uORB metadata structure for
|
||||
* a given topic.
|
||||
*
|
||||
* The topic must have been declared previously in scope
|
||||
* with ORB_DECLARE().
|
||||
*
|
||||
* @param name The name of the topic.
|
||||
*/
|
||||
#define ORB_ID(name) &g_orb_##name
|
||||
|
||||
/**
|
||||
* Declare the uORB metadata for a topic (used by code generators).
|
||||
*
|
||||
* @param name The name of the topic.
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
# define ORB_DECLARE(name) extern "C" const struct orb_metadata g_orb_##name
|
||||
#else
|
||||
# define ORB_DECLARE(name) extern const struct orb_metadata g_orb_##name
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Define (instantiate) the uORB metadata for a topic.
|
||||
*
|
||||
* The uORB metadata is used to help ensure that updates and
|
||||
* copies are accessing the right data.
|
||||
*
|
||||
* Note that there must be no more than one instance of this macro
|
||||
* for each topic.
|
||||
*
|
||||
* @param name The name of the topic.
|
||||
* @param struct The structure the topic provides.
|
||||
* @param cb The function pointer of output topic message.
|
||||
*/
|
||||
#ifdef CONFIG_DEBUG_UORB
|
||||
#define ORB_DEFINE(name, structure, cb) \
|
||||
const struct orb_metadata g_orb_##name = \
|
||||
{ \
|
||||
#name, \
|
||||
sizeof(structure), \
|
||||
cb, \
|
||||
};
|
||||
#else
|
||||
#define ORB_DEFINE(name, structure, cb) \
|
||||
const struct orb_metadata g_orb_##name = \
|
||||
{ \
|
||||
#name, \
|
||||
sizeof(structure), \
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_advertise_multi_queue
|
||||
*
|
||||
* Description:
|
||||
* This performs the initial advertisement of a topic; it creates the topic
|
||||
* node in /dev/sensor and publishes the initial data.
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta The uORB metadata (usually from the ORB_ID() macro)
|
||||
* data A pointer to the initial data to be published.
|
||||
* instance Pointer to an integer which yield the instance ID,
|
||||
* (has default 0 if pointer is NULL).
|
||||
* queue_size Maximum number of buffered elements.
|
||||
*
|
||||
* Returned Value:
|
||||
* -1 on error, otherwise returns an file descriptor
|
||||
* that can be used to publish to the topic.
|
||||
* If the topic in question is not known (due to an
|
||||
* ORB_DEFINE with no corresponding ORB_DECLARE)
|
||||
* this function will return -1 and set errno to ENOENT.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data,
|
||||
FAR int *instance,
|
||||
unsigned int queue_size);
|
||||
|
||||
static inline int orb_advertise(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data)
|
||||
{
|
||||
return orb_advertise_multi_queue(meta, data, NULL, 1);
|
||||
}
|
||||
|
||||
static inline int orb_advertise_queue(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data,
|
||||
unsigned int queue_size)
|
||||
{
|
||||
return orb_advertise_multi_queue(meta, data, NULL, queue_size);
|
||||
}
|
||||
|
||||
static inline int orb_advertise_multi(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data,
|
||||
FAR int *instance)
|
||||
{
|
||||
return orb_advertise_multi_queue(meta, data, instance, 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_unadvertise
|
||||
*
|
||||
* Description:
|
||||
* Unadvertise a topic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned by orb_advertise or orb_advertise_multi.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_unadvertise(int handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_publish_multi
|
||||
*
|
||||
* Description:
|
||||
* Publish the specified length of new data to a topic.
|
||||
*
|
||||
* The data is published to the topic and any waiting subscribers will be
|
||||
* notified. Subscribers that are not waiting can check the topic for
|
||||
* updates using orb_check.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle returned from orb_advertise.
|
||||
* data A pointer to the data to be published.
|
||||
* len The length of the data to be published.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t orb_publish_multi(int handle, FAR const void *data, size_t len);
|
||||
|
||||
static inline int orb_publish(FAR const struct orb_metadata *meta,
|
||||
int handle, FAR const void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = orb_publish_multi(handle, data, meta->o_size);
|
||||
return ret == meta->o_size ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
|
||||
FAR int *handle, FAR const void *data,
|
||||
FAR int *instance)
|
||||
{
|
||||
if (handle && *handle)
|
||||
{
|
||||
return orb_publish(meta, *handle, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = orb_advertise_multi(meta, data, instance);
|
||||
if (tmp < 0)
|
||||
{
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (handle)
|
||||
{
|
||||
*handle = tmp;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return orb_unadvertise(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_subscribe_multi
|
||||
*
|
||||
* Description:
|
||||
* Subscribe to a topic.
|
||||
*
|
||||
* The data is published to the topic and any waiting subscribers will be
|
||||
* notified. Subscribers that are not waiting can check the topic for
|
||||
* updates using orb_check.
|
||||
*
|
||||
* If there were any publications of the topic prior to the subscription,
|
||||
* an orb_check right after orb_subscribe_multi will return true.
|
||||
*
|
||||
* Subscription will succeed even if the topic has not been advertised;
|
||||
* in this case, the topic will have a timestamp of zero, it will never
|
||||
* signal a poll() event, checking will always return false and it cannot
|
||||
* be copied, until the topic is subsequently advertised.
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta The uORB metadata (usually from the ORB_ID() macro)
|
||||
* instance The instance of the topic. Instance 0 matches the topic of
|
||||
* the orb_subscribe() call.
|
||||
*
|
||||
* Returned Value:
|
||||
* -1 on error, otherwise returns a handle
|
||||
* that can be used to read and update the topic.
|
||||
* If the topic in question is not known (due to an
|
||||
* ORB_DEFINE_OPTIONAL with no corresponding ORB_DECLARE)
|
||||
* this function will return -1 and set errno to ENOENT.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_subscribe_multi(FAR const struct orb_metadata *meta,
|
||||
unsigned instance);
|
||||
|
||||
static inline int orb_subscribe(FAR const struct orb_metadata *meta)
|
||||
{
|
||||
return orb_subscribe_multi(meta, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_unsubscribe
|
||||
*
|
||||
* Description:
|
||||
* Unsubscribe from a topic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_unsubscribe(int handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_copy_multi
|
||||
*
|
||||
* Description:
|
||||
* Fetch the specified length of data from a topic.
|
||||
*
|
||||
* This is the only operation that will reset the internal marker that
|
||||
* indicates that a topic has been updated for a subscriber. Once poll
|
||||
* or check return indicating that an updaet is available, this call
|
||||
* must be used to update the subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* buffer Pointer to the buffer receiving the data, or NULL if the
|
||||
* caller wants to clear the updated flag without.
|
||||
* len The length to the buffer receiving the data.
|
||||
*
|
||||
* Returned Value:
|
||||
* The positive non-zero number of bytes read on success.
|
||||
* 0 on if an end-of-file condition,
|
||||
* -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t orb_copy_multi(int handle, FAR void *buffer, size_t len);
|
||||
|
||||
static inline int orb_copy(FAR const struct orb_metadata *meta,
|
||||
int handle, FAR void *buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = orb_copy_multi(handle, buffer, meta->o_size);
|
||||
return ret == meta->o_size ? 0 : -1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_get_state
|
||||
*
|
||||
* Description:
|
||||
* Get some state about all subscriber of topic.
|
||||
*
|
||||
* This state contains the maximum frequency and minimum batch interval
|
||||
* in all subscriber, and it also contanis enable to indicate whether
|
||||
* the current node is subscribed or activated.
|
||||
*
|
||||
* If no one subscribes this topic, the state is set:
|
||||
* max_frequency to 0. min_batch_interval to 0, enable to false.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle returned from orb_advertise / orb_subscribe.
|
||||
* state Pointer to an state of struct orb_state type. This is an
|
||||
* output parameter and will be set to the current state of topic.
|
||||
*
|
||||
* Returned Value:
|
||||
* -1 on error.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_get_state(int handle, FAR struct orb_state *state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_check
|
||||
*
|
||||
* Description:
|
||||
* Check whether a topic has been published to since the last orb_copy.
|
||||
*
|
||||
* This check can be used to determine whether to copy the topic when
|
||||
* not using poll(), or to avoid the overhead of calling poll() when the
|
||||
* topic is likely to have updated.
|
||||
*
|
||||
* Updates are tracked on a per-handle basis; this call will continue to
|
||||
* return true until orb_copy is called using the same handle.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* update Set to true if the topic has been updated since the
|
||||
* last time it was copied using this handle.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if the check was successful,
|
||||
* -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_check(int handle, FAR bool *updated);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Ioctl control for the subscriber, the same as ioctl().
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_advertise / orb_subscribe.
|
||||
* cmd Ioctl command.
|
||||
* arg Ioctl argument.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_ioctl(int handle, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_set_batch_interval
|
||||
*
|
||||
* Description:
|
||||
* The batch interval set through api is just the value user wants,
|
||||
* and the final value depends on the hardware FIFO capability.
|
||||
* This API will send POLLPRI event to notify publisher and
|
||||
* publisher determine the final batch interval.
|
||||
*
|
||||
* This API is only for topics with hardware fifo, such as sensor with
|
||||
* hardware fifo, otherwise it's meaningless.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* batch_interval An batch interval in us.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_set_batch_interval(int handle, unsigned batch_interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_get_batch_interval
|
||||
*
|
||||
* Description:
|
||||
* Get the batch interval in batch mode.
|
||||
*
|
||||
* This API is only for topics with hardware fifo, such as sensor with
|
||||
* hardware fifo, otherwise it's meaningless.
|
||||
*
|
||||
* @see orb_set_batch_interval()
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* batch_interval The returned batch interval in us.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_get_batch_interval(int handle, FAR unsigned *batch_interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
*
|
||||
* Description:
|
||||
* Set the minimum interval between which updates seen for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* interval An interval period in us.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_set_interval(int handle, unsigned interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
*
|
||||
* Description:
|
||||
* Get the minimum interval between which updates seen for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* interval The returned interval period in us.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_get_interval(int handle, FAR unsigned *interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
* orb_set_frequency
|
||||
*
|
||||
* Description:
|
||||
* Set the maximum frequency for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* frequency A frequency in hz.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
static inline int orb_set_frequency(int handle, unsigned frequency)
|
||||
{
|
||||
return orb_set_interval(handle, frequency ? 1000000 / frequency : 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
* orb_get_frequency
|
||||
*
|
||||
* Description:
|
||||
* Get the maximum frequency for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* frequency The returned frequency in hz.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, -1 otherwise with ERRNO set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
static inline int orb_get_frequency(int handle, FAR unsigned *frequency)
|
||||
{
|
||||
unsigned interval;
|
||||
int ret;
|
||||
|
||||
ret = orb_get_interval(handle, &interval);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*frequency = interval ? 1000000 / interval : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_elapsed_time
|
||||
*
|
||||
* Description:
|
||||
* Get current value of system time in us.
|
||||
*
|
||||
* Returned Value:
|
||||
* Absolute time.
|
||||
****************************************************************************/
|
||||
|
||||
orb_abstime orb_absolute_time(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_elapsed_time
|
||||
*
|
||||
* Description:
|
||||
* Compute the delta between a timestamp taken in the past and now.
|
||||
*
|
||||
* This function is not interrupt save.
|
||||
*
|
||||
* Input Parameters:
|
||||
* then Past system time.
|
||||
*
|
||||
* Returned Value:
|
||||
* Bewteen time.
|
||||
****************************************************************************/
|
||||
|
||||
static inline orb_abstime orb_elapsed_time(FAR const orb_abstime *then)
|
||||
{
|
||||
return orb_absolute_time() - *then;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_exists
|
||||
*
|
||||
* Description:
|
||||
* Check if a topic instance has already been advertised.
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta ORB topic metadata.
|
||||
* instance ORB instance
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if the topic exists, -1 otherwise.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_exists(FAR const struct orb_metadata *meta, int instance);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_group_count
|
||||
*
|
||||
* Description:
|
||||
* Get instance amount of advertised topic instances.
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta ORB topic metadata.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if none
|
||||
****************************************************************************/
|
||||
|
||||
int orb_group_count(FAR const struct orb_metadata *meta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_SYSTEM_UORB_UORB_UORB_H */
|
Loading…
x
Reference in New Issue
Block a user