Firmware
uORBDeviceNode.hpp
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2016 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 #pragma once
35 
36 #include "uORBCommon.hpp"
37 #include "uORBDeviceMaster.hpp"
38 
39 #include <lib/cdev/CDev.hpp>
40 
41 #include <containers/List.hpp>
42 
43 namespace uORB
44 {
45 class DeviceNode;
46 class DeviceMaster;
47 class Manager;
48 }
49 
53 class uORB::DeviceNode : public cdev::CDev, public ListNode<uORB::DeviceNode *>
54 {
55 public:
56  DeviceNode(const struct orb_metadata *meta, const uint8_t instance, const char *path, uint8_t priority,
57  uint8_t queue_size = 1);
58  ~DeviceNode();
59 
60  // no copy, assignment, move, move assignment
61  DeviceNode(const DeviceNode &) = delete;
62  DeviceNode &operator=(const DeviceNode &) = delete;
63  DeviceNode(DeviceNode &&) = delete;
64  DeviceNode &operator=(DeviceNode &&) = delete;
65 
70  int open(cdev::file_t *filp) override;
71 
75  int close(cdev::file_t *filp) override;
76 
88  ssize_t read(cdev::file_t *filp, char *buffer, size_t buflen) override;
89 
102  ssize_t write(cdev::file_t *filp, const char *buffer, size_t buflen) override;
103 
107  int ioctl(cdev::file_t *filp, int cmd, unsigned long arg) override;
108 
112  static ssize_t publish(const orb_metadata *meta, orb_advert_t handle, const void *data);
113 
114  static int unadvertise(orb_advert_t handle);
115 
116 #ifdef ORB_COMMUNICATOR
117  static int16_t topic_advertised(const orb_metadata *meta, int priority);
118  //static int16_t topic_unadvertised(const orb_metadata *meta, int priority);
119 
128  int16_t process_add_subscription(int32_t rateInHz);
129 
133  int16_t process_remove_subscription();
134 
138  int16_t process_received_message(int32_t length, uint8_t *data);
139 #endif /* ORB_COMMUNICATOR */
140 
149 
157 
163  bool is_published() const { return _published; }
164 
172  int update_queue_size(unsigned int queue_size);
173 
179  bool print_statistics(bool reset);
180 
181  uint8_t get_queue_size() const { return _queue_size; }
182 
183  int8_t subscriber_count() const { return _subscriber_count; }
184 
185  uint32_t lost_message_count() const { return _lost_messages; }
186 
187  unsigned published_message_count() const { return _generation; }
188 
189  const orb_metadata *get_meta() const { return _meta; }
190 
191  const char *get_name() const { return _meta->o_name; }
192 
193  uint8_t get_instance() const { return _instance; }
194 
195  int get_priority() const { return _priority; }
196  void set_priority(uint8_t priority) { _priority = priority; }
197 
198 protected:
199 
200  pollevent_t poll_state(cdev::file_t *filp) override;
201 
202  void poll_notify_one(px4_pollfd_struct_t *fds, pollevent_t events) override;
203 
204 private:
205  struct UpdateIntervalData {
206  struct hrt_call update_call;
207 #ifndef __PX4_NUTTX
208  uint64_t last_update;
209 #endif
210  unsigned interval;
211  bool update_reported;
212  };
213  struct SubscriberData {
214  ~SubscriberData() { if (update_interval) { delete (update_interval); } }
215 
216  unsigned generation;
217  UpdateIntervalData *update_interval;
219  // these flags are only used if update_interval != null
220  bool update_reported() const { return update_interval ? update_interval->update_reported : false; }
221  void set_update_reported(bool update_reported_flag)
222  { if (update_interval) { update_interval->update_reported = update_reported_flag; } }
223  };
224 
225  const orb_metadata *_meta;
226  const uint8_t _instance;
227  uint8_t *_data{nullptr};
228  hrt_abstime _last_update{0};
229  volatile unsigned _generation{0};
230  uint8_t _priority;
231  bool _published{false};
232  uint8_t _queue_size;
233  int8_t _subscriber_count{0};
234 
235  px4_task_t _publisher{0};
238  // statistics
239  uint32_t _lost_messages = 0;
242  inline static SubscriberData *filp_to_sd(cdev::file_t *filp);
243 
247  void update_deferred();
248 
254  static void update_deferred_trampoline(void *arg);
255 
264  bool appears_updated(SubscriberData *sd);
265 
266 };
ssize_t read(cdev::file_t *filp, char *buffer, size_t buflen) override
reads data from a subscriber node to the buffer provided.
Definition: uORBDeviceNode.cpp:168
An intrusive linked list.
Definition: List.hpp:45
int close(cdev::file_t *filp) override
Method to close a subscriber for this topic.
Definition: uORBDeviceNode.cpp:143
int update_queue_size(unsigned int queue_size)
Try to change the size of the queue.
Definition: uORBDeviceNode.cpp:771
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
Definition: uORBFastRpcChannel.hpp:44
void add_internal_subscriber()
Add the subscriber to the node&#39;s list of subscriber.
Definition: uORBDeviceNode.cpp:687
const char * o_name
unique object name
Definition: uORB.h:51
bool print_statistics(bool reset)
Print statistics (nr of lost messages)
Definition: uORBDeviceNode.cpp:667
int open(cdev::file_t *filp) override
Method to create a subscriber instance and return the struct pointing to the subscriber as a file poi...
Definition: uORBDeviceNode.cpp:74
void reset(enum BMP280_BUS busid)
Reset the driver.
Definition: bmp280.cpp:743
static ssize_t publish(const orb_metadata *meta, orb_advert_t handle, const void *data)
Method to publish a data to this node.
Definition: uORBDeviceNode.cpp:383
int ioctl(cdev::file_t *filp, int cmd, unsigned long arg) override
IOCTL control for the subscriber.
Definition: uORBDeviceNode.cpp:289
void poll_notify_one(px4_pollfd_struct_t *fds, pollevent_t events) override
Internal implementation of poll_notify.
Definition: uORBDeviceNode.cpp:496
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
bool is_published() const
Return true if this topic has been published.
Definition: uORBDeviceNode.hpp:163
ssize_t write(cdev::file_t *filp, const char *buffer, size_t buflen) override
writes the published data to the internal buffer to be read by subscribers later. ...
Definition: uORBDeviceNode.cpp:221
Definition: cdev_platform.hpp:20
Object metadata.
Definition: uORB.h:50
pollevent_t poll_state(cdev::file_t *filp) override
Check the current state of the device for poll events from the perspective of the file...
Definition: uORBDeviceNode.cpp:481
Definition: rc_loss_alarm.cpp:50
Abstract class for any character device.
Definition: CDev.hpp:58
Definition: video_device.h:50
Callout record.
Definition: drv_hrt.h:72
Per-object device instance.
Definition: uORBDeviceNode.hpp:53
void remove_internal_subscriber()
Removes the subscriber from the list.
Definition: uORBDeviceNode.cpp:707