def write(can, output_path=can_lib_h_path): header_name = '_PACK_UNPACK_H' with open(output_path, 'w') as f: fw = f.write # Setup file fw(ifndef(header_name)) # Includes fw('#include <stdint.h>' '\n' '#include <stdbool.h>' '\n\n' '#include "static.h"' '\n' '#include "driver.h"\n' '#include "constants.h"\n' '#include "structs.h"\n\n') # Declare for bus in can.bus: for msg in bus.frame: frame_handler(msg, bus.name, write_declare, fw) fw('\n\n') fw(endif(header_name))
def write(can, computers, output_path=bus_path): header_name = '_CAN_LIBRARY_BUS_H' with open(output_path, 'w') as f: fw = f.write fw(ifndef(header_name)) # Create enum among buses fw('typedef enum {\n') for bus in can.bus: fw('\t' + bus.name + ',\n') fw('} CANlib_Bus_T;\n\n') raw_buses = set() for computer in computers: if not ('can' in computer.participation['name'].keys()): # This computer neither sends nor recieves can messages continue raw_buses |= set( computer.participation['name']['can'].mapping.values()) assert 'INVALID_BUS' not in raw_buses, "INVALID_BUS is a reserved bus name" fw('typedef enum {\n') for bus in raw_buses: fw('\t' + bus + ',\n') fw('\tINVALID_BUS\n} CAN_Raw_Bus_T;\n\n') # Create forms enum for each bus for bus in can.bus: fw('typedef enum {\n') # First frame needs to start at 2, the rest will follow first_frame = True for msg in bus.frame: if is_multplxd(msg): for frame in msg.frame: fw('\t' + coord(bus.name, msg.name, frame.name)) if first_frame: fw(' = 2') first_frame = False fw(',\n') else: fw('\t' + coord(bus.name, msg.name)) if first_frame: fw(' = 2') first_frame = False fw(',\n') fw('} ' + '{}_T;\n\n'.format(coord(bus.name))) fw('{}_T CANlib_Identify_{}(Frame* frame);'.format( coord(bus.name), coord(bus.name, prefix=False)) + '\n\n') fw(endif(header_name))
def write(can, computers, output_path=computer_h_dir_path): os.makedirs(output_path, exist_ok=True) for computer in computers: header_name = '_CAN_LIBRARY_{}_H'.format(computer.name.upper()) f_path = os.path.join(output_path, 'canlib_{}.h'.format(computer.name)) if not ('can' in computer.participation['name'].keys()): # This computer neither sends nor recieves can messagess continue with open(f_path, 'w') as f: fw = f.write fw(ifndef(header_name)) fw('#include <stdint.h>\n') fw('#include <stdbool.h>\n\n') fw('#include "constants.h"\n') fw('#include "enum_atom.h"\n') fw('#include "structs.h"\n') fw('#include "static.h"\n') fw('#include "evil_macros.h"\n') fw('#include "pack_unpack.h"\n\n') fw('\n') fw('#ifdef __cplusplus\nextern "C" {\n#endif // __cplusplus\n\n') # Pub try: for bus_name, bus in computer.participation['name'][ 'can'].publish.items(): for frame in bus: frame_handler(frame, bus_name, declare_pub_frame, fw) except KeyError: pass # No CAN messages sent by this board fw('\n') # Sub try: for bus_name, bus in computer.participation['name'][ 'can'].subscribe.items(): for frame in bus: frame_handler(frame, bus_name, declare_sub_frame, fw) fw('\n') fw('void CANlib_update_can(void);\n') except KeyError: pass # No CAN messages received by this board fw('\n#ifdef __cplusplus\n} // extern "C"\n#endif // __cplusplus\n\n' ) fw(endif(header_name))
def write(can, output_path=enum_atom_path): header_name = '_CAN_LIBRARY_ENUM_ATOM_H' with open(output_path, 'w') as f: fw = f.write fw(ifndef(header_name)) for bus in can.bus: for msg in bus.frame: frame_handler(msg, bus.name, handle_frame, fw) fw(endif(header_name))
def write(can, output_path=structs_path): header_name = '_CAN_LIBRARY_STRUCTS' with open(output_path, 'w') as f: fw = f.write fw(ifndef(header_name)) fw('#include <stdint.h>\n') fw('#include <stdbool.h>\n\n') fw('#include "enum_atom.h"\n\n') for bus in can.bus: for msg in bus.frame: frame_handler(msg, bus.name, msg_handler, fw) fw(endif(header_name))
def write(can, output_path=constants_path): header_name = '_CAN_LIBRARY_CONSTANTS_H' with open(output_path, 'w') as f: fw = f.write fw(ifndef(header_name)) props = ( ('key', 'define', int), ('period', 'define', get_ms), ) optional_props = {'period'} for bus in can.bus: for attrnm, form, transform in props: finalnm = attrnm # Define it in scope because it relies on too many locals def msg_handler(frame, name_prepends): attr = None try: attr = getattr(frame, attrnm) except AttributeError as e: if not attrnm in optional_props: raise e if attr is None: if attrnm in optional_props: return else: raise AttributeError('{} missing required attribute {}'.format(frame.name, attrnm)) attr = transform(attr) fw(templ[form].format(coord(name_prepends, frame.name, finalnm), attr)) for msg in bus.frame: if is_multplxd(msg): # Keep multiplexed check because we want to call for # this function for both the top lvl multiplexed msg # and the sub-frames frame_handler(msg, bus.name, msg_handler) msg_handler(msg, bus.name) fw(endif(header_name))
def write(can, output_path=test_h_dir_path): os.makedirs(output_path, exist_ok=True) header_name = '_CAN_LIBRARY_TEST_H' f_path = os.path.join(output_path, 'canlib_test.h') with open(f_path, 'w') as f: fw = f.write fw(ifndef(header_name)) fw('#include <stdint.h>\n') fw('#include <stdbool.h>\n\n') fw('#include "constants.h"\n') fw('#include "enum_atom.h"\n') fw('#include "structs.h"\n') fw('#include "static.h"\n') fw('#include "evil_macros.h"\n') fw('#include "pack_unpack.h"\n\n') fw('#ifndef TEST\n' '#error "test.h should only be included in testing files!"\n' '#endif\n\n') fw('\n') # Pub for bus in can.bus: for frame in bus.frame: frame_handler(frame, bus.name, declare_pub_frame, fw) fw('\n') for bus in can.bus: for frame in bus.frame: frame_handler(frame, bus.name, declare_sub_frame, fw) fw('\n') fw('void CANlib_update_can_TEST(void);\n') fw(endif(header_name))