main.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <cstdio>
6 #include <cstdlib>
7 #include <algorithm>
8 #include <board.hpp>
9 #include <chip.h>
14 
15 /*
16  * GCC 4.9 cannot generate a working binary with higher optimization levels, although
17  * rest of the firmware can be compiled with -Os.
18  * GCC 4.8 and earlier don't work at all on this firmware.
19  */
20 #if __GNUC__
21 # pragma GCC optimize 1
22 #endif
23 
28 int rand()
29 {
30  static int x = 1;
31  x = x * 48271 % 2147483647;
32  return x;
33 }
34 
35 namespace
36 {
37 
38 static constexpr unsigned NodeMemoryPoolSize = 2800;
39 
44 typename uavcan::MakeString<22>::Type intToString(long long n)
45 {
46  char buf[24] = {};
47  const short sign = (n < 0) ? -1 : 1;
48  if (sign < 0)
49  {
50  n = -n;
51  }
52  unsigned pos = 0;
53  do
54  {
55  buf[pos++] = char(n % 10 + '0');
56  }
57  while ((n /= 10) > 0);
58  if (sign < 0)
59  {
60  buf[pos++] = '-';
61  }
62  buf[pos] = '\0';
63  for (unsigned i = 0, j = pos - 1U; i < j; i++, j--)
64  {
65  std::swap(buf[i], buf[j]);
66  }
67  return static_cast<const char*>(buf);
68 }
69 
71 {
74  return node;
75 }
76 
77 uavcan::GlobalTimeSyncSlave& getTimeSyncSlave()
78 {
79  static uavcan::GlobalTimeSyncSlave tss(getNode());
80  return tss;
81 }
82 
83 uavcan::Logger& getLogger()
84 {
85  static uavcan::Logger logger(getNode());
86  return logger;
87 }
88 
89 uavcan::NodeID performDynamicNodeIDAllocation()
90 {
91  uavcan::DynamicNodeIDClient client(getNode());
92 
93  const int client_start_res = client.start(getNode().getHardwareVersion().unique_id);
94  if (client_start_res < 0)
95  {
96  board::die();
97  }
98 
99  while (!client.isAllocationComplete())
100  {
102  (void)getNode().spin(uavcan::MonotonicDuration::fromMSec(100));
103  }
104 
105  return client.getAllocatedNodeID();
106 }
107 
108 void init()
109 {
111  board::syslog("Boot\r\n");
112 
113  board::setErrorLed(false);
114  board::setStatusLed(true);
115 
116  /*
117  * Configuring the clock - this must be done before the CAN controller is initialized
118  */
120 
121  /*
122  * Configuring the CAN controller
123  */
124  std::uint32_t bit_rate = 0;
125  while (bit_rate == 0)
126  {
127  board::syslog("CAN auto bitrate...\r\n");
129  }
130  board::syslog("Bitrate: ");
131  board::syslog(intToString(bit_rate).c_str());
132  board::syslog("\r\n");
133 
134  if (uavcan_lpc11c24::CanDriver::instance().init(bit_rate) < 0)
135  {
136  board::die();
137  }
138 
139  board::syslog("CAN init ok\r\n");
140 
142 
143  /*
144  * Configuring the node
145  */
146  getNode().setName("org.uavcan.lpc11c24_test");
147 
148  uavcan::protocol::SoftwareVersion swver;
149  swver.major = FW_VERSION_MAJOR;
150  swver.minor = FW_VERSION_MINOR;
151  swver.vcs_commit = GIT_HASH;
152  swver.optional_field_flags = swver.OPTIONAL_FIELD_FLAG_VCS_COMMIT;
153  getNode().setSoftwareVersion(swver);
154 
155  uavcan::protocol::HardwareVersion hwver;
157  board::readUniqueID(uid);
158  std::copy(std::begin(uid), std::end(uid), std::begin(hwver.unique_id));
159  getNode().setHardwareVersion(hwver);
160 
162 
163  /*
164  * Starting the node and performing dynamic node ID allocation
165  */
166  if (getNode().start() < 0)
167  {
168  board::die();
169  }
170 
171  board::syslog("Node ID allocation...\r\n");
172 
173  getNode().setNodeID(performDynamicNodeIDAllocation());
174 
175  board::syslog("Node ID ");
176  board::syslog(intToString(getNode().getNodeID().get()).c_str());
177  board::syslog("\r\n");
178 
180 
181  /*
182  * Example filter configuration.
183  * Can be removed safely.
184  */
185  {
186  constexpr unsigned NumFilters = 3;
187  uavcan::CanFilterConfig filters[NumFilters];
188 
189  // Acepting all service transfers addressed to us
190  filters[0].id = (unsigned(getNode().getNodeID().get()) << 8) | (1U << 7) | uavcan::CanFrame::FlagEFF;
191  filters[0].mask = 0x7F80 | uavcan::CanFrame::FlagEFF;
192 
193  // Accepting time sync messages
194  filters[1].id = (4U << 8) | uavcan::CanFrame::FlagEFF;
195  filters[1].mask = 0xFFFF80 | uavcan::CanFrame::FlagEFF;
196 
197  // Accepting zero CAN ID (just for the sake of testing)
198  filters[2].id = 0 | uavcan::CanFrame::FlagEFF;
200 
201  if (uavcan_lpc11c24::CanDriver::instance().configureFilters(filters, NumFilters) < 0)
202  {
203  board::syslog("Filter init failed\r\n");
204  board::die();
205  }
206  }
207 
208  /*
209  * Initializing other libuavcan-related objects
210  */
211  if (getTimeSyncSlave().start() < 0)
212  {
213  board::die();
214  }
215 
216  if (getLogger().init() < 0)
217  {
218  board::die();
219  }
220 
221  getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
222 
224 }
225 
226 }
227 
228 int main()
229 {
230  init();
231 
232  getNode().setModeOperational();
233 
234  uavcan::MonotonicTime prev_log_at;
235 
236  while (true)
237  {
238  const int res = getNode().spin(uavcan::MonotonicDuration::fromMSec(25));
239  board::setErrorLed(res < 0);
241 
242  const auto ts = uavcan_lpc11c24::clock::getMonotonic();
243  if ((ts - prev_log_at).toMSec() >= 1000)
244  {
245  prev_log_at = ts;
246 
247  /*
248  * CAN bus off state monitoring
249  */
250  if (uavcan_lpc11c24::CanDriver::instance().isInBusOffState())
251  {
252  board::syslog("CAN BUS OFF\r\n");
253  }
254 
255  /*
256  * CAN error counter, for debugging purposes
257  */
258  board::syslog("CAN errors: ");
259  board::syslog(intToString(static_cast<long long>(uavcan_lpc11c24::CanDriver::instance().getErrorCount())).c_str());
260  board::syslog(" ");
261  board::syslog(intToString(uavcan_lpc11c24::CanDriver::instance().getRxQueueOverflowCount()).c_str());
262  board::syslog("\r\n");
263 
264  /*
265  * We don't want to use formatting functions provided by libuavcan because they rely on std::snprintf(),
266  * so we need to construct the message manually:
267  */
268  uavcan::protocol::debug::LogMessage logmsg;
269  logmsg.level.value = uavcan::protocol::debug::LogLevel::INFO;
270  logmsg.source = "app";
271  logmsg.text = intToString(uavcan_lpc11c24::clock::getPrevUtcAdjustment().toUSec()).c_str();
272  (void)getLogger().log(logmsg);
273  }
274 
276  }
277 }
board::resetWatchdog
void resetWatchdog()
Definition: board.cpp:173
board::setStatusLed
void setStatusLed(bool state)
Definition: board.cpp:163
uavcan::CanFrame::FlagEFF
static const uint32_t FlagEFF
Extended frame format.
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:28
board::syslog
void syslog(const char *msg)
Definition: board.cpp:178
uavcan_lpc11c24::clock::getMonotonic
uavcan::MonotonicTime getMonotonic()
Definition: clock.cpp:83
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
get
ROSCPP_DECL bool get(const std::string &key, bool &b)
uavcan_lpc11c24.hpp
uavcan_lpc11c24::CanDriver::configureFilters
uavcan::int16_t configureFilters(const uavcan::CanFilterConfig *filter_configs, uavcan::uint16_t num_configs) override
Definition: can.cpp:469
uavcan::NodeID
Definition: transfer.hpp:112
uavcan_lpc11c24::clock::init
void init()
Definition: clock.cpp:43
uavcan::DurationBase< MonotonicDuration >::fromMSec
static MonotonicDuration fromMSec(int64_t ms)
Definition: time.hpp:41
board::UniqueIDSize
static constexpr unsigned UniqueIDSize
Definition: board.hpp:15
uavcan::CanFilterConfig
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:99
uavcan_lpc11c24::clock::getPrevUtcAdjustment
uavcan::UtcDuration getPrevUtcAdjustment()
Definition: clock.cpp:112
rand
int rand()
Definition: main.cpp:28
board::die
void die()
Definition: board.cpp:137
uavcan::Array
Definition: array.hpp:424
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
board::readUniqueID
void readUniqueID(std::uint8_t out_uid[UniqueIDSize])
Definition: board.cpp:155
uavcan::CanFilterConfig::mask
uint32_t mask
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:102
main
int main()
Definition: main.cpp:228
uavcan::CanFrame::MaskExtID
static const uint32_t MaskExtID
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:27
global_time_sync_slave.hpp
uavcan::DynamicNodeIDClient
Definition: dynamic_node_id_client.hpp:31
libuavcan_dsdl_compiler.logger
logger
Definition: libuavcan_dsdl_compiler/__init__.py:35
board.hpp
dynamic_node_id_client.hpp
start
ROSCPP_DECL void start()
swap
static uint8_t swap(uint8_t x)
Dreht die beiden Nibble in einem Byte um.
Definition: utils.h:289
uavcan_lpc11c24::CanDriver::instance
static CanDriver & instance()
Definition: platform_specific_components/lpc11c24/libuavcan/driver/include/uavcan_lpc11c24/can.hpp:30
uavcan::Logger
Definition: logger.hpp:58
board::setErrorLed
void setErrorLed(bool state)
Definition: board.cpp:168
logger.hpp
uavcan_kinetis::clock::init
void init()
Definition: clock.cpp:43
chip.h
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
uavcan::MonotonicTime
Definition: time.hpp:184
uavcan::GlobalTimeSyncSlave
Definition: global_time_sync_slave.hpp:28
uavcan_lpc11c24::SystemClock::instance
static SystemClock & instance()
Definition: clock.cpp:156
NodeMemoryPoolSize
constexpr unsigned NodeMemoryPoolSize
Definition: converters.hpp:57
uavcan::copy
UAVCAN_EXPORT OutputIt copy(InputIt first, InputIt last, OutputIt result)
Definition: templates.hpp:238
uavcan::CanFilterConfig::id
uint32_t id
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:101
pyuavcan_v0.driver.timestamp_estimator.x
x
Definition: timestamp_estimator.py:221
uavcan::Node
Definition: node.hpp:38
uavcan_lpc11c24::CanDriver::detectBitRate
static uavcan::uint32_t detectBitRate(void(*idle_callback)()=nullptr)
Definition: can.cpp:171


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