From 0a3e354c3d81866e1a755367ab5592b3ced868bb Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 23 Sep 2020 16:07:53 -0400 Subject: Update to match current binding expectations Changes: - Reworked header, footer, message structure definition, etc. to match the contents of the current generated files in the binding. - To enable the above, added some code to derive the API name for the app controller CAPI macro from the name given for the message set in the JSON. The name is lower-cased and spaces converted to dashes, this matches all the examples in the generated files in the binding. - Added logic to default message length to 8 if not set in JSON, this is required to match explicit checks and signal JSON changes in the binding. - Replaced is_bigendian and is_signed fields with new sign and bit_sign_position fields in JSON parsing and generated signal output. The sign field value enum has been copied from the binding to provide a reference for the values. - Update per-signal flags generation, to enable this updated flag #defines from binding's current can-message.hpp. Added a comment to document which flags are known to be used. - Removed "package" from "all" target in Makefile, as it is attached to widget packaging rules that are not applicable for the generator, which is built for host or toolchain usage. - Removed unused src/main.hpp header to avoid confusion. Bug-AGL: SPEC-3551 Signed-off-by: Scott Murray Change-Id: I9ef3df0ebcfbddc23c789b50e1575fc42031970d --- Makefile | 2 +- src/main.cpp | 152 ++++++++++++++++++++++---------------------------- src/main.hpp | 55 ------------------ src/openxc/signal.cpp | 23 ++++---- src/openxc/signal.hpp | 25 ++++++--- 5 files changed, 97 insertions(+), 160 deletions(-) delete mode 100644 src/main.hpp diff --git a/Makefile b/Makefile index 658ef32..35eed16 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ BUILD_DIR := build .PHONY: all clean mrproper ${BUILD_DIR}/Makefile -all: build package +all: build clean: @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean) || echo Nothing to clean diff --git a/src/main.cpp b/src/main.cpp index c001df3..660c347 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,18 +35,40 @@ #define EXIT_PROGRAM_ERROR 3 -/** +/* * FLAGS + * + * Taken from include/low-can/can-message.hpp in agl-service-can-low-level. + * The flags values in the generated message_definition_t definitions needs to + * match usage of these flags in the binding, e.g. in the various member + * functions in low-can-binding/can/message-definition.cpp. + * + * ATM the only flags known to be used are: + * + * CAN_PROTOCOL_WITH_FD_FRAME + * J1939_PROTOCOL + * ISOTP_PROTOCOL + * BYTE_FRAME_IS_BIG_ENDIAN + * + * Note that for BYTE_FRAME_IS_BIG_ENDIAN, even though it is referenced in + * message-definition.cpp, the member function that does so seems currently + * unused, so it is not clear what the intended usage actually is. + * The JSON parser for CAN messages would likely need an additional field + * added to allow setting it, for now that is being left for a future update. */ -#define INVALID_FLAG 0x0001 -#define STANDARD_ID 0x0002 -#define EXTENDED_ID 0x0004 -#define BCM_PROTOCOL 0x0008 -#define J1939_PROTOCOL 0x0010 -#define J1939_ADDR_CLAIM_PROTOCOL 0x0020 -#define ISOTP_PROTOCOL 0x0040 -#define FD_FRAME 0x0800 +#define CAN_PROTOCOL 0x0001 +#define CAN_PROTOCOL_WITH_FD_FRAME 0x0002 +#define J1939_ADDR_CLAIM_PROTOCOL 0x0004 +#define J1939_PROTOCOL 0x0008 +#define ISOTP_PROTOCOL 0x0010 +#define ISOTP_SEND 0x0020 +#define ISOTP_RECEIVE 0x0040 +#define BYTE_FRAME_IS_BIG_ENDIAN 0x0080 +#define BIT_POSITION_REVERSED 0x0100 +#define CONTINENTAL_BIT_POSITION 0x0200 +#define INVALID_FLAG 0x8000 + #define VERSION_LOW_CAN "2.0" @@ -128,17 +150,17 @@ std::ostream& operator<<(std::ostream& o, const generator>& v) template <> std::ostream& operator<<(std::ostream& o, const generator& v) { - o << v.line_prefix_ - << "{std::make_shared(message_set_t{" + o << "std::shared_ptr cms = " + << "std::make_shared(message_set_t{" << "0," << gen(v.v_.name()) << ",\n" - << "\t\t\t{ // beginning message_definition_ vector\n" - << gen(v.v_.messages(), "\t\t\t") - << "\n\t\t}, // end message_definition vector\n" - << "\t\t\t{ // beginning diagnostic_messages_ vector\n" - << gen(v.v_.diagnostic_messages(),"\t\t\t") << "\n" - << "\t\t\t} // end diagnostic_messages_ vector\n" - << "\t\t})} // end message_set entry\n"; + << "\t{ // beginning message_definition_ vector\n" + << gen(v.v_.messages(), "\t") + << "\t}, // end message_definition vector\n" + << "\t{ // beginning diagnostic_messages_ vector\n" + << gen(v.v_.diagnostic_messages(),"\t") << "\n" + << "\t} // end diagnostic_messages_ vector\n" + << "}); // end message_set entry\n"; return o; } @@ -192,8 +214,8 @@ std::ostream& operator<<(std::ostream& o, const generator& v) } std::string multi = "std::make_pair(" + multi_first + ", " + std::to_string(v.v_.multiplex().second) + ")"; o << v.line_prefix_ << '\t' << multi << ",// multiplex\n" - << v.line_prefix_ << '\t' << gen(v.v_.is_big_endian()) << ",// is_big_endian\n" - << v.line_prefix_ << '\t' << gen(v.v_.is_signed()) << ",// is_signed\n" + << v.line_prefix_ << "\tstatic_cast(" << gen(v.v_.sign()) << "),// signed\n" + << v.line_prefix_ << '\t' << gen(v.v_.bit_sign_position()) << ",// bit_sign_position\n" << v.line_prefix_ << "\t" << gen(v.v_.unit()) << "// unit\n" << v.line_prefix_ << "})}"; return o; @@ -207,11 +229,11 @@ std::ostream& operator<<(std::ostream& o, const generator& << gen(v.v_.bus()) << "," << v.v_.id() << "," << "\"" << v.v_.name() << "\"," - << v.v_.length() << ","; + << (v.v_.length() != 0 ? v.v_.length() : 8) << ","; uint32_t flags = 0; if(v.v_.is_fd()) { - flags = flags|FD_FRAME; + flags = flags|CAN_PROTOCOL_WITH_FD_FRAME; } if(v.v_.is_j1939()) @@ -224,37 +246,22 @@ std::ostream& operator<<(std::ostream& o, const generator& flags = flags|ISOTP_PROTOCOL; } - if(v.v_.is_extended()) - { - flags = flags|EXTENDED_ID; - } - else - { - flags = flags|STANDARD_ID; - } - - - if(v.v_.is_fd()) - { - flags = flags|FD_FRAME; - } - o << gen(flags) << ","; o << "frequency_clock_t(" << gen(v.v_.max_frequency()) << ")," << gen(v.v_.force_send_changed()) << ","; std::uint32_t index = 0; - o << "\n\t\t\t\t\t{ // beginning signals vector\n"; + o << "\n\t\t\t{ // beginning signals vector\n"; std::uint32_t signal_count = (uint32_t)v.v_.signals().size(); for(const openxc::signal& s : v.v_.signals()) { - o << gen(s, index,"\t\t\t\t\t\t"); + o << gen(s, index,"\t\t\t\t"); if (signal_count > 1) o << ','; --signal_count; o << '\n'; } - o << "\t\t\t\t\t} // end signals vector\n" - << "\t\t\t\t})} // end message_definition entry\n"; + o << "\t\t\t} // end signals vector\n" + << "\t\t})} // end message_definition entry\n"; return o; } @@ -283,56 +290,33 @@ std::ostream& operator<<(std::ostream& o, const generator\n" + << "#include \n" + << "#include \n\n"; if (header.size()) out << header << "\n"; - out << "application_t::application_t()\n" - << " : can_bus_manager_{utils::config_parser_t{\"/etc/dev-mapping.conf\"}}\n" - << " , message_set_{\n" + out << "extern \"C\" {\n" + << "CTLP_CAPI_REGISTER(\"" << capi_name << "\");\n" + << "\n" << gen(message_set, "\t\t") - << "\t} // end message_set vector\n" - << "{\n" - << " for(std::shared_ptr cms: message_set_)\n" - << " {\n" - << " std::vector> messages_definition = cms->get_messages_definition();\n" - << " for(std::shared_ptr cmd : messages_definition)\n" - << " {\n" - << " cmd->set_parent(cms);\n" - << " std::vector> signals = cmd->get_signals();\n" - << " for(std::shared_ptr sig: signals)\n" - << " {\n" - << " sig->set_parent(cmd);\n" - << " }\n" - << " }\n\n" - << " std::vector> diagnostic_messages = cms->get_diagnostic_messages();\n" - << " for(std::shared_ptr dm : diagnostic_messages)\n" - << " {\n" - << " dm->set_parent(cms);\n" - << " }\n" - << " }\n" - << " }\n\n" - << "const std::string application_t::get_diagnostic_bus() const\n" - << "{\n"; - - std::string active_bus = ""; - for (const auto& d : message_set.diagnostic_messages()) - { - if (d.bus().size() == 0) std::cerr << "ERROR: The bus name should be set for each diagnostic message." << std::endl; - if (active_bus.size() == 0) active_bus = d.bus(); - if (active_bus != d.bus()) std::cerr << "ERROR: The bus name should be the same for each diagnostic message." << std::endl; - } - - out << "\treturn " << gen(active_bus) << ";\n" - << "}\n\n"; - + << "\n" + << "CTLP_ONLOAD(plugin, handle) {\n" + << "\tafb_api_t api = (afb_api_t) plugin->api;\n" + << "\tCtlConfigT* CtlConfig = (CtlConfigT*) afb_api_get_userdata(api);\n" + << "\tapplication_t* app = (application_t*) getExternalData(CtlConfig);\n" + << "\n" + << "\treturn app->add_message_set(cms);\n" + << "}\n\n\n}\n"; out << decoder_t::apply_patch(); - - out << footer << std::endl; } diff --git a/src/main.hpp b/src/main.hpp deleted file mode 100644 index cf08e1a..0000000 --- a/src/main.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2015, 20"IoT.bzh" - * Author "Romain Forlot" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -struct afb_config_list { - struct afb_config_list *next; - char *value; -}; - -// main config structure -struct afb_config { - char *console; // console device name (can be a file or a tty) - char *rootdir; // base dir for files - char *roothttp; // directory for http files - char *rootbase; // Angular HTML5 base URL - char *rootapi; // Base URL for REST APIs - char *workdir; // where to run the program - char *uploaddir; // where to store transient files - char *token; // initial authentication token [default NULL no session] - - struct afb_config_list *aliases; - struct afb_config_list *dbus_clients; - struct afb_config_list *dbus_servers; - struct afb_config_list *ws_clients; - struct afb_config_list *ws_servers; - struct afb_config_list *so_bindings; - struct afb_config_list *ldpaths; - - char **exec; - - int httpdPort; - int background; // run in backround mode - int cacheTimeout; - int apiTimeout; - int cntxTimeout; // Client Session Context timeout - int nbSessionMax; // max count of sessions - int mode; // mode of listening - int tracereq; - int noHttpd; -}; - -extern struct afb_config *parse_arguments(int argc, char **argv); \ No newline at end of file diff --git a/src/openxc/signal.cpp b/src/openxc/signal.cpp index e60c3ee..858f64b 100755 --- a/src/openxc/signal.cpp +++ b/src/openxc/signal.cpp @@ -88,12 +88,14 @@ namespace openxc return multiplex_; } - bool signal::is_big_endian() const{ - return is_big_endian_; + sign_t signal::sign() const + { + return sign_; } - bool signal::is_signed() const{ - return is_signed_; + std::int32_t signal::bit_sign_position() const + { + return bit_sign_position_; } std::string signal::unit() const{ @@ -134,11 +136,10 @@ namespace openxc { multiplex_ = std::make_pair(false,0); } - is_big_endian_ = j.count("is_big_endian") ? j["is_big_endian"].get() : false; - is_signed_ = j.count("is_signed") ? j["is_signed"].get() : false; - unit_ = j.count("unit") ? j["unit"].get() : ""; - + bit_sign_position_ = j.count("bit_sign_position") ? j["bit_sign_position"].get() : -1; + sign_ = j.count("signed") ? (sign_t) j["signed"].get() : sign_t::UNSIGNED; + unit_ = j.count("unit") ? j["unit"].get() : ""; if (j.count("states")) { @@ -185,10 +186,8 @@ namespace openxc j["multiplex"] = multi; - - - j["is_big_endian"] = is_big_endian_; - j["is_signed"] = is_signed_; + j["bit_sign_position"] = bit_sign_position_; + j["signed"] = static_cast(sign_); j["unit"] = unit_; return j; } diff --git a/src/openxc/signal.hpp b/src/openxc/signal.hpp index 750926b..ce0a2e1 100755 --- a/src/openxc/signal.hpp +++ b/src/openxc/signal.hpp @@ -8,27 +8,36 @@ namespace openxc { + enum sign_t + { + UNSIGNED = 0, + SIGN_BIT = 1, + ONES_COMPLEMENT = 2, + TWOS_COMPLEMENT = 3, + SIGN_BIT_EXTERN = 4 + }; + class signal { private: std::string id_; std::string generic_name_; - std::uint32_t bit_position_; - std::uint32_t bit_size_; + std::uint32_t bit_position_; + std::uint32_t bit_size_; float factor_; float offset_; std::string decoder_; bool ignore_; bool enabled_; - std::map> states_; + std::map> states_; float max_frequency_; bool send_same_; bool force_send_changed_; bool writable_; std::string encoder_; - std::pair multiplex_; - bool is_big_endian_; - bool is_signed_; + std::pair multiplex_; + sign_t sign_; + std::int32_t bit_sign_position_; std::string unit_; public: @@ -49,8 +58,8 @@ namespace openxc bool writable() const; std::string encoder() const; std::pair multiplex() const; - bool is_big_endian() const; - bool is_signed() const; + sign_t sign() const; + std::int32_t bit_sign_position() const; std::string unit() const; void from_json(const nlohmann::json& j); -- cgit 1.2.3-korg