static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string dir, MCUFamilyBuilder fam) { var mainClassifier = fam.Definition.Subfamilies.First(f => f.IsPrimary); var allFiles = Directory.GetFiles(dir); foreach (var fn in allFiles) { string subfamily = Path.GetFileNameWithoutExtension(fn); if (!subfamily.StartsWith("startup_")) { continue; } subfamily = subfamily.Substring(8); yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.ChangeExtension(Path.GetFileName(fn), ".c"), MatchPredicate = m => (allFiles.Length == 1) || StringComparer.InvariantCultureIgnoreCase.Compare(mainClassifier.TryMatchMCUName(m.Name), subfamily) == 0, Vectors = StartupFileGenerator.ParseInterruptVectors(fn, tableStart: "g_pfnVectors:", tableEnd: @"/\*{10,999}|^[^/\*]+\*/ $", vectorLineA: @"^[ \t]+\.word[ \t]+([^ ]+)", vectorLineB: null, ignoredLine: @"^[ \t]+/\*|[ \t]+stm32.*|[ \t]+STM32.*|// External Interrupts", macroDef: ".equ[ \t]+([^ \t]+),[ \t]+(0x[0-9a-fA-F]+)", nameGroup: 1, commentGroup: 2) }); } }
static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string startupFileName, MCUFamilyBuilder fam) { List <StartupFileGenerator.InterruptVector[]> list = new List <StartupFileGenerator.InterruptVector[]>(); list.Add(StartupFileGenerator.ParseInterruptVectors(startupFileName, @"const pFunc __Vectors.*", @"[ \t]*\};", @"([^ \t,]+)[,]?[ \t]+// ([^\(]+)", @"([^ \t,]+)[,]?.*", @"^[ \t]*/.*", null, 1, 2)); List <StartupFileGenerator.InterruptVector> vectors = new List <StartupFileGenerator.InterruptVector>(list[0]); list.RemoveAt(0); //Fix the vector names from comments for (int i = 0; i < vectors.Count; i++) { if (vectors[i] == null) { continue; } if (i == 0) { vectors[i].Name = "_estack"; continue; } else if (i == 1) { vectors[i].Name = "Reset_Handler"; continue; } else if (vectors[i].OptionalComment == "Reserved") { vectors[i] = null; continue; } else { if (vectors[i] != null) { if (vectors[i].Name == "Default_Handler") { vectors[i] = null; } } } } yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.ChangeExtension(Path.GetFileName(startupFileName), ".c"), MatchPredicate = null, Vectors = vectors.ToArray() }); }
static StartupFileGenerator.InterruptVectorTable GenerateStartupFile(string pDir, string pFBase) { var vectorTable = new StartupFileGenerator.InterruptVectorTable { FileName = "startup_" + pFBase + "x.c", Vectors = StartupFileGenerator.ParseInterruptVectors(Path.Combine(pDir, "arm_startup_" + pFBase + ".s"), "^__Vectors", @"__Vectors_End", @"^[ \t]+DCD[ \t]+([^ \t]+)[ \t]+; *([^ \t].*)$", @"^[ \t]+DCD[ \t]+([^ \t]+)$", @"^[ \t]+;.*", null, 1, 2), }; if (pFBase.ToLower() == "nrf51") { vectorTable.AdditionalResetHandlerLines = new string[] { "asm volatile(\".equ NRF_POWER_RAMON_ADDRESS,0x40000524\");", "asm volatile(\".equ NRF_POWER_RAMON_RAMxON_ONMODE_Msk,3\");", "asm volatile(\"LDR R0, =NRF_POWER_RAMON_ADDRESS\");", "asm volatile(\"LDR R2, [R0]\");", "asm volatile(\"MOVS R1, #NRF_POWER_RAMON_RAMxON_ONMODE_Msk\");", "asm volatile(\"ORR R2, R2, R1\");", "asm volatile(\"STR R2, [R0]\");", }; } vectorTable.Vectors = new StartupFileGenerator.InterruptVector[] { new StartupFileGenerator.InterruptVector { Name = "_estack" } }.Concat(vectorTable.Vectors).ToArray(); vectorTable.MatchPredicate = m => m.Name.StartsWith(pFBase); return(vectorTable); }
//=============================================================== static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string dir) { var fn = dir; List <StartupFileGenerator.InterruptVector[]> list = new List <StartupFileGenerator.InterruptVector[]>(); list.Add(StartupFileGenerator.ParseInterruptVectors(fn, @"__Vectors:", @" .size __Vectors, . - __Vectors", // - start tabl @"[ \t]*.long[ \t]+([\w]+)[ \t/\*]+(.*[^\*/])", //.long - line A @"[ \t]*.Entry[ \t]+([\w]+)[ /\*]+(.*[^\*/])", //Entry - line B @"^[ \t/]*[\*#]+.*", //Ignor line @"(USE_LPCOPEN_IRQHANDLER_NAMES)", 1, 2)); List <StartupFileGenerator.InterruptVector> vectors = new List <StartupFileGenerator.InterruptVector>(list[0]); list.RemoveAt(0); //Fix the vector names from comments for (int i = 0; i < vectors.Count; i++) { if (vectors[i] == null) { continue; } if (i == 0) { vectors[i].Name = "_estack"; continue; } else if (i == 1) { vectors[i].Name = "Reset_Handler"; continue; } else if (vectors[i].OptionalComment == "Reserved") { vectors[i] = null; continue; } else { for (int c = 0; c < i; c++) { if (vectors[c] != null) { if (vectors[c].Name == vectors[i].Name) { int idx = vectors[c].OptionalComment.IndexOf(" "); if (idx == -1) { idx = 0; } vectors[i].Name = "INT_" + i + "_" + vectors[i].Name; } } } } } yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.ChangeExtension(Path.GetFileName(fn), ".c"), MatchPredicate = null, Vectors = vectors.ToArray() }); }
static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string dir, string startupFileName, MCUFamilyBuilder fam) { FileInfo[] startups = (new DirectoryInfo(dir)).GetFiles(startupFileName, SearchOption.AllDirectories); List <StartupFileGenerator.InterruptVector[]> list = new List <StartupFileGenerator.InterruptVector[]>(); // Read in all the relevant startup files foreach (var startup in startups) { if (!(startup.FullName.ToUpperInvariant().Contains(fam.Definition.Name.ToUpperInvariant()) || ((startup.FullName == "TM4C123") && startup.FullName.ToUpperInvariant().Contains("LM4F232")))) { continue; } list.Add(StartupFileGenerator.ParseInterruptVectors(startup.FullName, @"void \(\* const g_pfnVectors\[\]\)\(void\) \=", @"[ \t]*\};", @"([^ \t/]+)[,]?[ \t]+// ([^\(]+)", @"[ \t]*\(void \(\*\)\(void\)\)\(\(uint32_t\)pui32Stack \+ sizeof\(pui32Stack\)\)\,", @"\{|^[ /t]*// (.*)", null, 1, 2)); } List <StartupFileGenerator.InterruptVector> vectors = new List <StartupFileGenerator.InterruptVector>(list[0]); list.RemoveAt(0); foreach (var entry in list) { if ((entry.Length != vectors.Count) && (entry.Length != 224) && entry.Length != 138)//224 is length of two boot loader demo example interrupt tables, ignoring the extra entries there! { throw new Exception("Interrupt vector counts different!"); } for (int i = 0; i < vectors.Count; i++) { if (entry[i].OptionalComment == vectors[i].OptionalComment) { continue; } throw new Exception(); } } //Fix the vector names from comments for (int i = 0; i < vectors.Count; i++) { if (i == 0) { vectors[i].Name = "_estack"; continue; } else if (i == 1) { vectors[i].Name = "Reset_Handler"; continue; } else if (vectors[i].OptionalComment == "Reserved") { vectors[i] = null; continue; } TextInfo txt_info = new CultureInfo("").TextInfo; vectors[i].Name = txt_info.ToTitleCase(vectors[i].OptionalComment.Replace(" and ", " ")).Replace(" ", "") + "ISR"; if (vectors[i].Name.StartsWith("The")) { vectors[i].Name = vectors[i].Name.Substring(3); } vectors[i].Name = vectors[i].Name.Replace('/', '_'); } yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.GetFileName(startupFileName), MatchPredicate = m => true, Vectors = vectors.ToArray() }); }
static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string startupFileName, MCUFamilyBuilder fam) { string aStartNewName; string strPrefFam; if (fam.Definition.Name.StartsWith("AT")) { strPrefFam = fam.Definition.Name.Substring(2, fam.Definition.Name.Length - 2); } else { strPrefFam = fam.Definition.Name; } if (strPrefFam != "SAMG51") { strPrefFam = strPrefFam.Substring(0, strPrefFam.Length - 1); } if (strPrefFam == "SAM4cm3") { strPrefFam = strPrefFam.Substring(0, strPrefFam.Length - 1); } foreach (var fl in Directory.GetFiles(Path.GetDirectoryName(startupFileName), strPrefFam + "*.h", SearchOption.AllDirectories /* TopDirectoryOnly*/)) { if (fl.Contains("\\pio\\")) { continue; } string aNameFl = fl.Substring(fl.LastIndexOf("\\") + 1, fl.Length - fl.LastIndexOf("\\") - 1); if (Path.GetFileNameWithoutExtension(aNameFl).ToUpper() == strPrefFam.ToUpper()) { continue; } if (aNameFl.EndsWith("_1.h")) { continue; } if (aNameFl.EndsWith("_0.h")) { aNameFl = aNameFl.Replace("_0.h", ".h"); } aStartNewName = "startup_" + aNameFl; List <StartupFileGenerator.InterruptVector[]> list = new List <StartupFileGenerator.InterruptVector[]>(); list.Add(StartupFileGenerator.ParseInterruptVectors(fl, @"^typedef struct _DeviceVectors.*", @"} DeviceVectors;.*", @"[ \t]+void\*[ ]+([\w]+).*", @"([^ \t,]+)[,]?.*", @"^[ \t]*[/{]+.*", null, 1, 2)); List <StartupFileGenerator.InterruptVector> vectors = new List <StartupFileGenerator.InterruptVector>(list[0]); list.RemoveAt(0); //Fix the vector names from comments for (int i = 0; i < vectors.Count; i++) { if (vectors[i] == null) { continue; } if (i == 0) { vectors[i].Name = "_estack"; continue; } else if (i == 1) { vectors[i].Name = "Reset_Handler"; continue; } else if (vectors[i].Name.StartsWith("pvReserved")) { vectors[i] = null; continue; } else { if (vectors[i] == null) { continue; } if (!vectors[i].Name.StartsWith("pfn")) { throw new Exception("no pfn Func Startup Header"); } vectors[i].Name = vectors[i].Name.Substring(3, vectors[i].Name.Length - 3); } } yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.ChangeExtension(Path.GetFileName(aStartNewName), ".c"), MatchPredicate = m => (Path.GetFileNameWithoutExtension(aNameFl).ToUpper() == m.Name.Substring(2).ToUpper()), Vectors = vectors.ToArray() }); } }
private void GenerateMCUsAndMCUFamilies() { foreach (var mcuFamilyBuilder in _mcuFamilyBuilders) { var vectorTables = new List <StartupFileGenerator.InterruptVector[]>(); var vectorTableFiles = Directory.GetFiles( mcuFamilyBuilder.Definition.PrimaryHeaderDir + VECTOR_TABLE_RELATIVE_PATH, VECTOR_TABLE_FILE_PATTERN); foreach (var vectorTableFile in vectorTableFiles) { StartupFileGenerator.InterruptVector[] vectorTable = null; vectorTable = StartupFileGenerator.ParseInterruptVectors( vectorTableFile, @"^[ \t]*__isr_vector[ \t]*:", @"^[ \t]*.size[ \t]+__isr_vector", @"^[ \t]*.long[ \t]+(\w+)[ \t]*(\/\*[\s]*[\w \t\(,';\-\/\)]*[\s]*\*\/)", null, @"^[ \t\r\n]+(\/\*[ \w]+\*\/)?$", null, 1, 2); if (vectorTable.Length > 0) { var defaultISRNumber = 0; foreach (var vector in vectorTable) { if (vector == null) { continue; } if (vector.Name == DEFAULT_ISR_NAME) { vector.Name = DEFAULT_ISR_NAME + defaultISRNumber++; } else if (vector.Name == TRIM_VALUE) { vector.SpecialVectorValue = TRIM_VALUE; vector.Name = TRIM_VALUE_NAME; } } vectorTables.Add(vectorTable); } } if (vectorTables.Count == 0) { throw new Exception("Didn't find any vector table"); } CheckVectorTables(vectorTables); Directory.CreateDirectory(Path.Combine(Directories.OutputDir, mcuFamilyBuilder.FamilyFilePrefix)); GenerateStartupFiles(mcuFamilyBuilder, vectorTables[0]); if (_parsePeripheralRegisters) { var headerFiles = Directory.GetFiles(mcuFamilyBuilder.Definition.PrimaryHeaderDir + "/include", "*.h"); var familyHeaderFiles = headerFiles .Where(file => file.Substring(file.LastIndexOf(Path.DirectorySeparatorChar) + 1) == "M" + mcuFamilyBuilder.Definition.Name + ".h").ToArray(); if (familyHeaderFiles.Length == 0) { throw new Exception("No header file found for MCU family"); } else if (familyHeaderFiles.Length > 1) { throw new Exception("Only one header file expected for MCU family"); } mcuFamilyBuilder.AttachPeripheralRegisters(new[] { new MCUDefinitionWithPredicate { MCUName = mcuFamilyBuilder.Definition.Name, RegisterSets = PeripheralRegisterGenerator.GenerateFamilyPeripheralRegisters(familyHeaderFiles[0]), MatchPredicate = m => true } }); } var famObj = mcuFamilyBuilder.GenerateFamilyObject(true); famObj.ConfigurableProperties.PropertyGroups[0].Properties.Add( new PropertyEntry.Boolean { Name = "Disable Watchdog", UniqueID = "com.sysprogs.bspoptions.wdog", ValueForTrue = "DISABLE_WDOG", DefaultValue = true } ); famObj.AdditionalSourceFiles = new string[] { "$$SYS:BSP_ROOT$$/" + mcuFamilyBuilder.FamilyFilePrefix + STARTUP_FILES_FOLDER + "/startup.c", "$$SYS:BSP_ROOT$$/" + mcuFamilyBuilder.FamilyFilePrefix + STARTUP_FILES_FOLDER + "/vectors_" + mcuFamilyBuilder.Definition.Name + ".c" }; var deviceSpecificFiles = _projectFiles.Where(file => file.Contains("devices") || file.Contains("CMSIS")); famObj.AdditionalSourceFiles = LoadedBSP.Combine(famObj.AdditionalSourceFiles, deviceSpecificFiles.Where(f => f.Contains(famObj.ID) && !MCUFamilyBuilder.IsHeaderFile(f)).ToArray()); famObj.AdditionalHeaderFiles = LoadedBSP.Combine(famObj.AdditionalHeaderFiles, deviceSpecificFiles. Where(f => (f.Contains(famObj.ID) || f.Contains("CMSIS") || f.Contains("fsl_device_registers.h")) && MCUFamilyBuilder.IsHeaderFile(f)).ToArray()); famObj.AdditionalSystemVars = LoadedBSP.Combine(famObj.AdditionalSystemVars, _commonPseudofamily.Definition.AdditionalSystemVars); famObj.CompilationFlags = famObj.CompilationFlags.Merge(_flags); famObj.CompilationFlags.IncludeDirectories = new HashSet <string>(famObj.AdditionalSourceFiles.Concat(famObj.AdditionalHeaderFiles).Select(f => f.Substring(0, f.LastIndexOf("/")))).ToArray(); _mcuFamilies.Add(famObj); GenerateLinkerScripts(mcuFamilyBuilder); foreach (var mcuBuilder in mcuFamilyBuilder.MCUs) { mcuBuilder.StartupFile = "$$SYS:BSP_ROOT$$/" + mcuFamilyBuilder.FamilyFilePrefix + STARTUP_FILES_FOLDER + "/startup.c"; var mcu = mcuBuilder.GenerateDefinition(mcuFamilyBuilder, mcuFamilyBuilder.BSP, _parsePeripheralRegisters); mcu.FLASHBase = _mcuMemoryLayouts[mcu.ID].Memories.First(m => m.Name == FLASH_MEMORY).Start; mcu.RAMBase = _mcuMemoryLayouts[mcu.ID].Memories.First(m => m.Name == SRAM_MEMORY).Start; var preprocessorMacroses = mcu.CompilationFlags.PreprocessorMacros.ToList(); preprocessorMacroses.Add("CPU_" + mcu.ID); mcu.CompilationFlags.PreprocessorMacros = preprocessorMacroses.ToArray(); _mcus.Add(mcu); } foreach (var fw in mcuFamilyBuilder.GenerateFrameworkDefinitions()) { _frameworks.Add(fw); } foreach (var sample in mcuFamilyBuilder.CopySamples(_frameworks)) { _exampleDirs.Add(sample); } } }
static IEnumerable <StartupFileGenerator.InterruptVectorTable> ParseStartupFiles(string dir, string startupFileName, MCUFamilyBuilder fam) { string [] allFiles = Directory.GetFiles(dir); string aTemDir = fam.BSP.BSPRoot + "\\TempSource"; foreach (var fn in allFiles) { string aFN = Path.GetFileNameWithoutExtension(fn); if (!aFN.StartsWith("cr_") || !aFN.EndsWith("x")) { continue; } UpdateMacrosFile(fn, aTemDir, "const g_pfnVectors[])(void) =", "};", "#error "); } allFiles = Directory.GetFiles(aTemDir); List <StartupFileGenerator.InterruptVector[]> list = new List <StartupFileGenerator.InterruptVector[]>(); foreach (var fn in allFiles) { string subfamily = Path.GetFileNameWithoutExtension(fn); if (subfamily.StartsWith("CHIP_")) { subfamily = subfamily.Substring(5, subfamily.IndexOf("_cr_start") - 5); } else if (subfamily.StartsWith("ORIGINAL")) { int idx = subfamily.IndexOf("lpc"); if (idx < 0) { Console.WriteLine("subfamily not lpc"); continue; } else { subfamily = subfamily.Substring(idx, subfamily.Length - idx); } } else { continue; } list.Add(StartupFileGenerator.ParseInterruptVectors(fn, @"void \(\* const g_pfnVectors\[\]\)\(void\) \=", @"[ \t]*\};", @"([^ \t,]+)[,]?[ \t]+// ([^\(]+)", @"([^ \t,]+)[,]?.*", @"^[ \t]*//.*", @"(USE_LPCOPEN_IRQHANDLER_NAMES)", 1, 2)); List <StartupFileGenerator.InterruptVector> vectors = new List <StartupFileGenerator.InterruptVector>(list[0]); list.RemoveAt(0); //Fix the vector names from comments for (int i = 0; i < vectors.Count; i++) { if (vectors[i] == null) { continue; } if (i == 0) { vectors[i].Name = "_estack"; continue; } else if (i == 1) { vectors[i].Name = "Reset_Handler"; continue; } else if (vectors[i].OptionalComment == "Reserved") { vectors[i] = null; continue; } else { for (int c = 0; c < i; c++) { if (vectors[c] != null) { if (vectors[c].Name == vectors[i].Name) { int idx = vectors[c].OptionalComment.IndexOf(" "); if (idx == -1) { idx = 0; } vectors[i].Name = "INT_" + i + "_" + vectors[i].Name; } } } } } yield return(new StartupFileGenerator.InterruptVectorTable { FileName = Path.ChangeExtension(Path.GetFileName(fn), ".c"), MatchPredicate = m => (allFiles.Length == 1) || (GytTypMcuFile(Path.ChangeExtension(Path.GetFileName(fn), ".c"), m.Name)), Vectors = vectors.ToArray() }); } Directory.Delete(aTemDir, true); }