From 53ee04ba3c22de569bbddf15205975149158b07b Mon Sep 17 00:00:00 2001 From: Jiuzhu Dong Date: Thu, 28 Apr 2022 23:17:57 +0800 Subject: [PATCH] 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 --- system/uorb/listener.c | 34 ++++-------- system/uorb/uORB/uORB.c | 66 +++++++++++----------- system/uorb/uORB/uORB.h | 120 ++++++++++++++++++++++++++-------------- 3 files changed, 124 insertions(+), 96 deletions(-) diff --git a/system/uorb/listener.c b/system/uorb/listener.c index 5b18a54cf..579b2c8b7 100644 --- a/system/uorb/listener.c +++ b/system/uorb/listener.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -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) diff --git a/system/uorb/uORB/uORB.c b/system/uorb/uORB/uORB.c index 5fdf16e9f..2d02378a4 100644 --- a/system/uorb/uORB/uORB.c +++ b/system/uorb/uORB/uORB.c @@ -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) diff --git a/system/uorb/uORB/uORB.h b/system/uorb/uORB/uORB.h index 5161c31f6..b59913d75 100644 --- a/system/uorb/uORB/uORB.h +++ b/system/uorb/uORB/uORB.h @@ -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;