canard_nuttx.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 UAVCAN Team
3  *
4  * Distributed under the MIT License, available in the file LICENSE.
5  *
6  */
7 
8 #include "canard_nuttx.h"
9 #include <fcntl.h>
10 #include <poll.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <nuttx/can/can.h>
14 
15 int canardNuttXInit(CanardNuttXInstance* out_ins, const char* can_iface_name)
16 {
17  const int fd = open(can_iface_name, O_RDWR | O_NONBLOCK);
18  if (fd < 0)
19  {
20  return -1;
21  }
22 
23  out_ins->fd = fd;
24  return 0;
25 }
26 
28 {
29  const int close_result = close(ins->fd);
30  ins->fd = -1;
31  return close_result;
32 }
33 
34 int canardNuttXTransmit(CanardNuttXInstance* ins, const CanardCANFrame* frame, int timeout_msec)
35 {
36  struct pollfd fds;
37  memset(&fds, 0, sizeof(fds));
38  fds.fd = ins->fd;
39  fds.events |= POLLOUT;
40 
41  const int poll_result = poll(&fds, 1, timeout_msec);
42  if (poll_result < 0)
43  {
44  return -1;
45  }
46  if (poll_result == 0)
47  {
48  return 0;
49  }
50  if ((fds.revents & POLLOUT) == 0)
51  {
52  return -1;
53  }
54 
55  struct can_msg_s transmit_msg;
56  memset(&transmit_msg, 0, sizeof(transmit_msg));
57  transmit_msg.cm_hdr.ch_id = frame->id & CANARD_CAN_EXT_ID_MASK;
58  transmit_msg.cm_hdr.ch_dlc = frame->data_len;
59  transmit_msg.cm_hdr.ch_extid = (frame->id & CANARD_CAN_FRAME_EFF) != 0;
60  memcpy(transmit_msg.cm_data, frame->data, frame->data_len);
61 
62  const size_t msg_len = CAN_MSGLEN(transmit_msg.cm_hdr.ch_dlc);
63  const ssize_t nbytes = write(ins->fd, &transmit_msg, msg_len);
64  if (nbytes < 0 || (size_t)nbytes != msg_len)
65  {
66  return -1;
67  }
68 
69  return 1;
70 }
71 
72 int canardNuttXReceive(CanardNuttXInstance* ins, CanardCANFrame* out_frame, int timeout_msec)
73 {
74  struct pollfd fds;
75  memset(&fds, 0, sizeof(fds));
76  fds.fd = ins->fd;
77  fds.events |= POLLIN;
78 
79  const int poll_result = poll(&fds, 1, timeout_msec);
80  if (poll_result < 0)
81  {
82  return -1;
83  }
84  if (poll_result == 0)
85  {
86  return 0;
87  }
88  if ((fds.revents & POLLIN) == 0)
89  {
90  return -1;
91  }
92 
93  struct can_msg_s receive_msg;
94  const ssize_t nbytes = read(ins->fd, &receive_msg, sizeof(receive_msg));
95  if (nbytes < 0 || (size_t)nbytes < CAN_MSGLEN(0) || (size_t)nbytes > sizeof(receive_msg))
96  {
97  return -1;
98  }
99 
100  out_frame->id = receive_msg.cm_hdr.ch_id;
101  out_frame->data_len = receive_msg.cm_hdr.ch_dlc;
102  memcpy(out_frame->data, receive_msg.cm_data, receive_msg.cm_hdr.ch_dlc);
103 
104  if (receive_msg.cm_hdr.ch_extid != 0)
105  {
106  out_frame->id |= CANARD_CAN_FRAME_EFF;
107  }
108 
109  return 1;
110 }
111 
113 {
114  return ins->fd;
115 }
canardNuttXInit
int canardNuttXInit(CanardNuttXInstance *out_ins, const char *can_iface_name)
Definition: canard_nuttx.c:15
uavcan::CanFrame::id
uint32_t id
CAN ID with flags (above)
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:34
canardNuttXGetDeviceFileDescriptor
int canardNuttXGetDeviceFileDescriptor(const CanardNuttXInstance *ins)
Definition: canard_nuttx.c:112
CanardNuttXInstance
Definition: canard_nuttx.h:18
uavcan::CanFrame::data
uint8_t data[MaxDataLen]
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:35
frame
uavcan::CanFrame frame
Definition: can.cpp:78
canardNuttXClose
int canardNuttXClose(CanardNuttXInstance *ins)
Definition: canard_nuttx.c:27
canardNuttXReceive
int canardNuttXReceive(CanardNuttXInstance *ins, CanardCANFrame *out_frame, int timeout_msec)
Definition: canard_nuttx.c:72
CanardNuttXInstance::fd
int fd
Definition: canard_nuttx.h:20
canardNuttXTransmit
int canardNuttXTransmit(CanardNuttXInstance *ins, const CanardCANFrame *frame, int timeout_msec)
Definition: canard_nuttx.c:34
canard_nuttx.h


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