#! /usr/bin/env python import os import argparse import config import config.user_input.console from config.boards import list_of_boards, load_board_config from config.devices import list_of_devices, list_of_vendors, \ list_of_families, load_device_config from config.archs import list_of_archs, load_cpu_config script_dir = os.path.dirname(__file__) ADL_root_dir = os.path.abspath(os.path.join(script_dir, "..")) cwd = os.getcwd() interactive = True use_default = True def ensure_dir(directory): if not os.path.exists(directory): os.makedirs(directory) def board_config(config): config.query_enum_key("Board", list_of_boards(), "Custom_Board") if config.get_config("Board") != "Custom_Board": load_board_config(config) def mcu_config(config): config.query_enum_key("Architecture", list_of_archs(config)) if config.get_config("Architecture") != "Native": config.query_enum_key("Vendor", list_of_vendors(config)) config.query_enum_key("Device_Family", list_of_families(config)) config.query_enum_key("Device_Name", list_of_devices(config)) device = config.get_config("Device_Name") if device.startswith("STM32F4"): core = "ARM Cortex-M4F" elif device.startswith("STM32F7"): core = "ARM Cortex-M7F" elif device.startswith("nRF51"): core = "ARM Cortex-M0" elif device.startswith("FE3"): core = "RISC-V32" config.set_config_string_key("CPU_Core", core, "mcu definition") family = config.get_config("Device_Family") if family.startswith("STM32"): config.query_integer_key("High_Speed_External_Clock", 1000000, 32000000) elif family.startswith("FE310"): config.query_integer_key("FLASH_SIZE") load_cpu_config(config) load_device_config(config) # TDOD: Is the SVD mapping available? # TODO: Does the user want to generate it? def linker_script_config(config): config.query_bool_key('Generate_Linker_Script', default="True") if config.get_config('Generate_Linker_Script') == "True": config.query_bool_key('Has_Custom_Memory_Area_1', default="False") cnt = 1 while config.get_config('Has_Custom_Memory_Area_%d' % cnt) == "True": config.query_enum_key('Custom_Mem_%d_Kind' % cnt, ['ROM', 'RAM']) config.query_integer_key('Custom_Mem_%d_Addr' % cnt, 0) config.query_integer_key('Custom_Mem_%d_Size' % cnt, 0) config.query_string_key('Custom_Mem_%d_Name' % cnt, default="custom_mem_%d" % cnt) config.add_memory(config.get_config('Custom_Mem_%d_Kind' % cnt), config.get_config('Custom_Mem_%d_Name' % cnt), config.get_config('Custom_Mem_%d_Addr' % cnt), config.get_config('Custom_Mem_%d_Size' % cnt)) cnt += 1 config.query_bool_key('Has_Custom_Memory_Area_%d' % cnt, default="False") config.query_bool_key('Custom_Memory_Layout', default='False') if config.get_config('Custom_Memory_Layout') == "True": config.query_enum_key('Linker_Text_Section', config.memory_names(), default=config.default_rom_area()) config.query_enum_key('Linker_RO_Data_Section', config.memory_names(), default=config.default_rom_area()) config.query_enum_key('Linker_Data_Section', config.memory_names(), default=config.default_ram_area()) config.query_enum_key('Linker_BSS_Section', config.memory_names(), default=config.default_ram_area()) print "\nLinker script:" config.print_linker_script() def middleware_config(config): config.query_integer_key('Max_Path_Length', 0, default="1024") config.query_integer_key('Max_Mount_Points', 0, default="2") config.query_integer_key('Max_Mount_Name_Length', 0, default="128") origin = "middleware config" config.add_source_dir('middleware/src/filesystem', origin) config.add_source_dir('middleware/src/BLE', origin) config.add_source_dir('middleware/src/utils', origin) config.add_source_dir('middleware/src/audio', origin) config.add_source_dir('middleware/src/monitor', origin) config.add_source_dir('middleware/src/bitmap', origin) config.add_source_dir('middleware/src/command_line', origin) config.add_source_dir('middleware/src/sdmmc', origin) runtime_profile = config.get_config("Runtime_Profile") if runtime_profile is None: runtime_profile = '' if runtime_profile.startswith("ravenscar"): config.add_source_dir('middleware/src/ravenscar-common', origin) def components_config(config): config.add_source_dir('components/src/**', "components config") def runtime_config(config): config.query_string_key('Has_ZFP_Runtime', default="False") config.query_string_key('Has_Ravenscar_SFP_Runtime', default="False") config.query_string_key('Has_Ravenscar_Full_Runtime', default="False") profiles = [] if config.get_config("Has_Ravenscar_Full_Runtime") == "True": profiles.append("ravenscar-full") if config.get_config("Has_Ravenscar_SFP_Runtime") == "True": profiles.append("ravenscar-sfp") if config.get_config("Has_ZFP_Runtime") == "True": profiles.append("zfp") if len(profiles) > 0: config.query_enum_key('Runtime_Profile', profiles, default=profiles[0]) config.query_string_key('Runtime_Name_Suffix') suffix = config.get_config("Runtime_Name_Suffix") profile = config.get_config("Runtime_Profile") config.query_string_key('Runtime_Name', default=profile + "-" + suffix) def ADL_configuration(config, project_directory, project_name, source_dir_name, object_dir_name): config.add_source_dir('hal/src/', "HAL config") board_config(config) mcu_config(config) runtime_config(config) # Linker script configuration is not available for the moment # linker_script_config(config) middleware_config(config) components_config(config) print "The configuration is now finished." print "Let's generate some files:" relative_ADL_root_path = os.path.relpath(ADL_root_dir, project_directory) source_dir = os.path.join(project_directory, source_dir_name) ada_config_path = os.path.join(source_dir, "adl_config.ads") gpr_path = os.path.join(project_directory, "%s.gpr" % project_name.lower()) # GPR file gpr = "-- This project file was generated by the " + \ "Ada_Drivers_Library project wizard script\n" gpr += "library project %s is\n" % project_name gpr += """ type BUILD_TYPE is ("Debug", "Production"); Build : BUILD_Type := external ("ADL_BUILD", "Debug"); -- Target architecture Target := Project'Target; -- Callgraph info is not available on all architectures Callgraph_Switch := (); case Target is when "riscv32-unknown-elf" => null; when others => Callgraph_Switch := ("-fcallgraph-info=su"); end case; package Compiler is case Build is when "Production" => for Default_Switches ("Ada") use ("-g", "-O3", "-gnatp", "-gnatn"); when "Debug" => for Default_Switches ("Ada") use ("-g", "-O0", "-gnata") & Callgraph_Switch; end case; for Default_Switches ("ada") use Compiler'Default_Switches ("Ada") & ("-gnatwa", "-gnatwe", "-gnatQ", "-gnatw.X", "-gnaty", "-gnatyO", "-gnatyM120", "-ffunction-sections", "-fdata-sections"); end Compiler; """ gpr += " for Languages use (\"Ada\");\n" gpr += " for Create_Missing_Dirs use \"True\";\n" gpr += " for Object_Dir use \"%s_\" & Build;\n" % object_dir_name gpr += " for Library_Dir use \"%s_lib_\" & Build;\n" % object_dir_name gpr += " for Library_Kind use \"static\";\n" gpr += " for Library_Name use \"ada_drivers_library\";\n" gpr += config.gpr_configuration(relative_ADL_root_path, source_dir_name) gpr += "end %s;\n" % project_name print " -> Writing gprbuild project file." with open(gpr_path, "w") as f: f.write(gpr) # Ada config package print " -> Writing the Ada configuration file." ensure_dir(source_dir) ada = "-- This package was generated by the " + \ "Ada_Drivers_Library project wizard script\n" ada += "package ADL_Config is\n" ada += config.ada_configuration() ada += "end ADL_Config;\n" with open(ada_config_path, "w") as f: f.write(ada) config.print_remaining_pre_defined() print "Your Ada Drivers Library project is now ready to use." description = \ """Welcome to the Ada Drivers Library (ADL) project wizard. This script will ask you some questions to define the ADL configuration of your project. It will then generate the different files required to use ADL based on this configuration.""" parser = argparse.ArgumentParser(description=description) parser.add_argument('definitions', nargs='*', help="""Pre defined config key=value. Use this to give predefined answer to the configuration question. For instant Board=STM32F407_Discovery""") parser.add_argument('-i', '--input-config', type=argparse.FileType('r'), action='append', help="""Load pre defined config keys from a file. The file must containt couples of key=value, only one per line and nothing else.""") parser.add_argument('--script-mode', action="store_true", help="""Enable script mode. In script mode there is no input required from the user. Configuration values will be taken from pre-defined values (--input-config or command line definitions), or default value if any. The configuration will fail if there are now pre-defined or default value for a key. This mode can be used to automatically generated ADL project file from a known configuration.""") parser.add_argument('--dont-use-defaults', action="store_true", help="""When this switch is used in script mode, the configuration will not take into account default values. This means that the configuration will fail if a key doesn't have a pre-defined value from --input-config or command line definitions. This can be used to automatically detect discrepency when upgrading to a new version of ADL, for instance if a new config key was added.""") parser.add_argument("-d", "--project-dir", help="""Directory where the project will be created (default is Ada_Drivers_Library). Use '.' to create the project in the current directory.""", default="Ada_Drivers_Library") parser.add_argument("-p", "--project-name", help="""Name of the project file that will be generated (default is Ada_Drivers_Library)""", default="Ada_Drivers_Library") parser.add_argument("-s", "--source-dir", help="""Name of the source directory for you ADL project (default is src). This is where the Ada confiuration file will be written. You can also use this directory to add you own package specification and/or package implementation to the ADL project. The source directory will be created inside the project directory""", default="src") parser.add_argument("-o", "--object-dir", help="""Name of the object output directory that will be used for your ADL project (default is obj). The object directory will be created inside the project directory""", default="obj") args = parser.parse_args() print description interactive = not args.script_mode use_default = not args.dont_use_defaults ADL_config = config.Database(interactive, use_default, config.user_input.console) if args.input_config is not None: for f in args.input_config: ADL_config.parse_input_config(f) if args.definitions is not None: for d in args.definitions: key, value = d.partition("=")[::2] print "Add pre definition '%s' => '%s' from command line" % \ (key, value) ADL_config.pre_define(key, value, "command line") ensure_dir(args.project_dir) ADL_configuration(ADL_config, os.path.join(cwd, args.project_dir), args.project_name, args.source_dir, args.object_dir)