Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Committer:
RuslanUrya
Date:
Sat Apr 14 10:25:32 2018 +0000
Revision:
0:dfe6edabb8ec
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RuslanUrya 0:dfe6edabb8ec 1 /*
RuslanUrya 0:dfe6edabb8ec 2 * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
RuslanUrya 0:dfe6edabb8ec 3 */
RuslanUrya 0:dfe6edabb8ec 4
RuslanUrya 0:dfe6edabb8ec 5 #include <iostream>
RuslanUrya 0:dfe6edabb8ec 6 #include <string>
RuslanUrya 0:dfe6edabb8ec 7 #include <cstdlib>
RuslanUrya 0:dfe6edabb8ec 8 #include <cstdio>
RuslanUrya 0:dfe6edabb8ec 9 #include <sys/types.h>
RuslanUrya 0:dfe6edabb8ec 10 #include <unistd.h>
RuslanUrya 0:dfe6edabb8ec 11 #include "debug.hpp"
RuslanUrya 0:dfe6edabb8ec 12 // UAVCAN
RuslanUrya 0:dfe6edabb8ec 13 #include <uavcan/protocol/file_server.hpp>
RuslanUrya 0:dfe6edabb8ec 14 // UAVCAN Linux drivers
RuslanUrya 0:dfe6edabb8ec 15 #include <uavcan_linux/uavcan_linux.hpp>
RuslanUrya 0:dfe6edabb8ec 16 // UAVCAN POSIX drivers
RuslanUrya 0:dfe6edabb8ec 17 #include <uavcan_posix/basic_file_server_backend.hpp>
RuslanUrya 0:dfe6edabb8ec 18 #include <uavcan_posix/firmware_version_checker.hpp> // Compilability test
RuslanUrya 0:dfe6edabb8ec 19
RuslanUrya 0:dfe6edabb8ec 20 namespace
RuslanUrya 0:dfe6edabb8ec 21 {
RuslanUrya 0:dfe6edabb8ec 22
RuslanUrya 0:dfe6edabb8ec 23 uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, uavcan::NodeID nid, const std::string& name)
RuslanUrya 0:dfe6edabb8ec 24 {
RuslanUrya 0:dfe6edabb8ec 25 auto node = uavcan_linux::makeNode(ifaces);
RuslanUrya 0:dfe6edabb8ec 26
RuslanUrya 0:dfe6edabb8ec 27 node->setNodeID(nid);
RuslanUrya 0:dfe6edabb8ec 28 node->setName(name.c_str());
RuslanUrya 0:dfe6edabb8ec 29 node->getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
RuslanUrya 0:dfe6edabb8ec 30
RuslanUrya 0:dfe6edabb8ec 31 {
RuslanUrya 0:dfe6edabb8ec 32 const auto app_id = uavcan_linux::makeApplicationID(uavcan_linux::MachineIDReader().read(), name, nid.get());
RuslanUrya 0:dfe6edabb8ec 33
RuslanUrya 0:dfe6edabb8ec 34 uavcan::protocol::HardwareVersion hwver;
RuslanUrya 0:dfe6edabb8ec 35 std::copy(app_id.begin(), app_id.end(), hwver.unique_id.begin());
RuslanUrya 0:dfe6edabb8ec 36 std::cout << hwver << std::endl;
RuslanUrya 0:dfe6edabb8ec 37
RuslanUrya 0:dfe6edabb8ec 38 node->setHardwareVersion(hwver);
RuslanUrya 0:dfe6edabb8ec 39 }
RuslanUrya 0:dfe6edabb8ec 40
RuslanUrya 0:dfe6edabb8ec 41 const int start_res = node->start();
RuslanUrya 0:dfe6edabb8ec 42 ENFORCE(0 == start_res);
RuslanUrya 0:dfe6edabb8ec 43
RuslanUrya 0:dfe6edabb8ec 44 node->setModeOperational();
RuslanUrya 0:dfe6edabb8ec 45
RuslanUrya 0:dfe6edabb8ec 46 return node;
RuslanUrya 0:dfe6edabb8ec 47 }
RuslanUrya 0:dfe6edabb8ec 48
RuslanUrya 0:dfe6edabb8ec 49 void runForever(const uavcan_linux::NodePtr& node)
RuslanUrya 0:dfe6edabb8ec 50 {
RuslanUrya 0:dfe6edabb8ec 51 uavcan_posix::BasicFileServerBackend backend(*node);
RuslanUrya 0:dfe6edabb8ec 52
RuslanUrya 0:dfe6edabb8ec 53 uavcan::FileServer server(*node, backend);
RuslanUrya 0:dfe6edabb8ec 54
RuslanUrya 0:dfe6edabb8ec 55 const int server_init_res = server.start();
RuslanUrya 0:dfe6edabb8ec 56 if (server_init_res < 0)
RuslanUrya 0:dfe6edabb8ec 57 {
RuslanUrya 0:dfe6edabb8ec 58 throw std::runtime_error("Failed to start the server; error " + std::to_string(server_init_res));
RuslanUrya 0:dfe6edabb8ec 59 }
RuslanUrya 0:dfe6edabb8ec 60
RuslanUrya 0:dfe6edabb8ec 61 while (true)
RuslanUrya 0:dfe6edabb8ec 62 {
RuslanUrya 0:dfe6edabb8ec 63 const int res = node->spin(uavcan::MonotonicDuration::fromMSec(100));
RuslanUrya 0:dfe6edabb8ec 64 if (res < 0)
RuslanUrya 0:dfe6edabb8ec 65 {
RuslanUrya 0:dfe6edabb8ec 66 std::cerr << "Spin error: " << res << std::endl;
RuslanUrya 0:dfe6edabb8ec 67 }
RuslanUrya 0:dfe6edabb8ec 68 }
RuslanUrya 0:dfe6edabb8ec 69 }
RuslanUrya 0:dfe6edabb8ec 70
RuslanUrya 0:dfe6edabb8ec 71 struct Options
RuslanUrya 0:dfe6edabb8ec 72 {
RuslanUrya 0:dfe6edabb8ec 73 uavcan::NodeID node_id;
RuslanUrya 0:dfe6edabb8ec 74 std::vector<std::string> ifaces;
RuslanUrya 0:dfe6edabb8ec 75 };
RuslanUrya 0:dfe6edabb8ec 76
RuslanUrya 0:dfe6edabb8ec 77 Options parseOptions(int argc, const char** argv)
RuslanUrya 0:dfe6edabb8ec 78 {
RuslanUrya 0:dfe6edabb8ec 79 const char* const executable_name = *argv++;
RuslanUrya 0:dfe6edabb8ec 80 argc--;
RuslanUrya 0:dfe6edabb8ec 81
RuslanUrya 0:dfe6edabb8ec 82 const auto enforce = [executable_name](bool condition, const char* error_text) {
RuslanUrya 0:dfe6edabb8ec 83 if (!condition)
RuslanUrya 0:dfe6edabb8ec 84 {
RuslanUrya 0:dfe6edabb8ec 85 std::cerr << error_text << "\n"
RuslanUrya 0:dfe6edabb8ec 86 << "Usage:\n\t"
RuslanUrya 0:dfe6edabb8ec 87 << executable_name
RuslanUrya 0:dfe6edabb8ec 88 << " <node-id> <can-iface-name-1> [can-iface-name-N...]"
RuslanUrya 0:dfe6edabb8ec 89 << std::endl;
RuslanUrya 0:dfe6edabb8ec 90 std::exit(1);
RuslanUrya 0:dfe6edabb8ec 91 }
RuslanUrya 0:dfe6edabb8ec 92 };
RuslanUrya 0:dfe6edabb8ec 93
RuslanUrya 0:dfe6edabb8ec 94 enforce(argc >= 2, "Not enough arguments");
RuslanUrya 0:dfe6edabb8ec 95
RuslanUrya 0:dfe6edabb8ec 96 /*
RuslanUrya 0:dfe6edabb8ec 97 * Node ID is always at the first position
RuslanUrya 0:dfe6edabb8ec 98 */
RuslanUrya 0:dfe6edabb8ec 99 argc--;
RuslanUrya 0:dfe6edabb8ec 100 const int node_id = std::stoi(*argv++);
RuslanUrya 0:dfe6edabb8ec 101 enforce(node_id >= 1 && node_id <= 127, "Invalid node ID");
RuslanUrya 0:dfe6edabb8ec 102
RuslanUrya 0:dfe6edabb8ec 103 Options out;
RuslanUrya 0:dfe6edabb8ec 104 out.node_id = uavcan::NodeID(std::uint8_t(node_id));
RuslanUrya 0:dfe6edabb8ec 105
RuslanUrya 0:dfe6edabb8ec 106 while (argc --> 0)
RuslanUrya 0:dfe6edabb8ec 107 {
RuslanUrya 0:dfe6edabb8ec 108 const std::string token(*argv++);
RuslanUrya 0:dfe6edabb8ec 109
RuslanUrya 0:dfe6edabb8ec 110 if (token[0] != '-')
RuslanUrya 0:dfe6edabb8ec 111 {
RuslanUrya 0:dfe6edabb8ec 112 out.ifaces.push_back(token);
RuslanUrya 0:dfe6edabb8ec 113 }
RuslanUrya 0:dfe6edabb8ec 114 else
RuslanUrya 0:dfe6edabb8ec 115 {
RuslanUrya 0:dfe6edabb8ec 116 enforce(false, "Unexpected argument");
RuslanUrya 0:dfe6edabb8ec 117 }
RuslanUrya 0:dfe6edabb8ec 118 }
RuslanUrya 0:dfe6edabb8ec 119
RuslanUrya 0:dfe6edabb8ec 120 return out;
RuslanUrya 0:dfe6edabb8ec 121 }
RuslanUrya 0:dfe6edabb8ec 122
RuslanUrya 0:dfe6edabb8ec 123 }
RuslanUrya 0:dfe6edabb8ec 124
RuslanUrya 0:dfe6edabb8ec 125 int main(int argc, const char** argv)
RuslanUrya 0:dfe6edabb8ec 126 {
RuslanUrya 0:dfe6edabb8ec 127 try
RuslanUrya 0:dfe6edabb8ec 128 {
RuslanUrya 0:dfe6edabb8ec 129 auto options = parseOptions(argc, argv);
RuslanUrya 0:dfe6edabb8ec 130
RuslanUrya 0:dfe6edabb8ec 131 std::cout << "Self node ID: " << int(options.node_id.get()) << "\n"
RuslanUrya 0:dfe6edabb8ec 132 "Num ifaces: " << options.ifaces.size() << "\n"
RuslanUrya 0:dfe6edabb8ec 133 #ifdef NDEBUG
RuslanUrya 0:dfe6edabb8ec 134 "Build mode: Release"
RuslanUrya 0:dfe6edabb8ec 135 #else
RuslanUrya 0:dfe6edabb8ec 136 "Build mode: Debug"
RuslanUrya 0:dfe6edabb8ec 137 #endif
RuslanUrya 0:dfe6edabb8ec 138 << std::endl;
RuslanUrya 0:dfe6edabb8ec 139
RuslanUrya 0:dfe6edabb8ec 140 auto node = initNode(options.ifaces, options.node_id, "org.uavcan.linux_test_file_server");
RuslanUrya 0:dfe6edabb8ec 141 runForever(node);
RuslanUrya 0:dfe6edabb8ec 142 return 0;
RuslanUrya 0:dfe6edabb8ec 143 }
RuslanUrya 0:dfe6edabb8ec 144 catch (const std::exception& ex)
RuslanUrya 0:dfe6edabb8ec 145 {
RuslanUrya 0:dfe6edabb8ec 146 std::cerr << "Error: " << ex.what() << std::endl;
RuslanUrya 0:dfe6edabb8ec 147 return 1;
RuslanUrya 0:dfe6edabb8ec 148 }
RuslanUrya 0:dfe6edabb8ec 149 }