private void SetUpDeviceWithInfix(string infix, bool littleEndian = true)
        {
            var fileName = TemporaryFilesManager.Instance.GetTemporaryFile();

            File.WriteAllText(fileName, (littleEndian ? Prefix : BigEndianPrefix) + infix + Postfix);
            device = new SVDParser(fileName, currentMachine.SystemBus);
        }
        private void SetUpDeviceWithString(string content)
        {
            var fileName = TemporaryFilesManager.Instance.GetTemporaryFile();

            File.WriteAllText(fileName, content);
            device = new SVDParser(fileName, currentMachine.SystemBus);
        }
예제 #3
0
파일: Program.cs 프로젝트: whinis/BSPTools
        //===========================================================
        static void Main(string[] args)
        {
            List <HardwareRegister> registers;

            if (args.Length < 1)
            {
                throw new Exception("Usage: InfineonXMC.exe <InfineonXMC SW package directory>");
            }

            var    bspDir      = new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules");
            string aDirCoreReg = @"..\..\OutCorexx"; //bspDir.OutputDir

            var setsCortexM0 = SVDParser.ParseSVDFileToHardSet(Path.Combine(bspDir.RulesDir, @"XMC1100.svd"), "Cortex-M0 Private Peripheral Block");

            SaveReg(setsCortexM0, aDirCoreReg, CortexCore.M0, false);
            if (setsCortexM0 == null)
            {
                throw new Exception("No ppb reg M0");
            }

            // Cortex M4---
            var setsCortexM4 = SVDParser.ParseSVDFileToHardSet(Path.Combine(bspDir.RulesDir, @"XMC4100.svd"), "Cortex-M4 Private Peripheral Block");

            if (setsCortexM4 == null)
            {
                throw new Exception("No ppb reg M4");
            }

            SaveReg(setsCortexM4, aDirCoreReg, CortexCore.M4, true);

            // Cortex M3---
            registers = new List <HardwareRegister>(setsCortexM4.Registers);

            //FPU Remove
            registers.Remove(registers.FirstOrDefault(f => "CPACR" == f.Name));
            registers.Remove(registers.FirstOrDefault(f => "FPCCR" == f.Name));
            registers.Remove(registers.FirstOrDefault(f => "FPCAR" == f.Name));
            registers.Remove(registers.FirstOrDefault(f => "FPSCR" == f.Name));
            registers.Remove(registers.FirstOrDefault(f => "FPDSCR" == f.Name));
            setsCortexM4.Registers = registers.ToArray();

            SaveReg(setsCortexM4, aDirCoreReg, CortexCore.M3, true);

            // Cortex M0Plus---
            registers.Clear();
            registers.AddRange(setsCortexM0.Registers);
            registers.AddRange(LoadAddReg(Path.Combine(bspDir.RulesDir, "core_m0mpu.txt")));
            setsCortexM4.Registers = registers.ToArray();

            SaveReg(setsCortexM4, aDirCoreReg, CortexCore.M0Plus, false);

            // Cortex M7---
            setsCortexM4 = SVDParser.ParseSVDFileToHardSet(Path.Combine(bspDir.InputDir, @"CMSIS\Infineon\SVD\XMC4100.svd"), "Cortex-M4 Private Peripheral Block");
            registers.Clear();
            registers.AddRange(setsCortexM4.Registers);
            registers.AddRange(LoadAddReg(Path.Combine(bspDir.RulesDir, "core_m7ppb.txt")));
            setsCortexM4.Registers = registers.ToArray();

            SaveReg(setsCortexM4, aDirCoreReg, CortexCore.M7, true);
        }
 public void ShouldThrowOnNonexistingFile()
 {
     Assert.Throws <RecoverableException>(() =>
     {
         currentMachine = new Machine();
         device         = new SVDParser(Path.Combine("invalid", "path.svd"), currentMachine.SystemBus);
     });
 }
