Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UAVCAN UAVCAN_Subscriber
libuavcan_drivers/linux/apps/test_file_server.cpp@0:dfe6edabb8ec, 2018-04-14 (annotated)
- Committer:
- RuslanUrya
- Date:
- Sat Apr 14 10:25:32 2018 +0000
- Revision:
- 0:dfe6edabb8ec
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |