X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fmain.cpp;h=660c34744f18e926651bb8946c198f1467ebd2cd;hb=HEAD;hp=0608f168a883df9f5964396be7a1d5e010b58989;hpb=9a441dad97539ec696d33eabb8ac36c222790e7f;p=src%2Flow-level-can-generator.git diff --git a/src/main.cpp b/src/main.cpp index 0608f16..660c347 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,12 +27,54 @@ #include #include #include "openxc/message_set.hpp" +#include "openxc/decoder.hpp" #define EXIT_SUCCESS 0 #define EXIT_UNKNOWN_ERROR 1 #define EXIT_COMMAND_LINE_ERROR 2 #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 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" + + +std::string VERSION_FILE = "1.0"; + template struct generator { @@ -108,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(can_message_set_t{" + o << "std::shared_ptr cms = " + << "std::make_shared(message_set_t{" << "0," << gen(v.v_.name()) << ",\n" - << "\t\t\t{ // beginning can_message_definition_ vector\n" - << gen(v.v_.messages(), "\t\t\t") - << "\n\t\t}, // end can_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 can_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; } @@ -146,22 +188,35 @@ std::ostream& operator<<(std::ostream& o, const generator std::ostream& operator<<(std::ostream& o, const generator& v) { - o << v.line_prefix_ << "{std::make_shared (can_signal_t{\n" - << v.line_prefix_ << "\t" << gen(v.v_.generic_name()) << ",\n" - << v.line_prefix_ << "\t" << v.v_.bit_position() << ",\n" - << v.line_prefix_ << "\t" << v.v_.bit_size() << ",\n" - << v.line_prefix_ << "\t" << gen(v.v_.factor()) << ",\n" - << v.line_prefix_ << "\t" << v.v_.offset() << ",\n" - << v.line_prefix_ << "\t" << "0,\n" - << v.line_prefix_ << "\t" << "0,\n" - << v.line_prefix_ << "\tfrequency_clock_t(" << gen(v.v_.max_frequency()) << "),\n" - << v.line_prefix_ << "\t" << gen(v.v_.send_same()) << ",\n" - << v.line_prefix_ << "\t" << gen(v.v_.force_send_changed()) << ",\n" - << gen(v.v_.states(), v.line_prefix_ + '\t') << ",\n" - << v.line_prefix_ << '\t' << gen(v.v_.writable()) << ",\n" - << v.line_prefix_ << '\t' << (v.v_.decoder().size() ? v.v_.decoder() : "nullptr") << ",\n" - << v.line_prefix_ << '\t' << (v.v_.encoder().size() ? v.v_.encoder() : "nullptr") << ",\n" - << v.line_prefix_ << '\t' << "false\n" + o << v.line_prefix_ << "{std::make_shared (signal_t{\n" + << v.line_prefix_ << "\t" << gen(v.v_.generic_name()) << ",// generic_name\n" + << v.line_prefix_ << "\t" << v.v_.bit_position() << ",// bit_position\n" + << v.line_prefix_ << "\t" << v.v_.bit_size() << ",// bit_size\n" + << v.line_prefix_ << "\t" << gen(v.v_.factor()) << ",// factor\n" + << v.line_prefix_ << "\t" << gen(v.v_.offset()) << ",// offset\n" + << v.line_prefix_ << "\t" << "0,// min_value\n" + << v.line_prefix_ << "\t" << "0,// max_value\n" + << v.line_prefix_ << "\tfrequency_clock_t(" << gen(v.v_.max_frequency()) << "),// frequency\n" + << v.line_prefix_ << "\t" << gen(v.v_.send_same()) << ",// send_same\n" + << v.line_prefix_ << "\t" << gen(v.v_.force_send_changed()) << ",// force_send_changed\n" + << gen(v.v_.states(), v.line_prefix_ + '\t') << ",// states\n" + << v.line_prefix_ << '\t' << gen(v.v_.writable()) << ",// writable\n" + << v.line_prefix_ << '\t' << decoder_t::add_decoder(v.v_.decoder().size() ? v.v_.decoder() : v.v_.states().size() ? "decoder_t::decode_state" : "nullptr" + , VERSION_FILE + , VERSION_LOW_CAN) << ",// decoder\n" + << v.line_prefix_ << '\t' << (v.v_.encoder().size() ? v.v_.encoder() : "nullptr") << ",// encoder\n" + << v.line_prefix_ << '\t' << "false,// received\n"; + std::string multi_first = ""; + if(v.v_.multiplex().first){ + multi_first = "true"; + }else{ + multi_first = "false"; + } + 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_ << "\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; } @@ -170,25 +225,43 @@ template <> std::ostream& operator<<(std::ostream& o, const generator& v) { o << v.line_prefix_ - << "{std::make_shared(can_message_definition_t{" + << "{std::make_shared(message_definition_t{" << gen(v.v_.bus()) << "," << v.v_.id() << "," - << v.v_.is_fd() << "," - << "can_message_format_t::STANDARD," - << "frequency_clock_t(" << gen(v.v_.max_frequency()) << ")," - << gen(v.v_.force_send_changed()) << ",\n"; + << "\"" << v.v_.name() << "\"," + << (v.v_.length() != 0 ? v.v_.length() : 8) << ","; + uint32_t flags = 0; + if(v.v_.is_fd()) + { + flags = flags|CAN_PROTOCOL_WITH_FD_FRAME; + } + + if(v.v_.is_j1939()) + { + flags = flags|J1939_PROTOCOL; + } + + if(v.v_.is_isotp()) + { + flags = flags|ISOTP_PROTOCOL; + } + + o << gen(flags) << ","; + + o << "frequency_clock_t(" << gen(v.v_.max_frequency()) << ")," + << gen(v.v_.force_send_changed()) << ","; std::uint32_t index = 0; - o << "\t\t\t\t\t{ // beginning can_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 can_signals vector\n" - << "\t\t\t\t})} // end can_message_definition entry\n"; + o << "\t\t\t} // end signals vector\n" + << "\t\t})} // end message_definition entry\n"; return o; } @@ -202,7 +275,7 @@ 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" - << " , can_message_set_{\n" + out << "extern \"C\" {\n" + << "CTLP_CAPI_REGISTER(\"" << capi_name << "\");\n" + << "\n" << gen(message_set, "\t\t") - << "\t} // end can_message_set vector\n" - << "{\n" - << " for(auto& cms: can_message_set_)\n" - << " {\n" - << " std::vector >& can_messages_definition = cms->get_can_message_definition();\n" - << " for(auto& cmd : can_messages_definition)\n" - << " {\n" - << " cmd->set_parent(cms.get());\n" - << " std::vector >& can_signals = cmd->get_can_signals();\n" - << " for(auto& sig: can_signals)\n" - << " {\n" - << " sig->set_parent(cmd.get());\n" - << " }\n" - << " }\n\n" - << " std::vector >& diagnostic_messages = cms->get_diagnostic_messages();\n" - << " for(auto& dm : diagnostic_messages)\n" - << " {\n" - << " dm->set_parent(cms.get());\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; - } + << "\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 << "\treturn " << gen(active_bus) << ";\n" - << "}\n\n"; out << footer << std::endl; } @@ -321,6 +377,8 @@ std::cout<<" "<<"-o application-generated.cpp : output source file. Name /// @return Exit code, zero if success. int main(int argc, char *argv[]) { + + decoder_t::init_decoder(); try { std::string appName = argv[0]; @@ -387,6 +445,7 @@ int main(int argc, char *argv[]) throw std::runtime_error(ss.str()); } } + VERSION_FILE = message_set.version(); generate(header.str(), footer, message_set, output_file.size() ? out : std::cout); } catch (std::exception& e)