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); }
//=========================================================== 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); }); }
//=========================================================== 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); } }
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"); } }
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() } }); }
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); } }
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")); } }
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); } } }
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() } }); }
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); } } }
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(); } }