From 604fa25bef7f1f6b2c73322558850ce92d627b43 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Mon, 14 Aug 2023 18:58:34 -0700 Subject: [PATCH 1/4] Add comDriver type selection --- .../cookiecutter.json | 4 ++- .../{{cookiecutter.deployment_name}}/Main.cpp | 27 ++++++++++++++++++- .../Top/CMakeLists.txt | 6 +++++ .../Top/instances.fpp | 10 ++++++- ...{cookiecutter.deployment_name}}Packets.xml | 4 +++ ...cookiecutter.deployment_name}}Topology.cpp | 25 +++++++++++++++-- ...cookiecutter.deployment_name}}Topology.hpp | 2 +- ...iecutter.deployment_name}}TopologyDefs.hpp | 12 ++++++--- 8 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/cookiecutter.json b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/cookiecutter.json index 0971374a..08967e38 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/cookiecutter.json +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/cookiecutter.json @@ -1,7 +1,9 @@ { "deployment_name": "MyDeployment", + "com_driver_type": ["TcpClient", "TcpServer", "UART"], "__deployment_name_upper": "{{cookiecutter.deployment_name.upper()}}", "__prompts__": { - "deployment_name": "Deployment name" + "deployment_name": "Deployment name", + "com_driver_type": "Select communication driver type" } } diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp index 445819a5..ac03cecf 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp @@ -20,7 +20,11 @@ * @param app: name of application */ void print_usage(const char* app) { +{%- if cookiecutter.com_driver_type == "UART" %} + (void)printf("Usage: ./%s [options]\n-b\tBaud rate\n-d\tUART Device\n", app); +{%- else %} (void)printf("Usage: ./%s [options]\n-a\thostname/IP address\n-p\tport_number\n", app); +{%- endif %} } /** @@ -46,13 +50,28 @@ static void signalHandler(int signum) { * @return: 0 on success, something else on failure */ int main(int argc, char* argv[]) { - U32 port_number = 0; I32 option = 0; +{%- if cookiecutter.com_driver_type == "UART" %} + char* uart_device = nullptr; + U32 baud_rate = 0; +{%- else %} char* hostname = nullptr; + U32 port_number = 0; +{%- endif %} // Loop while reading the getopt supplied options while ((option = getopt(argc, argv, "hp:a:")) != -1) { switch (option) { +{%- if cookiecutter.com_driver_type == "UART" %} + // Handle the -b baud rate argument + case 'b': + baud_rate = static_cast(atoi(optarg)); + break; + // Handle the -p port number argument + case 'd': + uart_device = optarg; + break; +{%- else %} // Handle the -a argument for address/hostname case 'a': hostname = optarg; @@ -61,6 +80,7 @@ int main(int argc, char* argv[]) { case 'p': port_number = static_cast(atoi(optarg)); break; +{%- endif %} // Cascade intended: help output case 'h': // Cascade intended: help output @@ -73,8 +93,13 @@ int main(int argc, char* argv[]) { } // Object for communicating state to the reference topology {{cookiecutter.deployment_name}}::TopologyState inputs; +{%- if cookiecutter.com_driver_type == "UART" %} + inputs.baudRate = baud_rate; + inputs.uartDevice = uart_device; +{%- else %} inputs.hostname = hostname; inputs.port = port_number; +{%- endif %} // Setup program shutdown via Ctrl-C signal(SIGINT, signalHandler); diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/CMakeLists.txt b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/CMakeLists.txt index dc6e5d15..6e6e44e2 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/CMakeLists.txt +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/CMakeLists.txt @@ -16,7 +16,13 @@ set(MOD_DEPS Svc/LinuxTime # Communication Implementations Drv/Udp +{%- if cookiecutter.com_driver_type == "TcpClient" %} Drv/TcpClient +{%- elif cookiecutter.com_driver_type == "TcpServer" %} + Drv/TcpServer +{%- elif cookiecutter.com_driver_type == "UART" %} + Drv/LinuxUartDriver +{%- endif %} ) register_fprime_module() diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/instances.fpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/instances.fpp index 00f7acd6..c724e690 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/instances.fpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/instances.fpp @@ -98,11 +98,19 @@ module {{cookiecutter.deployment_name}} { # Passive component instances # ---------------------------------------------------------------------- - @ Communications driver. May be swapped with other comm drivers like UART + @ Communications driver. May be swapped with other com drivers like UART or TCP +{%- if cookiecutter.com_driver_type == "UART" %} + instance comDriver: Drv.LinuxUartDriver base id 0x4000 +{%- else %} @ Note: Here we have TCP reliable uplink and UDP (low latency) downlink instance comDriver: Drv.ByteStreamDriverModel base id 0x4000 \ +{%- if cookiecutter.com_driver_type == "TcpServer" %} + type "Drv::TcpServer" \ # type specified to select implementor of ByteStreamDriverModel + at "../../Drv/TcpServer/TcpServer.hpp" # location of above implementor must also be specified +{%- elif cookiecutter.com_driver_type == "TcpClient" %} type "Drv::TcpClient" \ # type specified to select implementor of ByteStreamDriverModel at "../../Drv/TcpClient/TcpClient.hpp" # location of above implementor must also be specified +{%- endif -%}{% endif %} instance framer: Svc.Framer base id 0x4100 diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml index c07c4dcd..25c73ccf 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml @@ -44,6 +44,10 @@ +{%- if cookiecutter.com_driver_type == "UART" %} + + +{%- endif %} diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp index 87c0a385..cc2b58ef 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp @@ -122,7 +122,7 @@ void configureTopology() { deframer.setup(deframing); // Note: Uncomment when using Svc:TlmPacketizer - //tlmSend.setPacketList({{cookiecutter.deployment_name}}PacketsPkts, {{cookiecutter.deployment_name}}PacketsIgnore, 1); + // tlmSend.setPacketList({{cookiecutter.deployment_name}}PacketsPkts, {{cookiecutter.deployment_name}}PacketsIgnore, 1); // Events (highest-priority) configurationTable.entries[0] = {.depth = 100, .priority = 0}; @@ -151,13 +151,29 @@ void setupTopology(const TopologyState& state) { // loadParameters(); // Autocoded task kick-off (active components). Function provided by autocoder. startTasks(state); - // Initialize socket client communication if and only if there is a valid specification +{%- if (cookiecutter.com_driver_type in ["TcpServer", "TcpClient"]) %} + // Initialize socket communication if and only if there is a valid specification if (state.hostname != nullptr && state.port != 0) { Os::TaskString name("ReceiveTask"); // Uplink is configured for receive so a socket task is started comDriver.configure(state.hostname, state.port); +{%- if (cookiecutter.com_driver_type == "TcpServer") %} + comDriver.startup(); +{%- endif %} comDriver.startSocketTask(name, true, COMM_PRIORITY, Default::STACK_SIZE); } +{%- elif cookiecutter.com_driver_type == "UART" %} + if (state.uartDevice != nullptr) { + Os::TaskString name("ReceiveTask"); + // Uplink is configured for receive so a socket task is started + if (comDriver.open(state.uartDevice, static_cast(state.baudRate), + Drv::LinuxUartDriver::NO_FLOW, Drv::LinuxUartDriver::PARITY_NONE, 1024)) { + comDriver.startReadThread(COMM_PRIORITY, Default::STACK_SIZE); + } else { + printf("Failed to open UART device %s at baud rate %" PRIu32 "\n", state.uartDevice, state.baudRate); + } + } +{%- endif %} } // Variables used for cycle simulation @@ -192,8 +208,13 @@ void teardownTopology(const TopologyState& state) { freeThreads(state); // Other task clean-up. +{%- if cookiecutter.com_driver_type == "UART" %} + comDriver.quitReadThread(); + (void)comDriver.join(nullptr); +{%- else %} comDriver.stopSocketTask(); (void)comDriver.joinSocketTask(nullptr); +{%- endif %} // Resource deallocation cmdSeq.deallocateBuffer(mallocator); diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.hpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.hpp index b6aaa894..37ff4e7e 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.hpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.hpp @@ -34,7 +34,7 @@ namespace {{cookiecutter.deployment_name}} { * The state argument carries command line inputs used to setup the topology. For an explanation of the required type * {{cookiecutter.deployment_name}}::TopologyState see: {{cookiecutter.deployment_name}}TopologyDefs.hpp. * - * \param state: object shuttling CLI arguments (hostname, port) needed to construct the topology + * \param state: object shuttling CLI arguments (e.g. hostname/port, or UART baudrate) needed to construct the topology */ void setupTopology(const TopologyState& state); diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp index 3cce468b..c8089035 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp @@ -19,13 +19,17 @@ namespace {{cookiecutter.deployment_name}} { * \brief required type definition to carry state * * The topology autocoder requires an object that carries state with the name `{{cookiecutter.deployment_name}}::TopologyState`. Only the type - * definition is required by the autocoder and the contents of this object are otherwise opaque to the autocoder. The - * contents are entirely up to the definition of the project. This reference application specifies hostname and port - * fields, which are derived by command line inputs. + * definition is required by the autocoder and the contents of this object are otherwise opaque to the autocoder. The contents are entirely up + * to the definition of the project. Here, they are derived from command line inputs. */ struct TopologyState { +{%- if (cookiecutter.com_driver_type == "UART") %} + const char* uartDevice; + PlatformUIntType baudRate; +{%- else %} const char* hostname; - U32 port; + PlatformUIntType port; +{%- endif %} }; /** From 71ed416755f4b434d1eac05ce3b350938a030ca0 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 15 Aug 2023 09:14:06 -0700 Subject: [PATCH 2/4] fix getopt --- .../{{cookiecutter.deployment_name}}/Main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp index ac03cecf..31678dd7 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp @@ -60,14 +60,18 @@ int main(int argc, char* argv[]) { {%- endif %} // Loop while reading the getopt supplied options +{%- if cookiecutter.com_driver_type == "UART" %} + while ((option = getopt(argc, argv, "hb:d:")) != -1) { +{%- else %} while ((option = getopt(argc, argv, "hp:a:")) != -1) { +{%- endif %} switch (option) { {%- if cookiecutter.com_driver_type == "UART" %} // Handle the -b baud rate argument case 'b': baud_rate = static_cast(atoi(optarg)); break; - // Handle the -p port number argument + // Handle the -d device argument case 'd': uart_device = optarg; break; From 1730ed9642465731c4c8bd49a0072a1d12427b01 Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Tue, 15 Aug 2023 09:36:16 -0700 Subject: [PATCH 3/4] spelling --- .github/actions/spelling/expect.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 49d49ee2..c6372f92 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -1,6 +1,7 @@ argc atoi bak +baudrate Callee cargs CDH @@ -168,6 +169,7 @@ Pkts Popen postprocessed printf +PRIu proj ptf py @@ -252,6 +254,7 @@ typehints typename tz tzinfo +uart Udp uint Uncomment From e0837175e1d6ce5eef6a0ea4b6c0411d308f8d6f Mon Sep 17 00:00:00 2001 From: thomas-bc Date: Wed, 16 Aug 2023 11:19:58 -0700 Subject: [PATCH 4/4] review changes --- .../{{cookiecutter.deployment_name}}/Main.cpp | 8 ++++---- .../Top/{{cookiecutter.deployment_name}}Packets.xml | 8 ++++---- .../Top/{{cookiecutter.deployment_name}}Topology.cpp | 2 +- .../Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp index 31678dd7..53576bf1 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Main.cpp @@ -52,11 +52,11 @@ static void signalHandler(int signum) { int main(int argc, char* argv[]) { I32 option = 0; {%- if cookiecutter.com_driver_type == "UART" %} - char* uart_device = nullptr; + CHAR* uart_device = nullptr; U32 baud_rate = 0; {%- else %} - char* hostname = nullptr; - U32 port_number = 0; + CHAR* hostname = nullptr; + U16 port_number = 0; {%- endif %} // Loop while reading the getopt supplied options @@ -82,7 +82,7 @@ int main(int argc, char* argv[]) { break; // Handle the -p port number argument case 'p': - port_number = static_cast(atoi(optarg)); + port_number = static_cast(atoi(optarg)); break; {%- endif %} // Cascade intended: help output diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml index 25c73ccf..77bfc1e4 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Packets.xml @@ -44,10 +44,6 @@ -{%- if cookiecutter.com_driver_type == "UART" %} - - -{%- endif %} @@ -86,5 +82,9 @@ +{%- if cookiecutter.com_driver_type == "UART" %} + + +{%- endif %} diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp index cc2b58ef..d8ff602a 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}Topology.cpp @@ -167,7 +167,7 @@ void setupTopology(const TopologyState& state) { Os::TaskString name("ReceiveTask"); // Uplink is configured for receive so a socket task is started if (comDriver.open(state.uartDevice, static_cast(state.baudRate), - Drv::LinuxUartDriver::NO_FLOW, Drv::LinuxUartDriver::PARITY_NONE, 1024)) { + Drv::LinuxUartDriver::NO_FLOW, Drv::LinuxUartDriver::PARITY_NONE, Svc::DeframerCfg::RING_BUFFER_SIZE)) { comDriver.startReadThread(COMM_PRIORITY, Default::STACK_SIZE); } else { printf("Failed to open UART device %s at baud rate %" PRIu32 "\n", state.uartDevice, state.baudRate); diff --git a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp index c8089035..66d25b58 100644 --- a/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp +++ b/src/fprime/cookiecutter_templates/cookiecutter-fprime-deployment/{{cookiecutter.deployment_name}}/Top/{{cookiecutter.deployment_name}}TopologyDefs.hpp @@ -24,11 +24,11 @@ namespace {{cookiecutter.deployment_name}} { */ struct TopologyState { {%- if (cookiecutter.com_driver_type == "UART") %} - const char* uartDevice; - PlatformUIntType baudRate; + const CHAR* uartDevice; + U32 baudRate; {%- else %} - const char* hostname; - PlatformUIntType port; + const CHAR* hostname; + U16 port; {%- endif %} };