Esempio n. 1
0
        private static void GenerateBSP(List <DeviceInfo> devList, string outputDir)
        {
            BoardSupportPackage bsp = new BoardSupportPackage
            {
                GNUTargetID          = "avr",
                PackageID            = "com.sysprogs.avr.core",
                PackageDescription   = "AVR MCUs",
                GeneratedMakFileName = "avr.mak",
                Examples             = new string[]
                {
                    "Samples/LEDBlink"
                }
            };

            bsp.SupportedMCUs = devList.Select(d => d.ToBSPMCU()).ToArray();
            bsp.MCUFamilies   = new MCUFamily[] { new MCUFamily {
                                                      ID = "avr"
                                                  } };
            bsp.DebugMethodPackages = new string[] { "debuggers\\core", "debuggers\\avarice" };

            string defDir = Path.Combine(outputDir, "DeviceDefinitions");

            Directory.CreateDirectory(defDir);
            foreach (var dev in devList)
            {
                MCUDefinition d = dev.ToDeviceDefinition();
                if (d == null)
                {
                    Console.WriteLine("Warning: no register information found for " + dev.Name);
                    continue;
                }
                using (var fs = File.Create(Path.Combine(defDir, dev.Name + ".xml.gz")))
                    using (var gs = new GZipStream(fs, CompressionMode.Compress))
                        XmlTools.SaveObjectToStream(d, gs);
            }

            XmlTools.SaveObject(bsp, Path.Combine(outputDir, "bsp.xml"));
        }
Esempio n. 2
0
        public static MCU GenerateMCUDefinition(string bspDir, string linkerScript, string generatorResourceDir, string target, string debugComponentDir)
        {
            string mcuName        = Path.GetFileNameWithoutExtension(linkerScript).TrimStart('D');
            string copiedFilesDir = Path.Combine(bspDir, "DeviceFiles", mcuName);

            Directory.CreateDirectory(copiedFilesDir);
            File.Copy(linkerScript, Path.Combine(bspDir, "LinkerScripts", Path.GetFileName(linkerScript)), true);
            Dictionary <string, int> memorySizes = new Dictionary <string, int>();

            Regex rgMemory = new Regex("^[ \t]+([^ ]+)[ \t]+:[ \t]+ORIGIN[ \t]*=[ \t]*0x([0-9a-fA-F]+),[ \t]*LENGTH[ \t]*=[ \t]*([0-9]+)");

            foreach (var line in File.ReadAllLines(linkerScript))
            {
                var m = rgMemory.Match(line);
                if (m.Success)
                {
                    memorySizes[m.Groups[1].Value] = int.Parse(m.Groups[3].Value);
                }
            }

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

            foreach (var rf in RenamedFiles)
            {
                string file = Path.Combine(generatorResourceDir, string.Format(rf.SourceFileFormat, mcuName));
                if (!File.Exists(file))
                {
                    Directory.Delete(copiedFilesDir, true);
                    return(null);
                }

                var lines = File.ReadAllLines(file);
                if (rf.MakeWeakFunctions)
                {
                    Regex rgFunc = new Regex("void[ \t]+(INT_[a-zA-Z0-9_]+)[ \t]*\\(void\\)");
                    for (int i = 0; i < lines.Length; i++)
                    {
                        var m = rgFunc.Match(lines[i]);
                        if (m.Success)
                        {
                            lines[i] = lines[i].Substring(0, m.Groups[1].Index) + "__attribute__((weak)) " + lines[i].Substring(m.Groups[1].Index);
                        }
                    }
                }

                File.WriteAllLines(Path.Combine(copiedFilesDir, rf.TargetFileName), lines);

                if (rf.TargetFileName.EndsWith(".h"))
                {
                    headers.Add($"$$SYS:BSP_ROOT$$/DeviceFiles/{mcuName}/rf.TargetFileName");
                }
            }

            var mcu = new MCU
            {
                ID               = mcuName,
                FamilyID         = target,
                CompilationFlags = new ToolFlags
                {
                    IncludeDirectories = new[] { $"$$SYS:BSP_ROOT$$/DeviceFiles/{mcuName}" },
                    LinkerScript       = "$$SYS:BSP_ROOT$$/LinkerScripts/" + Path.GetFileName(linkerScript),
                    LDFLAGS            = "-nostartfiles -Wl,-e_PowerON_Reset",
                    COMMONFLAGS        = "$$com.sysprogs.renesas.doubles$$ $$com.sysprogs.renesas.core$$",
                },
                AdditionalSourcesRequiredForTesting = true,
                AdditionalHeaderFiles = headers.ToArray()
            };

            string peripheralFile = Path.Combine(debugComponentDir, "IoFiles", mcuName + ".sfrx");

            if (File.Exists(peripheralFile))
            {
                var doc = new XmlDocument();
                doc.Load(peripheralFile);

                MCUDefinition definition = new MCUDefinition
                {
                    MCUName      = mcuName,
                    RegisterSets = doc.DocumentElement.SelectNodes("moduletable/module").OfType <XmlElement>().Select(TransformRegisterSet).Where(s => s != null).ToArray()
                };

                using (var fs = new FileStream(Path.Combine(bspDir, "DeviceDefinitions", mcuName + ".xml.gz"), FileMode.Create, FileAccess.Write))
                    using (var gs = new GZipStream(fs, CompressionMode.Compress))
                        XmlTools.SaveObjectToStream(definition, gs);

                mcu.MCUDefinitionFile = $"DeviceDefinitions/{mcuName}.xml";
            }

            memorySizes.TryGetValue("ROM", out mcu.FLASHSize);
            memorySizes.TryGetValue("RAM", out mcu.RAMSize);
            return(mcu);
        }