예제 #5
0
파일: Program.cs 프로젝트: whinis/BSPTools
        //===========================================================
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: InfineonXMC.exe <InfineonXMC SW package directory>");
            }

            using (var bspBuilder = new InfineonXMCBSPBuilder(BSPDirectories.MakeDefault(args)))
            {
                var devices = BSPGeneratorTools.ReadMCUDevicesFromCommaDelimitedCSVFile(bspBuilder.Directories.RulesDir + @"\McuInfineonDevices.csv",
                                                                                        "Product", "Program Memory(KB) ", "SRAM (KB) ", "CORE", true);
                devices = UpdateListMCU(devices);

                List <MCUFamilyBuilder> allFamilies = new List <MCUFamilyBuilder>();
                foreach (var fn in Directory.GetFiles(bspBuilder.Directories.RulesDir + @"\Families", "*.xml"))
                {
                    allFamilies.Add(new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(fn)));
                }

                var rejects = BSPGeneratorTools.AssignMCUsToFamilies(devices, allFamilies);
                if (rejects.Count > 0)
                {
                    throw new Exception($"Found {rejects.Count} MCUs not assigned to any family");
                }
                List <MCUFamily>         familyDefinitions = new List <MCUFamily>();
                List <MCU>               mcuDefinitions    = new List <MCU>();
                List <EmbeddedFramework> frameworks        = new List <EmbeddedFramework>();
                List <string>            exampleDirs       = new List <string>();

                bool noPeripheralRegisters = args.Contains("/noperiph");
                List <KeyValuePair <string, string> > macroToHeaderMap = new List <KeyValuePair <string, string> >();

                var           commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml"));
                var           flags        = new ToolFlags();
                List <string> projectFiles = new List <string>();
                commonPseudofamily.CopyFamilyFiles(ref flags, projectFiles);

                foreach (var sample in commonPseudofamily.CopySamples())
                {
                    exampleDirs.Add(sample.RelativePath);
                }

                foreach (var fam in allFamilies)
                {
                    var rejectedMCUs = fam.RemoveUnsupportedMCUs();
                    if (rejectedMCUs.Length != 0)
                    {
                        Console.WriteLine("Unsupported {0} MCUs:", fam.Definition.Name);
                        foreach (var mcu in rejectedMCUs)
                        {
                            Console.WriteLine("\t{0}", mcu.Name);
                        }
                    }

                    fam.AttachStartupFiles(ParseStartupFiles(fam.Definition.StartupFileDir));
                    if (!noPeripheralRegisters)
                    {
                        fam.AttachPeripheralRegisters(new MCUDefinitionWithPredicate[] { SVDParser.ParseSVDFile(Path.Combine(fam.Definition.PrimaryHeaderDir, @"CMSIS\Infineon\SVD\" + fam.Definition.Name + ".svd"), fam.Definition.Name) });
                    }

                    var famObj = fam.GenerateFamilyObject(true);

                    famObj.AdditionalSourceFiles = LoadedBSP.Combine(famObj.AdditionalSourceFiles, projectFiles.Where(f => !MCUFamilyBuilder.IsHeaderFile(f)).ToArray());
                    famObj.AdditionalHeaderFiles = LoadedBSP.Combine(famObj.AdditionalHeaderFiles, projectFiles.Where(f => MCUFamilyBuilder.IsHeaderFile(f)).ToArray());

                    famObj.AdditionalSystemVars = LoadedBSP.Combine(famObj.AdditionalSystemVars, commonPseudofamily.Definition.AdditionalSystemVars);
                    famObj.CompilationFlags     = famObj.CompilationFlags.Merge(flags);
                    famObj.CompilationFlags.PreprocessorMacros = LoadedBSP.Combine(famObj.CompilationFlags.PreprocessorMacros, new string[] { "$$com.sysprogs.bspoptions.primary_memory$$_layout" });

                    familyDefinitions.Add(famObj);
                    fam.GenerateLinkerScripts(false);
                    foreach (var mcu in fam.MCUs)
                    {
                        mcuDefinitions.Add(mcu.GenerateDefinition(fam, bspBuilder, !noPeripheralRegisters));
                    }

                    foreach (var fw in fam.GenerateFrameworkDefinitions())
                    {
                        frameworks.Add(fw);
                    }

                    foreach (var sample in fam.CopySamples())
                    {
                        exampleDirs.Add(sample.RelativePath);
                    }
                }

                BoardSupportPackage bsp = new BoardSupportPackage
                {
                    PackageID            = "com.sysprogs.arm.infineon.xmc",
                    PackageDescription   = "Infineon XMC Devices",
                    GNUTargetID          = "arm-eabi",
                    GeneratedMakFileName = "infineon_xmc.mak",
                    MCUFamilies          = familyDefinitions.ToArray(),
                    SupportedMCUs        = mcuDefinitions.ToArray(),
                    Frameworks           = frameworks.ToArray(),
                    Examples             = exampleDirs.ToArray(),
                    FileConditions       = bspBuilder.MatchedFileConditions.Values.ToArray(),
                    PackageVersion       = "2.1.24R2"
                };

                bspBuilder.Save(bsp, true);
            }
        }
예제 #6
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: rs14100.exe <rs14100 SW package directory>");
            }
            using (var bspBuilder = new RS14100BSPBuilder(BSPDirectories.MakeDefault(args)))
            {
                bool noPeripheralRegisters = args.Contains("/noperiph");
                bool noPack = args.Contains("/nopack");

                MCUFamilyBuilder famBuilder = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(Path.Combine(bspBuilder.Directories.RulesDir, "rs14100.xml")));

                foreach (var name in new[] { "RS14100" })
                {
                    famBuilder.MCUs.Add(new MCUBuilder
                    {
                        Core             = CortexCore.M4,
                        FlashSize        = 0x000EE000,
                        RAMSize          = 0x00030000,
                        Name             = name,
                        LinkerScriptPath = $"$$SYS:BSP_ROOT$$/DeviceDefinition/arm-gcc-link.ld",
                        StartupFile      = "$$SYS:BSP_ROOT$$/DeviceDefinition/startup_RS1xxxx.c"
                    });
                }


                List <EmbeddedFramework>             frameworks  = new List <EmbeddedFramework>();
                List <MCUFamilyBuilder.CopiedSample> exampleDirs = new List <MCUFamilyBuilder.CopiedSample>();

                var           famObj       = famBuilder.GenerateFamilyObject(MCUFamilyBuilder.CoreSpecificFlags.All & ~MCUFamilyBuilder.CoreSpecificFlags.PrimaryMemory);
                List <string> projectFiles = new List <string>();

                if (!noPeripheralRegisters)
                {
                    var definition = SVDParser.ParseSVDFile(Path.Combine(bspBuilder.Directories.InputDir, "RS1xxxx.svd"), "RS14100");
                    definition.MatchPredicate = m => true;

                    famBuilder.AttachPeripheralRegisters(new[] { definition }, "DeviceDefinition");
                }

                foreach (var fw in famBuilder.GenerateFrameworkDefinitions())
                {
                    frameworks.Add(fw);
                }

                foreach (var sample in famBuilder.CopySamples())
                {
                    exampleDirs.Add(sample);
                }

                List <MCU> mcuDefinitions = new List <MCU>();
                foreach (var mcuDef in famBuilder.MCUs)
                {
                    var mcu = mcuDef.GenerateDefinition(famBuilder, bspBuilder, !noPeripheralRegisters, true);
                    mcuDefinitions.Add(mcu);
                }

                BoardSupportPackage bsp = new BoardSupportPackage
                {
                    PackageID            = "com.sysprogs.arm.rs14100",
                    PackageDescription   = "Redpine RS14100 Devices",
                    GNUTargetID          = "arm-eabi",
                    GeneratedMakFileName = "rs14100.mak",
                    MCUFamilies          = new[] { famObj },
                    SupportedMCUs        = mcuDefinitions.ToArray(),
                    Frameworks           = frameworks.ToArray(),
                    Examples             = exampleDirs.Where(s => !s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                    TestExamples         = exampleDirs.Where(s => s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                    FileConditions       = bspBuilder.MatchedFileConditions.Values.ToArray(),
                    PackageVersion       = "1.1.3"
                };

                bspBuilder.ValidateBSP(bsp);
                bspBuilder.Save(bsp, !noPack, false);

                //StandaloneBSPValidator.Program.RunJob( "..\\..\\rs14100.validatejob", "f:\\bsptest");
            }
        }
예제 #7
0
        public static ParsedSDK ParseKSDKManifest(string sdkDirectory, IWarningSink sink)
        {
            string[] manifestFiles = Directory.GetFiles(sdkDirectory, "*manifest.xml");
            if (manifestFiles.Length < 1)
            {
                throw new Exception($"No manifest files in {sdkDirectory}");
            }

            string manifestFile = Directory.GetFiles(sdkDirectory, "*manifest.xml")[0];

            List <VendorSample> vsl = new List <VendorSample>();

            XmlDocument doc = new XmlDocument();

            doc.Load(manifestFile);

            List <MCU>             mcus          = new List <MCU>();
            List <MCUFamily>       families      = new List <MCUFamily>();
            List <ParsedComponent> allFrameworks = new List <ParsedComponent>();
            bool linkerScriptHandled             = false;

            List <string> allFiles = new List <string>();
            Dictionary <string, ParsedDevice>      deviceDict    = new Dictionary <string, ParsedDevice>();
            Dictionary <string, EmbeddedFramework> frameworkDict = new Dictionary <string, EmbeddedFramework>();
            List <FileCondition> allConditions        = new List <FileCondition>();
            string           fwPrefix                 = "com.sysprogs.ksdk2x_imported.";
            HashSet <string> alwaysIncludedFrameworks = new HashSet <string>();
            // HashSet<string> alwaysExcludedFrameworks = new HashSet<string>();
            List <string>     lstdevAll = new List <string>();
            List <CopiedFile> cfs       = new List <CopiedFile>();
            var dictCopiedFile          = new ListDictionary <string, CopiedFile>();
            var dictAddIncludeDir       = new ListDictionary <string, string>();


            foreach (XmlElement devNode in doc.SelectNodes("//devices/device"))
            {
                lstdevAll.Add(new ParsedDevice(devNode, sdkDirectory).DeviceName);
            }

            foreach (XmlElement devNode in doc.SelectNodes("//devices/device"))
            {
                ParsedDevice dev = new ParsedDevice(devNode, sdkDirectory);

                var mcuFamily = dev.ToMCUFamily();

                int FLASHSize, RAMSize;
                int.TryParse((devNode.SelectSingleNode("memory/@flash_size_kb")?.Value ?? ""), out FLASHSize);
                int.TryParse((devNode.SelectSingleNode("memory/@ram_size_kb")?.Value ?? ""), out RAMSize);
                FLASHSize *= 1024;
                RAMSize   *= 1024;

                families.Add(mcuFamily);
                string svdFile = null;

                //Map each component to an instance of EmbeddedFramework
                foreach (XmlNode componentNode in doc.SelectNodes($"//components/component"))
                {
                    string componentName = componentNode.SelectSingleNode("@name")?.Value ?? "";
                    string componentType = componentNode.SelectSingleNode("@type")?.Value ?? "";
                    string device        = componentNode.SelectSingleNode("@device")?.Value ?? "";
                    string idComponent   = componentNode.SelectSingleNode("@id")?.Value ?? "";
                    device = idComponent.Split('.').Last();

                    if (device != dev.DeviceName && (lstdevAll.Contains(device)))
                    {
                        continue;
                    }
                    switch (componentType)
                    {
                    case "documentation":
                    case "SCR":
                    case "EULA":
                        continue;

                    case "debugger":
                    case "linker":
                    {
                        List <string> relPaths   = new List <string>();
                        bool          isDebug    = componentType == "debugger";
                        string        sourceType = isDebug ? "debug" : "linker";
                        foreach (var src in componentNode.SelectNodes($"source[@type='{sourceType}' and @toolchain='armgcc']").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                        {
                            foreach (var fn in src.AllFiles)
                            {
                                relPaths.Add(fn.RelativePath);
                            }
                        }

                        if (relPaths.Count > 0)
                        {
                            if (isDebug)
                            {
                                svdFile = relPaths[0];
                            }
                            else if (!linkerScriptHandled)
                            {
                                linkerScriptHandled = true;
                                if (relPaths.Count == 1)
                                {
                                    mcuFamily.CompilationFlags.LinkerScript = "$$SYS:BSP_ROOT$$/" + relPaths[0];
                                }
                                else
                                {
                                    const string optionID = "com.sysprogs.imported.ksdk2x.linker_script";
                                    mcuFamily.CompilationFlags.LinkerScript = $"$$SYS:BSP_ROOT$$/$${optionID}$$";
                                    if ((mcuFamily.ConfigurableProperties?.PropertyGroups?.Count ?? 0) == 0)
                                    {
                                        mcuFamily.ConfigurableProperties = new PropertyList {
                                            PropertyGroups = new List <PropertyGroup> {
                                                new PropertyGroup()
                                            }
                                        }
                                    }
                                    ;

                                    mcuFamily.ConfigurableProperties.PropertyGroups[0].Properties.Add(new PropertyEntry.Enumerated
                                        {
                                            UniqueID       = optionID,
                                            Name           = "Linker script",
                                            AllowFreeEntry = false,
                                            SuggestionList = relPaths.Select(p => new PropertyEntry.Enumerated.Suggestion {
                                                InternalValue = p, UserFriendlyName = Path.GetFileName(p)
                                            }).ToArray()
                                        });
                                }
                            }
                        }
                    }
                        continue;

                    case "CMSIS":

                        //KSDK 2.x defines a Include_xxx framework for each possible CMSIS core. Those frameworks are redundant (normal 'Include' framework references the same include path) and should be removed to avoid confusion.
                        if (componentName.StartsWith("Include_"))
                        {
                            continue;
                        }
                        if (idComponent == "platform.CMSIS_Driver")
                        {
                            continue;
                        }

                        if (componentName == "Include")
                        {
                            alwaysIncludedFrameworks.Add(fwPrefix + componentName);    //!!! +"."+dev.DeviceName);
                        }
                        if (idComponent == "platform.CMSIS")
                        {
                            alwaysIncludedFrameworks.Add(fwPrefix + idComponent);    //!!! + "." + dev.DeviceName);
                        }
                        break;

                    case "project_template":
                        continue;

                    default:
                        break;
                    }

                    List <string> headerFiles        = new List <string>();
                    List <string> includeDirectories = new List <string>();
                    List <string> sourceFiles        = new List <string>();
                    List <string> libFiles           = new List <string>();

                    var IDFr = fwPrefix + idComponent;

                    foreach (ParsedSource src in componentNode.SelectNodes("source").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                    {
                        if (src.Exclude)
                        {
                            continue;
                        }

                        if (src.Type == "c_include")
                        {
                            includeDirectories.Add(src.BSPPath);
                        }

                        foreach (var file in src.AllFiles)
                        {
                            if (file.BSPPath.EndsWith("ucosii.c") && !componentName.Contains("ucosii"))
                            {
                                continue;
                            }
                            if (file.BSPPath.EndsWith("ucosiii.c") && !componentName.Contains("ucosiii"))
                            {
                                continue;
                            }

                            if (file.BSPPath.Contains("freertos"))
                            {
                                allConditions.Add(new FileCondition
                                {
                                    FilePath           = file.BSPPath,
                                    ConditionToInclude = new Condition.ReferencesFramework
                                    {
                                        FrameworkID = fwPrefix + "middleware.freertos." + dev.DeviceName
                                    }
                                });
                            }

                            if (src.TargetPath != "")
                            {
                                dictCopiedFile.Add(IDFr, new CopiedFile {
                                    SourcePath = file.BSPPath, TargetPath = src.TargetPath + "/" + Path.GetFileName(file.BSPPath)
                                });
                                foreach (XmlElement patch in componentNode.SelectNodes("include_paths/include_path"))
                                {
                                    dictAddIncludeDir.Add(IDFr, patch.GetAttribute("path"));
                                }
                            }
                            if (src.Type == "lib")
                            {
                                libFiles.Add(file.BSPPath);
                            }

                            if (src.Type == "src" || src.Type == "asm_include")
                            {
                                sourceFiles.Add(file.BSPPath);
                            }
                            else if (src.Type == "c_include")
                            {
                                headerFiles.Add(file.BSPPath);
                            }
                        }
                    }

                    foreach (XmlElement patch in componentNode.SelectNodes("include_paths/include_path"))
                    {
                        includeDirectories.Add(patch.GetAttribute("path"));
                    }

                    string[] dependencyList = componentNode.Attributes?.GetNamedItem("dependency")?.Value?.Split(' ')
                                              ?.Select(id => fwPrefix + id)
                                              ?.ToArray() ?? new string[0];

                    var FilterRegex = device.Length > 5 ? $"^{device.Substring(0, 5)}.*" : $"^{device}.*"; //MK02F MK22F
                    if (device.Length == 0)
                    {
                        FilterRegex = "";
                    }

                    EmbeddedFramework fw = new EmbeddedFramework
                    {
                        ID                           = $"{IDFr}",
                        MCUFilterRegex               = FilterRegex,
                        UserFriendlyName             = $"{componentName} ({componentType})",
                        ProjectFolderName            = componentName,
                        AdditionalSourceFiles        = sourceFiles.Distinct().ToArray(),
                        AdditionalHeaderFiles        = headerFiles.Distinct().ToArray(),
                        RequiredFrameworks           = dependencyList,
                        AdditionalIncludeDirs        = includeDirectories.Distinct().ToArray(),
                        AdditionalLibraries          = libFiles.ToArray(),
                        AdditionalPreprocessorMacros = componentNode.SelectNodes("defines/define").OfType <XmlElement>().Select(el => new ParsedDefine(el).Definition).ToArray(),
                    };

                    if (componentName == "freertos" && componentType == "OS")
                    {
                        fw.AdditionalPreprocessorMacros = LoadedBSP.Combine(fw.AdditionalPreprocessorMacros, "USE_RTOS=1;USE_FREERTOS".Split(';'));
                        fw.ConfigurableProperties       = new PropertyList
                        {
                            PropertyGroups = new List <PropertyGroup>()
                            {
                                new PropertyGroup
                                {
                                    Properties = new List <PropertyEntry>()
                                    {
                                        new PropertyEntry.Enumerated
                                        {
                                            Name              = "FreeRTOS Heap Implementation",
                                            UniqueID          = "com.sysprogs.bspoptions.stm32.freertos.heap",
                                            DefaultEntryIndex = 3,
                                            SuggestionList    = new PropertyEntry.Enumerated.Suggestion[]
                                            {
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_1", UserFriendlyName = "Heap1 - no support for freeing"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_2", UserFriendlyName = "Heap2 - no block consolidation"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_3", UserFriendlyName = "Heap3 - use newlib malloc()/free()"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_4", UserFriendlyName = "Heap4 - contiguous heap area"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_5", UserFriendlyName = "Heap5 - scattered heap area"
                                                },
                                            }
                                        }
                                    }
                                }
                            }
                        };

                        foreach (var fn in fw.AdditionalSourceFiles)
                        {
                            string name = Path.GetFileName(fn);
                            if (name.StartsWith("heap_"))
                            {
                                allConditions.Add(new FileCondition {
                                    FilePath = fn, ConditionToInclude = new Condition.Equals {
                                        Expression = "$$com.sysprogs.bspoptions.stm32.freertos.heap$$", ExpectedValue = Path.GetFileNameWithoutExtension(fn)
                                    }
                                });
                            }
                        }
                    }

                    if (frameworkDict.ContainsKey(fw.ID))
                    {
                        sink.LogWarning("Duplicate framework for " + fw.ID);
                        continue;
                    }

                    frameworkDict[fw.ID] = fw;

                    if (string.IsNullOrEmpty(fw.ID))
                    {
                        sink.LogWarning($"Found a framework with empty ID. Skipping...");
                        continue;
                    }

                    if (string.IsNullOrEmpty(fw.UserFriendlyName))
                    {
                        fw.UserFriendlyName = fw.ID;
                    }

                    allFrameworks.Add(new ParsedComponent {
                        Framework = fw, OriginalType = componentType, OriginalName = componentName
                    });
                    allFiles.AddRange(sourceFiles);
                    allFiles.AddRange(headerFiles);
                }

                string deviceDefinitionFile = null;
                if (svdFile != null)
                {
                    try
                    {
                        var mcuDef = SVDParser.ParseSVDFile(Path.Combine(sdkDirectory, svdFile), dev.DeviceName);
                        deviceDefinitionFile = Path.ChangeExtension(svdFile, ".vgdbdevice");

                        XmlSerializer ser = new XmlSerializer(typeof(MCUDefinition));
                        using (var fs = File.Create(Path.Combine(sdkDirectory, Path.ChangeExtension(svdFile, ".vgdbdevice.gz"))))
                            using (var gs = new GZipStream(fs, CompressionMode.Compress, true))
                                ser.Serialize(gs, new MCUDefinition(mcuDef));
                    }
                    catch (Exception ex)
                    {
                        sink.LogWarning($"Failed to parse {svdFile}: {ex.Message}");
                    }
                }

                foreach (XmlNode packageNode in devNode.SelectNodes($"package/@name"))
                {
                    string pkgName = packageNode?.Value;
                    if (string.IsNullOrEmpty(pkgName))
                    {
                        continue;
                    }

                    deviceDict[pkgName] = dev;

                    mcus.Add(new MCU
                    {
                        ID = pkgName,
                        UserFriendlyName = $"{pkgName} (KSDK 2.x)",
                        FamilyID         = mcuFamily.ID,
                        FLASHSize        = FLASHSize,
                        RAMSize          = RAMSize,
                        CompilationFlags = new ToolFlags
                        {
                            PreprocessorMacros = new string[] { "CPU_" + pkgName },
                        },

                        MCUDefinitionFile = deviceDefinitionFile
                    });
                }
            }

            if (families.Count == 0)
            {
                throw new Exception("The selected KSDK contains no families");
            }

            List <VendorSample> samples = new List <VendorSample>();

            foreach (XmlElement boardNode in doc.SelectNodes("//boards/board"))
            {
                string       boardName = boardNode.GetAttribute("name");
                string       deviceID  = boardNode.GetAttribute("package");
                ParsedDevice dev;
                if (!deviceDict.TryGetValue(deviceID, out dev))
                {
                    continue;
                }

                foreach (XmlElement directExampleNode in boardNode.SelectNodes("examples/example"))
                {
                    var exampleNode = directExampleNode;

                    var externalNode = exampleNode.SelectSingleNode("external/files");
                    if (externalNode != null)
                    {
                        var path = (externalNode.ParentNode as XmlElement)?.GetAttribute("path");
                        var mask = (externalNode as XmlElement)?.GetAttribute("mask");
                        if (path != null && mask != null)
                        {
                            {
                                var sampleFiles = Directory.GetFiles(Path.Combine(sdkDirectory, path), mask);
                                var fn          = sampleFiles?.FirstOrDefault();
                                if (fn != null)
                                {
                                    XmlDocument doc2 = new XmlDocument();
                                    doc2.Load(fn);
                                    exampleNode = doc2.DocumentElement.SelectSingleNode("example") as XmlElement;
                                    if (exampleNode == null)
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                    }

                    List <string> dependencyList = new List <string>(exampleNode.Attributes?.GetNamedItem("dependency")?.Value?.Split(' ')
                                                                     ?.Select(id => fwPrefix + id) ?? new string[0]);

                    var name = exampleNode.GetAttribute("id") ?? "???";

                    dependencyList.AddRange(alwaysIncludedFrameworks);

                    for (int i = 0; i < dependencyList.Count; i++)
                    {
                        EmbeddedFramework fw;
                        if (frameworkDict.TryGetValue(dependencyList[i], out fw) && fw?.RequiredFrameworks != null)
                        {
                            dependencyList.AddRange(fw.RequiredFrameworks.Except(dependencyList));
                        }
                    }
                    List <string>     dependencyList1     = new List <string>(dependencyList.Distinct());
                    List <CopiedFile> CopiedFileForSample = new List <CopiedFile>();
                    List <string>     includeDirectories  = new List <string>();
                    foreach (var fr1 in dependencyList1)
                    {
                        if (!dictCopiedFile.ContainsKey(fr1))
                        {
                            continue;
                        }

                        var l = dictCopiedFile[fr1];
                        CopiedFileForSample.AddRange(l);
                        if (dictAddIncludeDir.ContainsKey(fr1))
                        {
                            includeDirectories.AddRange(dictAddIncludeDir[fr1]);
                        }
                    }
                    List <PropertyDictionary2.KeyValue> CfgEntr = new List <PropertyDictionary2.KeyValue>();

                    string typFpu = "soft";
                    var    tth    = exampleNode.SelectSingleNode("toolchainSettings/toolchainSetting/option[@id='com.crt.advproject.gcc.fpu']")?.InnerText ?? "soft";

                    if (tth.Contains("hard"))
                    {
                        typFpu = "hard";
                    }

                    CfgEntr.Add(new PropertyDictionary2.KeyValue
                    {
                        Key   = "com.sysprogs.bspoptions.arm.floatmode",
                        Value = "-mfloat-abi=" + typFpu
                    });


                    VendorSample sample = new VendorSample
                    {
                        DeviceID         = deviceID,
                        UserFriendlyName = name,
                        BoardName        = boardName,
                        Configuration    = new VendorSampleConfiguration
                        {
                            Frameworks       = dependencyList.Distinct().ToArray(),
                            MCUConfiguration = new PropertyDictionary2 {
                                Entries = CfgEntr.ToArray()
                            }
                        },
                        VirtualPath = exampleNode.GetAttribute("category"),
                        ExtraFiles  = CopiedFileForSample.Distinct().ToArray(),

                        NoImplicitCopy = true
                    };

                    List <string> headerFiles = new List <string>();

                    List <string> sourceFiles = new List <string>();
                    foreach (var cf in CopiedFileForSample.Distinct())
                    {
                        includeDirectories.Add(Path.GetDirectoryName(cf.TargetPath));
                    }


                    foreach (var src in exampleNode.SelectNodes("source").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                    {
                        foreach (var file in src.AllFiles)
                        {
                            if (src.Type == "src" || src.Type == "asm_include")
                            {
                                sourceFiles.Add(file.BSPPath);
                            }
                            else if (src.Type == "c_include")
                            {
                                headerFiles.Add(file.BSPPath);
                            }
                            if (src.Type == "lib")
                            {
                                sourceFiles.Add(file.BSPPath);
                            }
                        }
                    }

                    sample.PreprocessorMacros = exampleNode.SelectNodes("toolchainSettings/toolchainSetting/option[@id='gnu.c.compiler.option.preprocessor.def.symbols']/value").OfType <XmlElement>().
                                                Select(node => node.InnerText.Replace("'\"", "'<").Replace("\"'", ">'")).ToArray();

                    sample.SourceFiles = sourceFiles.ToArray();
                    sample.HeaderFiles = headerFiles.ToArray();

                    if (sourceFiles.Count == 0 && headerFiles.Count == 0)
                    {
                        continue;
                    }

                    string[] matchingComponents = null;

                    foreach (var fn in sourceFiles.Concat(headerFiles))
                    {
                        string[] components = fn.Split('/', '\\');
                        if (matchingComponents == null)
                        {
                            matchingComponents = components;
                        }
                        else
                        {
                            int matches = CountMatches(matchingComponents, components);
                            if (matches < matchingComponents.Length)
                            {
                                Array.Resize(ref matchingComponents, matches);
                            }
                        }
                    }

                    if (matchingComponents != null)
                    {
                        sample.Path = string.Join("/", matchingComponents);
                    }

                    foreach (var hf in headerFiles)
                    {
                        int c = hf.LastIndexOf('/');
                        includeDirectories.Add(hf.Substring(0, c));
                    }

                    sample.IncludeDirectories = includeDirectories.Distinct().ToArray();
                    samples.Add(sample);
                }
            }

            return(new ParsedSDK
            {
                BSP = new BoardSupportPackage
                {
                    PackageID = "com.sysprogs.imported.ksdk2x." + families[0].ID,
                    PackageDescription = "Imported KSDK 2.x for " + families[0].ID,
                    PackageVersion = doc.SelectSingleNode("//ksdk/@version")?.Value ?? "unknown",
                    GNUTargetID = "arm-eabi",
                    Frameworks = allFrameworks.Where(f => f.OriginalType != "project_template").Select(f => f.Framework).ToArray(),
                    MCUFamilies = families.ToArray(),
                    SupportedMCUs = mcus.ToArray(),
                    FileConditions = allConditions.ToArray(),
                    VendorSampleCatalogName = "KSDK Samples",
                    EmbeddedSamples = allFrameworks.Where(f => f.OriginalType == "project_template").Select(f => f.ToProjectSample(alwaysIncludedFrameworks)).ToArray(),
                },

                VendorSampleDirectory = new VendorSampleDirectory
                {
                    Samples = samples.ToArray()
                }
            });
        }
예제 #8
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: nrf5x.exe <Nordic SW package directory>");
            }
            bool usingIoTSDK = false;

            /*            if (Directory.Exists(Path.Combine(args[0], @"components\iot\ble_6lowpan")))
             *          {
             *              usingIoTSDK = true;
             *              Console.WriteLine("Detected IoT SDK");
             *          }*/

            if (usingIoTSDK)
            {
                bspBuilder = new NordicBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules_iot"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("s1xx_iot", 0x1f000, 0x2800, "nrf52", "IoT", bspBuilder.Directories.InputDir));
            }
            else
            {
                bspBuilder = new NordicBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S132", "nrf52832.*", null, bspBuilder.Directories.InputDir));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S140", "nrf52840.*", null, bspBuilder.Directories.InputDir));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S112", "nrf52810.*", null, bspBuilder.Directories.InputDir));
            }
            List <MCUBuilder> devices = new List <MCUBuilder>();

#if NRF51_SUPPORT
            if (!usingIoTSDK)
            {
                foreach (string part in new string[] { "nRF51822", "nRF51422" })
                {
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAA", FlashSize = 256 * 1024, RAMSize = 16 * 1024, Core = CortexCore.M0
                    });
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAB", FlashSize = 128 * 1024, RAMSize = 16 * 1024, Core = CortexCore.M0
                    });
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAC", FlashSize = 256 * 1024, RAMSize = 32 * 1024, Core = CortexCore.M0
                    });
                }
            }
#endif


            devices.Add(new MCUBuilder {
                Name = "nRF52832_XXAA", FlashSize = 512 * 1024, RAMSize = 64 * 1024, Core = CortexCore.M4, StartupFile = "$$SYS:BSP_ROOT$$/nRF5x/components/toolchain/gcc/gcc_startup_nrf52.S"
            });
            devices.Add(new MCUBuilder {
                Name = "nRF52840_XXAA", FlashSize = 1024 * 1024, RAMSize = 256 * 1024, Core = CortexCore.M4, StartupFile = "$$SYS:BSP_ROOT$$/nRF5x/components/toolchain/gcc/gcc_startup_nrf52840.S"
            });
            devices.Add(new MCUBuilder {
                Name = "nRF52810_XXAA", FlashSize = 192 * 1024, RAMSize = 24 * 1024, Core = CortexCore.M4_NOFPU, StartupFile = "$$SYS:BSP_ROOT$$/nRF5x/components/toolchain/gcc/gcc_startup_nrf52810.S"
            });

            List <MCUFamilyBuilder> allFamilies = new List <MCUFamilyBuilder>();
            foreach (var fn in Directory.GetFiles(bspBuilder.Directories.RulesDir + @"\Families", "*.xml"))
            {
                allFamilies.Add(new NordicFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(fn)));
            }

            var rejects = BSPGeneratorTools.AssignMCUsToFamilies(devices, allFamilies);

            List <EmbeddedFramework>             frameworks  = new List <EmbeddedFramework>();
            List <MCUFamilyBuilder.CopiedSample> exampleDirs = new List <MCUFamilyBuilder.CopiedSample>();

            bool noPeripheralRegisters = true;

            List <MCUFamily> familyDefinitions = new List <MCUFamily>();
            List <MCU>       mcuDefinitions    = new List <MCU>();

            var           commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml"));
            var           flags        = new ToolFlags();
            List <string> projectFiles = new List <string>();
            commonPseudofamily.CopyFamilyFiles(ref flags, projectFiles);
            flags = flags.Merge(commonPseudofamily.Definition.CompilationFlags);

            List <ConditionalToolFlags> condFlags = new List <ConditionalToolFlags>();

            foreach (var fam in allFamilies)
            {
                fam.GenerateLinkerScripts(false);
                Console.WriteLine("Processing " + fam.Definition.Name + " family...");
                string famBase = fam.Definition.Name.Substring(0, 5).ToLower();

                var rejectedMCUs = fam.RemoveUnsupportedMCUs(true);
                if (rejectedMCUs.Length != 0)
                {
                    Console.WriteLine("Unsupported {0} MCUs:", fam.Definition.Name);
                    foreach (var mcu in rejectedMCUs)
                    {
                        Console.WriteLine("\t{0}", mcu.Name);
                    }
                }

                List <Framework> bleFrameworks = new List <Framework>();
                foreach (var line in File.ReadAllLines(bspBuilder.Directories.RulesDir + @"\BLEFrameworks.txt"))
                {
                    int    idx  = line.IndexOf('|');
                    string dir  = line.Substring(0, idx);
                    string desc = line.Substring(idx + 1);

                    string id = Path.GetFileName(dir);
                    if (!id.StartsWith("ble_"))
                    {
                        id = "ble_" + id;
                    }

                    if (dir.StartsWith("services\\", StringComparison.CurrentCultureIgnoreCase))
                    {
                        id = "ble_svc_" + id.Substring(4);
                    }

                    bleFrameworks.Add(new Framework
                    {
                        Name              = string.Format("Bluetooth LE - {0} ({1})", desc, Path.GetFileName(dir)),
                        ID                = "com.sysprogs.arm.nordic." + famBase + "." + id,
                        ClassID           = "com.sysprogs.arm.nordic.nrfx." + id,
                        ProjectFolderName = "BLE " + desc,
                        DefaultEnabled    = false,
                        CopyJobs          = new CopyJob[]
                        {
                            new CopyJob
                            {
                                SourceFolder = allFamilies[0].Definition.PrimaryHeaderDir + @"\..\components\ble\" + dir,
                                TargetFolder = dir,
                                FilesToCopy  = "*.c;*.h",
                            }
                        }
                    });
                }

                fam.Definition.AdditionalFrameworks = fam.Definition.AdditionalFrameworks.Concat(bleFrameworks).ToArray();

                // Starting from SDK 14.0 we use the original Nordic startup files & linker scripts as they contain various non-trivial logic
#if GENERATE_STARTUP_FILES
                StartupFileGenerator.InterruptVectorTable[] aStartupVectors;
                if (usingIoTSDK)
                {
                    aStartupVectors = new StartupFileGenerator.InterruptVectorTable[] {
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF52")
                    }
                }
                ;
                else
                {
                    aStartupVectors = new StartupFileGenerator.InterruptVectorTable[] {
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF51"),
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF52")
                    }
                };

                fam.AttachStartupFiles(aStartupVectors);
#endif

                //  SVD Files
                var aMcuDef1 = (new MCUDefinitionWithPredicate[] { SVDParser.ParseSVDFile(Path.Combine(fam.Definition.PrimaryHeaderDir, "nRF51.svd"), "nRF51") });
                aMcuDef1[0].MatchPredicate = m => m.Name.StartsWith("nRF51");

                var aMcuDef2 = (new MCUDefinitionWithPredicate[] { SVDParser.ParseSVDFile(Path.Combine(fam.Definition.PrimaryHeaderDir, "nRF52.svd"), "nRF52") });
                aMcuDef2[0].MatchPredicate = m => m.Name.StartsWith("nRF52");

                fam.AttachPeripheralRegisters(aMcuDef1.Concat(aMcuDef2));

                var famObj = fam.GenerateFamilyObject(true);

                famObj.AdditionalSourceFiles = LoadedBSP.Combine(famObj.AdditionalSourceFiles, projectFiles.Where(f => !MCUFamilyBuilder.IsHeaderFile(f)).ToArray());
                famObj.AdditionalHeaderFiles = LoadedBSP.Combine(famObj.AdditionalHeaderFiles, projectFiles.Where(f => MCUFamilyBuilder.IsHeaderFile(f)).ToArray());

                famObj.AdditionalSystemVars = LoadedBSP.Combine(famObj.AdditionalSystemVars, commonPseudofamily.Definition.AdditionalSystemVars);
                famObj.CompilationFlags     = famObj.CompilationFlags.Merge(flags);

                familyDefinitions.Add(famObj);
                fam.GenerateLinkerScripts(false);

                SysVarEntry suffixEntry = null;

                foreach (var mcu in fam.MCUs)
                {
                    var mcuDef = mcu.GenerateDefinition(fam, bspBuilder, !noPeripheralRegisters, false, MCUFamilyBuilder.CoreSpecificFlags.All & ~MCUFamilyBuilder.CoreSpecificFlags.PrimaryMemory);

                    if (mcu.Name.StartsWith("nRF52832"))
                    {
                        //Although documented as a legacy definition, skipping this breaks fds_internal_defs.h
                        mcuDef.CompilationFlags.PreprocessorMacros = mcuDef.CompilationFlags.PreprocessorMacros.Concat(new[] { "NRF52" }).ToArray();
                    }

                    var compatibleSoftdevs = new[]
                    {
                        new PropertyEntry.Enumerated.Suggestion {
                            InternalValue = "nosoftdev", UserFriendlyName = "None"
                        }
                    }
                    .Concat(bspBuilder.SoftDevices.Where(sd => sd.IsCompatible(mcu.Name))
                            .SelectMany(s => new[]
                    {
                        new PropertyEntry.Enumerated.Suggestion {
                            InternalValue = s.Name, UserFriendlyName = s.UserFriendlyName
                        },
                        new PropertyEntry.Enumerated.Suggestion {
                            InternalValue = s.Name + "_reserve", UserFriendlyName = $"{s.UserFriendlyName} (programmed separately)"
                        }
                    }))
                    .ToArray();

                    if (mcuDef.ConfigurableProperties == null)
                    {
                        mcuDef.ConfigurableProperties = new PropertyList {
                            PropertyGroups = new List <PropertyGroup>()
                        }
                    }
                    ;
                    mcuDef.ConfigurableProperties.PropertyGroups.Add(new PropertyGroup
                    {
                        Properties = new List <PropertyEntry>
                        {
                            new PropertyEntry.Enumerated
                            {
                                UniqueID          = NordicBSPBuilder.SoftdevicePropertyID,
                                Name              = "Softdevice",
                                DefaultEntryIndex = 1,
                                SuggestionList    = compatibleSoftdevs,
                            }
                        }
                    });

                    if (mcu.Name.StartsWith("nRF52") && !mcu.Name.StartsWith("nRF52810"))
                    {
                        var prop = mcuDef.ConfigurableProperties.PropertyGroups[0].Properties.Find(p => p.UniqueID == "com.sysprogs.bspoptions.arm.floatmode") as PropertyEntry.Enumerated;
                        var idx  = Array.FindIndex(prop.SuggestionList, p => p.UserFriendlyName == "Hardware");
                        prop.DefaultEntryIndex = idx;
                        prop.SuggestionList[idx].UserFriendlyName = "Hardware (required when using a softdevice)";   //Otherwise the system_nrf52.c file won't initialize the FPU and the internal initialization of the softdevice will later fail.
                    }

                    string defaultConfig;
                    if (mcu.Name.StartsWith("nRF52840"))
                    {
                        defaultConfig = "pca10056/s140";
                    }
                    else if (mcu.Name.StartsWith("nRF52810"))
                    {
                        defaultConfig = "pca10040e/s112";
                    }
                    else
                    {
                        defaultConfig = "pca10040/s132";
                    }

                    suffixEntry = new SysVarEntry {
                        Key = "com.sysprogs.nordic.default_config_suffix", Value = defaultConfig
                    };
                    mcuDef.AdditionalSystemVars = LoadedBSP.Combine(mcuDef.AdditionalSystemVars, new SysVarEntry[] { suffixEntry });

                    mcuDefinitions.Add(mcuDef);
                }

                if (fam.Definition.ConditionalFlags != null)
                {
                    condFlags.AddRange(fam.Definition.ConditionalFlags);
                }

                foreach (var fw in fam.GenerateFrameworkDefinitions())
                {
                    frameworks.Add(fw);
                }

                foreach (var sample in fam.CopySamples(null, new SysVarEntry[] { new SysVarEntry {
                                                                                     Key = "com.sysprogs.nordic.default_config_suffix", Value = "pca10040e/s112"
                                                                                 } }))
                {
                    exampleDirs.Add(sample);
                }
            }

            const string softdevExpression = "$$com.sysprogs.bspoptions.nrf5x.softdevice$$";

            foreach (var softdev in bspBuilder.SoftDevices)
            {
                condFlags.Add(new ConditionalToolFlags
                {
                    FlagCondition = new Condition.Equals {
                        Expression = softdevExpression, ExpectedValue = softdev.Name + "_reserve"
                    },
                    Flags = new ToolFlags
                    {
                        PreprocessorMacros = familyDefinitions.First().CompilationFlags.PreprocessorMacros.Where(f => f.Contains(softdevExpression)).Select(f => f.Replace(softdevExpression, softdev.Name)).ToArray(),
                        IncludeDirectories = familyDefinitions.First().CompilationFlags.IncludeDirectories.Where(f => f.Contains(softdevExpression)).Select(f => f.Replace(softdevExpression, softdev.Name)).ToArray()
                    }
                });
            }

            bspBuilder.GenerateSoftdeviceLibraries();

            Console.WriteLine("Building BSP archive...");
            string strPackageID, strPackageDesc, strPAckVersion;
            if (usingIoTSDK)
            {
                strPackageID   = "com.sysprogs.arm.nordic.nrf5x-iot";
                strPackageDesc = "Nordic NRF52 IoT";
                strPAckVersion = "0.9";

                foreach (var mcu in mcuDefinitions)
                {
                    mcu.UserFriendlyName = mcu.ID + " (IoT)";
                }
            }
            else
            {
                strPackageID   = "com.sysprogs.arm.nordic.nrf5x";
                strPackageDesc = "Nordic NRF52x Devices";
                strPAckVersion = "14.2R2";
            }

            BoardSupportPackage bsp = new BoardSupportPackage
            {
                PackageID            = strPackageID,
                PackageDescription   = strPackageDesc,
                GNUTargetID          = "arm-eabi",
                GeneratedMakFileName = "nrf5x.mak",
                MCUFamilies          = familyDefinitions.ToArray(),
                SupportedMCUs        = mcuDefinitions.ToArray(),
                Frameworks           = frameworks.ToArray(),
                Examples             = exampleDirs.Where(s => !s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                TestExamples         = exampleDirs.Where(s => s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                PackageVersion       = strPAckVersion,
                FileConditions       = bspBuilder.MatchedFileConditions.ToArray(),
                MinimumEngineVersion = "5.0",
                ConditionalFlags     = condFlags.ToArray(),
                InitializationCodeInsertionPoints = commonPseudofamily.Definition.InitializationCodeInsertionPoints,
            };

            bspBuilder.Save(bsp, true, false);
        }
    }
예제 #9
0
파일: Program.cs 프로젝트: whinis/BSPTools
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: risc-v.exe <freedom-e-sdk directory with build logs>");
            }

            const string TargetVariable       = "com.sysprogs.riscv.target";
            const string LinkerScriptVariant  = "com.sysprogs.riscv.linkerscript";
            string       linkerScriptTemplate = $"$$SYS:BSP_ROOT$$/bsp/$${TargetVariable}$$/metal.$${LinkerScriptVariant}$$.lds";
            const string FamilyName           = "SIFIVE";

            using (var bspBuilder = new RISCVBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules", @"..\..\logs")))
            {
                BoardSupportPackage bsp = new BoardSupportPackage
                {
                    PackageID            = "com.sysprogs.arm.riscv.sifive",
                    PackageDescription   = "SiFive Freedom E Devices",
                    GNUTargetID          = "riscv64-unknown-elf",
                    RequiredToolchainID  = "com.visualgdb.risc-v",
                    GeneratedMakFileName = "sifive.mak",
                    PackageVersion       = "1.0",
                    MinimumEngineVersion = "5.4",

                    MCUFamilies = new[]
                    {
                        new MCUFamily
                        {
                            ID = FamilyName,
                            CompilationFlags = new ToolFlags
                            {
                                IncludeDirectories  = new[] { $"$$SYS:BSP_ROOT$$/bsp/$${TargetVariable}$$/install/include" },
                                LinkerScript        = linkerScriptTemplate,
                                AdditionalLibraries = new[] { "c", "gcc", "m" },
                            },

                            ConfigurableProperties = new PropertyList
                            {
                                PropertyGroups = new List <PropertyGroup>
                                {
                                    new PropertyGroup
                                    {
                                        Properties = new List <PropertyEntry>
                                        {
                                            new PropertyEntry.Enumerated
                                            {
                                                UniqueID       = LinkerScriptVariant,
                                                Name           = "Default Linker Script",
                                                SuggestionList = new [] { "default", "freertos", "ramrodata", "scratchpad" }.Select(s => new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = s
                                                }).ToArray(),
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                };

                List <MCU> mcus = new List <MCU>();
                var        commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml"));
                List <MCUDefinitionWithPredicate> registers = new List <MCUDefinitionWithPredicate>();

                foreach (var bspDir in Directory.GetDirectories(Path.Combine(bspBuilder.Directories.InputDir, "bsp")))
                {
                    var target  = Path.GetFileName(bspDir);
                    var logFile = Path.Combine(bspBuilder.Directories.InputDir, target + ".log");
                    if (!File.Exists(logFile))
                    {
                        throw new Exception($"Missing {logFile}. Please run _buildall.sh in the SDK directory using WSL.");
                    }

                    var parsedLog = BuildLogFileParser.ParseRISCVBuildLog(logFile);
                    if (parsedLog.LinkerScript == null)
                    {
                        throw new Exception("Unknown linker script");
                    }

                    var script = bspBuilder.WSLPathToBSPPath(parsedLog.LinkerScript).Replace('/', '\\');
                    if (StringComparer.InvariantCultureIgnoreCase.Compare(script, linkerScriptTemplate.Replace($"$${TargetVariable}$$", target).Replace($"$${LinkerScriptVariant}$$", "default").Replace('/', '\\')) != 0)
                    {
                        throw new Exception("Unexpected linker script: " + script);
                    }

                    var memories = LinkerScriptTools.ScanLinkerScriptForMemories(script.Replace("$$SYS:BSP_ROOT$$", bspBuilder.Directories.InputDir));

                    var mcu = new MCU
                    {
                        ID = target.ToUpper(),
                        UserFriendlyName = target.ToUpper(),
                        FamilyID         = FamilyName,

                        MemoryMap = new AdvancedMemoryMap
                        {
                            Memories = memories,
                        },

                        CompilationFlags = new ToolFlags
                        {
                            IncludeDirectories = parsedLog.allIncludes.Where(inc => inc != ".").Select(bspBuilder.WSLPathToBSPPath).ToArray(),
                            PreprocessorMacros = parsedLog.allDefines.Where(kv => !kv.Key.StartsWith("PACKAGE")).Select(kv => $"{kv.Key}={kv.Value}").ToArray(),
                            COMMONFLAGS        = string.Join(" ", parsedLog.allFlags),
                            LDFLAGS            = string.Join(" ", parsedLog.AllLDFlags),
                        },
                        AdditionalSystemVars = new[]
                        {
                            new SysVarEntry
                            {
                                Key   = TargetVariable,
                                Value = target,
                            }
                        },

                        RAMSize           = (int)(memories.FirstOrDefault(m => m.Name == "ram")?.Size ?? 0),
                        FLASHSize         = (int)(memories.FirstOrDefault(m => m.Name == "rom")?.Size ?? 0),
                        MCUDefinitionFile = $"DeviceDefinitions/{target.ToUpper()}.xml",
                    };

                    if (mcu.RAMSize < 0)
                    {
                        mcu.RAMSize = 0;
                    }

                    var parsedSVD = SVDParser.ParseSVDFile(Path.Combine(bspDir, "design.svd"), target.ToUpper());
                    parsedSVD.MatchPredicate = new MCUPredicateImpl(mcu).Match;
                    registers.Add(parsedSVD);

                    commonPseudofamily.MCUs.Add(new MCUBuilder {
                        Name = mcu.ID
                    });

                    mcus.Add(mcu);
                }

                commonPseudofamily.AttachPeripheralRegisters(registers);
                bsp.SupportedMCUs = mcus.ToArray();


                List <string> projectFiles = new List <string>();
                PropertyList  unused       = null;

                if (commonPseudofamily.Definition.CoreFramework != null)
                {
                    foreach (var job in commonPseudofamily.Definition.CoreFramework.CopyJobs)
                    {
                        job.CopyAndBuildFlags(bspBuilder, projectFiles, null, ref unused, null);
                    }
                }

                bsp.Frameworks = commonPseudofamily.GenerateFrameworkDefinitions().ToArray();

                var samples = commonPseudofamily.CopySamples(bsp.Frameworks).ToArray();
                bsp.Examples = samples.Select(s => s.RelativePath).ToArray();


                var mainFamily = bsp.MCUFamilies.First();

                if (mainFamily.AdditionalSourceFiles != null || mainFamily.AdditionalHeaderFiles != null || bsp.FileConditions != null)
                {
                    throw new Exception("TODO: merge lists");
                }

                mainFamily.AdditionalSourceFiles = projectFiles.Where(f => !MCUFamilyBuilder.IsHeaderFile(f)).ToArray();
                mainFamily.AdditionalHeaderFiles = projectFiles.Where(f => MCUFamilyBuilder.IsHeaderFile(f)).ToArray();
                bsp.FileConditions = bspBuilder.MatchedFileConditions.Values.ToArray();

                XmlTools.SaveObject(bsp, Path.Combine(bspBuilder.BSPRoot, "BSP.XML"));
            }
        }
예제 #10
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: nrf5x.exe <Nordic SW package directory>");
            }
            bool usingIoTSDK = false;

            if (Directory.Exists(Path.Combine(args[0], @"components\iot\ble_6lowpan")))
            {
                usingIoTSDK = true;
                Console.WriteLine("Detected IoT SDK");
            }

            NordicBSPBuilder bspBuilder;

            if (usingIoTSDK)
            {
                bspBuilder = new NordicBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules_iot"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("s1xx_iot", 0x1f000, 0x2800, "nrf52", "IoT"));
            }
            else
            {
                bspBuilder = new NordicBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S130", 0x1b000, 0x13c8, "nrf51", "Bluetooth LE Universal"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S132", 0x20000, 0x2168, "nrf52832", "Bluetooth LE"));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S140", 0x21000, 0x2780, "nrf52840", "Bluetooth LE"));
            }
            List <MCUBuilder> devices = new List <MCUBuilder>();

            if (!usingIoTSDK)
            {
                foreach (string part in new string[] { "nRF51822", "nRF51422" })
                {
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAA", FlashSize = 256 * 1024, RAMSize = 16 * 1024, Core = CortexCore.M0
                    });
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAB", FlashSize = 128 * 1024, RAMSize = 16 * 1024, Core = CortexCore.M0
                    });
                    devices.Add(new MCUBuilder {
                        Name = part + "_XXAC", FlashSize = 256 * 1024, RAMSize = 32 * 1024, Core = CortexCore.M0
                    });
                }
            }

            devices.Add(new MCUBuilder {
                Name = "nRF52832_XXAA", FlashSize = 512 * 1024, RAMSize = 64 * 1024, Core = CortexCore.M4
            });
            devices.Add(new MCUBuilder {
                Name = "nRF52840_XXAA", FlashSize = 1024 * 1024, RAMSize = 256 * 1024, Core = CortexCore.M4
            });

            List <MCUFamilyBuilder> allFamilies = new List <MCUFamilyBuilder>();

            foreach (var fn in Directory.GetFiles(bspBuilder.Directories.RulesDir + @"\Families", "*.xml"))
            {
                allFamilies.Add(new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(fn)));
            }

            var rejects = BSPGeneratorTools.AssignMCUsToFamilies(devices, allFamilies);

            List <EmbeddedFramework>             frameworks  = new List <EmbeddedFramework>();
            List <MCUFamilyBuilder.CopiedSample> exampleDirs = new List <MCUFamilyBuilder.CopiedSample>();

            bool noPeripheralRegisters = true;

            List <MCUFamily> familyDefinitions = new List <MCUFamily>();
            List <MCU>       mcuDefinitions    = new List <MCU>();

            var           commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml"));
            var           flags        = new ToolFlags();
            List <string> projectFiles = new List <string>();

            commonPseudofamily.CopyFamilyFiles(ref flags, projectFiles);
            flags = flags.Merge(commonPseudofamily.Definition.CompilationFlags);

            List <ConditionalToolFlags> condFlags = new List <ConditionalToolFlags>();

            foreach (var fam in allFamilies)
            {
                Console.WriteLine("Processing " + fam.Definition.Name + " family...");
                string famBase = fam.Definition.Name.Substring(0, 5).ToLower();

                var rejectedMCUs = fam.RemoveUnsupportedMCUs(true);
                if (rejectedMCUs.Length != 0)
                {
                    Console.WriteLine("Unsupported {0} MCUs:", fam.Definition.Name);
                    foreach (var mcu in rejectedMCUs)
                    {
                        Console.WriteLine("\t{0}", mcu.Name);
                    }
                }

                List <Framework> bleFrameworks = new List <Framework>();
                foreach (var line in File.ReadAllLines(bspBuilder.Directories.RulesDir + @"\BLEFrameworks.txt"))
                {
                    int    idx  = line.IndexOf('|');
                    string dir  = line.Substring(0, idx);
                    string desc = line.Substring(idx + 1);

                    string id = Path.GetFileName(dir);
                    if (!id.StartsWith("ble_"))
                    {
                        id = "ble_" + id;
                    }

                    if (dir.StartsWith("services\\", StringComparison.CurrentCultureIgnoreCase))
                    {
                        id = "ble_svc_" + id.Substring(4);
                    }

                    bleFrameworks.Add(new Framework
                    {
                        Name              = string.Format("Bluetooth LE - {0} ({1})", desc, Path.GetFileName(dir)),
                        ID                = "com.sysprogs.arm.nordic." + famBase + "." + id,
                        ClassID           = "com.sysprogs.arm.nordic.nrfx." + id,
                        ProjectFolderName = "BLE " + desc,
                        DefaultEnabled    = false,
                        CopyJobs          = new CopyJob[]
                        {
                            new CopyJob
                            {
                                SourceFolder = allFamilies[0].Definition.PrimaryHeaderDir + @"\..\components\ble\" + dir,
                                TargetFolder = dir,
                                FilesToCopy  = "*.c;*.h",
                            }
                        }
                    });
                }

                fam.Definition.AdditionalFrameworks = fam.Definition.AdditionalFrameworks.Concat(bleFrameworks).ToArray();
                // Startup Files
                StartupFileGenerator.InterruptVectorTable[] aStartupVectors;
                if (usingIoTSDK)
                {
                    aStartupVectors = new StartupFileGenerator.InterruptVectorTable[] {
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF52")
                    }
                }
                ;
                else
                {
                    aStartupVectors = new StartupFileGenerator.InterruptVectorTable[] {
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF51"),
                        GenerateStartupFile(fam.Definition.StartupFileDir, "nRF52")
                    }
                };

                fam.AttachStartupFiles(aStartupVectors);
                //  SVD Files
                var aMcuDef1 = (new MCUDefinitionWithPredicate[] { SVDParser.ParseSVDFile(Path.Combine(fam.Definition.PrimaryHeaderDir, "nRF51.svd"), "nRF51") });
                aMcuDef1[0].MatchPredicate = m => m.Name.StartsWith("nRF51");

                var aMcuDef2 = (new MCUDefinitionWithPredicate[] { SVDParser.ParseSVDFile(Path.Combine(fam.Definition.PrimaryHeaderDir, "nRF52.svd"), "nRF52") });
                aMcuDef2[0].MatchPredicate = m => m.Name.StartsWith("nRF52");

                fam.AttachPeripheralRegisters(aMcuDef1.Concat(aMcuDef2));

                var famObj = fam.GenerateFamilyObject(true);

                famObj.AdditionalSourceFiles = LoadedBSP.Combine(famObj.AdditionalSourceFiles, projectFiles.Where(f => !MCUFamilyBuilder.IsHeaderFile(f)).ToArray());
                famObj.AdditionalHeaderFiles = LoadedBSP.Combine(famObj.AdditionalHeaderFiles, projectFiles.Where(f => MCUFamilyBuilder.IsHeaderFile(f)).ToArray());

                famObj.AdditionalSystemVars = LoadedBSP.Combine(famObj.AdditionalSystemVars, commonPseudofamily.Definition.AdditionalSystemVars);
                famObj.CompilationFlags     = famObj.CompilationFlags.Merge(flags);

                familyDefinitions.Add(famObj);
                fam.GenerateLinkerScripts(false);

                SysVarEntry defaultConfigFolder51 = new SysVarEntry {
                    Key = "com.sysprogs.nordic.default_config_suffix", Value = "pca10040/s132"
                };                                                                                                                                 // s132_pca10036" };
                SysVarEntry defaultConfigFolder52 = new SysVarEntry {
                    Key = "com.sysprogs.nordic.default_config_suffix", Value = "pca10028/s130"
                };                                                                                                                                 // s130_pca10028" };

                foreach (var mcu in fam.MCUs)
                {
                    var mcuDef = mcu.GenerateDefinition(fam, bspBuilder, !noPeripheralRegisters);
                    var compatibleSoftdevs = new PropertyEntry.Enumerated.Suggestion[] { new PropertyEntry.Enumerated.Suggestion {
                                                                                             InternalValue = "nosoftdev", UserFriendlyName = "None"
                                                                                         } }.Concat(bspBuilder.SoftDevices.Where(sd => sd.IsCompatible(mcu.Name)).Select(s => new PropertyEntry.Enumerated.Suggestion {
                        InternalValue = s.Name, UserFriendlyName = s.UserFriendlyName
                    })).ToArray();

                    if (mcuDef.ConfigurableProperties == null)
                    {
                        mcuDef.ConfigurableProperties = new PropertyList {
                            PropertyGroups = new List <PropertyGroup>()
                        }
                    }
                    ;
                    mcuDef.ConfigurableProperties.PropertyGroups.Add(new PropertyGroup
                    {
                        Properties = new List <PropertyEntry>
                        {
                            new PropertyEntry.Enumerated
                            {
                                UniqueID          = NordicBSPBuilder.SoftdevicePropertyID,
                                Name              = "Softdevice",
                                DefaultEntryIndex = 1,
                                SuggestionList    = compatibleSoftdevs,
                            }
                        }
                    });

                    if (mcu.Name.StartsWith("nRF52"))
                    {
                        var prop = mcuDef.ConfigurableProperties.PropertyGroups[0].Properties.Find(p => p.UniqueID == "com.sysprogs.bspoptions.arm.floatmode") as PropertyEntry.Enumerated;
                        var idx  = Array.FindIndex(prop.SuggestionList, p => p.UserFriendlyName == "Hardware");
                        prop.DefaultEntryIndex = idx;
                        prop.SuggestionList[idx].UserFriendlyName = "Hardware (required when using a softdevice)";   //Otherwise the system_nrf52.c file won't initialize the FPU and the internal initialization of the softdevice will later fail.

                        mcuDef.AdditionalSystemVars = LoadedBSP.Combine(mcuDef.AdditionalSystemVars, new SysVarEntry[] { defaultConfigFolder51 });
                    }
                    else
                    {
                        mcuDef.AdditionalSystemVars = LoadedBSP.Combine(mcuDef.AdditionalSystemVars, new SysVarEntry[] { defaultConfigFolder52 });
                    }

                    mcuDefinitions.Add(mcuDef);
                }

                if (fam.Definition.ConditionalFlags != null)
                {
                    condFlags.AddRange(fam.Definition.ConditionalFlags);
                }

                foreach (var fw in fam.GenerateFrameworkDefinitions())
                {
                    frameworks.Add(fw);
                }

                foreach (var sample in fam.CopySamples(null, new SysVarEntry[] { defaultConfigFolder51 }))
                {
                    exampleDirs.Add(sample);
                }
                //                var prioritizer = new SamplePrioritizer(Path.Combine(bspBuilder.Directories.RulesDir, "SamplePriorities.txt"));
                //                exampleDirs.Sort((a, b) => prioritizer.Prioritize(a.RelativePath, b.RelativePath));
            }
            bspBuilder.GenerateSoftdeviceLibraries();

            Console.WriteLine("Building BSP archive...");
            string strPackageID, strPackageDesc, strPAckVersion;

            if (usingIoTSDK)
            {
                strPackageID   = "com.sysprogs.arm.nordic.nrf5x-iot";
                strPackageDesc = "Nordic NRF52 IoT";
                strPAckVersion = "0.9";

                foreach (var mcu in mcuDefinitions)
                {
                    mcu.UserFriendlyName = mcu.ID + " (IoT)";
                }
            }
            else
            {
                strPackageID   = "com.sysprogs.arm.nordic.nrf5x";
                strPackageDesc = "Nordic NRF5x Devices";
                strPAckVersion = "13.0-alpha";
            }

            BoardSupportPackage bsp = new BoardSupportPackage
            {
                PackageID            = strPackageID,
                PackageDescription   = strPackageDesc,
                GNUTargetID          = "arm-eabi",
                GeneratedMakFileName = "nrf5x.mak",
                MCUFamilies          = familyDefinitions.ToArray(),
                SupportedMCUs        = mcuDefinitions.ToArray(),
                Frameworks           = frameworks.ToArray(),
                Examples             = exampleDirs.Where(s => !s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                TestExamples         = exampleDirs.Where(s => s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                PackageVersion       = strPAckVersion,
                FileConditions       = bspBuilder.MatchedFileConditions.ToArray(),
                MinimumEngineVersion = "5.0",
                ConditionalFlags     = condFlags.ToArray(),
            };

            bspBuilder.Save(bsp, true);
        }
    }
}
예제 #11
0
        public static ParsedSDK ParseKSDKManifest(string sdkDirectory, IWarningSink sink)
        {
            string[] manifestFiles = Directory.GetFiles(sdkDirectory, "*manifest.xml");
            if (manifestFiles.Length < 1)
            {
                throw new Exception($"No manifest files in {sdkDirectory}");
            }

            string manifestFile = Directory.GetFiles(sdkDirectory, "*manifest.xml")[0];

            List <VendorSample> vsl = new List <VendorSample>();

            XmlDocument doc = new XmlDocument();

            doc.Load(manifestFile);

            List <MCU>             mcus          = new List <MCU>();
            List <MCUFamily>       families      = new List <MCUFamily>();
            List <ParsedComponent> allFrameworks = new List <ParsedComponent>();
            bool linkerScriptHandled             = false;

            List <string> allFiles = new List <string>();
            Dictionary <string, ParsedDevice>      deviceDict    = new Dictionary <string, ParsedDevice>();
            Dictionary <string, EmbeddedFramework> frameworkDict = new Dictionary <string, EmbeddedFramework>();
            List <FileCondition> allConditions        = new List <FileCondition>();
            string           fwPrefix                 = "com.sysprogs.ksdk2x_imported.";
            HashSet <string> alwaysIncludedFrameworks = new HashSet <string>();

            foreach (XmlElement devNode in doc.SelectNodes("//devices/device"))
            {
                ParsedDevice dev = new ParsedDevice(devNode, sdkDirectory);

                var mcuFamily = dev.ToMCUFamily();

                int FLASHSize, RAMSize;
                int.TryParse((devNode.SelectSingleNode("memory/@flash_size_kb")?.Value ?? ""), out FLASHSize);
                int.TryParse((devNode.SelectSingleNode("memory/@ram_size_kb")?.Value ?? ""), out RAMSize);
                FLASHSize *= 1024;
                RAMSize   *= 1024;

                families.Add(mcuFamily);
                string svdFile = null;

                //Map each component to an instance of EmbeddedFramework
                foreach (XmlNode componentNode in doc.SelectNodes($"//components/component"))
                {
                    string componentName = componentNode.SelectSingleNode("@name")?.Value ?? "";
                    string componentType = componentNode.SelectSingleNode("@type")?.Value ?? "";
                    string device        = componentNode.SelectSingleNode("@device")?.Value ?? "";

                    switch (componentType)
                    {
                    case "documentation":
                    case "SCR":
                    case "EULA":
                        continue;

                    case "debugger":
                    case "linker":
                    {
                        List <string> relPaths   = new List <string>();
                        bool          isDebug    = componentType == "debugger";
                        string        sourceType = isDebug ? "debug" : "linker";
                        foreach (var src in componentNode.SelectNodes($"source[@type='{sourceType}']").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                        {
                            foreach (var fn in src.AllFiles)
                            {
                                relPaths.Add(fn.RelativePath);
                            }
                        }

                        if (relPaths.Count > 0)
                        {
                            if (isDebug)
                            {
                                svdFile = relPaths[0];
                            }
                            else if (!linkerScriptHandled)
                            {
                                linkerScriptHandled = true;
                                if (relPaths.Count == 1)
                                {
                                    mcuFamily.CompilationFlags.LinkerScript = "$$SYS:BSP_ROOT$$/" + relPaths[0];
                                }
                                else
                                {
                                    const string optionID = "com.sysprogs.imported.ksdk2x.linker_script";
                                    mcuFamily.CompilationFlags.LinkerScript = $"$$SYS:BSP_ROOT$$/$${optionID}$$";
                                    mcuFamily.ConfigurableProperties.PropertyGroups[0].Properties.Add(new PropertyEntry.Enumerated
                                        {
                                            UniqueID       = optionID,
                                            Name           = "Linker script",
                                            AllowFreeEntry = false,
                                            SuggestionList = relPaths.Select(p => new PropertyEntry.Enumerated.Suggestion {
                                                InternalValue = p, UserFriendlyName = Path.GetFileName(p)
                                            }).ToArray()
                                        });
                                }
                            }
                        }
                    }
                        continue;

                    case "CMSIS":
                        //KSDK 2.x defines a Include_xxx framework for each possible CMSIS core. Those frameworks are redundant (normal 'Include' framework references the same include path) and should be removed to avoid confusion.
                        if (componentName.StartsWith("Include_"))
                        {
                            continue;
                        }
                        if (componentName == "Include")
                        {
                            alwaysIncludedFrameworks.Add(fwPrefix + componentName);
                        }
                        break;

                    default:
                        break;
                    }

                    List <string> headerFiles        = new List <string>();
                    List <string> includeDirectories = new List <string>();
                    List <string> sourceFiles        = new List <string>();

                    foreach (ParsedSource src in componentNode.SelectNodes("source").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                    {
                        if (src.Type == "c_include")
                        {
                            includeDirectories.Add(src.BSPPath);
                        }

                        foreach (var file in src.AllFiles)
                        {
                            if (src.Type == "src" || src.Type == "asm_include")
                            {
                                sourceFiles.Add(file.BSPPath);
                            }
                            else if (src.Type == "c_include")
                            {
                                headerFiles.Add(file.BSPPath);
                            }
                        }
                    }

                    if (componentName == "clock" && componentType == "driver")
                    {
                        alwaysIncludedFrameworks.Add(fwPrefix + componentName);
                    }

                    string[] dependencyList = componentNode.Attributes?.GetNamedItem("dependency")?.Value?.Split(' ')
                                              ?.Select(id => fwPrefix + id)
                                              ?.ToArray() ?? new string[0];

                    EmbeddedFramework fw = new EmbeddedFramework
                    {
                        ID = $"{fwPrefix}{componentName}",
                        UserFriendlyName             = $"{componentName} ({componentType})",
                        ProjectFolderName            = componentName,
                        AdditionalSourceFiles        = sourceFiles.Distinct().ToArray(),
                        AdditionalHeaderFiles        = headerFiles.Distinct().ToArray(),
                        RequiredFrameworks           = dependencyList,
                        AdditionalIncludeDirs        = includeDirectories.Distinct().ToArray(),
                        AdditionalPreprocessorMacros = componentNode.SelectNodes("defines/define").OfType <XmlElement>().Select(el => new ParsedDefine(el).Definition).ToArray(),
                    };

                    if (componentName == "freertos" && componentType == "OS")
                    {
                        fw.AdditionalPreprocessorMacros = LoadedBSP.Combine(fw.AdditionalPreprocessorMacros, "USE_RTOS=1;USE_FREERTOS".Split(';'));
                        fw.ConfigurableProperties       = new PropertyList
                        {
                            PropertyGroups = new List <PropertyGroup>()
                            {
                                new PropertyGroup
                                {
                                    Properties = new List <PropertyEntry>()
                                    {
                                        new PropertyEntry.Enumerated
                                        {
                                            Name              = "FreeRTOS Heap Implementation",
                                            UniqueID          = "com.sysprogs.bspoptions.stm32.freertos.heap",
                                            DefaultEntryIndex = 3,
                                            SuggestionList    = new PropertyEntry.Enumerated.Suggestion[]
                                            {
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_1", UserFriendlyName = "Heap1 - no support for freeing"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_2", UserFriendlyName = "Heap2 - no block consolidation"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_3", UserFriendlyName = "Heap3 - use newlib malloc()/free()"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_4", UserFriendlyName = "Heap4 - contiguous heap area"
                                                },
                                                new PropertyEntry.Enumerated.Suggestion {
                                                    InternalValue = "heap_5", UserFriendlyName = "Heap5 - scattered heap area"
                                                },
                                            }
                                        }
                                    }
                                }
                            }
                        };

                        foreach (var fn in fw.AdditionalSourceFiles)
                        {
                            string name = Path.GetFileName(fn);
                            if (name.StartsWith("heap_"))
                            {
                                allConditions.Add(new FileCondition {
                                    FilePath = fn, ConditionToInclude = new Condition.Equals {
                                        Expression = "$$com.sysprogs.bspoptions.stm32.freertos.heap$$", ExpectedValue = Path.GetFileNameWithoutExtension(fn)
                                    }
                                });
                            }
                        }
                    }

                    if (frameworkDict.ContainsKey(fw.ID))
                    {
                        sink.LogWarning("Duplicate framework for " + fw.ID);
                        continue;
                    }

                    frameworkDict[fw.ID] = fw;

                    if (string.IsNullOrEmpty(fw.ID))
                    {
                        sink.LogWarning($"Found a framework with empty ID. Skipping...");
                        continue;
                    }

                    if (string.IsNullOrEmpty(fw.UserFriendlyName))
                    {
                        fw.UserFriendlyName = fw.ID;
                    }

                    allFrameworks.Add(new ParsedComponent {
                        Framework = fw, OriginalType = componentType, OriginalName = componentName
                    });
                    allFiles.AddRange(sourceFiles);
                    allFiles.AddRange(headerFiles);
                }

                string deviceDefinitionFile = null;
                if (svdFile != null)
                {
                    try
                    {
                        var mcuDef = SVDParser.ParseSVDFile(Path.Combine(sdkDirectory, svdFile), dev.DeviceName);
                        deviceDefinitionFile = Path.ChangeExtension(svdFile, ".vgdbdevice");

                        XmlSerializer ser = new XmlSerializer(typeof(MCUDefinition));
                        using (var fs = File.Create(Path.Combine(sdkDirectory, Path.ChangeExtension(svdFile, ".vgdbdevice.gz"))))
                            using (var gs = new GZipStream(fs, CompressionMode.Compress, true))
                                ser.Serialize(gs, new MCUDefinition(mcuDef));
                    }
                    catch (Exception ex)
                    {
                        sink.LogWarning($"Failed to parse {svdFile}: {ex.Message}");
                    }
                }

                foreach (XmlNode packageNode in devNode.SelectNodes($"package/@name"))
                {
                    string pkgName = packageNode?.Value;
                    if (string.IsNullOrEmpty(pkgName))
                    {
                        continue;
                    }

                    deviceDict[pkgName] = dev;

                    mcus.Add(new MCU
                    {
                        ID = pkgName,
                        UserFriendlyName = $"{pkgName} (KSDK 2.x)",
                        FamilyID         = mcuFamily.ID,
                        FLASHSize        = FLASHSize,
                        RAMSize          = RAMSize,
                        CompilationFlags = new ToolFlags
                        {
                            PreprocessorMacros = new string[] { "CPU_" + pkgName }
                        },

                        MCUDefinitionFile = deviceDefinitionFile
                    });
                }
            }

            if (families.Count == 0)
            {
                throw new Exception("The selected KSDK contains no families");
            }

            List <VendorSample> samples = new List <VendorSample>();

            foreach (XmlElement boardNode in doc.SelectNodes("//boards/board"))
            {
                string       boardName = boardNode.GetAttribute("name");
                string       deviceID  = boardNode.GetAttribute("package");
                ParsedDevice dev;
                if (!deviceDict.TryGetValue(deviceID, out dev))
                {
                    continue;
                }

                foreach (XmlElement exampleNode in boardNode.SelectNodes("examples/example"))
                {
                    List <string> dependencyList = new List <string>(exampleNode.Attributes?.GetNamedItem("dependency")?.Value?.Split(' ')
                                                                     ?.Select(id => fwPrefix + id) ?? new string[0]);

                    dependencyList.AddRange(alwaysIncludedFrameworks);

                    for (int i = 0; i < dependencyList.Count; i++)
                    {
                        EmbeddedFramework fw;
                        if (frameworkDict.TryGetValue(dependencyList[i], out fw) && fw?.RequiredFrameworks != null)
                        {
                            dependencyList.AddRange(fw.RequiredFrameworks.Except(dependencyList));
                        }
                    }

                    VendorSample sample = new VendorSample
                    {
                        DeviceID         = deviceID,
                        UserFriendlyName = exampleNode.GetAttribute("name") ?? "???",
                        BoardName        = boardName,
                        Configuration    = new VendorSampleConfiguration
                        {
                            Frameworks = dependencyList.ToArray()
                        },
                        VirtualPath    = exampleNode.GetAttribute("category"),
                        NoImplicitCopy = true
                    };

                    List <string> headerFiles        = new List <string>();
                    List <string> includeDirectories = new List <string>();
                    List <string> sourceFiles        = new List <string>();

                    foreach (var src in exampleNode.SelectNodes("source").OfType <XmlElement>().Select(e => new ParsedSource(e, dev)))
                    {
                        foreach (var file in src.AllFiles)
                        {
                            if (src.Type == "src" || src.Type == "asm_include")
                            {
                                sourceFiles.Add(file.BSPPath);
                            }
                            else if (src.Type == "c_include")
                            {
                                headerFiles.Add(file.BSPPath);
                            }
                        }
                    }

                    sample.SourceFiles = sourceFiles.ToArray();
                    sample.HeaderFiles = headerFiles.ToArray();

                    if (sourceFiles.Count == 0 && headerFiles.Count == 0)
                    {
                        continue;
                    }

                    string[] matchingComponents = null;

                    foreach (var fn in sourceFiles.Concat(headerFiles))
                    {
                        string[] components = fn.Split('/', '\\');
                        if (matchingComponents == null)
                        {
                            matchingComponents = components;
                        }
                        else
                        {
                            int matches = CountMatches(matchingComponents, components);
                            if (matches < matchingComponents.Length)
                            {
                                Array.Resize(ref matchingComponents, matches);
                            }
                        }
                    }

                    if (matchingComponents != null)
                    {
                        sample.Path = string.Join("/", matchingComponents);
                    }

                    samples.Add(sample);
                }
            }


            return(new ParsedSDK
            {
                BSP = new BoardSupportPackage
                {
                    PackageID = "com.sysprogs.imported.ksdk2x." + families[0].ID,
                    PackageDescription = "Imported KSDK 2.x for " + families[0].ID,
                    PackageVersion = doc.SelectSingleNode("//ksdk/@version")?.Value ?? "unknown",
                    GNUTargetID = "arm-eabi",
                    Frameworks = allFrameworks.Where(f => f.OriginalType != "project_template").Select(f => f.Framework).ToArray(),
                    MCUFamilies = families.ToArray(),
                    SupportedMCUs = mcus.ToArray(),
                    FileConditions = allFiles
                                     .Where(f => f.IndexOf("freertos", StringComparison.InvariantCultureIgnoreCase) != -1)
                                     .Select(f => new FileCondition {
                        FilePath = f, ConditionToInclude = new Condition.ReferencesFramework {
                            FrameworkID = fwPrefix + "freertos"
                        }
                    })
                                     .Concat(allConditions)
                                     .ToArray(),
                    VendorSampleCatalogName = "KSDK Samples",
                    EmbeddedSamples = allFrameworks.Where(f => f.OriginalType == "project_template").Select(f => f.ToProjectSample(alwaysIncludedFrameworks)).ToArray(),
                },

                VendorSampleDirectory = new VendorSampleDirectory
                {
                    Samples = samples.ToArray()
                }
            });
        }
예제 #12
0
파일: Program.cs 프로젝트: whinis/BSPTools
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                throw new Exception("Usage: nrf5x.exe <Nordic SW package directory>");
            }

            using (var bspBuilder = new NordicBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules", @"..\..\logs")))
            {
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S132", "nrf52832.*", true, null, bspBuilder.Directories.InputDir));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S140", "nrf52840.*", true, null, bspBuilder.Directories.InputDir));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S112", "nrf5281.*", false, null, bspBuilder.Directories.InputDir));
                bspBuilder.SoftDevices.Add(new NordicBSPBuilder.SoftDevice("S113", "nrf528.*", true, null, bspBuilder.Directories.InputDir));

                List <MCUBuilder> devices = new List <MCUBuilder>
                {
                    new NordicMCUBuilder("nRF52832_XXAA", 512, 64, CortexCore.M4, true, "S132", "PCA10040"),
                    new NordicMCUBuilder("nRF52810_XXAA", 192, 24, CortexCore.M4, false, "S112", "PCA10040"),
                    new NordicMCUBuilder("nRF52811_XXAA", 192, 24, CortexCore.M4, false, "S112", "PCA10056"),
                    new NordicMCUBuilder("nRF52833_XXAA", 512, 128, CortexCore.M4, true, "S140", "PCA10100"),
                    new NordicMCUBuilder("nRF52840_XXAA", 1024, 256, CortexCore.M4, true, "S140", "PCA10056"),
                };

                List <MCUFamilyBuilder> allFamilies = new List <MCUFamilyBuilder>();
                foreach (var fn in Directory.GetFiles(bspBuilder.Directories.RulesDir + @"\Families", "*.xml"))
                {
                    allFamilies.Add(new NordicFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(fn)));
                }

                var rejects = BSPGeneratorTools.AssignMCUsToFamilies(devices, allFamilies);

                List <EmbeddedFramework>             frameworks  = new List <EmbeddedFramework>();
                List <MCUFamilyBuilder.CopiedSample> exampleDirs = new List <MCUFamilyBuilder.CopiedSample>();

                bool noPeripheralRegisters = args.Contains("/noperiph");

                List <MCUFamily> familyDefinitions = new List <MCUFamily>();
                List <MCU>       mcuDefinitions    = new List <MCU>();

                var           commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml"));
                var           flags        = new ToolFlags();
                List <string> projectFiles = new List <string>();
                commonPseudofamily.CopyFamilyFiles(ref flags, projectFiles);
                flags = flags.Merge(commonPseudofamily.Definition.CompilationFlags);

                List <ConditionalToolFlags> condFlags = new List <ConditionalToolFlags>();

                foreach (var fam in allFamilies)
                {
                    fam.GenerateLinkerScripts(false);
                    Console.WriteLine("Processing " + fam.Definition.Name + " family...");

                    var rejectedMCUs = fam.RemoveUnsupportedMCUs();
                    if (rejectedMCUs.Length != 0)
                    {
                        Console.WriteLine("Unsupported {0} MCUs:", fam.Definition.Name);
                        foreach (var mcu in rejectedMCUs)
                        {
                            Console.WriteLine("\t{0}", mcu.Name);
                        }
                    }

                    bspBuilder.RuleGenerator.GenerateRulesForFamily(fam.Definition);

                    List <MCUDefinitionWithPredicate> hardwareRegisterFiles = new List <MCUDefinitionWithPredicate>();
                    foreach (var svd in Directory.GetFiles(fam.Definition.PrimaryHeaderDir, "*.svd"))
                    {
                        var name = Path.GetFileNameWithoutExtension(svd).ToUpper();
                        if (name == "NRF52")
                        {
                            name = "NRF52832";
                        }

                        if (!name.StartsWith("NRF52"))
                        {
                            continue;
                        }

                        var registers = SVDParser.ParseSVDFile(svd, name);
                        hardwareRegisterFiles.Add(new MCUDefinitionWithPredicate
                        {
                            MCUName        = name,
                            RegisterSets   = registers.RegisterSets,
                            MatchPredicate = m => m.Name.StartsWith(registers.MCUName, StringComparison.InvariantCultureIgnoreCase)
                        });
                    }

                    fam.AttachPeripheralRegisters(hardwareRegisterFiles);

                    var famObj = fam.GenerateFamilyObject(MCUFamilyBuilder.CoreSpecificFlags.All);

                    famObj.AdditionalSourceFiles = LoadedBSP.Combine(famObj.AdditionalSourceFiles, projectFiles.Where(f => !MCUFamilyBuilder.IsHeaderFile(f)).ToArray());
                    famObj.AdditionalHeaderFiles = LoadedBSP.Combine(famObj.AdditionalHeaderFiles, projectFiles.Where(f => MCUFamilyBuilder.IsHeaderFile(f)).ToArray());

                    famObj.AdditionalSystemVars = LoadedBSP.Combine(famObj.AdditionalSystemVars, commonPseudofamily.Definition.AdditionalSystemVars);
                    famObj.CompilationFlags     = famObj.CompilationFlags.Merge(flags);

                    familyDefinitions.Add(famObj);
                    fam.GenerateLinkerScripts(false);

                    foreach (var mcu in fam.MCUs)
                    {
                        var mcuDef = mcu.GenerateDefinition(fam, bspBuilder, !noPeripheralRegisters, false, MCUFamilyBuilder.CoreSpecificFlags.All & ~MCUFamilyBuilder.CoreSpecificFlags.PrimaryMemory);

                        if (mcu.Name.StartsWith("nRF52832"))
                        {
                            //Although documented as a legacy definition, skipping this breaks fds_internal_defs.h
                            mcuDef.CompilationFlags.PreprocessorMacros = mcuDef.CompilationFlags.PreprocessorMacros.Concat(new[] { "NRF52" }).ToArray();
                        }

                        var nosoftdev = new[]
                        {
                            new PropertyEntry.Enumerated.Suggestion {
                                InternalValue = "nosoftdev", UserFriendlyName = "None"
                            }
                        };

                        var compatibleSoftdevs = bspBuilder.SoftDevices.Where(sd => sd.IsCompatible(mcu.Name)).SelectMany(
                            s => new[]
                        {
                            new PropertyEntry.Enumerated.Suggestion {
                                InternalValue = s.Name, UserFriendlyName = s.UserFriendlyName
                            },
                            new PropertyEntry.Enumerated.Suggestion {
                                InternalValue = s.Name + "_reserve", UserFriendlyName = $"{s.UserFriendlyName} (programmed separately)"
                            }
                        });

                        if (mcuDef.ConfigurableProperties == null)
                        {
                            mcuDef.ConfigurableProperties = new PropertyList {
                                PropertyGroups = new List <PropertyGroup>()
                            }
                        }
                        ;

                        mcuDef.ConfigurableProperties.PropertyGroups.Add(new PropertyGroup
                        {
                            Properties = new List <PropertyEntry>
                            {
                                new PropertyEntry.Enumerated
                                {
                                    UniqueID          = NordicBSPBuilder.SoftdevicePropertyID,
                                    Name              = "Softdevice",
                                    DefaultEntryIndex = 1,
                                    SuggestionList    = nosoftdev.Concat(compatibleSoftdevs).ToArray(),
                                }
                            }
                        });

                        if (mcu.Name.StartsWith("nRF52") && !mcu.Name.StartsWith("nRF5281"))
                        {
                            var prop = mcuDef.ConfigurableProperties.PropertyGroups[0].Properties.Find(p => p.UniqueID == "com.sysprogs.bspoptions.arm.floatmode") as PropertyEntry.Enumerated;
                            var idx  = Array.FindIndex(prop.SuggestionList, p => p.UserFriendlyName == "Hardware");
                            prop.DefaultEntryIndex = idx;
                            prop.SuggestionList[idx].UserFriendlyName = "Hardware (required when using a softdevice)";   //Otherwise the system_nrf52.c file won't initialize the FPU and the internal initialization of the softdevice will later fail.
                        }

                        string defaultConfig;
                        if (mcu.Name.StartsWith("nRF52840"))
                        {
                            defaultConfig = "pca10056/s140";
                        }
                        else if (mcu.Name.StartsWith("nRF52810"))
                        {
                            defaultConfig = "pca10040e/s112";
                        }
                        else if (mcu.Name.StartsWith("nRF52811"))
                        {
                            defaultConfig = "pca10056e/s112";
                        }
                        else
                        {
                            defaultConfig = "pca10040/s132";
                        }

                        var extraEntries = new[] {
                            new SysVarEntry {
                                Key = "com.sysprogs.nordic.default_config_suffix", Value = defaultConfig
                            },
                            new SysVarEntry {
                                Key = "com.sysprogs.nordic.default_config_suffix_blank", Value = "pca10040"
                            }
                        };

                        mcuDef.AdditionalSystemVars = LoadedBSP.Combine(mcuDef.AdditionalSystemVars, extraEntries);

                        mcuDefinitions.Add(mcuDef);
                    }

                    if (fam.Definition.ConditionalFlags != null)
                    {
                        condFlags.AddRange(fam.Definition.ConditionalFlags);
                    }

                    foreach (var fw in fam.GenerateFrameworkDefinitions())
                    {
                        frameworks.Add(fw);
                    }

                    string dirpca = "pca10040e/s112";
                    foreach (var sample in fam.CopySamples(null, new SysVarEntry[] { new SysVarEntry {
                                                                                         Key = "com.sysprogs.nordic.default_config_suffix", Value = dirpca
                                                                                     },
                                                                                     new SysVarEntry {
                                                                                         Key = "com.sysprogs.nordic.default_config_suffix_blank", Value = "pca10040"
                                                                                     } }))
                    {
                        exampleDirs.Add(sample);
                    }
                }

                const string softdevExpression = "$$com.sysprogs.bspoptions.nrf5x.softdevice$$";

                foreach (var softdev in bspBuilder.SoftDevices)
                {
                    condFlags.Add(new ConditionalToolFlags
                    {
                        FlagCondition = new Condition.Equals {
                            Expression = softdevExpression, ExpectedValue = softdev.Name + "_reserve"
                        },
                        Flags = new ToolFlags
                        {
                            PreprocessorMacros = familyDefinitions.First().CompilationFlags.PreprocessorMacros.Where(f => f.Contains(softdevExpression)).Select(f => f.Replace(softdevExpression, softdev.Name)).ToArray(),
                            IncludeDirectories = familyDefinitions.First().CompilationFlags.IncludeDirectories.Where(f => f.Contains(softdevExpression)).Select(f => f.Replace(softdevExpression, softdev.Name)).ToArray()
                        }
                    });
                }

                bspBuilder.GenerateSoftdeviceLibraries();
                bspBuilder.RuleGenerator.PatchGeneratedFrameworks(frameworks, condFlags);

                //  CheckEntriesSample(Path.Combine(bspBuilder.Directories.OutputDir, @"nRF5x\components\libraries"),
                //                     Path.Combine(bspBuilder.Directories.OutputDir, "Samples"));

                Console.WriteLine("Building BSP archive...");

                BoardSupportPackage bsp = new BoardSupportPackage
                {
                    PackageID                         = "com.sysprogs.arm.nordic.nrf5x",
                    PackageDescription                = "Nordic NRF52x Devices",
                    GNUTargetID                       = "arm-eabi",
                    GeneratedMakFileName              = "nrf5x.mak",
                    MCUFamilies                       = familyDefinitions.ToArray(),
                    SupportedMCUs                     = mcuDefinitions.ToArray(),
                    Frameworks                        = frameworks.ToArray(),
                    Examples                          = exampleDirs.Where(s => !s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                    TestExamples                      = exampleDirs.Where(s => s.IsTestProjectSample).Select(s => s.RelativePath).ToArray(),
                    PackageVersion                    = "16.0",
                    FirstCompatibleVersion            = "16.0",
                    FileConditions                    = bspBuilder.MatchedFileConditions.Values.ToArray(),
                    MinimumEngineVersion              = "5.0",
                    ConditionalFlags                  = condFlags.ToArray(),
                    InitializationCodeInsertionPoints = commonPseudofamily.Definition.InitializationCodeInsertionPoints,
                };

                bspBuilder.ValidateBSP(bsp);

                List <ConfigurationFixSampleReference> samplesForComputingSymbolLists = new List <ConfigurationFixSampleReference>();

                foreach (var sampleName in new[] { "BLEMouse", "IoT/Icmp", "BLEMultilinkCentral", "LEDBlink_FreeRTOS" })
                {
                    samplesForComputingSymbolLists.Add(new ConfigurationFixSampleReference
                    {
                        MCUID      = "nRF52840_XXAA",
                        SamplePath = "$$SYS:BSP_ROOT$$/samples/" + sampleName
                    });
                }

                bspBuilder.ReverseFileConditions.SaveIfConsistent(bspBuilder.Directories.OutputDir, bspBuilder.ExportRenamedFileTable(), true, samplesForComputingSymbolLists.ToArray());

                bspBuilder.Save(bsp, false, false);
            }
        }
    }
