static void Main(string[] args) { if (args.Length < 1) { throw new Exception("Usage: risc-v.exe <freedom-e-sdk directory>"); } var bspBuilder = new RISCVBSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules")); PathTools.CopyDirectoryRecursive(@"..\..\bsp-template", bspBuilder.Directories.OutputDir); var bsp = XmlTools.LoadObject <BoardSupportPackage>(Path.Combine(bspBuilder.BSPRoot, "bsp.xml")); var commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml")); 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); } } List <EmbeddedFramework> frameworks = new List <EmbeddedFramework>(bsp.Frameworks); frameworks.AddRange(commonPseudofamily.GenerateFrameworkDefinitions()); bsp.Frameworks = frameworks.ToArray(); var samples = commonPseudofamily.CopySamples(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.ToArray(); XmlTools.SaveObject(bsp, Path.Combine(bspBuilder.BSPRoot, "BSP.XML")); }
public void UpdateGitAndRescanTargets() { string gitExe = (Registry.CurrentUser.OpenSubKey(@"Software\Sysprogs\BSPGenerators")?.GetValue("git") as string) ?? "git.exe"; string pythonExe = (Registry.CurrentUser.OpenSubKey(@"Software\Sysprogs\BSPGenerators")?.GetValue("python") as string) ?? "python.exe"; Process proc; if (Directory.Exists(mbedRoot)) { proc = Process.Start(new ProcessStartInfo(gitExe, "reset --hard") { WorkingDirectory = mbedRoot, UseShellExecute = false }); } else { proc = Process.Start(new ProcessStartInfo(gitExe, $"clone https://github.com/ARMmbed/mbed-os.git mbed") { WorkingDirectory = outputDir, UseShellExecute = false }); proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("Git exited with code " + proc.ExitCode); } proc = Process.Start(new ProcessStartInfo(gitExe, $"checkout mbed-os-{Version}") { WorkingDirectory = outputDir + "\\mbed", UseShellExecute = false }); } proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("Git exited with code " + proc.ExitCode); } foreach (var lds in Directory.GetFiles(mbedRoot, "*.ld", SearchOption.AllDirectories)) { if (File.ReadAllText(lds).Contains("\n#if")) { ProcessStartInfo preprocessInfo = new ProcessStartInfo($@"{toolchainDir}\bin\arm-eabi-cpp.exe", $"-P -C {lds} -o {lds}.preprocessed"); preprocessInfo.UseShellExecute = false; preprocessInfo.EnvironmentVariables["PATH"] += $@";{toolchainDir}\bin"; proc = Process.Start(preprocessInfo); proc.WaitForExit(); File.Copy(lds + ".preprocessed", lds, true); File.Delete(lds + ".preprocessed"); } } var patchedFile = Path.Combine(mbedRoot, @"tools\config\__init__.py"); var lines = File.ReadAllLines(patchedFile).ToList(); var idx2 = Enumerable.Range(0, lines.Count).First(i => lines[i].Contains("self.value = int(value) if isinstance(value, bool) else value")); if (!lines[idx2 + 1].Contains("is_bool")) { lines.Insert(idx2 + 1, " self.is_bool = isinstance(value, bool) #Patch by Sysprogs"); File.WriteAllLines(patchedFile, lines); } //7. Enable exporting LPC targets patchedFile = Path.Combine(mbedRoot, @"tools\export\exporters.py"); lines = File.ReadAllLines(patchedFile).ToList(); string str = "target.post_binary_hook['function'] in whitelist:"; idx2 = Enumerable.Range(0, lines.Count).FirstOrDefault(i => lines[i].Contains(str)); if (idx2 > 0) { int subIdx = lines[idx2].IndexOf(str); lines[idx2] = lines[idx2].Substring(0, subIdx) + "True:"; File.WriteAllLines(patchedFile, lines); } string sampleDir = Path.Combine(mbedRoot, "samples"); if (Directory.Exists(sampleDir)) { Directory.Delete(sampleDir, true); } PathTools.CopyDirectoryRecursive(Path.Combine(dataDir, "samples"), sampleDir); ProcessStartInfo bspGenInfo = new ProcessStartInfo(pythonExe, Path.Combine(dataDir, "BuildConfigExtractor.py")); bspGenInfo.UseShellExecute = false; bspGenInfo.EnvironmentVariables["PYTHONPATH"] = mbedRoot; bspGenInfo.EnvironmentVariables["PATH"] += $@";{toolchainDir}\bin"; proc = Process.Start(bspGenInfo); proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("BSP generator exited with code " + proc.ExitCode); } }
public IEnumerable <CopiedSample> CopySamples(IEnumerable <EmbeddedFramework> allFrameworks = null, IEnumerable <SysVarEntry> extraVariablesToValidateSamples = null) { if (Definition.SmartSamples != null) { foreach (var sample in Definition.SmartSamples) { string destFolder = Path.Combine(BSP.BSPRoot, sample.DestinationFolder); string sourceDir = sample.SourceFolder; BSP.ExpandVariables(ref sourceDir); PathTools.CopyDirectoryRecursive(sourceDir, destFolder); var sampleObj = XmlTools.LoadObject <EmbeddedProjectSample>(Path.Combine(destFolder, "sample.xml")); if (sample.AdditionalSources != null) { sampleObj.AdditionalSourcesToCopy = sample.AdditionalSources.Select(f => { int idx = f.IndexOf("=>"); if (idx == -1) { return new AdditionalSourceFile { SourcePath = f } } ; else { return new AdditionalSourceFile { SourcePath = f.Substring(0, idx).Trim(), TargetFileName = f.Substring(idx + 2).Trim() } }; }).ToArray(); foreach (var f in sampleObj.AdditionalSourcesToCopy) { string path = f.SourcePath.Replace("$$SYS:BSP_ROOT$$", BSP.Directories.OutputDir); if (!File.Exists(path)) { if (extraVariablesToValidateSamples != null) { foreach (var v in extraVariablesToValidateSamples) { path = path.Replace("$$" + v.Key + "$$", v.Value); } } if (!File.Exists(path)) { Console.WriteLine("Missing sample file: " + f.SourcePath); } } } } if (sampleObj.MCUFilterRegex == null & allFrameworks != null && sampleObj.RequiredFrameworks != null) { string[] devices = null; foreach (var fw in allFrameworks) { if (fw.MCUFilterRegex == null) { continue; } if (sampleObj.RequiredFrameworks.Contains(fw.ID) || sampleObj.RequiredFrameworks.Contains(fw.ClassID)) { if (devices == null) { devices = fw.MCUFilterRegex.Split('|'); } else { devices = devices.Intersect(fw.MCUFilterRegex.Split('|')).ToArray(); } } } if (devices != null) { sampleObj.MCUFilterRegex = string.Join("|", devices); } } if (sampleObj.MCUFilterRegex == null && sample.MCUFilterRegex != null) { sampleObj.MCUFilterRegex = sample.MCUFilterRegex; } XmlTools.SaveObject(sampleObj, Path.Combine(destFolder, "sample.xml")); yield return(new CopiedSample { RelativePath = sample.DestinationFolder, IsTestProjectSample = sample.IsTestProjectSample }); } } }
public IEnumerable <CopiedSample> CopySamples(IEnumerable <EmbeddedFramework> allFrameworks = null, IEnumerable <SysVarEntry> extraVariablesToValidateSamples = null) { if (Definition.SmartSamples != null) { foreach (var sample in Definition.SmartSamples) { string destFolder = Path.Combine(BSP.BSPRoot, sample.DestinationFolder); string sourceDir = sample.SourceFolder; BSP.ExpandVariables(ref sourceDir); if (sample.CopyFilters == null) { PathTools.CopyDirectoryRecursive(sourceDir, destFolder); } else { var filters = new CopyFilters(sample.CopyFilters); foreach (var fn in Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories)) { string relPath = fn.Substring(sourceDir.Length).TrimStart('\\'); if (filters.IsMatch(relPath)) { string targetPath = Path.Combine(destFolder, relPath); Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); File.Copy(fn, targetPath); } } } if (sample.AdditionalBuildTimeSources != null) { foreach (var src in sample.AdditionalBuildTimeSources) { string source = src; BSP.ExpandVariables(ref source); string targetPath = Path.Combine(destFolder, Path.GetFileName(source)); File.Copy(source, targetPath); } } if (sample.Patches != null) { foreach (var p in sample.Patches) { foreach (var fn in p.FilePath.Split(';')) { List <string> allLines = File.ReadAllLines(Path.Combine(destFolder, fn)).ToList(); p.Apply(allLines); File.WriteAllLines(Path.Combine(destFolder, fn), allLines); } } } var sampleObj = sample.EmbeddedSample ?? XmlTools.LoadObject <EmbeddedProjectSample>(Path.Combine(destFolder, "sample.xml")); if (sampleObj.RequiredFrameworks == null && allFrameworks != null) { sampleObj.RequiredFrameworks = allFrameworks.Where(fw => fw.DefaultEnabled).Select(fw => fw.ClassID ?? fw.ID)?.ToArray(); } if (sample.AdditionalSources != null) { sampleObj.AdditionalSourcesToCopy = sample.AdditionalSources.Select(f => { int idx = f.IndexOf("=>"); if (idx == -1) { return new AdditionalSourceFile { SourcePath = f } } ; else { return new AdditionalSourceFile { SourcePath = f.Substring(0, idx).Trim(), TargetFileName = f.Substring(idx + 2).Trim() } }; }).ToArray(); for (int i = 0; i < sampleObj.AdditionalSourcesToCopy.Length; i++) { string path = sampleObj.AdditionalSourcesToCopy[i].SourcePath.Replace("$$SYS:BSP_ROOT$$", BSP.Directories.OutputDir); if (!File.Exists(path)) { if (extraVariablesToValidateSamples != null) { foreach (var v in extraVariablesToValidateSamples) { path = path.Replace("$$" + v.Key + "$$", v.Value); } } if (!File.Exists(path)) { var args = new MissingSampleFileArgs { UnexpandedPath = sampleObj.AdditionalSourcesToCopy[i].SourcePath, ExpandedPath = path }; OnMissingSampleFile(args); if (args.SubstitutePath != null) { if (args.SubstitutePath.StartsWith(BSP.BSPRoot)) { args.SubstitutePath = "$$SYS:BSP_ROOT$$" + args.SubstitutePath.Substring(BSP.BSPRoot.Length).Replace('\\', '/'); } else if (args.SubstitutePath.StartsWith("$$")) { //Already encoded } else { throw new Exception("Invalid substitute path: " + args.SubstitutePath); } sampleObj.AdditionalSourcesToCopy[i].SourcePath = args.SubstitutePath; } } } } } if (sampleObj.MCUFilterRegex == null & allFrameworks != null && sampleObj.RequiredFrameworks != null) { string[] devices = null; foreach (var fw in allFrameworks) { if (fw.MCUFilterRegex == null) { continue; } if (sampleObj.RequiredFrameworks.Contains(fw.ID) || sampleObj.RequiredFrameworks.Contains(fw.ClassID)) { if (devices == null) { devices = fw.MCUFilterRegex.Split('|'); } else { devices = devices.Intersect(fw.MCUFilterRegex.Split('|')).ToArray(); } } } if (devices != null) { sampleObj.MCUFilterRegex = string.Join("|", devices); } } if (sampleObj.MCUFilterRegex == null && sample.MCUFilterRegex != null) { sampleObj.MCUFilterRegex = sample.MCUFilterRegex; } XmlTools.SaveObject(sampleObj, Path.Combine(destFolder, "sample.xml")); yield return(new CopiedSample { RelativePath = sample.DestinationFolder, IsTestProjectSample = sample.IsTestProjectSample }); } } }
static void Main(string[] args) { if (args.Length < 1) { throw new Exception("Usage: esp32.exe <esp-idf directory>"); } var bspBuilder = new ESP32BSPBuilder(new BSPDirectories(args[0], @"..\..\Output", @"..\..\rules")); PathTools.CopyDirectoryRecursive(@"..\..\bsp-template", bspBuilder.Directories.OutputDir); string registerSetFile = Path.Combine(bspBuilder.Directories.OutputDir, "registers.xml"); var registers = PeripheralRegisterParser.ParsePeripheralRegisters(Path.Combine(bspBuilder.Directories.InputDir, "esp-idf")); XmlTools.SaveObject(new MCUDefinition { MCUName = "ESP32", RegisterSets = registers }, registerSetFile); var bsp = XmlTools.LoadObject <BoardSupportPackage>(Path.Combine(bspBuilder.BSPRoot, "bsp.xml")); var commonPseudofamily = new MCUFamilyBuilder(bspBuilder, XmlTools.LoadObject <FamilyDefinition>(bspBuilder.Directories.RulesDir + @"\CommonFiles.xml")); List <EmbeddedFramework> frameworks = new List <EmbeddedFramework>(bsp.Frameworks); frameworks.AddRange(commonPseudofamily.GenerateFrameworkDefinitions()); bsp.Frameworks = frameworks.ToArray(); List <string> projectFiles = new List <string>(); if (commonPseudofamily.Definition.CoreFramework != null) { foreach (var job in commonPseudofamily.Definition.CoreFramework.CopyJobs) { job.CopyAndBuildFlags(bspBuilder, projectFiles, null); } } 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.ToArray(); foreach (var fn in Directory.GetFiles(Path.Combine(bspBuilder.Directories.OutputDir, @"esp-idf\components\nghttp"), "*.?", SearchOption.AllDirectories)) { string ext = Path.GetExtension(fn).ToLower(); if (ext != ".c" && ext != ".h") { continue; } var lines = File.ReadAllLines(fn); bool changed = false; for (int i = 0; i < lines.Length; i++) { if (lines[i].Contains("<config.h>")) { lines[i] = lines[i].Replace("<config.h>", "<nghttp-config.h>"); changed = true; } } if (changed) { File.WriteAllLines(fn, lines); } } foreach (var mcu in bsp.SupportedMCUs) { mcu.MCUDefinitionFile = Path.GetFileName(registerSetFile); } File.WriteAllText(Path.Combine(bspBuilder.Directories.OutputDir, @"esp-idf\components\nghttp\port\include\nghttp-config.h"), "#include \"config.h\"\n"); string linkerScript = Path.Combine(bspBuilder.Directories.OutputDir, @"esp-idf\components\esp32\ld\esp32.common.ld"); var lines2 = File.ReadAllLines(linkerScript).ToList(); Regex rgLibrary = new Regex(@"(.*)\*lib([0-9a-zA-Z_]+).a:\(([^()]+)\)"); Regex rgFileInLibrary = new Regex(@"(.*)\*lib([0-9a-zA-Z_]+).a:([0-9a-zA-Z]+\.o)\(([^()]+)\)"); for (int i = 0; i < lines2.Count; i++) { var m = rgLibrary.Match(lines2[i]); if (m.Success) { string dir = Path.Combine(bspBuilder.Directories.OutputDir, @"esp-idf\components\" + m.Groups[2].Value); if (Directory.Exists(dir)) { string[] fns = Directory.GetFiles(dir) .Select(f => Path.GetFileName(f)) .Where(f => f.EndsWith(".S", StringComparison.InvariantCultureIgnoreCase) || f.EndsWith(".c", StringComparison.InvariantCultureIgnoreCase)) .Select(f => Path.ChangeExtension(f, ".o")) .OrderBy(f => f) .ToArray(); int j = 0; foreach (var fn in fns) { lines2.Insert(i + ++j, $"{m.Groups[1].Value}*{fn}({m.Groups[3].Value})"); } lines2.RemoveAt(i--); continue; } } m = rgFileInLibrary.Match(lines2[i]); if (m.Success) { lines2[i] = $"{m.Groups[1].Value}*{m.Groups[3].Value}({m.Groups[4].Value})"; } } File.WriteAllLines(linkerScript, lines2); XmlTools.SaveObject(bsp, Path.Combine(bspBuilder.BSPRoot, "BSP.XML")); }
static void Main(string[] args) { string outputDir = Path.GetFullPath(@"..\..\Output"); string dataDir = Path.GetFullPath(@"..\..\data"); Directory.CreateDirectory(outputDir); string mbedRoot = Path.Combine(outputDir, "mbed"); List <KeyValuePair <Regex, string> > nameRules = new List <KeyValuePair <Regex, string> >(); foreach (var line in File.ReadAllLines(Path.Combine(dataDir, "DeviceNameRules.txt"))) { int idx = line.IndexOf('='); nameRules.Add(new KeyValuePair <Regex, string>(new Regex(line.Substring(0, idx).Trim()), line.Substring(idx + 1).Trim())); } bool regenerate = true; if (regenerate) { string gitExe = (Registry.CurrentUser.OpenSubKey(@"Software\Sysprogs\BSPGenerators")?.GetValue("git") as string) ?? "git.exe"; string pythonExe = (Registry.CurrentUser.OpenSubKey(@"Software\Sysprogs\BSPGenerators")?.GetValue("python") as string) ?? "python.exe"; Process proc; if (Directory.Exists(mbedRoot)) { // Prevent pull fail due to modified files proc = Process.Start(new ProcessStartInfo(gitExe, "reset --hard") { WorkingDirectory = mbedRoot, UseShellExecute = false }); proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("Git reset command exited with code " + proc.ExitCode); } proc = Process.Start(new ProcessStartInfo(gitExe, "pull origin fix_5.2") { WorkingDirectory = mbedRoot, UseShellExecute = false }); } else { proc = Process.Start(new ProcessStartInfo(gitExe, "clone https://github.com/oter/mbed-os.git -b fix_5.2 mbed") { WorkingDirectory = outputDir, UseShellExecute = false }); } proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("Git exited with code " + proc.ExitCode); } string sampleDir = Path.Combine(mbedRoot, "samples"); if (Directory.Exists(sampleDir)) { Directory.Delete(sampleDir, true); } PathTools.CopyDirectoryRecursive(Path.Combine(dataDir, "samples"), sampleDir); ProcessStartInfo bspGenInfo = new ProcessStartInfo(pythonExe, Path.Combine(dataDir, "visualgdb_bsp.py") + " --alltargets"); bspGenInfo.UseShellExecute = false; bspGenInfo.EnvironmentVariables["PYTHONPATH"] = mbedRoot; proc = Process.Start(bspGenInfo); proc.WaitForExit(); if (proc.ExitCode != 0) { throw new Exception("BSP generator exited with code " + proc.ExitCode); } } File.Copy(Path.Combine(dataDir, "stubs.cpp"), Path.Combine(mbedRoot, "stubs.cpp"), true); Dictionary <string, string> mcuDefs = new Dictionary <string, string>(); var linkedBSPs = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\VisualGDB\EmbeddedBSPs\arm-eabi", "*.bsplink").Select(f => File.ReadAllText(f)); foreach (var dir in Directory.GetDirectories(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\VisualGDB\EmbeddedBSPs\arm-eabi").Concat(linkedBSPs)) { var anotherBSP = XmlTools.LoadObject <BoardSupportPackage>(Path.Combine(dir, "bsp.xml")); foreach (var mcu in anotherBSP.SupportedMCUs) { if (mcu.MCUDefinitionFile != null) { mcuDefs[mcu.ID] = Path.Combine(dir, mcu.MCUDefinitionFile); } } } string bspFile = Path.Combine(mbedRoot, "BSP.xml"); var bsp = XmlTools.LoadObject <BoardSupportPackage>(bspFile); var defDir = Directory.CreateDirectory(Path.Combine(mbedRoot, "DeviceDefinitions")); foreach (var mcu in bsp.SupportedMCUs) { foreach (var rule in nameRules) { var m = rule.Key.Match(mcu.ID); if (m.Success) { string devRegex = rule.Value; for (int i = 1; i < m.Groups.Count; i++) { devRegex = devRegex.Replace(@"\" + i, m.Groups[i].Value); } Regex devRegexObj = new Regex(devRegex); string definition = null; foreach (var dev in mcuDefs) { if (devRegexObj.IsMatch(dev.Key)) { definition = dev.Value; } } if (definition == null) { Console.WriteLine("Warning: cannot find device register definition for " + devRegex); } else { mcu.MCUDefinitionFile = "DeviceDefinitions/" + Path.GetFileName(definition); File.Copy(definition + ".gz", Path.Combine(mbedRoot, mcu.MCUDefinitionFile + ".gz"), true); } break; } } } ProduceBSPArchive(mbedRoot, bsp); var testfFiles = new TestInfo[] { new TestInfo("test_usbcd.xml", 0, 0), new TestInfo("test_ledblink_rtos.xml", 0, 0), new TestInfo("test_ledblink.xml", 0, 0), }; bool performTests = true; if (performTests) { foreach (var test in testfFiles) { Console.WriteLine("Testing BSP..."); var job = XmlTools.LoadObject <TestJob>(Path.Combine(dataDir, test.Filename)); if (job.ToolchainPath.StartsWith("[")) { job.ToolchainPath = (string)Registry.CurrentUser.OpenSubKey(@"Software\Sysprogs\GNUToolchains").GetValue(job.ToolchainPath.Trim('[', ']')); if (job.ToolchainPath == null) { throw new Exception("Cannot locate toolchain path from registry"); } } var toolchain = LoadedToolchain.Load(Environment.ExpandEnvironmentVariables(job.ToolchainPath), new ToolchainRelocationManager()); var lbsp = LoadedBSP.Load(new BSPManager.BSPSummary(Environment.ExpandEnvironmentVariables(Path.Combine(outputDir, "mbed"))), toolchain); var r = StandaloneBSPValidator.Program.TestBSP(job, lbsp, Path.Combine(outputDir, "TestResults")); test.Passed = r.Passed; test.Failed = r.Failed; } foreach (var test in testfFiles) { Console.WriteLine("Results for the test: " + test.Filename); Console.WriteLine("Passed: " + test.Passed.ToString()); Console.WriteLine("Failed: " + test.Failed.ToString()); Console.WriteLine(); } } }