Esempio n. 3
0
        static void InsertRegisterValidationCode(string sourceFile, MCUDefinition mcuDefinition, LoadedRenamingRule[] renameRules, string[] pNonValidatedRegisters)
        {
            if (!File.Exists(sourceFile))
                throw new Exception("File does not exist: " + sourceFile);

            if (mcuDefinition != null)
            {
                using (var sw = new StreamWriter(sourceFile, true))
                {
                    sw.WriteLine();
                    sw.WriteLine("#define STATIC_ASSERT(COND) typedef char static_assertion[(COND)?1:-1]");
                    sw.WriteLine("void ValidateOffsets()");
                    sw.WriteLine("{");
                    foreach (var regset in mcuDefinition.RegisterSets)
                        foreach (var reg in regset.Registers)
                        {
                            string regName = reg.Name;
                            if (IsNoValid(regset.UserFriendlyName, pNonValidatedRegisters))
                                continue;

                            if (renameRules != null)
                                foreach (var rule in renameRules)
                                {
                                    if (rule.RegisterSetRegex?.IsMatch(regset.UserFriendlyName) != false)
                                    {
                                        var match = rule.RegisterRegex.Match(regName);
                                        if (match.Success)
                                        {
                                            switch (rule.Mode)
                                            {
                                                case RegisterRenamingMode.Normal:
                                                    regName = string.Format("{0}[{1}]", match.Groups[1], int.Parse(match.Groups[2].ToString()) + rule.Offset);
                                                    break;
                                                case RegisterRenamingMode.HighLow:
                                                    regName = string.Format("{0}[{1}]", match.Groups[1], match.Groups[2].ToString() == "H" ? 1 : 0);
                                                    break;
                                                case RegisterRenamingMode.WithSuffix:
                                                    regName = string.Format("{0}[{1}].{2}", match.Groups[1], int.Parse(match.Groups[2].ToString()) + rule.Offset, match.Groups[3]);
                                                    break;
                                            }
                                            break;
                                        }
                                    }
                                }

                            if (mcuDefinition.MCUName.StartsWith("MSP432"))
                            {
                                if (regName.Contains("RESERVED"))
                                    continue;
                                sw.WriteLine("STATIC_ASSERT((unsigned)&({0}->r{1}) == {2});", regset.UserFriendlyName, regName, reg.Address);
                            }
                            else
                                sw.WriteLine("STATIC_ASSERT((unsigned)&({0}->{1}) == {2});", regset.UserFriendlyName, regName, reg.Address);
                        }
                    sw.WriteLine("}");
                }
            }
        }