예제 #13
0
            void AttachSVDFilesAndLinkerScriptsToDevices(ISDKImportHost host)
            {
                foreach (var sd in _SpecializedDevices)
                {
                    if (_Components.FirstOrDefault(c => c.Type == ComponentType.SVDFile && c.Filter.MatchesDevice(sd)) is ParsedComponent svdComponent)
                    {
                        var svdFiles = svdComponent.LocateAllFiles(sd, _Directory).ToArray();
                        Debug.Assert(svdFiles.Length <= 1); //If we get multiple matching SVD files, we might have skipped some conditions.

                        if (svdFiles.Length > 0)
                        {
                            try
                            {
                                var fullPath = svdFiles[0].GetLocalPath(_Directory);

                                var mcuDef        = host?.TryParseSVDFile(fullPath, sd.Device.DeviceName) ?? SVDParser.ParseSVDFile(fullPath, sd.Device.DeviceName);
                                var convertedFile = new FileReference(Path.ChangeExtension(svdFiles[0].RelativePath, ".vgdbdevice"), svdFiles[0].Type);

                                XmlSerializer ser = new XmlSerializer(typeof(MCUDefinition));
                                using (var fs = File.Create(Path.ChangeExtension(convertedFile.GetLocalPath(_Directory), ".vgdbdevice.gz")))
                                    using (var gs = new GZipStream(fs, CompressionMode.Compress, true))
                                        ser.Serialize(gs, new MCUDefinition(mcuDef));

                                sd.ConvertedSVDFile = convertedFile;
                            }
                            catch (Exception ex)
                            {
                                _Sink.LogWarning($"Failed to process {svdFiles[0]}: {ex.Message}");
                            }
                        }
                    }

                    sd.DiscoveredLinkerScripts = _Components.Where(c => c.Type == ComponentType.LinkerScript && c.Filter.MatchesDevice(sd))
                                                 .SelectMany(c => c.LocateAllFiles(sd, _Directory)).ToArray();
                }
            }