uorb/listener: add new api: orb_open and orb_close
don't using subscriber to get state to avoid rpmsg access Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
d44dd1c426
commit
53ee04ba3c
@ -33,6 +33,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <uORB/uORB.h>
|
||||
|
||||
@ -139,21 +140,15 @@ static int listener_get_state(FAR struct orb_object *object,
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
fd = orb_subscribe_multi(object->meta, object->instance);
|
||||
fd = orb_open(object->meta->o_name, object->instance, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
ret = orb_get_state(fd, state);
|
||||
orb_unsubscribe(fd);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
state->nsubscribers--; /* Ignore temp subscriber */
|
||||
return 0;
|
||||
orb_close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -174,8 +169,6 @@ static int listener_add_object(FAR struct list_node *objlist,
|
||||
FAR struct orb_object *object)
|
||||
{
|
||||
FAR struct listen_object_s *tmp;
|
||||
struct orb_state state;
|
||||
int ret;
|
||||
|
||||
tmp = malloc(sizeof(struct listen_object_s));
|
||||
if (tmp == NULL)
|
||||
@ -183,20 +176,10 @@ static int listener_add_object(FAR struct list_node *objlist,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = listener_get_state(object, &state);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tmp->object.meta = object->meta;
|
||||
tmp->object.instance = object->instance;
|
||||
tmp->timestamp = orb_absolute_time();
|
||||
tmp->generation = state.generation;
|
||||
|
||||
tmp->timestamp = 0;
|
||||
list_add_tail(objlist, &tmp->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -249,6 +232,13 @@ static int listener_update(FAR struct list_node *objlist,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (old->timestamp == 0)
|
||||
{
|
||||
old->timestamp = orb_absolute_time();
|
||||
old->generation = state.generation;
|
||||
return 0;
|
||||
}
|
||||
|
||||
delta_time = now_time - old->timestamp;
|
||||
delta_generation = state.generation - old->generation;
|
||||
if (delta_generation && delta_time)
|
||||
|
@ -37,7 +37,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_open
|
||||
* Name: orb_advsub_open
|
||||
*
|
||||
* Description:
|
||||
* Open device node as advertiser / subscriber, regist node and save meta
|
||||
@ -45,7 +45,7 @@
|
||||
*
|
||||
* Input Parameters:
|
||||
* meta The uORB metadata (usually from the ORB_ID() macro)
|
||||
* advertiser Whether advertiser or subscriber.
|
||||
* flag The open flag.
|
||||
* instance Instance number to open.
|
||||
* queue_size Maximum number of buffered elements.
|
||||
*
|
||||
@ -53,11 +53,10 @@
|
||||
* 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)
|
||||
static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags,
|
||||
int instance, unsigned int queue_size)
|
||||
{
|
||||
char path[ORB_PATH_MAX];
|
||||
bool first_open = false;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
@ -66,11 +65,11 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
|
||||
|
||||
/* Check existance before open */
|
||||
|
||||
ret = access(path, F_OK);
|
||||
if (ret < 0)
|
||||
flags |= O_CLOEXEC;
|
||||
fd = open(path, flags);
|
||||
if (fd < 0)
|
||||
{
|
||||
struct sensor_reginfo_s reginfo;
|
||||
|
||||
reginfo.path = path;
|
||||
reginfo.esize = meta->o_size;
|
||||
reginfo.nbuffer = queue_size;
|
||||
@ -90,18 +89,16 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
|
||||
return ret;
|
||||
}
|
||||
|
||||
first_open = true;
|
||||
}
|
||||
fd = open(path, flags);
|
||||
if (fd < 0)
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != -EEXIST)
|
||||
{
|
||||
ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only first advertiser can successfully set buffer number */
|
||||
@ -118,6 +115,19 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int orb_open(FAR const char *name, int instance, int flags)
|
||||
{
|
||||
char path[ORB_PATH_MAX];
|
||||
|
||||
snprintf(path, ORB_PATH_MAX, ORB_SENSOR_PATH"%s%d", name, instance);
|
||||
return open(path, O_CLOEXEC | flags);
|
||||
}
|
||||
|
||||
int orb_close(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
|
||||
FAR const void *data, FAR int *instance,
|
||||
unsigned int queue_size)
|
||||
@ -129,7 +139,7 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
|
||||
|
||||
inst = instance ? *instance : orb_group_count(meta);
|
||||
|
||||
fd = orb_open(meta, true, inst, queue_size);
|
||||
fd = orb_advsub_open(meta, O_WRONLY, inst, queue_size);
|
||||
if (fd < 0)
|
||||
{
|
||||
uorberr("%s advertise failed (%i)", meta->o_name, fd);
|
||||
@ -155,11 +165,6 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
|
||||
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);
|
||||
@ -168,12 +173,7 @@ ssize_t orb_publish_multi(int fd, const void *data, size_t 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);
|
||||
return orb_advsub_open(meta, O_RDONLY, instance, 0);
|
||||
}
|
||||
|
||||
ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len)
|
||||
@ -225,9 +225,9 @@ int orb_check(int fd, FAR bool *updated)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int orb_ioctl(int handle, int cmd, unsigned long arg)
|
||||
int orb_ioctl(int fd, int cmd, unsigned long arg)
|
||||
{
|
||||
return ioctl(handle, cmd, arg);
|
||||
return ioctl(fd, cmd, arg);
|
||||
}
|
||||
|
||||
int orb_set_interval(int fd, unsigned interval)
|
||||
|
@ -173,6 +173,38 @@ extern "C"
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_open
|
||||
*
|
||||
* Description:
|
||||
* Open device exist node with name, instance and flags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* name The topic name.
|
||||
* instance Instance number to open.
|
||||
* flags The open flags.
|
||||
*
|
||||
* Returned Value:
|
||||
* fd on success, otherwise returns negative value and set errno.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_open(FAR const char *name, int instance, int flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_close
|
||||
*
|
||||
* Description:
|
||||
* Close fd.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fd A fd returned by orb_open.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_close(int fd);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_advertise_multi_queue
|
||||
*
|
||||
@ -227,13 +259,16 @@ static inline int orb_advertise_multi(FAR const struct orb_metadata *meta,
|
||||
* Unadvertise a topic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned by orb_advertise or orb_advertise_multi.
|
||||
* fd A fd returned by orb_advertise or orb_advertise_multi.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_unadvertise(int handle);
|
||||
static inline int orb_unadvertise(int fd)
|
||||
{
|
||||
return orb_close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_publish_multi
|
||||
@ -246,7 +281,7 @@ int orb_unadvertise(int handle);
|
||||
* updates using orb_check.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle returned from orb_advertise.
|
||||
* fd The fd returned from orb_advertise.
|
||||
* data A pointer to the data to be published.
|
||||
* len The length of the data to be published.
|
||||
*
|
||||
@ -254,24 +289,24 @@ int orb_unadvertise(int handle);
|
||||
* 0 on success, -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t orb_publish_multi(int handle, FAR const void *data, size_t len);
|
||||
ssize_t orb_publish_multi(int fd, 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 fd, FAR const void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = orb_publish_multi(handle, data, meta->o_size);
|
||||
ret = orb_publish_multi(fd, 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 *fd, FAR const void *data,
|
||||
FAR int *instance)
|
||||
{
|
||||
if (handle && *handle)
|
||||
if (fd && *fd)
|
||||
{
|
||||
return orb_publish(meta, *handle, data);
|
||||
return orb_publish(meta, *fd, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -283,9 +318,9 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (handle)
|
||||
if (fd)
|
||||
{
|
||||
*handle = tmp;
|
||||
*fd = tmp;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
@ -319,7 +354,7 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
|
||||
* the orb_subscribe() call.
|
||||
*
|
||||
* Returned Value:
|
||||
* -1 on error, otherwise returns a handle
|
||||
* -1 on error, otherwise returns a fd
|
||||
* 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)
|
||||
@ -341,13 +376,16 @@ static inline int orb_subscribe(FAR const struct orb_metadata *meta)
|
||||
* Unsubscribe from a topic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd returned from orb_subscribe.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_unsubscribe(int handle);
|
||||
static inline int orb_unsubscribe(int fd)
|
||||
{
|
||||
return orb_close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_copy_multi
|
||||
@ -361,7 +399,7 @@ int orb_unsubscribe(int handle);
|
||||
* must be used to update the subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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.
|
||||
@ -372,14 +410,14 @@ int orb_unsubscribe(int handle);
|
||||
* -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t orb_copy_multi(int handle, FAR void *buffer, size_t len);
|
||||
ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len);
|
||||
|
||||
static inline int orb_copy(FAR const struct orb_metadata *meta,
|
||||
int handle, FAR void *buffer)
|
||||
int fd, FAR void *buffer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = orb_copy_multi(handle, buffer, meta->o_size);
|
||||
ret = orb_copy_multi(fd, buffer, meta->o_size);
|
||||
return ret == meta->o_size ? 0 : -1;
|
||||
}
|
||||
|
||||
@ -397,7 +435,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
|
||||
* max_frequency to 0. min_batch_interval to 0, enable to false.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle The handle returned from orb_advertise / orb_subscribe.
|
||||
* fd The fd 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.
|
||||
*
|
||||
@ -405,7 +443,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
|
||||
* -1 on error.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_get_state(int handle, FAR struct orb_state *state);
|
||||
int orb_get_state(int fd, FAR struct orb_state *state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_check
|
||||
@ -417,20 +455,20 @@ int orb_get_state(int handle, FAR struct orb_state *state);
|
||||
* 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.
|
||||
* Updates are tracked on a per-fd basis; this call will continue to
|
||||
* return true until orb_copy is called using the same fd.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd returned from orb_subscribe.
|
||||
* update Set to true if the topic has been updated since the
|
||||
* last time it was copied using this handle.
|
||||
* last time it was copied using this fd.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 if the check was successful,
|
||||
* -1 otherwise with errno set accordingly.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_check(int handle, FAR bool *updated);
|
||||
int orb_check(int fd, FAR bool *updated);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_ioctl
|
||||
@ -439,7 +477,7 @@ int orb_check(int handle, FAR bool *updated);
|
||||
* Ioctl control for the subscriber, the same as ioctl().
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_advertise / orb_subscribe.
|
||||
* fd A fd returned from orb_advertise / orb_subscribe.
|
||||
* cmd Ioctl command.
|
||||
* arg Ioctl argument.
|
||||
*
|
||||
@ -447,7 +485,7 @@ int orb_check(int handle, FAR bool *updated);
|
||||
* 0 on success.
|
||||
****************************************************************************/
|
||||
|
||||
int orb_ioctl(int handle, int cmd, unsigned long arg);
|
||||
int orb_ioctl(int fd, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_set_batch_interval
|
||||
@ -462,14 +500,14 @@ int orb_ioctl(int handle, int cmd, unsigned long arg);
|
||||
* hardware fifo, otherwise it's meaningless.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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);
|
||||
int orb_set_batch_interval(int fd, unsigned batch_interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: orb_get_batch_interval
|
||||
@ -483,14 +521,14 @@ int orb_set_batch_interval(int handle, unsigned batch_interval);
|
||||
* @see orb_set_batch_interval()
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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);
|
||||
int orb_get_batch_interval(int fd, FAR unsigned *batch_interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
@ -499,14 +537,14 @@ int orb_get_batch_interval(int handle, FAR unsigned *batch_interval);
|
||||
* Set the minimum interval between which updates seen for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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);
|
||||
int orb_set_interval(int fd, unsigned interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
@ -515,14 +553,14 @@ int orb_set_interval(int handle, unsigned interval);
|
||||
* Get the minimum interval between which updates seen for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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);
|
||||
int orb_get_interval(int fd, FAR unsigned *interval);
|
||||
|
||||
/****************************************************************************
|
||||
* Name:
|
||||
@ -532,16 +570,16 @@ int orb_get_interval(int handle, FAR unsigned *interval);
|
||||
* Set the maximum frequency for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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)
|
||||
static inline int orb_set_frequency(int fd, unsigned frequency)
|
||||
{
|
||||
return orb_set_interval(handle, frequency ? 1000000 / frequency : 0);
|
||||
return orb_set_interval(fd, frequency ? 1000000 / frequency : 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -552,19 +590,19 @@ static inline int orb_set_frequency(int handle, unsigned frequency)
|
||||
* Get the maximum frequency for a subscription.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle A handle returned from orb_subscribe.
|
||||
* fd A fd 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)
|
||||
static inline int orb_get_frequency(int fd, FAR unsigned *frequency)
|
||||
{
|
||||
unsigned interval;
|
||||
int ret;
|
||||
|
||||
ret = orb_get_interval(handle, &interval);
|
||||
ret = orb_get_interval(fd, &interval);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user