PX4之uORB

    xiaoxiao2021-03-26  22

    1、orb_advertise_multi ,一个驱动对应多个实例。适用于驱动相似的多个传感器驱动。

    orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority) {     int result, fd;     orb_advert_t advertiser;     /* open the node as an advertiser */     fd = node_open(PUBSUB, meta, data, true, instance, priority);     if (fd == ERROR)         return ERROR;     /* get the advertiser handle and close the node */     result = ioctl(fd, ORBIOCGADVERTISER, (unsigned long)&advertiser);     close(fd);     if (result == ERROR)         return ERROR;     /* the advertiser must perform an initial publish to initialise the object */     result = orb_publish(meta, advertiser, data);     if (result == ERROR)         return ERROR;     return advertiser; }

    --------------------》

    int node_open(Flavor f, const struct orb_metadata *meta, const void *data, bool advertiser, int *instance = nullptr, int priority = ORB_PRIO_DEFAULT) {     char path[orb_maxpath];     int fd, 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;     }     /*      * Generate the path to the node and try to open it.      */     ret = node_mkpath(path, f, meta, instance);     if (ret != OK) {         errno = -ret;         return ERROR;     }     /* open the path as either the advertiser or the subscriber */     fd = open(path, (advertiser) ? O_WRONLY : O_RDONLY);     /* if we want to advertise and the node existed, we have to re-try again */     if ((fd >= 0) && (instance != nullptr) && (advertiser)) {         /* close the fd, we want a new one */         close(fd);         /* the node_advertise call will automatically go for the next free entry */         fd = -1;     }     /* we may need to advertise the node... */     if (fd < 0) {         /* try to create the node */         ret = node_advertise(meta, instance, priority);         if (ret == OK) {             /* update the path, as it might have been updated during the node_advertise call */             ret = node_mkpath(path, f, meta, instance);             if (ret != OK) {                 errno = -ret;                 return ERROR;             }         }         /* on success, try the open again */         if (ret == OK) {             fd = open(path, (advertiser) ? O_WRONLY : O_RDONLY);         }     }     if (fd < 0) {         errno = EIO;         return ERROR;     }     /* everything has been OK, we can return the handle now */     return fd; }

    ------------------------------------------------------->

    int node_advertise(const struct orb_metadata *meta, int *instance = nullptr, int priority = ORB_PRIO_DEFAULT) {     int fd = -1;     int ret = ERROR;     /* fill advertiser data */     const struct orb_advertdata adv = { meta, instance, priority };     /* open the control device */     fd = open(TOPIC_MASTER_DEVICE_PATH, 0);     if (fd < 0)         goto out;     /* advertise the object */     ret = ioctl(fd, ORBIOCADVERTISE, (unsigned long)(uintptr_t)&adv);     /* it's OK if it already exists */     if ((OK != ret) && (EEXIST == errno)) {         ret = OK;     } out:     if (fd >= 0)         close(fd);     return ret; }

    ------------------------------------------------------------->

    int ORBDevMaster::ioctl(struct file *filp, int cmd, unsigned long arg) {     int ret;     switch (cmd) {     case ORBIOCADVERTISE: {             const struct orb_advertdata *adv = (const struct orb_advertdata *)arg;             const struct orb_metadata *meta = adv->meta;             const char *objname;             const char *devpath;             char nodepath[orb_maxpath];             ORBDevNode *node;             /* set instance to zero - we could allow selective multi-pubs later based on value */             if (adv->instance != nullptr) {                 *(adv->instance) = 0;                    //注意在这里轻质把instance变量转化为0             }             /* construct a path to the node - this also checks the node name */             ret = node_mkpath(nodepath, _flavor, meta, adv->instance);             if (ret != OK) {                 return ret;             }             /* ensure that only one advertiser runs through this critical section */             lock();             ret = ERROR;             /* try for topic groups */             const unsigned max_group_tries = (adv->instance != nullptr) ? ORB_MULTI_MAX_INSTANCES : 1;             unsigned group_tries = 0;             do {                 /* if path is modifyable change try index */                 if (adv->instance != nullptr) {                     /* replace the number at the end of the string */                     nodepath[strlen(nodepath) - 1] = '0' + group_tries;                     *(adv->instance) = group_tries;                 }                 /* driver wants a permanent copy of the node name, so make one here */                 objname = strdup(meta->o_name);                 if (objname == nullptr) {                     return -ENOMEM;                 }                 /* driver wants a permanent copy of the path, so make one here */                 devpath = strdup(nodepath);                 if (devpath == nullptr) {                     return -ENOMEM;                 }                 /* construct the new node */                 node = new ORBDevNode(meta, objname, devpath, adv->priority);                 /* if we didn't get a device, that's bad */                 if (node == nullptr) {                     unlock();                     return -ENOMEM;                 }                 /* initialise the node - this may fail if e.g. a node with this name already exists */                 ret = node->init();                                  /* if init failed, discard the node and its name */                 if (ret != OK) {                     delete node;                     free((void *)objname);                     free((void *)devpath);                 }                 group_tries++;             } while (ret != OK && (group_tries < max_group_tries));             if (group_tries > max_group_tries) {                 ret = -ENOMEM;             }             /* the file handle for the driver has been created, unlock */             unlock();             return ret;         }     default:         /* give it to the superclass */         return CDev::ioctl(filp, cmd, arg);     } }

    蓝色字体中的红色字体是关键,可以看到已经存在的实例会报错。

    转载请注明原文地址: https://ju.6miu.com/read-556969.html

    最新回复(0)