diff --git a/.vscode/settings.json b/.vscode/settings.json index 019c2c08..9b9746dc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,10 +19,22 @@ "utility": "cpp", "variant": "cpp", "atomic": "cpp", +<<<<<<< HEAD + "string": "cpp", + "string_view": "cpp", + "ranges": "cpp", + "span": "cpp", + "bitset": "cpp", + "initializer_list": "cpp", + "stacktrace": "cpp", + "regex": "cpp", + "valarray": "cpp" +======= "bitset": "cpp", "cstdlib": "cpp", "mutex": "cpp", "shared_mutex": "cpp", "regex": "cpp" +>>>>>>> origin/main } } diff --git a/CMakeLists.txt b/CMakeLists.txt index dc90ed69..90fb9790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,15 +3,51 @@ cmake_minimum_required(VERSION 3.14) project(template-project LANGUAGES ASM C CXX) set(EXECUTABLE ${PROJECT_NAME}.elf) -set(STLIB_DIR ${CMAKE_CURRENT_LIST_DIR}/deps/ST-LIB) +set(Board "VCU") # User must change the Board name +set(STLIB_DIR ${CMAKE_CURRENT_LIST_DIR}/deps/ST-LIB) set(LD_SCRIPT ${STLIB_DIR}/STM32H723ZGTX_FLASH.ld) + +find_package(Python3 COMPONENTS Interpreter REQUIRED) + +set(GENERATOR_SCRIPT "${CMAKE_SOURCE_DIR}/Core/Inc/Code_generation/Generator.py") + +add_custom_target(run_generator ALL + COMMAND ${Python3_EXECUTABLE} ${GENERATOR_SCRIPT} ${Board} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} +) + if(CMAKE_HOST_WIN32 ) set(VENV_PYTHON ${CMAKE_SOURCE_DIR}/virtual/Scripts/python) else() set(VENV_PYTHON ${CMAKE_SOURCE_DIR}/virtual/bin/python) endif() -option(USE_ETHERNET "Enable ethernet peripheral" OFF) -option(TARGET_NUCLEO "Targets the STM32H723 Nucleo dev board" OFF) + +add_custom_target( + my_custom_target_that_always_runs ALL + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_tmp.h +) +add_custom_command( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/_tmp.h # fake! ensure we run! + COMMAND ${VENV_PYTHON} ${CMAKE_SOURCE_DIR}/tools/generate_binary_metadata.py +) + +option(USE_ETHERNET "Enable ethernet peripheral" OFF) +option(TARGET_NUCLEO "Targets the STM32H723 Nucleo development board" OFF) + +if (PROJECT_IS_TOP_LEVEL AND (NOT CMAKE_CROSSCOMPILING)) + include(FetchContent) + option(BUILD_GMOCK OFF) + option(INSTALL_GTEST OFF) + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.15.2 + ) + FetchContent_MakeAvailable(googletest) + add_library(GTest::GTest INTERFACE IMPORTED) + target_link_libraries(GTest::GTest INTERFACE gtest_main) +endif() message(STATUS "Template project: CMAKE_CROSSCOMPILING = ${CMAKE_CROSSCOMPILING}") message(STATUS "Template project: USE_ETHERNET = ${USE_ETHERNET}") @@ -129,3 +165,6 @@ else() COMMENT "Removing BOARD build marker (NUCLEO build)" ) endif() + + + diff --git a/Core/Inc/Code_generation/Generator.py b/Core/Inc/Code_generation/Generator.py index 02b074fe..2180d1a3 100644 --- a/Core/Inc/Code_generation/Generator.py +++ b/Core/Inc/Code_generation/Generator.py @@ -1,19 +1,28 @@ -import json +import sys from Packet_generation.Packet_generation import * from State_machine_generation.State_machine_generation import * +if len(sys.argv)<2: + print("Please enter a board name,exiting...") + sys.exit() + +JSONpath = "Core/Inc/Code_generation/JSON_ADE" +aux = sys.argv[1] +filtered = "" +for char in aux: + if char.isalpha(): + filtered += char + else: + break +board = filtered -JSONpath = "Core/Inc/Code_generation/JSON_ADE" -boards = Generate_PacketDescription(JSONpath) -board = input("Enter board name: ") -while board not in boards: - print("Board not found, select an available board") - board = input("Enter board name: ") -Generate_DataPackets_hpp(board) -Generate_OrderPackets_hpp(board) -Generate_Protections_hpp(board) +boards = Generate_PacketDescription(JSONpath, board) + if __name__ == "__main__": + Generate_DataPackets_hpp(board) + Generate_OrderPackets_hpp(board) + # Generate_Protections_hpp(board), no protections for now with open("state_machine.json", "r") as file: data = json.load(file) sm = parse_state_machine(data) @@ -26,4 +35,5 @@ + \ No newline at end of file diff --git a/Core/Inc/Code_generation/JSON_ADE b/Core/Inc/Code_generation/JSON_ADE index 73fb6443..76d1b303 160000 --- a/Core/Inc/Code_generation/JSON_ADE +++ b/Core/Inc/Code_generation/JSON_ADE @@ -1 +1 @@ -Subproject commit 73fb6443119d83d58aab8a8fe17be0d1533d4d25 +Subproject commit 76d1b30360d881a6af4ef9dbf307f418980c9594 diff --git a/Core/Inc/Code_generation/Packet_generation/DataTemplate.hpp b/Core/Inc/Code_generation/Packet_generation/DataTemplate.hpp index 416dba97..0d7c81e9 100644 --- a/Core/Inc/Code_generation/Packet_generation/DataTemplate.hpp +++ b/Core/Inc/Code_generation/Packet_generation/DataTemplate.hpp @@ -3,26 +3,43 @@ //Data packets for {{board}} -AUTOGENERATED CODE, DO NOT MODIFY- class DataPackets{ - {% for enum in enums %}enum class {{enum.name}}:uint8_t{ + public: + {% for enum in enums %}enum class {{enum.name}}:uint8_t + { {% for value in enum["values"] %}{{value}}={{loop.index0}}{%if not loop.last%},{%endif%} {% endfor %}}; - {%endfor %} + {%endfor %} private: - constexpr static size_t size={{size}}; - uint32_t id{0}; + inline static uint32_t id{0}; public: - std::array packets; - {%for packet in packets%}StackPacket* {{packet.name}}; + {%for packet in packets%}static inline HeapPacket* {{packet.name}}{}; + {% endfor %} + + {% for socket in sockets %}static inline {{socket.type}}* {{socket.name}} = nullptr; {% endfor %} - DataPackets({%for value in data %}{{value.type}} &{{value.name}}{%if not loop.last%},{%endif%}{%endfor%}}}) -{ + DataPackets({%for value in data %}{{value.type}} &{{value.name}}{%if not loop.last%},{%endif%}{%endfor%}) +{ + {% for socket in ServerSockets%}{{socket.name}} = new ServerSocket("{{socket.board_ip}}",{{socket.port}}); + {% endfor %} + {% for socket in DatagramSockets%}{{socket.name}} = new DatagramSocket("{{socket.board_ip}}",{{socket.port}},"{{socket.remote_ip}}",{{socket.port}}); + {% endfor %} + {% for socket in Sockets%}{{socket.name}} = new Socket("{{socket.board_ip}}",{{socket.local_port}},"{{socket.remote_ip}}",{{socket.remote_port}}); + {% endfor %} + {% for packet in packets %}{{packet.name}} = new HeapPacket(static_cast({{packet.id}}){% if packet.data%},{{packet.data}}{% endif%}); - {% for packet in packets %}{{packet.name}} = new StackPacket({{packet.id}}{% if packet.data%},{{packet.data}}{% endif%}); - packets[id]={{packet.name}}; - id++; {% endfor %} + {%for packet in sending_packets %}Scheduler::register_task({% if packet.period_type == "ms" %}{{(packet.period*1000)}}{% else %}{{packet.period}}{% endif %},+[](){ + {% if packet.name is string %} DataPackets::{{packet.socket}}->send_packet(*DataPackets::{{packet.name}}); + {%else%} + {%for name in packet.name%}DataPackets::{{packet.socket}}->send_packet(*{{name}}); + {%endfor%} + {% endif %} + }); + {%endfor%} + + } }; \ No newline at end of file diff --git a/Core/Inc/Code_generation/Packet_generation/OrderTemplate.hpp b/Core/Inc/Code_generation/Packet_generation/OrderTemplate.hpp index 4dafe252..dc894260 100644 --- a/Core/Inc/Code_generation/Packet_generation/OrderTemplate.hpp +++ b/Core/Inc/Code_generation/Packet_generation/OrderTemplate.hpp @@ -2,29 +2,29 @@ #include "ST-LIB.hpp" //Order packets for {{board}} -AUTOGENERATED CODE, DO NOT MODIFY- + +{%for packet in packets%}extern void {{packet.name}}_cb(); +{% endfor %} class OrderPackets{ - {% for enum in enums %}enum class {{enum.name}}:uint8_t{ + {% for enum in enums %}enum class {{enum.name}}:uint8_t + { {% for value in enum["values"] %}{{value}}={{loop.index0}}{%if not loop.last%},{%endif%} {% endfor %}}; - {% endfor %} - {%for packet in packets%}bool {{packet.name}}_callback(); {% endfor %} + + private: - constexpr static size_t size={{size}}; uint32_t id{0}; public: - std::array packets; - {%for packet in packets%}StackOrder* {{packet.name}}; + {%for packet in packets%}HeapOrder* {{packet.name}}; {% endfor %} - OrderPackets({%for value in data %}{{value.type}} &{{value.name}}{%if not loop.last%},{%endif%}{%endfor%}}}) + OrderPackets({%for value in data %}{{value.type}} &{{value.name}}{%if not loop.last%},{%endif%}{%endfor%}) { - {% for packet in packets %}{{packet.name}}=new StackOrder({{packet.id}},{{packet.name}}_callback{% if packet.data%},{{packet.data}}{% endif%}); - packets[id]={{packet.name}}; - id++; + {% for packet in packets %}{{packet.name}}=new HeapOrder({{packet.id}},&{{packet.name}}_cb{% if packet.data%},{{packet.data}}{% endif%}); {% endfor %} } }; \ No newline at end of file diff --git a/Core/Inc/Code_generation/Packet_generation/Packet_descriptions.py b/Core/Inc/Code_generation/Packet_generation/Packet_descriptions.py index 54de2ce0..f0f43eb7 100644 --- a/Core/Inc/Code_generation/Packet_generation/Packet_descriptions.py +++ b/Core/Inc/Code_generation/Packet_generation/Packet_descriptions.py @@ -1,84 +1,152 @@ -import re +import re import json -class BoardDescription: +class BoardDescription: def __init__(self,name:str,board:dict,JSONpath:str): self.name = name self.id = board["board_id"] self.ip = board["board_ip"] + #Sockets: + with open(JSONpath+"/boards/"+name+"/sockets.json") as s: + socks = json.load(s) + self.sockets=self.SocketsDescription(socks,self.ip) + #Packets: + self.sending_packets = [] self.data_size =0 self.order_size =0 - i = 0 + self.measurement_lists = [] self.packets = {} + for measurement in board["measurements"]: + with open(JSONpath+"/boards/" + name + "/" + measurement) as f: + m = json.load(f) + self.measurement_lists.append(m) for packets in board["packets"]: packets_name = re.split(r'_|\.', packets)[0] self.packets[packets_name] = [] - measurement = self._MeasurementFileSearch(packets,board["measurements"]) - with open(JSONpath+"/boards/" + name+"/" + board["packets"][i]) as f: + with open(JSONpath+"/boards/" + name+"/" + packets) as f: p= json.load(f) - with open(JSONpath+"/boards/" + name + "/" + measurement) as f: - m = json.load(f) - i += 1 - for packet in p["packets"]: - j=0 - self.packets[packets_name].append(PacketDescription(packet,m)) - if self.packets[packets_name][j].type != "order": + i=0 + for packet in p: + self.packets[packets_name].append(PacketDescription(packet,self.measurement_lists)) + aux_sending= PacketDescription.check_for_sending(packet) + if aux_sending is not None: + self.sending_packets.append(aux_sending) + + if self.packets[packets_name][i].type != "order": self.data_size += 1 else: self.order_size += 1 - j += 1 - @staticmethod - def _MeasurementFileSearch(packet:str,measurements:dict): - packet_name = packet.split('_')[0] - for measurement in measurements: - measurement_name = measurement.split('_')[0] - if packet_name[0] == measurement_name[0]: - return measurement - else: - return measurements[0] + i += 1 + + self.sending_packets = self.fix_sendind_packets(self.sending_packets) + + @staticmethod + def fix_sendind_packets(sending_packets:list): + fixed_packets = [] + lookup = {} + for item in sending_packets: + if not isinstance(item, dict): + continue + period = item.get("period") + period_type = item.get("period_type") + socket = item.get("socket") + name = item.get("name") + key = (period,period_type, socket) + lookup.setdefault(key, []).append(name) + + for (period,period_type, socket), names in lookup.items(): + entry = {"period": period,"period_type":period_type, "socket": socket} + if len(names) == 1: + entry["name"] = names[0] + else: + entry["name"] = names + fixed_packets.append(entry) + + return fixed_packets + + + + class SocketsDescription: + def __init__(self,sockets:list,board_ip:str): + self.allSockets=[] + self.ServerSockets = [] + self.Sockets = [] + self.DatagramSockets = [] + self.board_ip = board_ip + for sock in sockets: + name = sock["name"].replace(" ", "_").replace("-", "_") + sock_type = sock["type"] + self.allSockets.append({"name": name,"type":sock_type}) + + if sock_type == "ServerSocket": + self.ServerSockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "port": sock["port"]}) + elif sock_type == "Socket": + self.Sockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "local_port": sock["local_port"], "remote_ip": sock["remote_ip"], "remote_port": sock["remote_port"]}) + elif sock_type == "DatagramSocket": + self.DatagramSockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "port": sock["port"],"remote_ip":sock["remote_ip"]}) + + + class PacketDescription: - def __init__(self, packet:dict,measurements:dict): + def __init__(self, packet:dict,measurements:list): self.id =packet["id"] - self.name = (packet["name"].replace(" ", "_").replace("(", "").replace(")", "")) + self.name = packet["name"].replace(" ", "_").replace("-", "_") self.type = packet["type"] self.variables = [] self.measurements = [] + if "variables" not in packet: + return for variable in packet["variables"]: - self.variables.append(variable["name"]) - self.measurements.append(MeasurmentsDescription(measurements,variable["name"])) - - + self.variables.append(variable) + self.measurements.append(MeasurmentsDescription(measurements,variable)) + + @staticmethod + def check_for_sending(packet:dict): + if "period" in packet and "period_type" in packet and "socket" in packet: + name = packet["name"].replace(" ", "_").replace("-", "_") + return {"name": name,"period": packet["period"],"period_type":packet["period_type"],"socket": packet["socket"]} + + elif "period_ms" in packet and "socket" in packet: + name = packet["name"].replace(" ", "_").replace("-", "_") + return {"name": name,"period": packet["period_ms"],"period_type":"ms","socket": packet["socket"]} + else: + return None class MeasurmentsDescription: - def __init__(self,measurements:dict, variable:str): + def __init__(self,measurements:list, variable:str): self.id = variable + if not hasattr(self.__class__, 'viewed_measurements'): + self.__class__.viewed_measurements = {} measurement = self._MeasurementSearch(measurements,variable) + if measurement is None: + print(variable) raise Exception("Measurement not found") - else: - self.name = measurement["name"] - self.type = self._unsigned_int_correction(measurement["type"]) - if self.type == "enum": - values = [] - for value in measurement["enumValues"]: - values.append(str(value)) - self.enum ={"name": measurement["id"], "values": self._Enum_values_correction(values)} - self.type = measurement["id"] - protections = self._protection_search(measurement) - if protections is not None: - self.protections = self.Protections(protections) - + + self.name = measurement["name"] + self.type = (self._unsigned_int_correction(measurement["type"]).replace(" ", "_").replace("-", "_")) + if self.type == "enum": + values = [] + for value in measurement["enumValues"]: + values.append(str(value)) + self.enum ={"name": (measurement["id"].replace(" ", "_").replace("-", "_")), "values": self._Enum_values_correction(values)} + self.type = (measurement["id"].replace(" ", "_").replace("-", "_")) + @staticmethod def _Enum_values_correction(values:list): for i in range(len(values)): - values[i] = values[i].replace(" ", "_") + values[i] = values[i].replace(" ", "_").replace("-", "_") return values @staticmethod - def _MeasurementSearch(measurements:dict, variable:str): - for measurment in measurements["measurements"]: - if measurment["id"] == variable: - return measurment + def _MeasurementSearch(measurements:list, variable:str): + if variable in MeasurmentsDescription.viewed_measurements: + return MeasurmentsDescription.viewed_measurements[variable] + for measurement_list in measurements: + for measurment in measurement_list: + if measurment["id"] == variable: + MeasurmentsDescription.viewed_measurements[variable] = measurment + return measurment return None @@ -87,48 +155,6 @@ def _unsigned_int_correction(type:str): aux_type = type[:4] if aux_type == "uint": type += "_t" - return type - - @staticmethod - def _protection_search(measurement:dict): - warningRange = measurement.get("warningRange") - safeRange = measurement.get("safeRange") - if warningRange is None and safeRange is None: - return None - - protections = [[None, None], [None, None]] - - if safeRange is not None: - for i in range(len(safeRange)): - protections[0][i] = safeRange[i] - - if warningRange is not None: - for i in range(len(warningRange)): - protections[1][i] = warningRange[i] - - return protections - - class Protections: - class Below: - def __init__(self, protections:list): - self.Protectionvalue = [None, None] - self.ProtectionType = "Below" - if protections[0] is not None and protections[0][0] is not None: - self.Protectionvalue[0] = protections[0][0] - if protections[1] is not None and protections[1][0] is not None: - self.Protectionvalue[1] = protections[1][0] - - class Above: - def __init__(self, protections:list): - self.Protectionvalue = [None, None] - self.ProtectionType = "Above" - if protections[0] is not None and protections[0][1] is not None: - self.Protectionvalue[0] = protections[0][1] - if protections[1] is not None and protections[1][1] is not None: - self.Protectionvalue[1] = protections[1][1] - - def __init__(self, protections:list): - self.protections = [None, None] - self.protections[0] = self.Below(protections) - self.protections[1] = self.Above(protections) - + elif type == "float32": + type = "float" + return type \ No newline at end of file diff --git a/Core/Inc/Code_generation/Packet_generation/Packet_generation.py b/Core/Inc/Code_generation/Packet_generation/Packet_generation.py index 7c4decf1..a4ad083b 100644 --- a/Core/Inc/Code_generation/Packet_generation/Packet_generation.py +++ b/Core/Inc/Code_generation/Packet_generation/Packet_generation.py @@ -2,20 +2,24 @@ import json import os import jinja2 +import sys templates_path = "Core/Inc/Code_generation/Packet_generation" -def Generate_PacketDescription(JSONpath:str): +def Generate_PacketDescription(JSONpath:str,board:str): with open(JSONpath+"/boards.json") as f: boards = json.load(f) boards_name = [] - for board in boards["boards"]: - - with open(JSONpath+"/" + (boards["boards"][board])) as f: + for b in boards: + boards_name.append(b) + if board in boards_name: + with open(JSONpath+"/" + (boards[board])) as f: b = json.load(f) - board_instance = BoardDescription(board, b,JSONpath) - boards_name.append(board_instance.name) - globals()[board] = board_instance + board_instance = BoardDescription(board, b,JSONpath) + globals()[board] = board_instance + else: + print(f"Board {board} not found, exiting...") + sys.exit() return boards_name @@ -29,7 +33,7 @@ def GenerateDataEnum(board:BoardDescription): for packet_instance in board.packets[packet]: if packet_instance.type != "order": for measurement in packet_instance.measurements: - if hasattr(measurement, "enum"): + if hasattr(measurement, "enum")and measurement.enum not in Enums: Enums.append(measurement.enum) return Enums @@ -41,14 +45,18 @@ def GenerateDataPackets(board:BoardDescription): for packet_instance in board.packets[packet]: if packet_instance.type != "order": tempdata = "" + tempdata_but_pointer = "" for variable in packet_instance.variables: tempdata +=(str(variable) +",") + tempdata_but_pointer +=("&"+str(variable) +",") if tempdata.endswith(","): tempdata = tempdata[:-1] - aux_packet = {"name": packet_instance.name, "data":tempdata , "id": packet_instance.id} + if tempdata_but_pointer.endswith(","): + tempdata_but_pointer = tempdata_but_pointer[:-1] + aux_packet = {"name": packet_instance.name, "data":tempdata_but_pointer.replace(" ", "_").replace("-", "_") , "id": packet_instance.id} Packets.append(aux_packet) for measurement in packet_instance.measurements: - aux_data = {"type": measurement.type, "name": measurement.id} + aux_data = {"type": measurement.type, "name": measurement.id.replace(" ", "_").replace("-", "_")} totaldata.append(aux_data) return Packets,totaldata @@ -60,6 +68,11 @@ def GenerateDataPackets(board:BoardDescription): "packets" : packets, "data": data, "size": board.order_size, + "sockets":board.sockets.allSockets, + "ServerSockets":board.sockets.ServerSockets, + "Sockets":board.sockets.Sockets, + "DatagramSockets":board.sockets.DatagramSockets, + "sending_packets": board.sending_packets, } return context @@ -88,7 +101,7 @@ def GenerateOrderEnum(board:BoardDescription): for packet_instance in board.packets[packet]: if packet_instance.type == "order": for measurement in packet_instance.measurements: - if hasattr(measurement, "enum"): + if hasattr(measurement, "enum") and measurement.enum not in Enums: Enums.append(measurement.enum) return Enums @@ -100,15 +113,19 @@ def GenerateOrderPackets(board:BoardDescription): for packet_instance in board.packets[packet]: if packet_instance.type == "order": tempdata = "" + tempdata_but_pointer = "" for variable in packet_instance.variables: tempdata +=(str(variable) +",") + tempdata_but_pointer +=("&"+str(variable) +",") if tempdata.endswith(","): - tempdata = tempdata[:-1] - aux_packet = {"name": packet_instance.name, "data":tempdata , "id": packet_instance.id} + tempdata = tempdata[:-1] + tempdata_but_pointer = tempdata_but_pointer[:-1] + aux_packet = {"name": packet_instance.name, "data":tempdata_but_pointer , "id": packet_instance.id} Packets.append(aux_packet) for measurement in packet_instance.measurements: aux_data = {"type": measurement.type, "name": measurement.id} - totaldata.append(aux_data) + if aux_data not in totaldata: + totaldata.append(aux_data) return Packets,totaldata @@ -140,65 +157,3 @@ def Generate_OrderPackets_hpp(board_input:str): Output.write(template.render(context)) -#--------------Protections.hpp generation---------------# - -def Generate_Protections_context(board:BoardDescription): - def Get_Bondaries(measurement:MeasurmentsDescription): - Boundaries = [] - for i in {0,1}: - for j in {0,1}: - if measurement.protections.protections[i].Protectionvalue[j] is None: - continue - temp_boundary= {"type": measurement.type, "Above_or_Below":measurement.protections.protections[i].ProtectionType, "value": measurement.protections.protections[i].Protectionvalue[j],"coma":"," } - Boundaries.append(temp_boundary) - - Boundaries[-1]["coma"] = "" - return Boundaries - - - def Get_protection_packets(board:BoardDescription): - protections = [] - for packet in board.packets: - for packet_instance in board.packets[packet]: - for measurement in packet_instance.measurements: - if hasattr(measurement, "protections"): - protections.append(measurement) - if len(protections) == 0: - return False - return protections - - - protection_packets = Get_protection_packets(board) - if protection_packets == False: - return False - protections=[] - data =[] - for measurement in protection_packets: - Boundaries = Get_Bondaries(measurement) - aux_protection = {"packet": measurement.id, "Boundaries": Boundaries} - aux_data = {"type": measurement.type, "name": measurement.id} - if aux_data not in data: - data.append(aux_data) - if aux_protection in protections: - continue - protections.append(aux_protection) - - context ={ - "board": board.name, - "data": data, - "protections": protections - } - return context - -def Generate_Protections_hpp(board_input:str): - protections_path = "Core/Inc/Communications/Packets/Protections.hpp" - board_instance = globals()[board_input] - env= jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path)) - template = env.get_template("ProtectionsTemplate.hpp") - context = Generate_Protections_context(board_instance) - if context == False: - if os.path.exists(protections_path): - os.remove(protections_path) - return - with open(protections_path,"w") as Output: - Output.write(template.render(context)) \ No newline at end of file diff --git a/Core/Inc/Communications/Packets/.gitignore b/Core/Inc/Communications/Packets/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/Core/Inc/state_machine.hpp b/Core/Inc/state_machine.hpp new file mode 100644 index 00000000..0a448b41 --- /dev/null +++ b/Core/Inc/state_machine.hpp @@ -0,0 +1,73 @@ +#pragma once +#include "ST-LIB.hpp" +using namespace std::chrono_literals; + +// AUTOGENERATED CODE, DO NOT EDIT MANUALLY + +class Example{ + + public: + + static bool from_1_to_2(); + static bool from_1_to_2(); + static bool from_1_to_nested_1(); + static void enter_action_1(); + static void enter_action_2(); + static void enter_action_3(); + static void enter_action_4(); + static void low_precision_action(); + static void low_precision_action(); + static void mid_precision_action_to_nested_state(); + static void mid_precision_action_to_nested_state(); + static void high_precision_action_with_description(); + static void high_precision_action_with_description(); + static void exit_action_1(); + static void exit_action_2(); + + StateMachine Example_State_Machine; + StateMachine Nested_State_Machine; + + enum ExampleStates { + NAME_1, + NAME_2, + }; + + enum Nested{ + NESTED_NAME_1, + NESTED_NAME_2, + }; + + Example(){ + + Example_State_Machine = StateMachine(ExampleStates::NAME_1); + + Nested_State_Machine = StateMachine(Nested::NESTED_NAME_1); + Example_State_Machine.add_state_machine(Nested_State_Machine, ExampleStates::NAME_1); + Nested_State_Machine.add_state(Nested::NESTED_NAME_2); + + Example_State_Machine.add_state(ExampleStates::NAME_2); + + Example_State_Machine.add_transition(ExampleStates::NAME_1, ExampleStates::NAME_2, from_1_to_2); + // Transitioning from 1 to 2 + Example_State_Machine.add_transition(ExampleStates::NAME_1, ExampleStates::NAME_2, from_1_to_2); + Example_State_Machine.add_transition(ExampleStates::NAME_1, Nested::NESTED_NAME_1, from_1_to_nested_1); + + Example_State_Machine.add_enter_action(enter_action_1, ExampleStates::NAME_1); + Example_State_Machine.add_enter_action(enter_action_2, ExampleStates::NAME_1); + // Description of enter_action_3 + Example_State_Machine.add_enter_action(enter_action_3, ExampleStates::NAME_2); + Example_State_Machine.add_enter_action(enter_action_4, ExampleStates::NAME_2); + Example_State_Machine.add_low_precision_cyclic_action(low_precision_action, 30ms, ExampleStates::NAME_1); + Example_State_Machine.add_low_precision_cyclic_action(low_precision_action, 30ms, ExampleStates::NAME_2); + Example_State_Machine.add_mid_precision_cyclic_action(mid_precision_action_to_nested_state, 60ms, ExampleStates::NAME_1); + Example_State_Machine.add_mid_precision_cyclic_action(mid_precision_action_to_nested_state, 60ms, Nested::NESTED_NAME_1); + // Cyclic action example with description + Example_State_Machine.add_high_precision_cyclic_action(high_precision_action_with_description, 90ms, ExampleStates::NAME_1); + // Cyclic action example with description + Example_State_Machine.add_high_precision_cyclic_action(high_precision_action_with_description, 90ms, ExampleStates::NAME_2); + Example_State_Machine.add_exit_action(exit_action_1, Nested::NESTED_NAME_2); + Example_State_Machine.add_exit_action(exit_action_2, Nested::NESTED_NAME_2); + + } + +}; \ No newline at end of file diff --git a/Core/Src/Runes/generated_metadata.cpp b/Core/Src/Runes/generated_metadata.cpp index 77dbc457..dc82fcfa 100644 --- a/Core/Src/Runes/generated_metadata.cpp +++ b/Core/Src/Runes/generated_metadata.cpp @@ -5,11 +5,11 @@ extern "C"{ const char DESCRIPTION[255] __attribute__((section(".metadata_pool")))= "****************" // placeholder for beggining - "20250605T165128" // DateTime using ISO-8601 format + "20260123T210152" // DateTime using ISO-8601 format " " // alignment - "77b804dd" // STLIB commit + "332e04d7" // STLIB commit "--------" // ADJ commit - "3a365135" // Board commit + "01cca436" // Board commit // the '=' is used for unparsing ; } \ No newline at end of file diff --git a/template-project.code-workspace b/template-project.code-workspace index b8682958..1909c9d2 100644 --- a/template-project.code-workspace +++ b/template-project.code-workspace @@ -2,9 +2,6 @@ "folders": [ { "path": "." - }, - { - "path": "../Projectos/ST-LIB" } ], "settings": {