uc_kinetis_thread.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014, 2018 Pavel Kirienko <pavel.kirienko@gmail.com>
3  * Kinetis Port Author David Sidrane <david_s5@nscdg.com>
4  */
5 
8 #include <uavcan_kinetis/can.hpp>
9 #include "internal.hpp"
10 
11 namespace uavcan_kinetis
12 {
13 
14 
15 const unsigned BusEvent::MaxPollWaiters;
16 const char* const BusEvent::DevName = "/dev/uavcan/busevent";
17 
19 {
20  return static_cast<BusEvent*>(filp->f_inode->i_private)->open(filp);
21 }
22 
24 {
25  return static_cast<BusEvent*>(filp->f_inode->i_private)->close(filp);
26 }
27 
28 int BusEvent::pollTrampoline(::file* filp, ::pollfd* fds, bool setup)
29 {
30  return static_cast<BusEvent*>(filp->f_inode->i_private)->poll(filp, fds, setup);
31 }
32 
33 int BusEvent::open(::file* filp)
34 {
35  (void)filp;
36  return 0;
37 }
38 
39 int BusEvent::close(::file* filp)
40 {
41  (void)filp;
42  return 0;
43 }
44 
45 int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup)
46 {
47  CriticalSectionLocker locker;
48  int ret = -1;
49 
50  if (setup)
51  {
52  ret = addPollWaiter(fds);
53  if (ret == 0)
54  {
55  /*
56  * Two events can be reported via POLLIN:
57  * - The RX queue is not empty. This event is level-triggered.
58  * - Transmission complete. This event is edge-triggered.
59  * FIXME Since TX event is edge-triggered, it can be lost between poll() calls.
60  */
61  fds->revents |= fds->events & (can_driver_.hasReadableInterfaces() ? POLLIN : 0);
62  if (fds->revents != 0)
63  {
64  (void)sem_post(fds->sem);
65  }
66  }
67  }
68  else
69  {
70  ret = removePollWaiter(fds);
71  }
72 
73  return ret;
74 }
75 
76 int BusEvent::addPollWaiter(::pollfd* fds)
77 {
78  for (unsigned i = 0; i < MaxPollWaiters; i++)
79  {
80  if (pollset_[i] == UAVCAN_NULLPTR)
81  {
82  pollset_[i] = fds;
83  return 0;
84  }
85  }
86  return -ENOMEM;
87 }
88 
89 int BusEvent::removePollWaiter(::pollfd* fds)
90 {
91  for (unsigned i = 0; i < MaxPollWaiters; i++)
92  {
93  if (fds == pollset_[i])
94  {
96  return 0;
97  }
98  }
99  return -EINVAL;
100 }
101 
103  : can_driver_(can_driver),
104  signal_(false)
105 {
106  std::memset(&file_ops_, 0, sizeof(file_ops_));
107  std::memset(pollset_, 0, sizeof(pollset_));
111  // TODO: move to init(), add proper error handling
112  if (register_driver(DevName, &file_ops_, 0666, static_cast<void*>(this)) != 0)
113  {
114  std::abort();
115  }
116 }
117 
119 {
120  (void)unregister_driver(DevName);
121 }
122 
124 {
125  // TODO blocking wait
126  const uavcan::MonotonicTime deadline = clock::getMonotonic() + duration;
127  while (clock::getMonotonic() < deadline)
128  {
129  {
130  CriticalSectionLocker locker;
131  if (signal_)
132  {
133  signal_ = false;
134  return true;
135  }
136  }
137  ::usleep(1000);
138  }
139  return false;
140 }
141 
143 {
144  signal_ = true; // HACK
145  for (unsigned i = 0; i < MaxPollWaiters; i++)
146  {
147  ::pollfd* const fd = pollset_[i];
148  if (fd != UAVCAN_NULLPTR)
149  {
150  fd->revents |= fd->events & POLLIN;
151  if ((fd->revents != 0) && (fd->sem->semcount <= 0))
152  {
153  (void)sem_post(fd->sem);
154  }
155  }
156  }
157 }
158 
159 }
setup
internal.hpp
UAVCAN_NULLPTR
#define UAVCAN_NULLPTR
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:51
can.hpp
uavcan_kinetis::BusEvent::~BusEvent
~BusEvent()
Definition: uc_kinetis_thread.cpp:118
uavcan_kinetis::CanDriver
Definition: platform_specific_components/kinetis/libuavcan/driver/include/uavcan_kinetis/can.hpp:267
uavcan_kinetis::BusEvent::openTrampoline
static int openTrampoline(::file *filp)
Definition: uc_kinetis_thread.cpp:18
uavcan_kinetis::BusEvent::poll
int poll(::file *filp, ::pollfd *fds, bool setup)
Definition: uc_kinetis_thread.cpp:45
uavcan::MonotonicDuration
Definition: time.hpp:182
uavcan_kinetis::CanDriver::hasReadableInterfaces
bool hasReadableInterfaces() const
Definition: uc_kinetis_flexcan.cpp:873
uavcan_kinetis::BusEvent::MaxPollWaiters
static const unsigned MaxPollWaiters
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:31
uavcan_kinetis::BusEvent::close
int close(::file *filp)
Definition: uc_kinetis_thread.cpp:39
uavcan_kinetis
Definition: platform_specific_components/kinetis/libuavcan/driver/include/uavcan_kinetis/can.hpp:13
uavcan_kinetis::BusEvent::addPollWaiter
int addPollWaiter(::pollfd *fds)
Definition: uc_kinetis_thread.cpp:76
uavcan_kinetis::BusEvent::open
int open(::file *filp)
Definition: uc_kinetis_thread.cpp:33
pyuavcan_v0.file
file
Definition: pyuavcan/pyuavcan_v0/__init__.py:42
uavcan_kinetis::BusEvent::wait
bool wait(uavcan::MonotonicDuration duration)
Definition: uc_kinetis_thread.cpp:123
uavcan_kinetis::BusEvent::removePollWaiter
int removePollWaiter(::pollfd *fds)
Definition: uc_kinetis_thread.cpp:89
uavcan_kinetis::clock::getMonotonic
uavcan::MonotonicTime getMonotonic()
Definition: clock.cpp:83
uavcan_kinetis::BusEvent::pollset_
::pollfd * pollset_[MaxPollWaiters]
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:34
uavcan_kinetis::BusEvent::can_driver_
CanDriver & can_driver_
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:35
thread.hpp
uavcan_kinetis::BusEvent::signal_
bool signal_
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:36
uavcan::MonotonicTime
Definition: time.hpp:184
uavcan_kinetis::BusEvent::pollTrampoline
static int pollTrampoline(::file *filp, ::pollfd *fds, bool setup)
Definition: uc_kinetis_thread.cpp:28
uavcan_kinetis::BusEvent::DevName
static const char *const DevName
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:50
clock.hpp
uavcan_kinetis::BusEvent::file_ops_
::file_operations file_ops_
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:33
uavcan_kinetis::BusEvent::signalFromInterrupt
void signalFromInterrupt()
Definition: uc_kinetis_thread.cpp:142
uavcan_kinetis::BusEvent
Definition: kinetis/libuavcan/driver/include/uavcan_kinetis/thread.hpp:29
uavcan_kinetis::BusEvent::closeTrampoline
static int closeTrampoline(::file *filp)
Definition: uc_kinetis_thread.cpp:23
uavcan_kinetis::BusEvent::BusEvent
BusEvent(CanDriver &can_driver)
Definition: uc_kinetis_thread.cpp:102


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03