KaCanOpen
 All Classes Functions Variables Typedefs Enumerations Pages
sdo.h
1 /*
2  * Copyright (c) 2015, Thomas Keh
3  * 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 are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #pragma once
33 
34 #include <functional>
35 #include <vector>
36 #include <mutex>
37 #include <list>
38 #include <unordered_map>
39 
40 #include "message.h"
41 #include "sdo_response.h"
42 
43 namespace kaco {
44 
45  // forward declaration
46  class Core;
47 
58  class SDO {
59 
60  public:
61 
65  using SDOReceivedCallback = std::function< void(SDOResponse) >;
66 
69  SDO(Core& core);
70 
72  SDO(const SDO&) = delete;
73 
81  void download(uint8_t node_id, uint16_t index, uint8_t subindex, uint32_t size, const std::vector<uint8_t>& bytes);
82 
89  std::vector<uint8_t> upload(uint8_t node_id, uint16_t index, uint8_t subindex);
90 
95  void process_incoming_message(const Message& message);
96 
105  SDOResponse send_sdo_and_wait(uint8_t command, uint8_t node_id, uint16_t index, uint8_t subindex, const std::array<uint8_t,4>& data);
106 
107  private:
108 
109  enum Flag : uint8_t {
110 
111  // client command specifiers
112  initiate_download_request = 0x20,
113  download_segment_request = 0x00,
114  initiate_upload_request = 0x40,
115  upload_segment_request = 0x60,
116 
117  // server command specifiers
118  initiate_download_response = 0x60,
119  download_segment_response = 0x20,
120  initiate_upload_response = 0x40,
121  upload_segment_response = 0x00,
122 
123  toggle_bit = 0x10,
124  no_more_segments = 0x01,
125  size_indicated = 0x01,
126  expedited_transfer = 0x02,
127 
128  error = 0x80
129 
130  };
131 
132  static const bool debug = false;
133 
134  Core& m_core;
135 
136  // Recevicers on per-node basis. Never call send_sdo_and_wait() from inside!
137  // TODO: Add m_server_sdo_callbacks and add m_client_sdo_callbacks for custom usage.
138  // IDEA: We could store the promise directly, but this won't obviate synchronization...
139  std::array<SDOReceivedCallback,256> m_send_and_wait_receivers;
140 
141  // We must synchronize access to the m_send_and_wait_receivers array entries.
142  mutable std::array<std::mutex,256> m_send_and_wait_receiver_mutexes;
143 
144  // We lock send_sdo_and_wait() on per-node basis because concurrent responses could be confused
145  // and because m_receivers manipulation must be synchronized
146  mutable std::array<std::mutex,256> m_send_and_wait_mutex;
147 
148  uint8_t size_flag(uint8_t size);
149 
151  static void received_unassigned_sdo(SDOResponse);
152 
153  };
154 
155 } // end namespace kaco
This class implements the CanOpen SDO protocol.
Definition: sdo.h:58
SDO(Core &core)
Constructor.
Definition: sdo.cpp:45
void download(uint8_t node_id, uint16_t index, uint8_t subindex, uint32_t size, const std::vector< uint8_t > &bytes)
SDO download: Write value into remote device's object dictionary.
Definition: sdo.cpp:50
This struct contains the response of a SDO request. Note that there are two types of response - segme...
Definition: sdo_response.h:43
SDOResponse send_sdo_and_wait(uint8_t command, uint8_t node_id, uint16_t index, uint8_t subindex, const std::array< uint8_t, 4 > &data)
Sends an SDO message and waits for the response.
Definition: sdo.cpp:178
This class implements the Core of KaCanOpen It communicates with the CAN driver, sends CAN messages a...
Definition: core.h:59
void process_incoming_message(const Message &message)
Process incoming SDO message.
Definition: sdo.cpp:156
This struct represents a CANOpen message.
Definition: message.h:39
std::vector< uint8_t > upload(uint8_t node_id, uint16_t index, uint8_t subindex)
SDO download: Get value from remote device's object dictionary.
Definition: sdo.cpp:84
std::function< void(SDOResponse) > SDOReceivedCallback
Type of a sdo message receiver function Important: Never call send_sdo_and_wait or process_incoming_m...
Definition: sdo.h:65