Esempio n. 4
0
        static void InsertRegisterValidationCode(string sourceFile, MCUDefinition mcuDefinition, LoadedRenamingRule[] renameRules, string[] pNonValidatedRegisters, string[] pUndefinedMacros)
        {
            if (!File.Exists(sourceFile))
            {
                throw new Exception("File does not exist: " + sourceFile);
            }

            if (mcuDefinition != null)
            {
                using (var sw = new StreamWriter(sourceFile, true))
                {
                    sw.WriteLine();
                    sw.WriteLine("#define STATIC_ASSERT(COND) typedef char static_assertion[(COND)?1:-1]");
                    sw.WriteLine("void ValidateOffsets()");
                    sw.WriteLine("{");
                    foreach (var regset in mcuDefinition.RegisterSets)
                    {
                        foreach (var reg in regset.Registers)
                        {
                            string regName = reg.Name;
                            if (IsNoValid(regset.UserFriendlyName, pNonValidatedRegisters))
                            {
                                continue;
                            }
                            if (IsNoValid(regName, pNonValidatedRegisters))
                            {
                                continue;
                            }
                            if (IsNoValid(regName, pUndefinedMacros))
                            {
                                sw.WriteLine($"#undef {regName}");
                            }
                            if (renameRules != null)
                            {
                                foreach (var rule in renameRules)
                                {
                                    if (rule.RegisterSetRegex?.IsMatch(regset.UserFriendlyName) != false)
                                    {
                                        var match = rule.RegisterRegex.Match(regName);
                                        if (match.Success)
                                        {
                                            switch (rule.Mode)
                                            {
                                            case RegisterRenamingMode.Normal:
                                                regName = string.Format("{0}[{1}]", match.Groups[1], int.Parse(match.Groups[2].ToString()) + rule.Offset);
                                                break;

                                            case RegisterRenamingMode.HighLow:
                                                regName = string.Format("{0}[{1}]", match.Groups[1], match.Groups[2].ToString() == "H" ? 1 : 0);
                                                break;

                                            case RegisterRenamingMode.WithSuffix:
                                                regName = string.Format("{0}[{1}].{2}", match.Groups[1], int.Parse(match.Groups[2].ToString()) + rule.Offset, match.Groups[3]);
                                                break;
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                            if (regset.UserFriendlyName.StartsWith("ARM Cortex M"))
                            {
                                continue;
                            }
                            if (mcuDefinition.MCUName.StartsWith("MSP432"))
                            {
                                if (regName.Contains("RESERVED"))
                                {
                                    continue;
                                }
                                sw.WriteLine("STATIC_ASSERT((unsigned)&({0}->r{1}) == {2});", regset.UserFriendlyName, regName, reg.Address);
                            }
                            else
                            {
                                sw.WriteLine("STATIC_ASSERT((unsigned)&({0}->{1}) == {2});", regset.UserFriendlyName, regName, reg.Address);
                            }
                        }
                    }
                    sw.WriteLine("}");
                }
            }
        }
Esempio n. 5
0
        static void GenerateBSP(string toolchainDir, string ccsDir)
        {
            string[] keys = null;

            string bspDir = toolchainDir + @"\msp430-bsp";

            Dictionary <string, Dictionary <string, string> > tiMCUs = new Dictionary <string, Dictionary <string, string> >(StringComparer.CurrentCultureIgnoreCase);

            foreach (var line in File.ReadAllLines(@"..\..\msp430.csv"))
            {
                string[] cells = line.Split(';');
                if (keys == null)
                {
                    keys = cells;
                    continue;
                }

                Dictionary <string, string> entry = new Dictionary <string, string>();

                for (int i = 0; i < cells.Length; i++)
                {
                    entry[keys[i]] = cells[i];
                }

                tiMCUs[cells[0]] = entry;
                int idx = cells[0].IndexOf('-');
                if (idx != -1)
                {
                    tiMCUs[cells[0].Substring(0, idx)] = entry;
                }
            }

            Regex rgLen    = new Regex(".*LENGTH = 0x([0-9a-fA-F]{4}).*");
            Regex rgOrigin = new Regex(".*ORIGIN = 0x([0-9a-fA-F]{4}).*");
            Regex rgPeriph = new Regex("__([^ ]+) = (0x[a-fA-F0-9]+);");

            List <string>    families = new List <string>();
            List <MCU>       MCUs     = new List <MCU>();
            List <MCUFamily> famList  = new List <MCUFamily>();

            Directory.CreateDirectory(bspDir);
            Directory.CreateDirectory(bspDir + "\\devices");

            XmlSerializer regSer = new XmlSerializer(typeof(MCUDefinition));

            string[] files = Directory.GetFiles(Path.Combine(toolchainDir, "include"), "*.h");

            for (int i = 0; i < files.Length; i++)
            {
                string file = files[i];

                var    proc    = new Process();
                string mcuName = Path.GetFileNameWithoutExtension(file).ToLower();

                proc.StartInfo.FileName               = toolchainDir + @"\bin\msp430-elf-gcc.exe";
                proc.StartInfo.Arguments              = $"-I. -E {mcuName}.h -o - -mmcu={mcuName}";
                proc.StartInfo.WorkingDirectory       = Path.Combine(toolchainDir, "include");
                proc.StartInfo.UseShellExecute        = false;
                proc.StartInfo.RedirectStandardOutput = true;

                proc.Start();
                List <string> lines = new List <string>();
                for (; ;)
                {
                    var line = proc.StandardOutput.ReadLine();
                    if (line == null)
                    {
                        break;
                    }
                    lines.Add(line);
                }

                proc.WaitForExit();
                if (proc.ExitCode != 0)
                {
                    continue;
                }

                List <HardwareRegister> regs = new List <HardwareRegister>();

                MCU mcu = new MCU();
                mcu.ID = mcuName;
                mcu.CompilationFlags.COMMONFLAGS = "-mmcu=" + mcuName;

                string ld = Path.ChangeExtension(file, ".ld");
                if (!File.Exists(ld))
                {
                    continue;
                }
                foreach (var line in File.ReadAllLines(ld))
                {
                    if (line.StartsWith("  RAM"))
                    {
                        var m = rgLen.Match(line);
                        mcu.RAMSize = int.Parse(m.Groups[1].ToString(), System.Globalization.NumberStyles.HexNumber);
                        m           = rgOrigin.Match(line);
                        mcu.RAMBase = uint.Parse(m.Groups[1].ToString(), System.Globalization.NumberStyles.HexNumber);
                    }
                    if (line.StartsWith("  ROM"))
                    {
                        var m = rgLen.Match(line);
                        mcu.FLASHSize = int.Parse(m.Groups[1].ToString(), System.Globalization.NumberStyles.HexNumber);
                        m             = rgOrigin.Match(line);
                        mcu.FLASHBase = uint.Parse(m.Groups[1].ToString(), System.Globalization.NumberStyles.HexNumber);
                    }
                }

                if (mcu.RAMSize == 0)
                {
                    throw new Exception("RAM size cannot be 0");
                }


                foreach (var line in lines)
                {
                    Regex rgRegister = new Regex("extern volatile (.*) ([^ ]+) __asm__\\(\"([^\"]+)\"\\)");

                    var m = rgRegister.Match(line);
                    if (!m.Success)
                    {
                        if (line.Contains("extern") && line.Contains("__asm__"))
                        {
                            throw new Exception("Suspicious line");
                        }
                        continue;
                    }

                    string type = m.Groups[1].Value;
                    string name = m.Groups[2].Value;
                    if (name.EndsWith("_H") || name.EndsWith("_L"))
                    {
                        continue;
                    }
                    if (!m.Groups[3].Value.StartsWith("0x"))
                    {
                        throw new Exception("Invalid addr for " + name);
                    }
                    ulong addr = ulong.Parse(m.Groups[3].Value.Substring(2), System.Globalization.NumberStyles.HexNumber);

                    HardwareRegister reg = new HardwareRegister();
                    // TODO: the registers are not all 8 bits
                    // According to some datasheets (not all were checked):
                    // 01FFh to 0100h -> 16 bits
                    // 0FFh to 010h -> 8bits
                    // 0Fh to 00h -> 8-bit SFR (special function register)
                    if (type == "unsigned char")
                    {
                        reg.SizeInBits = 8;
                    }
                    else if (type == "unsigned int")
                    {
                        reg.SizeInBits = 16;
                    }
                    else if (type == "unsigned long int")
                    {
                        reg.SizeInBits = 32;
                    }
                    else
                    {
                        throw new Exception("Unknown type");
                    }

                    reg.Name    = name;
                    reg.Address = m.Groups[3].Value;
                    regs.Add(reg);
                }

                string family = "Other";

                Dictionary <string, string> info;
                if (tiMCUs.TryGetValue(mcu.ID, out info))
                {
                    family = info["Description"];
                }

                int idx = families.IndexOf(family);
                if (idx == -1)
                {
                    idx = families.Count;
                    families.Add(family);
                    famList.Add(new MCUFamily {
                        ID = "fam_" + idx, UserFriendlyName = family, CompilationFlags = null
                    });
                }

                mcu.FamilyID          = "fam_" + idx.ToString();
                mcu.MCUDefinitionFile = "devices\\" + mcu.ID + ".xml";
                mcu.HierarchicalPath  = family;
                MCUs.Add(mcu);


                MCUDefinition desc = new MCUDefinition {
                    MCUName = mcu.ID, RegisterSets = new HardwareRegisterSet[] { new HardwareRegisterSet {
                                                                                     Registers = regs.ToArray()
                                                                                 } }
                };                                                                                                                                                                   //, Specs = specs };
                AdjustHardwareRegisters(ccsDir, mcu.ID, ref desc.RegisterSets);

                using (var fs = File.Create(bspDir + "\\" + mcu.MCUDefinitionFile + ".gz"))
                    using (var gs = new GZipStream(fs, CompressionMode.Compress))
                        regSer.Serialize(gs, desc);


                Console.WriteLine($"Processed {mcuName} ({i}/{files.Length}) [{i * 100 / files.Length}%]");
            }


            //Build the XML file
            BoardSupportPackage bsp = new BoardSupportPackage {
                GNUTargetID = "msp430", PackageID = "com.sysprogs.msp430.core", PackageDescription = "MSP430 MCUs"
            };

            bsp.SupportedMCUs       = MCUs.ToArray();
            bsp.MCUFamilies         = famList.ToArray();
            bsp.DebugMethodPackages = new string[] { "debuggers\\core", "debuggers\\mspdebug" };


            bsp.Examples = new string[] { "Samples\\LEDBlink" };

#if BSP_ADDITIONAL_GCC_FLAGS
            bsp.AdditionalGCCFlags = new PropertyList
            {
                PropertyGroups = new PropertyGroup[] { new PropertyGroup {
                                                           Name       = "MSP430 Options",
                                                           Properties = new PropertyEntry[] {
                                                               new PropertyEntry.Boolean {
                                                                   Name          = "Disable watchdog on startup",
                                                                   Description   = "Link the crt0 modules that disable the watchdog on startup",
                                                                   UniqueID      = "com.sysprogs.msp430.mdisable-watchdog",
                                                                   ValueForTrue  = "-mdisable-watchdog",
                                                                   ValueForFalse = "",
                                                               },
                                                               new PropertyEntry.Boolean {
                                                                   Name          = "Enable libcalls for shifts",
                                                                   Description   = "Use library routines for non-constant shifts",
                                                                   UniqueID      = "com.sysprogs.msp430.menable-libcall-shift",
                                                                   ValueForTrue  = "-menable-libcall-shift",
                                                                   ValueForFalse = "",
                                                               },
                                                               new PropertyEntry.Boolean {
                                                                   Name          = "Inline hardware multiplication",
                                                                   Description   = "Issue inline multiplication code for 32-bit integers",
                                                                   UniqueID      = "com.sysprogs.msp430.minline-hwmul",
                                                                   ValueForTrue  = "-minline-hwmul",
                                                                   ValueForFalse = "",
                                                               },
                                                               new PropertyEntry.Enumerated {
                                                                   Name           = "Interrupt vector count",
                                                                   Description    = "Specify number of interrupt vectors on chip:",
                                                                   UniqueID       = "com.sysprogs.msp430.mivcnt",
                                                                   GNUPrefix      = "-mivcnt=",
                                                                   SuggestionList = new PropertyEntry.Enumerated.Suggestion[]
                                                                   {
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "", UserFriendlyName = "(default)"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "16"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "32"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "64"
                                                                       },
                                                                   },
                                                                   AllowFreeEntry = true,
                                                               },
                                                               new PropertyEntry.Enumerated {
                                                                   Name           = "Hardware multiplier",
                                                                   Description    = "Define available hardware multiplier",
                                                                   UniqueID       = "com.sysprogs.msp430.mmpy",
                                                                   GNUPrefix      = "-mmpy=",
                                                                   SuggestionList = new PropertyEntry.Enumerated.Suggestion[]
                                                                   {
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "", UserFriendlyName = "(default)"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "16"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "16se"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "32"
                                                                       },
                                                                       new PropertyEntry.Enumerated.Suggestion {
                                                                           InternalValue = "32dw"
                                                                       },
                                                                   }
                                                               },
                                                               new PropertyEntry.Boolean {
                                                                   Name          = "No hardware multiplication in ISRs",
                                                                   Description   = "Assume interrupt routine does not do hardware multiplication",
                                                                   UniqueID      = "com.sysprogs.msp430.noint-hwmul",
                                                                   ValueForTrue  = "-noint-hwmul",
                                                                   ValueForFalse = "",
                                                               },
                                                               new PropertyEntry.Boolean {
                                                                   Name          = "Prologue space optimization",
                                                                   Description   = "Use subroutine call for function prologue/epilogue when possible",
                                                                   UniqueID      = "com.sysprogs.msp430.msave-prologue",
                                                                   ValueForTrue  = "-msave-prologue",
                                                                   ValueForFalse = "",
                                                               },
                                                           }
                                                       } }
            };
#endif

            XmlSerializer ser = new XmlSerializer(typeof(BoardSupportPackage), PropertyEntry.EntryTypes);
            using (var fs = File.Create(bspDir + "\\BSP.xml"))
                ser.Serialize(fs, bsp);

            //mcuSelector1.Reset();
            var lBsp = LoadedBSP.Load(new BSPSummary(bspDir), null);
            //mcuSelector1.AddBSP(lBsp);
            //embeddedDebugSettingsControl1.Reset();
            //embeddedDebugSettingsControl1.AddDebugMethods(lBsp.KnownDebugMethods);
        }