예제 #1
0
        public GeneratedProject(LoadedBSP.ConfiguredMCU mcu, VendorSample vs, string projectDir, Dictionary <string, string> bspDict, string[] frameworks)
            : this(projectDir, mcu, frameworks)
        {
            _ProjectDir   = projectDir;
            _LinkerScript = vs.LinkerScript;

            _SourceFiles.AddRange(vs.SourceFiles.Select(s => VariableHelper.ExpandVariables(s, bspDict)));

            var cf = vs.ExtraFiles?.Select(s1 =>
            {
                var s2         = VariableHelper.ExpandVariables(s1.SourcePath, bspDict);
                var targetFile = projectDir + "\\" + s1.TargetPath.Replace("/", "\\");
                var pth        = Path.GetDirectoryName(targetFile);
                if (!Directory.Exists(pth))
                {
                    Directory.CreateDirectory(pth);
                }
                if (!File.Exists(targetFile))
                {
                    File.Copy(s2.Replace("/", "\\"), targetFile);
                }
                return(s1.TargetPath);
            });

            if (cf != null)
            {
                _SourceFiles.AddRange(cf);
            }
        }
예제 #2
0
        public GeneratedProject(LoadedBSP.ConfiguredMCU mcu, VendorSample vs, string projectDir, Dictionary <string, string> bspDict, string[] frameworks)
            : this(projectDir, mcu, frameworks)
        {
            _ProjectDir = projectDir;

            _SourceFiles.AddRange(vs.SourceFiles.Select(s => VariableHelper.ExpandVariables(s, bspDict)));
        }
예제 #3
0
        public GeneratedProject(LoadedBSP.ConfiguredMCU mcu, VendorSample vs, string projectDir, Dictionary<string, string> bspDict, string[] frameworks)
            : this(projectDir, mcu, frameworks)
        {
            _ProjectDir = projectDir;

            _SourceFiles.AddRange(vs.SourceFiles.Select(s=>VariableHelper.ExpandVariables(s, bspDict)));
        }
예제 #4
0
 protected virtual void AdjustVendorSampleProperties(VendorSample vs)
 {
     if (vs.SourceFiles.FirstOrDefault(f => ShouldFileTriggerHardFloat(f)) != null)
     {
         if (vs.Configuration.MCUConfiguration != null)
         {
             var dict = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.MCUConfiguration);
             dict["com.sysprogs.bspoptions.arm.floatmode"] = "-mfloat-abi=hard";
             vs.Configuration.MCUConfiguration             = new PropertyDictionary2 {
                 Entries = dict.Select(kv => new PropertyDictionary2.KeyValue {
                     Key = kv.Key, Value = kv.Value
                 }).ToArray()
             };
         }
         else
         {
             vs.Configuration.MCUConfiguration = new PropertyDictionary2
             {
                 Entries = new PropertyDictionary2.KeyValue[]
                 { new PropertyDictionary2.KeyValue {
                       Key = "com.sysprogs.bspoptions.arm.floatmode", Value = "-mfloat-abi=hard"
                   } }
             };
         }
     }
 }
예제 #5
0
 static bool IsNonGCCFile(VendorSample vs, string fn)
 {
     if (fn.StartsWith(vs.Path + @"\MDK-ARM", StringComparison.InvariantCultureIgnoreCase))
     {
         return(true);
     }
     return(false);
 }
예제 #6
0
            protected override void AdjustVendorSampleProperties(VendorSample vs)
            {
                base.AdjustVendorSampleProperties(vs);
                vs.SourceFiles = vs.SourceFiles.Where(s => !IsNonGCCFile(vs, s)).ToArray();

                if (vs.SourceFiles.FirstOrDefault(f => f.Contains("libBle_Mesh_CM4_GCC")) != null)
                {
                    var dict = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.MCUConfiguration);
                    dict["com.sysprogs.bspoptions.arm.floatmode"] = "-mfloat-abi=soft";
                    vs.Configuration.MCUConfiguration             = new PropertyDictionary2(dict);
                }
            }
예제 #7
0
파일: Program.cs 프로젝트: kmnaxin/BSPTools
        private static TestResult BuildAndRunValidationJob(LoadedBSP.LoadedMCU mcu,
                                                           string mcuDir,
                                                           bool validateRegisters,
                                                           LoadedRenamingRule[] renameRules,
                                                           GeneratedProject prj,
                                                           ToolFlags flags,
                                                           Dictionary <string, bool> sourceExtensions,
                                                           string[] nonValidateReg,
                                                           string[] UndefinedMacros,
                                                           VendorSample vendorSample = null,
                                                           bool keepDirectoryAfterSuccessfulBuild = false)
        {
            BuildJob job    = new BuildJob();
            string   prefix = string.Format("{0}\\{1}\\{2}-", mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, mcu.BSP.Toolchain.Toolchain.GNUTargetID);

            job.OtherTasks.Add(new BuildTask
            {
                Executable = prefix + "g++",
                Arguments  = $"{flags.StartGroup} {flags.EffectiveLDFLAGS} $^ {flags.EndGroup} -o $@",
                AllInputs  = prj.SourceFiles.Where(f => sourceExtensions.ContainsKey(Path.GetExtension(f).TrimStart('.')))
                             .Select(f => Path.ChangeExtension(Path.GetFileName(f), ".o"))
                             .Concat(prj.SourceFiles.Where(f => f.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase)))
                             .ToArray(),
                PrimaryOutput = "test.elf",
            });

            job.OtherTasks.Add(new BuildTask
            {
                Executable    = prefix + "objcopy",
                Arguments     = "-O binary $< $@",
                AllInputs     = new[] { "test.elf" },
                PrimaryOutput = "test.bin",
            });


            foreach (var sf in prj.SourceFiles)
            {
                var    sfE = sf.Replace('\\', '/');
                string ext = Path.GetExtension(sf);
                if (!sourceExtensions.ContainsKey(ext.TrimStart('.')))
                {
                    if (ext != ".txt" && ext != ".a" && ext != ".h")
                    {
                        Console.WriteLine($"#{sf} is not a recognized source file");
                    }
                }
                else
                {
                    bool   isCpp = ext.ToLower() != ".c";
                    string obj   = Path.ChangeExtension(Path.GetFileName(sfE), ".o");
                    job.CompileTasks.Add(new BuildTask
                    {
                        PrimaryOutput = Path.ChangeExtension(Path.GetFileName(sfE), ".o"),
                        AllInputs     = new[] { sfE },
                        Executable    = prefix + (isCpp ? "g++" : "gcc"),
                        Arguments     = $"-c $< { (isCpp ? "-std=gnu++11 " : " ")} {flags.GetEffectiveCFLAGS(isCpp, ToolFlags.FlagEscapingMode.ForMakefile)} -o {obj}".Replace('\\', '/').Replace("/\"", "\\\""),
                    });
                }
            }


            bool errorsFound = false;

            foreach (var g in job.CompileTasks.GroupBy(t => t.PrimaryOutput.ToLower()))
            {
                if (g.Count() > 1)
                {
                    Console.WriteLine($"ERROR: {g.Key} corresponds to the following files:");
                    foreach (var f in g)
                    {
                        Console.WriteLine("\t" + f.AllInputs.FirstOrDefault());
                    }
                    errorsFound = true;
                }
            }

            if (errorsFound)
            {
                throw new Exception("Multiple source files with the same name found");
            }

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

            comments.Add("Tool flags:");
            comments.Add("\tInclude directories:");
            foreach (var dir in flags.IncludeDirectories ?? new string[0])
            {
                comments.Add("\t\t" + dir);
            }
            comments.Add("\tPreprocessor macros:");
            foreach (var dir in flags.PreprocessorMacros ?? new string[0])
            {
                comments.Add("\t\t" + dir);
            }
            comments.Add("\tLibrary directories:");
            foreach (var dir in flags.AdditionalLibraryDirectories ?? new string[0])
            {
                comments.Add("\t\t" + dir);
            }
            comments.Add("\tLibrary names:");
            foreach (var dir in flags.AdditionalLibraries ?? new string[0])
            {
                comments.Add("\t\t" + dir);
            }
            comments.Add("\tExtra linker inputs:");
            foreach (var dir in flags.AdditionalLinkerInputs ?? new string[0])
            {
                comments.Add("\t\t" + dir);
            }
            comments.Add("\tCFLAGS:" + flags.CFLAGS);
            comments.Add("\tCXXFLAGS:" + flags.CXXFLAGS);
            comments.Add("\tLDFLAGS:" + flags.LDFLAGS);
            comments.Add("\tCOMMONFLAGS:" + flags.COMMONFLAGS);

            job.GenerateMakeFile(Path.Combine(mcuDir, "Makefile"), "test.bin", comments);

            if (!string.IsNullOrEmpty(mcu.MCUDefinitionFile) && validateRegisters)
            {
                string firstSrcFileInPrjDir = prj.SourceFiles.First(fn => Path.GetDirectoryName(fn) == mcuDir);
                InsertRegisterValidationCode(firstSrcFileInPrjDir, XmlTools.LoadObject <MCUDefinition>(mcu.MCUDefinitionFile), renameRules, nonValidateReg, UndefinedMacros);
            }

            bool buildSucceeded;

            if (true)
            {
                var proc = Process.Start(new ProcessStartInfo("cmd.exe", "/c " + Path.Combine(mcu.BSP.Toolchain.Directory, mcu.BSP.Toolchain.Toolchain.BinaryDirectory, "make.exe") + " -j" + Environment.ProcessorCount + " > build.log 2>&1")
                {
                    UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = mcuDir
                });
                proc.WaitForExit();
                buildSucceeded = proc.ExitCode == 0;
            }
            else
            {
                buildSucceeded = job.BuildFast(mcuDir, Environment.ProcessorCount);
            }

            bool   success = false;
            string mapFile = Path.Combine(mcuDir, GeneratedProject.MapFileName);

            if (buildSucceeded && File.Exists(mapFile))
            {
                success = File.ReadAllLines(Path.Combine(mcuDir, mapFile)).Where(l => RgMainMap.IsMatch(l)).Count() > 0;

                if (success)
                {
                    string binFile = Path.Combine(mcuDir, "test.bin");
                    using (var fs = File.Open(binFile, FileMode.Open))
                        if (fs.Length < 512)
                        {
                            success = false;
                        }
                }
            }

            if (!success)
            {
                if (vendorSample != null)
                {
                    vendorSample.AllDependencies = null;
                }
                return(new TestResult(TestBuildResult.Failed, Path.Combine(mcuDir, "build.log")));
            }

            if (vendorSample != null)
            {
                vendorSample.AllDependencies = Directory.GetFiles(mcuDir, "*.d")
                                               .SelectMany(f => SplitDependencyFile(f).Where(t => !t.EndsWith(":")))
                                               .Distinct()
                                               .ToArray();
            }

            if (!keepDirectoryAfterSuccessfulBuild)
            {
                Directory.Delete(mcuDir, true);
            }

            return(new TestResult(TestBuildResult.Succeeded, Path.Combine(mcuDir, "build.log")));
        }
예제 #8
0
        public static ParsedSDK ParseKSDKManifest(string sdkDirectory, IWarningSink sink)
        {
            string[] manifestFiles = Directory.GetFiles(sdkDirectory, "*manifest.xml");
            if (manifestFiles.Length < 1)
            {
                throw new Exception($"No manifest files in {sdkDirectory}");
            }

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

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

            XmlDocument doc = new XmlDocument();

            doc.Load(manifestFile);

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

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

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

                var mcuFamily = dev.ToMCUFamily();

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

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

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

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

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

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

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

                    default:
                        break;
                    }

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

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

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

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

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

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

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

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

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

                    frameworkDict[fw.ID] = fw;

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

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

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

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

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

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

                    deviceDict[pkgName] = dev;

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

                        MCUDefinitionFile = deviceDefinitionFile
                    });
                }
            }

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

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

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

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

                    dependencyList.AddRange(alwaysIncludedFrameworks);

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

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

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

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

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

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

                    string[] matchingComponents = null;

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

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

                    samples.Add(sample);
                }
            }


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

                VendorSampleDirectory = new VendorSampleDirectory
                {
                    Samples = samples.ToArray()
                }
            });
        }
예제 #9
0
 protected override void OnVendorSampleParsed(VendorSample sample, CommonConfigurationOptions options)
 {
     base.OnVendorSampleParsed(sample, options);
     OptionDictionary[sample] = options; //Remember advanced sample data that didn't make it into the VendorSample object.
 }
예제 #10
0
            VendorSample ParseMakFile(string nameFile, string relativePath, string SDKdir)
            {
                VendorSample  vs         = new VendorSample();
                List <string> lstFileC   = new List <string>();
                List <string> lstFileInc = new List <string>();
                List <string> splitArgs  = new List <string>();
                List <string> lstDef     = new List <string>();
                Dictionary <string, string> lstConstDir          = new Dictionary <string, string>();
                HashSet <string>            referencedFrameworks = new HashSet <string>();
                string  aCurDir = Path.GetDirectoryName(nameFile);
                Boolean flFlags = false;

                lstFileInc.Add(aCurDir);

                foreach (var ln in File.ReadAllLines(nameFile))
                {
                    if (ln.StartsWith("CFLAGS =") || ln.StartsWith("CPPFLAGS ="))
                    {
                        flFlags = true;
                    }

                    if (flFlags)
                    {
                        if (ln.Contains(" -I") || ln.Contains(" \"-I"))
                        {
                            if (ln.Contains("$(GCC_ARMCOMPILER)"))
                            {
                                continue;   //Toolchain-provided header directories should be handled automatically by toolchain itself.
                            }
                            lstFileInc.Add(GetUpDir(ToAbsolutePath(ln.Replace("CFLAGS =", "").Replace("\"", "").Replace("-I", "").Trim(' ', '\\'), SDKdir, lstConstDir), aCurDir));
                        }

                        if (ln.Contains(" -D"))
                        {
                            lstDef.Add(ln.Replace("-D", "").Replace("\"", "").Trim(' ', '\\'));
                        }
                    }


                    if (ln.StartsWith("LFLAGS =") || ln.StartsWith(".PRECIOUS:"))
                    {
                        flFlags = false;
                    }

                    if (ln.Contains("-std"))
                    {
                        if (ln.Contains("c99"))
                        {
                            vs.CLanguageStandard = "c99";
                        }
                        else
                        {
                            vs.CPPLanguageStandard = ln.Replace("-std=", "").Trim('\\', ' ', '\t');
                        }
                    }

                    if (ln.Contains(".obj:"))
                    {
                        string files = ln.Remove(0, ln.IndexOf(":") + 1).Split('$')[0].Trim(' ');
                        foreach (var file in files.Split(' '))
                        {
                            var fullPath = Path.GetFullPath(Path.Combine(aCurDir, file));

                            if (!File.Exists(fullPath))
                            {
                                throw new Exception("Missing " + fullPath);
                            }
                            lstFileC.Add(fullPath);
                        }
                    }

                    if (ln.Contains("\"-L"))
                    {
                        //We ignore the library search paths
                    }

                    if (ln.Contains(" -l:"))
                    {
                        referencedFrameworks.Add(_FrameworkLocator.LocateFrameworkForLibraryFile(ln.Replace("\"", "").Trim(' ', '\\')));
                    }

                    Match m = Regex.Match(ln, @"([\w]+)[ \t]*:=[ \t]*([$(\w)/]*)");
                    if (m.Success)
                    {
                        lstConstDir.Add(m.Groups[1].Value, m.Groups[2].Value);
                    }
                }


                if (lstFileInc.Where(f => f.Contains("$")).Count() > 0)
                {
                    throw new Exception("Path contains macros " + string.Join(", ", lstFileInc.Where(f => f.Contains("$"))));
                }

                vs.IncludeDirectories = lstFileInc.Distinct().ToArray();
                vs.PreprocessorMacros = lstDef.ToArray();
                vs.SourceFiles        = lstFileC.Distinct().ToArray();
                vs.Configuration      = new VendorSampleConfiguration
                {
                    Frameworks = referencedFrameworks.Where(f => f != null).ToArray(),
                };

                if (vs.Configuration.Frameworks.Contains("com.sysprogs.arm.ti.cc3220.freertos"))
                {
                    AddConfigurationEntries(ref vs.Configuration.Configuration, "com.sysprogs.bspoptions.cc3220.freertos.heap=heap_4", "com.sysprogs.bspoptions.cc3220.freertos.portcore=CM4F");
                    AddConfigurationEntries(ref vs.Configuration.MCUConfiguration, "com.sysprogs.bspoptions.arm.floatmode=-mfloat-abi=hard");
                }

                if (vs.Configuration.Frameworks.Contains("com.sysprogs.arm.ti.cc3220.mqtt"))
                {
                    AddConfigurationEntries(ref vs.Configuration.Configuration, "com.sysprogs.bspoptions.MQTT_Client=1", "com.sysprogs.bspoptions.MQTT_Server=1");
                }

                const string BoardSuffix = "_LAUNCHXL";

                vs.DeviceID = nameFile.Split('\\').Last(component => component.EndsWith(BoardSuffix, StringComparison.InvariantCultureIgnoreCase));
                vs.DeviceID = vs.DeviceID.Substring(0, vs.DeviceID.Length - BoardSuffix.Length);

                if (File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Where(ln => ln.StartsWith("NAME")).Count() == 0)
                {
                    vs.UserFriendlyName = "noname";
                }
                else
                {
                    vs.UserFriendlyName = File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Single(ln => ln.StartsWith("NAME")).Split('=')[1].Trim(' ').ToUpper();
                }


                var relativePathComponents = relativePath.Split('\\');

                vs.UserFriendlyName += "-" + relativePathComponents[0];

                return(vs);
            }
예제 #11
0
파일: Program.cs 프로젝트: whinis/BSPTools
            protected override ParsedVendorSamples ParseVendorSamples(string SDKdir, IVendorSampleFilter filter)
            {
                /*
                 *  Since most of the original SDK samples only consist of a handful of files, we use a very simplified logic to enumerate them:
                 *      1. Locate all "Makefile" and "readme.txt" files.
                 *      2. Discard those that don't have .c files in the same directory, or have multiple directories with .c files.
                 *      3. Depending on the config files stored in the same directory, we pick one of the 3 predefined profiles (wlan, bluetooth, periph).
                 *         The profiles come from manually created VisualGDB projects and specify a minimum viable configuration to build basic samples.
                 *
                 *   Then, we try building all samples discovered via this simplified algorithm, and the successfully built ones into the BSP.
                 */
                var sampleBase = Path.Combine(SDKdir, "Examples");
                var allFiles   = Directory.GetFiles(sampleBase, "*.*", SearchOption.AllDirectories);

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

                var wlanConfig = XmlTools.LoadObject <EmbeddedProfile>(Path.Combine(RulesDirectory, "wlan.xml"));
                var bareConfig = XmlTools.LoadObject <EmbeddedProfile>(Path.Combine(RulesDirectory, "periph.xml"));
                var btConfig   = XmlTools.LoadObject <EmbeddedProfile>(Path.Combine(RulesDirectory, "bluetooth.xml"));

                foreach (var dir in allFiles.Where(f => Path.GetFileName(f) == "Makefile" || Path.GetFileName(f).ToLower() == "readme.txt").Select(Path.GetDirectoryName).Distinct())
                {
                    var matchingSources = allFiles.Where(f => Path.GetExtension(f) == ".c" && f.StartsWith(dir + "\\")).ToArray();
                    var matchingDirs    = matchingSources.Select(Path.GetDirectoryName).Distinct().ToArray();

                    if (matchingDirs.Length != 1)
                    {
                        continue;
                    }

                    string name   = Path.GetFileName(dir);
                    string macros = null;

                    EmbeddedProfile matchingProfile;
                    if (File.Exists(Path.Combine(dir, "rsi_ble_config.h")))
                    {
                        matchingProfile = btConfig;
                        macros          = "BT_BDR_MODE=0";
                    }
                    if (File.Exists(Path.Combine(dir, "rsi_wlan_config.h")))
                    {
                        matchingProfile = wlanConfig;
                    }
                    else
                    {
                        matchingProfile = bareConfig;
                        macros          = "__SYSTICK";
                    }

                    var sample = new VendorSample
                    {
                        DeviceID           = "RS14100",
                        SourceFiles        = matchingSources,
                        UserFriendlyName   = name,
                        InternalUniqueID   = dir.Substring(SDKdir.Length).TrimStart('\\').Replace('\\', '_'),
                        Path               = dir,
                        IncludeDirectories = new[] { dir },
                        VirtualPath        = Path.GetDirectoryName(dir).Substring(SDKdir.Length).TrimStart('\\'),

                        Configuration = matchingProfile.ToConfiguration(),
                    };

                    if (File.Exists(Path.Combine(dir, "readme.txt")))
                    {
                        sample.Description = File.ReadAllText(Path.Combine(dir, "readme.txt"));
                    }

                    if (macros != null)
                    {
                        sample.PreprocessorMacros = macros.Split(';');
                    }

                    vendorSamples.Add(sample);
                }

                return(new ParsedVendorSamples {
                    VendorSamples = vendorSamples.ToArray()
                });
            }
예제 #12
0
        public VendorSample BuildVendorSample(string rootDir, string boardName, SpecializedDevice device, string package, HashSet <string> allComponentIDs, HashSet <string> implicitFrameworks)
        {
            Dictionary <string, string> properties = new Dictionary <string, string>();

            if (!string.IsNullOrEmpty(ExplicitFPUSetting))
            {
                properties["com.sysprogs.bspoptions.arm.floatmode"] = ExplicitFPUSetting.Contains("hard") ? "-mfloat-abi=hard" : "-mfloat-abi=soft";
            }

            string sampleName = ID;

            if (!string.IsNullOrEmpty(RelativePath))
            {
                string[] relativePathComponents = RelativePath.Split('/');
                if (relativePathComponents.Length > 3 && relativePathComponents[0] == "boards")
                {
                    string expectedPrefix = relativePathComponents[1] + "_" + relativePathComponents[2] + "_";
                    if (sampleName.StartsWith(expectedPrefix))
                    {
                        sampleName = sampleName.Substring(expectedPrefix.Length);
                    }
                }
            }


            VendorSample sample = new VendorSample
            {
                DeviceID         = device.MakeMCUID(package),
                UserFriendlyName = sampleName,
                InternalUniqueID = ID,
                Description      = Description,
                BoardName        = boardName,
                Configuration    = new VendorSampleConfiguration
                {
                    Frameworks       = Dependencies.Where(d => allComponentIDs.Contains(d)).Select(d => ParsedComponent.FrameworkIDPrefix + d).Concat(implicitFrameworks).Distinct().ToArray(),
                    MCUConfiguration = new PropertyDictionary2(properties)
                },

                VirtualPath        = Category,
                PreprocessorMacros = Defines,

                NoImplicitCopy = true
            };

            List <string>    sources = new List <string>(), headers = new List <string>();
            HashSet <string> includeDirectories = new HashSet <string>();

            string[] matchingPathComponents = null;

            foreach (var lst in SourceLists)
            {
                foreach (var file in lst.LocateAllFiles(device, rootDir))
                {
                    var bspPath = file.GetBSPPath();
                    UpdateMatchingPathComponents(bspPath, ref matchingPathComponents);

                    file.UpdateIncludeDirectoryList(includeDirectories);

                    switch (file.Type)
                    {
                    case SourceType.Library:
                    case SourceType.Source:
                        sources.Add(bspPath);
                        break;

                    case SourceType.Header:
                        headers.Add(bspPath);
                        break;

                    case SourceType.LinkerScript:
                        sample.LinkerScript = bspPath;
                        break;
                    }
                }
            }

            sample.CLanguageStandard = MapLanguageStandard(LanguageStandard);
            sample.LDFLAGS           = string.Join(" ", AdvancedLinkerOptions.Where(f => f.StartsWith("--defsym")).Select(f => "-Wl," + f).ToArray());
            if (sample.LDFLAGS == "")
            {
                sample.LDFLAGS = null;
            }

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

            sample.SourceFiles        = sources.ToArray();
            sample.HeaderFiles        = headers.ToArray();
            sample.IncludeDirectories = includeDirectories.ToArray();

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

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

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

            XmlDocument doc = new XmlDocument();

            doc.Load(manifestFile);

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

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


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

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

                var mcuFamily = dev.ToMCUFamily();

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

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

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

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

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

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

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

                    case "CMSIS":

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

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

                    case "project_template":
                        continue;

                    default:
                        break;
                    }

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

                    var IDFr = fwPrefix + idComponent;

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

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

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

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

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

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

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

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

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

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

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

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

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

                    frameworkDict[fw.ID] = fw;

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

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

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

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

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

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

                    deviceDict[pkgName] = dev;

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

                        MCUDefinitionFile = deviceDefinitionFile
                    });
                }
            }

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

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

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

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

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

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

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

                    dependencyList.AddRange(alwaysIncludedFrameworks);

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

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

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

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

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


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

                        NoImplicitCopy = true
                    };

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

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


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

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

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

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

                    string[] matchingComponents = null;

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

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

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

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

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

                VendorSampleDirectory = new VendorSampleDirectory
                {
                    Samples = samples.ToArray()
                }
            });
        }
예제 #14
0
        static VendorSample ParseDependFiles(string ExamplDir, string namelog)
        {
            VendorSample  vs         = new VendorSample();
            List <string> lstFileC   = new List <string>();
            List <string> lstFileInc = new List <string>();
            List <string> splitArgs  = new List <string>();
            List <string> lstDef     = new List <string>();
            Boolean       flBoot     = false;

            //--------log parser---
            foreach (var ln in File.ReadAllLines(namelog))
            {
                if (ln.Contains("xtensa-esp32-elf-gcc") && ln.Contains("bootloader.elf"))
                {
                    flBoot = true;
                }

                if (!flBoot)
                {
                    continue;
                }

                if (ln.Contains("bootloader_random.c"))
                {
                    continue;
                }

                string ln1 = ln.Replace("-I ", "-I");
                while (ln1.Contains("-I "))
                {
                    ln1 = ln1.Replace("-I ", "-I");
                }
                while (ln1.Contains("-D "))
                {
                    ln1 = ln1.Replace("-D ", "-D");
                }


                if (!ln1.Contains("xtensa-esp32-elf-gcc") && !ln1.Contains("xtensa-esp32-elf-c++"))
                {
                    continue;
                }
                if (!ln1.Contains(" -C ") && !ln1.Contains(" -c "))
                {
                    continue;
                }
                // Get Arguments
                int    munArg;
                IntPtr ptrToSplitArgs = CommandLineToArgvW(ln1, out munArg);
                if (ptrToSplitArgs == IntPtr.Zero)
                {
                    throw new Exception("no arg");
                }

                for (int i = 0; i < munArg; i++)
                {
                    string arg = Marshal.PtrToStringUni(
                        Marshal.ReadIntPtr(ptrToSplitArgs, i * IntPtr.Size));
                    arg = arg.Replace('\'', '\"');
                    if (!splitArgs.Contains(arg))
                    {
                        splitArgs.Add(arg);
                    }
                }

                // Processing arguments
                lstFileInc.AddRange(string.Join(" ", splitArgs.Where(ar => ar.StartsWith("-I"))).Split(new string[] { "-I" }, StringSplitOptions.RemoveEmptyEntries));
                lstDef.AddRange(string.Join(" ", splitArgs.Where(ar => ar.StartsWith("-D") && !ar.Contains("BOOTLOADER_BUILD"))).Split(new string[] { "-D" }, StringSplitOptions.RemoveEmptyEntries));

                lstFileInc = lstFileInc.Distinct().ToList();

                lstFileC.AddRange(splitArgs.Where(ar => (ar.EndsWith(".c") || ar.EndsWith(".cpp") || ar.ToLower().EndsWith(".s"))));

                if (splitArgs.Where(ar => ar.EndsWith(".c") || ar.EndsWith(".cpp") || ar.ToLower().EndsWith(".s")).Count() > 1)
                {
                    throw new Exception("many source argumens");
                }


                //arguments from file
                var fileArg = splitArgs.SingleOrDefault(ar => ar.StartsWith("@"));
                if (fileArg != null)
                {
                    continue;
                }
                splitArgs.Clear();
            }

            //-------------------
            if (lstFileC.Count == 0)
            {
                Console.WriteLine($"{namelog}  No Source File");
                return(null);
            }
            vs.PreprocessorMacros = lstDef.Distinct().ToArray();
            vs.BoardName          = "ESP32";
            vs.DeviceID           = "ESP32";
            var dlC = lstFileC.Distinct().ToList();

            //--------------------------

            ChackRenameFiles(ref dlC, "$$SYS:BSP_ROOT$$");
            ChackRenameFiles(ref lstFileInc, "$$SYS:BSP_ROOT$$");
            int ind = ExamplDir.IndexOf("\\esp-idf.orig");

            lstFileInc.Insert(1, $@"$$SYS:BSP_ROOT$$/..{ExamplDir.Remove(0, ind)}/build/include".Replace("\\", "/"));// sdkconfig.h

            vs.SourceFiles = dlC.Distinct().ToArray();
            var lstFileInc1 = lstFileInc.Select(f => Path.GetDirectoryName(f)).Distinct();

            vs.IncludeDirectories = lstFileInc.ToArray();
            return(vs);
        }
예제 #15
0
 public VendorSampleID(VendorSample sample)
 {
     SampleName          = sample.UserFriendlyName;
     BoardNameOrDeviceID = sample.BoardName ?? sample.DeviceID;
 }
예제 #16
0
파일: Program.cs 프로젝트: kmnaxin/BSPTools
        public static TestResult TestVendorSampleAndUpdateDependencies(LoadedBSP.LoadedMCU mcu, VendorSample vs, string mcuDir, string sampleDirPath, bool codeRequiresDebugInfoFlag, bool keepDirectoryAfterSuccessfulBuild)
        {
            if (Directory.Exists(mcuDir))
            {
                Directory.Delete(mcuDir, true);
            }
            Directory.CreateDirectory(mcuDir);

            var configuredMCU = new LoadedBSP.ConfiguredMCU(mcu, GetDefaultPropertyValues(mcu.ExpandedMCU.ConfigurableProperties));

            configuredMCU.Configuration["com.sysprogs.toolchainoptions.arm.libnosys"] = "--specs=nosys.specs";

            if (configuredMCU.ExpandedMCU.FLASHSize == 0)
            {
                configuredMCU.Configuration["com.sysprogs.bspoptions.primary_memory"] = "sram";
            }

            var entries = vs.Configuration.MCUConfiguration?.Entries;

            if (entries != null)
            {
                foreach (var e in entries)
                {
                    configuredMCU.Configuration[e.Key] = e.Value;
                }
            }

            var bspDict = configuredMCU.BuildSystemDictionary(default(SystemDirectories));

            bspDict["PROJECTNAME"] = "test";
            if (sampleDirPath != null)
            {
                bspDict["SYS:VSAMPLE_DIR"] = sampleDirPath;
            }

            var prj = new GeneratedProject(configuredMCU, vs, mcuDir, bspDict, vs.Configuration.Frameworks ?? new string[0]);

            var projectCfg = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.MCUConfiguration);

            var frameworkCfg = PropertyDictionary2.ReadPropertyDictionary(vs.Configuration.Configuration);

            foreach (var k in projectCfg.Keys)
            {
                bspDict[k] = projectCfg[k];
            }
            var frameworkIDs = vs.Configuration.Frameworks?.ToDictionary(fw => fw, fw => true);

            prj.AddBSPFilesToProject(bspDict, frameworkCfg, frameworkIDs);
            var flags = prj.GetToolFlags(bspDict, frameworkCfg, frameworkIDs);

            if (flags.LinkerScript != null && !Path.IsPathRooted(flags.LinkerScript))
            {
                flags.LinkerScript = Path.Combine(VariableHelper.ExpandVariables(vs.Path, bspDict, frameworkCfg), flags.LinkerScript).Replace('\\', '/');
            }

            //ToolFlags flags = new ToolFlags { CXXFLAGS = "  ", COMMONFLAGS = "-mcpu=cortex-m3  -mthumb", LDFLAGS = "-Wl,-gc-sections -Wl,-Map," + "test.map", CFLAGS = "-ffunction-sections -Os -MD" };

            if (!string.IsNullOrEmpty(vs.CLanguageStandard))
            {
                flags.CFLAGS += $" -std={vs.CLanguageStandard}";
            }
            if (!string.IsNullOrEmpty(vs.CPPLanguageStandard))
            {
                flags.CXXFLAGS += $" -std={vs.CPPLanguageStandard}";
            }

            flags.CFLAGS   += " -MD";
            flags.CXXFLAGS += " -MD";

            if (codeRequiresDebugInfoFlag)
            {
                flags.CFLAGS   += " -ggdb";
                flags.CXXFLAGS += " -ggdb";
            }

            flags.IncludeDirectories = LoadedBSP.Combine(flags.IncludeDirectories, vs.IncludeDirectories).Distinct().ToArray();
            flags.PreprocessorMacros = LoadedBSP.Combine(flags.PreprocessorMacros, vs.PreprocessorMacros);

            flags.LDFLAGS = flags.LDFLAGS + " " + vs.LDFLAGS;
            flags         = LoadedBSP.ConfiguredMCU.ExpandToolFlags(flags, bspDict, null);

            Dictionary <string, bool> sourceExtensions = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase);

            sourceExtensions.Add("c", true);
            sourceExtensions.Add("cpp", true);
            sourceExtensions.Add("s", true);

            return(BuildAndRunValidationJob(mcu, mcuDir, false, null, prj, flags, sourceExtensions, null, null, vs, keepDirectoryAfterSuccessfulBuild));
        }
예제 #17
0
파일: Program.cs 프로젝트: kmnaxin/BSPTools
 protected override void AdjustVendorSampleProperties(VendorSample vs)
 {
     base.AdjustVendorSampleProperties(vs);
     vs.BSPReferencesAreCopyable = true;
     vs.SourceFiles = vs.SourceFiles.Where(s => !rgSystemFile.IsMatch(s)).ToArray();
 }
예제 #18
0
 public void OnSampleParsed(VendorSample sample)
 {
 }
예제 #19
0
 public SingleSampleFilter(VendorSample existingSample)
 {
     _ExistingSample = existingSample;
     _Path           = Path.GetFullPath(_ExistingSample.Path);
 }
예제 #20
0
파일: Program.cs 프로젝트: xllj/BSPTools
        static public List <VendorSample> GetInfoProjectFromMDK(string pDirPrj, string topLevelDir, List <string> extraIncludeDirs)
        {
            List <VendorSample> aLstVSampleOut = new List <VendorSample>();
            int    aCntTarget = 0;
            string aFilePrj   = pDirPrj + "\\Project.uvprojx";
            string aNamePrj   = pDirPrj.Replace("\\MDK-ARM", "");

            aNamePrj = aNamePrj.Substring(aNamePrj.LastIndexOf("\\") + 1);
            List <string> sourceFiles   = new List <string>();
            List <string> includeDirs   = new List <string>();
            bool          flGetProperty = false;
            string        aTarget       = "";
            VendorSample  sample        = new VendorSample();

            foreach (var ln in File.ReadAllLines(aFilePrj))
            {
                if (ln.Contains("<Target>"))
                {
                    if (aCntTarget == 0)
                    {
                        sample = new VendorSample();
                    }
                    aCntTarget++;
                }
                if (ln.Contains("</Target>"))
                {
                    if (aCntTarget == 0)
                    {
                        throw new Exception("wrong tag Targets");
                    }
                    else
                    {
                        aCntTarget--;
                    }
                }

                if (ln.Contains("<Cads>"))
                {
                    flGetProperty = true;
                }
                else if (ln.Contains("</Cads>"))
                {
                    flGetProperty = false;
                }

                Match m = Regex.Match(ln, "[ \t]*<Device>(.*)</Device>[ \t]*");
                if (m.Success)
                {
                    sample.DeviceID = m.Groups[1].Value;
                    if (sample.DeviceID.EndsWith("x"))
                    {
                        sample.DeviceID = sample.DeviceID.Remove(sample.DeviceID.Length - 2, 2);
                    }
                }
                m = Regex.Match(ln, "[ \t]*<TargetName>(.*)</TargetName>[ \t]*");
                if (m.Success)
                {
                    aTarget = m.Groups[1].Value;
                }

                MatchCollection m1 = Regex.Matches(ln, @"[ ]*<FilePath>([\w\-:\\./]*)</FilePath>[ ]*");
                foreach (Match mc in m1)
                {
                    string filePath = mc.Groups[1].Value;
                    if (filePath.StartsWith(@"./") || filePath.StartsWith(@".\"))
                    {
                        filePath = pDirPrj + filePath.Substring(1);
                    }
                    if (filePath.EndsWith(".s", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (filePath.EndsWith(".lib", StringComparison.InvariantCultureIgnoreCase))
                    {
                        filePath = filePath.Replace("_Keil.lib", "_GCC.a");
                        if (!File.Exists(Path.Combine(pDirPrj, filePath)))
                        {
                            continue;
                        }
                    }

                    if (!sourceFiles.Contains(filePath))
                    {
                        sourceFiles.Add(filePath);
                    }
                }

                if (flGetProperty)
                {
                    m = Regex.Match(ln, "[ \t]*<IncludePath>(.*)</IncludePath>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                    {
                        sample.IncludeDirectories = m.Groups[1].Value.Split(';').Select(d => d.TrimEnd('/', '\\')).ToArray();
                    }

                    m = Regex.Match(ln, "[ \t]*<Define>(.*)</Define>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                    {
                        sample.PreprocessorMacros = m.Groups[1].Value.Split(',');
                    }
                }


                if (ln.Contains("</Target>") && aCntTarget == 0)
                {
                    sample.Path             = Path.GetDirectoryName(pDirPrj);
                    sample.UserFriendlyName = aNamePrj;
                    sample.BoardName        = aTarget;
                    sample.SourceFiles      = ToAbsolutePath(pDirPrj, topLevelDir, sourceFiles).ToArray();

                    foreach (var fl in sample.IncludeDirectories)
                    {
                        includeDirs.Add(fl);
                    }
                    includeDirs.AddRange(extraIncludeDirs);
                    sample.IncludeDirectories = ToAbsolutePath(pDirPrj, topLevelDir, includeDirs).ToArray();

                    string readmeFile = Path.Combine(pDirPrj, @"..\readme.txt");
                    if (File.Exists(readmeFile))
                    {
                        string readmeContents = File.ReadAllText(readmeFile);
                        Regex  rgTitle        = new Regex(@"@page[ \t]+[^ \t]+[ \t]+([^ \t][^@]*)\r\n *\r\n", RegexOptions.Singleline);
                        m = rgTitle.Match(readmeContents);
                        if (m.Success)
                        {
                            sample.Description = m.Groups[1].Value;
                        }
                    }

                    aLstVSampleOut.Add(sample);
                }
            }
            return(aLstVSampleOut);
        }
예제 #21
0
 protected virtual void OnVendorSampleParsed(VendorSample sample, CommonConfigurationOptions options)
 {
 }
예제 #22
0
        static public List<VendorSample> GetInfoProjectFromMDK(string pDirPrj, string topLevelDir, List<string> extraIncludeDirs)
        {
            List<VendorSample> aLstVSampleOut = new List<VendorSample>();
            int aCntTarget = 0;
            string aFilePrj = pDirPrj + "\\Project.uvprojx";
            string aNamePrj = pDirPrj.Replace("\\MDK-ARM", "");
            aNamePrj = aNamePrj.Substring(aNamePrj.LastIndexOf("\\") + 1);
            List<string> sourceFiles = new List<string>();
            List<string> includeDirs = new List<string>();
            bool flGetProperty = false;
            string aTarget = "";
            VendorSample aSimpleOut = new VendorSample();
            foreach (var ln in File.ReadAllLines(aFilePrj))
            {
                if (ln.Contains("<Target>"))
                {
                    if (aCntTarget == 0)
                        aSimpleOut = new VendorSample();
                    aCntTarget++;
                }
                if (ln.Contains("</Target>"))
                    if (aCntTarget == 0)
                        throw new Exception("wrong tag Targets");
                    else
                        aCntTarget--;

                if (ln.Contains("<Cads>"))
                    flGetProperty = true;
                else if (ln.Contains("</Cads>"))
                    flGetProperty = false;

                Match m = Regex.Match(ln, "[ \t]*<Device>(.*)</Device>[ \t]*");
                if (m.Success)
                {
                    aSimpleOut.DeviceID = m.Groups[1].Value;
                    if (aSimpleOut.DeviceID.EndsWith("x"))
                        aSimpleOut.DeviceID = aSimpleOut.DeviceID.Remove(aSimpleOut.DeviceID.Length - 2, 2);
                }
                m = Regex.Match(ln, "[ \t]*<TargetName>(.*)</TargetName>[ \t]*");
                if (m.Success)
                    aTarget = m.Groups[1].Value;

                MatchCollection m1 = Regex.Matches(ln, @"[ ]*<FilePath>([\w\-:\\./]*)</FilePath>[ ]*");
                foreach (Match mc in m1)
                {
                    string filePath = mc.Groups[1].Value;
                    if (filePath.StartsWith(@"./") || filePath.StartsWith(@".\"))
                        filePath = pDirPrj + filePath.Substring(1);
                    if (filePath.EndsWith(".s", StringComparison.InvariantCultureIgnoreCase))
                        continue;

                    if (!sourceFiles.Contains(filePath))
                        sourceFiles.Add(filePath);
                }

                if (flGetProperty)
                {
                    m = Regex.Match(ln, "[ \t]*<IncludePath>(.*)</IncludePath>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                        aSimpleOut.IncludeDirectories = m.Groups[1].Value.Split(';');

                    m = Regex.Match(ln, "[ \t]*<Define>(.*)</Define>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                        aSimpleOut.PreprocessorMacros = m.Groups[1].Value.Split(',');
                }


                if (ln.Contains("</Target>") && aCntTarget == 0)
                {
                    aSimpleOut.Path = Path.GetDirectoryName(pDirPrj);
                    aSimpleOut.UserFriendlyName = aNamePrj;
                    aSimpleOut.BoardName = aTarget;
                    aSimpleOut.SourceFiles = ToAbsolutePath(pDirPrj, topLevelDir, sourceFiles).ToArray();

                    foreach (var fl in aSimpleOut.IncludeDirectories)
                        includeDirs.Add(fl);
                    includeDirs.AddRange(extraIncludeDirs);
                    aSimpleOut.IncludeDirectories = ToAbsolutePath(pDirPrj, topLevelDir, includeDirs).ToArray();

                    string readmeFile = Path.Combine(pDirPrj, @"..\readme.txt");
                    if (File.Exists(readmeFile))
                    {
                        string readmeContents = File.ReadAllText(readmeFile);
                        Regex rgTitle = new Regex(@"@page[ \t]+[^ \t]+[ \t]+([^ \t][^@]*)\r\n *\r\n", RegexOptions.Singleline);
                        m = rgTitle.Match(readmeContents);
                        if (m.Success)
                        {
                            aSimpleOut.Description = m.Groups[1].Value;
                        }
                    }

                    aLstVSampleOut.Add(aSimpleOut);
                }
            }
            return aLstVSampleOut;
        }
예제 #23
0
        //-----------------------------------------------
        static List <VendorSample> ParseVendorSamples(string SDKdir)
        {
            string[] ExampleDirs = Directory.GetFiles(Path.Combine(SDKdir, $@"esp-idf.orig\examples"), "Makefile", SearchOption.AllDirectories).ToArray();

            List <VendorSample> allSamples = new List <VendorSample>();
            var count          = 0;
            int FaildSamlesdef = 0;

            foreach (var makfile in ExampleDirs)
            {
                var    mainexamplDir = Path.GetDirectoryName(makfile);
                string nameExampl    = mainexamplDir.Substring(mainexamplDir.IndexOf("examples") + 9).Replace("Makefile", "").Replace('\\', '-');

                /*
                 * if (count == 3)
                 *  break;
                 * count++;
                 */

                var nameLog = Path.Combine(Path.GetDirectoryName(mainexamplDir), "Logs", $"{nameExampl}.log");
                if (!Directory.Exists(Path.Combine(Path.GetDirectoryName(mainexamplDir), "Logs")))
                {
                    Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(mainexamplDir), "Logs"));
                }

                if (File.Exists(nameLog))
                {
                    continue;
                }


                if (Directory.Exists(Path.Combine(Path.GetFullPath(mainexamplDir), "build")))
                {
                    if (Directory.GetFiles(Path.Combine(Path.GetFullPath(mainexamplDir), "build"), "*.elf").Count() > 0)
                    {
                        Console.WriteLine(mainexamplDir + " elf exist");
                        //continue;
                        Directory.Delete(Path.Combine(Path.GetFullPath(mainexamplDir), "build"), true);// new compiling!
                    }
                    try
                    {
                        Directory.Delete(Path.Combine(Path.GetFullPath(mainexamplDir), "build"), true);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("No delete folder " + mainexamplDir + "-" + ex.Message);
                        continue;
                    }
                }

                Process compiler = new Process();

                DateTime start = DateTime.Now;
                Console.WriteLine($"Compiling {nameExampl} defconfig  ...");
                string DirMake = mainexamplDir.Replace('\\', '/');

                compiler.StartInfo.FileName         = @"c:/sysgcc/esp32/bin/bash.exe";
                compiler.StartInfo.Arguments        = $" --login -c \"make VERBOSE=1 -C {DirMake} defconfig   >" + nameLog.Replace(".", "def.") + " 2>&1 \"";
                compiler.StartInfo.UseShellExecute  = false;
                compiler.StartInfo.WorkingDirectory = Path.GetDirectoryName($"c:\\SysGCC\\esp32\\bin");
                compiler.EnableRaisingEvents        = true;
                compiler.Start();
                compiler.WaitForExit();
                Console.WriteLine($"[{(DateTime.Now - start).TotalMilliseconds:f0} msec]");
                bool buildSucceeded;
                buildSucceeded = compiler.ExitCode == 0;

                if (!buildSucceeded)
                {
                    FaildSamlesdef++;
                    FaildSamles++;
                    Console.WriteLine($"fail {FaildSamlesdef} compil defcongig {nameExampl} ...");
                    continue;
                }


                start = DateTime.Now;
                Console.WriteLine($"Compiling {nameExampl} ...");
                compiler.StartInfo.FileName         = @"c:/sysgcc/esp32/bin/bash.exe";
                compiler.StartInfo.Arguments        = $"--login -c \"make VERBOSE=1 -C {DirMake} >" + nameLog.Replace('\\', '/') + " 2>&1\"";
                compiler.StartInfo.UseShellExecute  = false;
                compiler.StartInfo.WorkingDirectory = Path.GetDirectoryName(@"c:\SysGCC\esp32\bin");
                compiler.StartInfo.WorkingDirectory = Path.GetDirectoryName($"c:\\SysGCC\\esp32\\bin");
                compiler.EnableRaisingEvents        = true;
                compiler.Start();

                compiler.WaitForExit();

                Console.WriteLine($"[{(DateTime.Now - start).TotalMilliseconds:f0} msec]");


                CntSamles++;


                buildSucceeded = compiler.ExitCode == 0;

                Console.ForegroundColor = ConsoleColor.Green;
                if (!buildSucceeded)
                {
                    if (!Directory.Exists(outputDir))
                    {
                        Directory.CreateDirectory(outputDir);
                    }

                    FaildSamles++;
                    Console.ForegroundColor = ConsoleColor.Red;
                    File.Copy(nameLog, Path.Combine(outputDir, $"FaildLogs{nameExampl.Replace('\\', '-')}"), true);
                }
                ToLog(string.Format("{2}: {0} - {1} (Failed: {3})", nameExampl, buildSucceeded ? "Succes" : "Failed ", CntSamles, FaildSamles));
                Console.ForegroundColor = ConsoleColor.Gray;

                if (!buildSucceeded)
                {
                    continue;
                }
            }
            Console.WriteLine($"Total fail compil defcongig  {FaildSamlesdef}");
            Console.WriteLine($"Total fail compil {FaildSamles}");
            count = 0;
            foreach (var makfile in ExampleDirs)
            {
                var    mainexamplDir = Path.GetDirectoryName(makfile);
                string nameExampl    = mainexamplDir.Substring(mainexamplDir.IndexOf("examples") + 9).Replace("Makefile", "").Replace('\\', '-');

                /*
                 * if (count == 1)
                 *  break;
                 * count++;
                 */

                var nameLog = Path.Combine(Path.GetDirectoryName(mainexamplDir), "Logs", $"{nameExampl}.log");

                if (!File.Exists(nameLog))
                {
                    Console.WriteLine($"No Log file {1}", Path.GetDirectoryName(nameLog));
                    continue;
                }
                Console.WriteLine($"Start parser { nameExampl}");
                VendorSample vs = ParseDependFiles(mainexamplDir, nameLog);
                if (vs == null)
                {
                    continue;
                }
                string[] frs = { "noFrameworks" };

                vs.CLanguageStandard        = "gnu99";
                vs.CPPLanguageStandard      = "gnu++11";
                vs.UserFriendlyName         = nameExampl;
                vs.Configuration.Frameworks = frs.ToArray();//null;

                allSamples.Add(vs);
                //Clear
                //File.Delete(Path.Combine(compiler.StartInfo.WorkingDirectory, "log.txt"));
                //Directory.Delete(Path.Combine(compiler.StartInfo.WorkingDirectory, "_build"), true);*/
            }
            return(allSamples);
        }
예제 #24
0
 protected override void AdjustVendorSampleProperties(VendorSample vs)
 {
     base.AdjustVendorSampleProperties(vs);
     vs.SourceFiles = vs.SourceFiles.Where(s => !IsNonGCCFile(vs, s)).ToArray();
 }
예제 #25
0
        //-----------------------------------------------
        static VendorSample ParseNativeBuildLog(string namelog)
        {
            VendorSample  vs         = new VendorSample();
            List <string> lstFileC   = new List <string>();
            List <string> lstFileInc = new List <string>();
            List <string> splitArgs  = new List <string>();
            List <string> lstDef     = new List <string>();
            string        aCurDir    = Path.GetDirectoryName(namelog);

            foreach (var ln in File.ReadAllLines(namelog))
            {
                if (!ln.Contains(toolchainDir))
                {
                    continue;
                }
                // Get Arguments
                int    munArg;
                IntPtr ptrToSplitArgs = CommandLineToArgvW(ln, out munArg);
                if (ptrToSplitArgs == IntPtr.Zero)
                {
                    throw new Exception("no arg");
                }

                for (int i = 0; i < munArg; i++)
                {
                    string arg = Marshal.PtrToStringUni(
                        Marshal.ReadIntPtr(ptrToSplitArgs, i * IntPtr.Size));
                    if (!splitArgs.Contains(arg))
                    {
                        splitArgs.Add(arg);
                    }
                }
            }

            // Processing arguments
            lstFileInc.AddRange(string.Join(" ", splitArgs.Where(ar => ar.StartsWith("-I"))).Split(new string[] { "-I" }, StringSplitOptions.RemoveEmptyEntries));
            lstDef.AddRange(string.Join(" ", splitArgs.Where(ar => ar.StartsWith("-D"))).Split(new string[] { "-D" }, StringSplitOptions.RemoveEmptyEntries));

            lstFileC.AddRange(splitArgs.Where(ar => ar.EndsWith(".c") && !ar.Contains(@"components/toolchain/")));


            //arguments from file
            var fileArg = splitArgs.SingleOrDefault(ar => ar.StartsWith("@"));

            if (fileArg != null)
            {
                var Libs = from t in File.ReadAllText(Path.Combine(aCurDir, fileArg.Substring(1))).Split(' ') where t.EndsWith(".a") orderby t select t;
                lstFileC.AddRange(Libs);
            }

            BuildAbsolutePath(aCurDir, ref lstFileInc);
            BuildAbsolutePath(aCurDir, ref lstFileC);

            var aProjectName = File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Single(ln => ln.StartsWith("PROJECT_NAME")).Split('=')[1].Trim(' ').ToUpper();

            var fl = File.ReadAllText(Path.Combine(aCurDir, "Makefile"));

            if (!fl.Contains("SOFTDEVICE_PRESENT"))
            {
                vs.Configuration.MCUConfiguration = new PropertyDictionary2
                {
                    Entries = new PropertyDictionary2.KeyValue[] {
                        new PropertyDictionary2.KeyValue {
                            Key = "com.sysprogs.bspoptions.nrf5x.softdevice", Value = "nosoftdev"
                        }
                    }.ToArray()
                };
            }
            else
            {
                var n = lstFileC.FindIndex(fi => fi.Contains("/softdevice_handler.c"));
                if (n >= 0)
                {
                    lstFileC.RemoveAt(n);
                }
            }
            vs.IncludeDirectories = lstFileInc.ToArray();
            vs.PreprocessorMacros = lstDef.ToArray();
            vs.SourceFiles        = lstFileC.ToArray();
            vs.DeviceID           = File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Single(ln => ln.StartsWith("TARGETS")).Split('=')[1].Trim(' ').ToUpper();
            vs.UserFriendlyName   = aProjectName;
            return(vs);
        }
예제 #26
0
        public static ParsedSDK ParseKSDKManifest(string sdkDirectory, IWarningSink sink)
        {
            string[] manifestFiles = Directory.GetFiles(sdkDirectory, "*manifest.xml");
            if (manifestFiles.Length < 1)
                throw new Exception($"No manifest files in {sdkDirectory}");

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

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

            XmlDocument doc = new XmlDocument();
            doc.Load(manifestFile);

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

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

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

                var mcuFamily = dev.ToMCUFamily();

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

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

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

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

                                if (relPaths.Count > 0)
                                {
                                    if (isDebug)
                                        svdFile = relPaths[0];
                                    else if (!linkerScriptHandled)
                                    {
                                        linkerScriptHandled = true;
                                        if (relPaths.Count == 1)
                                            mcuFamily.CompilationFlags.LinkerScript = "$$SYS:BSP_ROOT$$/" + relPaths[0];
                                        else
                                        {
                                            const string optionID = "com.sysprogs.imported.ksdk2x.linker_script";
                                            mcuFamily.CompilationFlags.LinkerScript = $"$$SYS:BSP_ROOT$$/$${optionID}$$";
                                            mcuFamily.ConfigurableProperties.PropertyGroups[0].Properties.Add(new PropertyEntry.Enumerated
                                            {
                                                UniqueID = optionID,
                                                Name = "Linker script",
                                                AllowFreeEntry = false,
                                                SuggestionList = relPaths.Select(p => new PropertyEntry.Enumerated.Suggestion { InternalValue = p, UserFriendlyName = Path.GetFileName(p) }).ToArray()
                                            });
                                        }
                                    }
                                }
                            }
                            continue;
                        case "CMSIS":
                            //KSDK 2.x defines a Include_xxx framework for each possible CMSIS core. Those frameworks are redundant (normal 'Include' framework references the same include path) and should be removed to avoid confusion.
                            if (componentName.StartsWith("Include_"))
                                continue;
                            if (componentName == "Include")
                                alwaysIncludedFrameworks.Add(fwPrefix + componentName);
                            break;
                        default:
                            break;
                    }

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

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

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

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

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

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

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

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

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

                    frameworkDict[fw.ID] = fw;

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

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

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

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

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

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

                    deviceDict[pkgName] = dev;

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

                        MCUDefinitionFile = deviceDefinitionFile
                    });
                }
            }

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

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

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

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

                    dependencyList.AddRange(alwaysIncludedFrameworks);

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

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

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

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

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

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

                    string[] matchingComponents = null;

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

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

                    samples.Add(sample);
                }
            }

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

                VendorSampleDirectory = new VendorSampleDirectory
                {
                    Samples = samples.ToArray()
                }
            };
        }
예제 #27
0
        static public List <VendorSample> GetInfoProjectFromMDK(string pDirPrj, string topLevelDir, string boardName, List <string> extraIncludeDirs)
        {
            List <VendorSample> aLstVSampleOut = new List <VendorSample>();
            int    aCntTarget = 0;
            string aFilePrj   = Directory.GetFiles(pDirPrj, "*.uvprojx")[0];

            string aNamePrj = Path.GetFileName(Path.GetDirectoryName(pDirPrj));

            List <string> sourceFiles   = new List <string>();
            List <string> includeDirs   = new List <string>();
            bool          flGetProperty = false;
            string        aTarget       = "";
            VendorSample  sample        = new VendorSample();

            foreach (var ln in File.ReadAllLines(aFilePrj))
            {
                if (ln.Contains("<Target>"))
                {
                    if (aCntTarget == 0)
                    {
                        sample = new VendorSample();
                    }
                    aCntTarget++;
                }
                if (ln.Contains("</Target>"))
                {
                    if (aCntTarget == 0)
                    {
                        throw new Exception("wrong tag Targets");
                    }
                    else
                    {
                        aCntTarget--;
                    }
                }

                if (ln.Contains("<Cads>"))
                {
                    flGetProperty = true;
                }
                else if (ln.Contains("</Cads>"))
                {
                    flGetProperty = false;
                }

                Match m = Regex.Match(ln, "[ \t]*<Device>(.*)</Device>[ \t]*");
                if (m.Success)
                {
                    sample.DeviceID = m.Groups[1].Value;
                    if (sample.DeviceID.EndsWith("x"))
                    {
                        sample.DeviceID = sample.DeviceID.Remove(sample.DeviceID.Length - 2, 2);
                    }
                }
                m = Regex.Match(ln, "[ \t]*<TargetName>(.*)</TargetName>[ \t]*");
                if (m.Success)
                {
                    aTarget = m.Groups[1].Value;
                }

                MatchCollection m1 = Regex.Matches(ln, @"[ ]*<FilePath>([\w\-:\\./]*)</FilePath>[ ]*");
                foreach (Match mc in m1)
                {
                    string filePath = mc.Groups[1].Value;
                    if (filePath.StartsWith(@"./") || filePath.StartsWith(@".\"))
                    {
                        filePath = pDirPrj + filePath.Substring(1);
                    }
                    if (filePath.EndsWith(".s", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (filePath.EndsWith(".lib", StringComparison.InvariantCultureIgnoreCase))
                    {
                        filePath = filePath.Replace("_Keil_wc16.lib", "_GCC_wc32.a");
                        filePath = filePath.Replace("_Keil.lib", "_GCC.a");
                        filePath = filePath.Replace("_Keil_ARGB.lib", "_GCC_ARGB.a");
                        filePath = filePath.Replace(@"Keil\touchgfx_core.lib", @"gcc\libtouchgfx-float-abi-hard.a");
                        if (!File.Exists(Path.Combine(pDirPrj, filePath)))
                        {
                            continue;
                        }
                    }
                    if (filePath.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase) && filePath.IndexOf("_IAR", StringComparison.InvariantCultureIgnoreCase) != -1)
                    {
                        filePath = filePath.Replace("_IAR_ARGB.a", "_GCC_ARGB.a");
                        if (!File.Exists(Path.Combine(pDirPrj, filePath)))
                        {
                            continue;
                        }
                    }

                    if (filePath.EndsWith(".a", StringComparison.InvariantCultureIgnoreCase))
                    {
                        filePath = filePath.Replace("_wc16", "_wc32");
                    }

                    if (!sourceFiles.Contains(filePath))
                    {
                        sourceFiles.Add(filePath);
                    }
                }

                if (flGetProperty)
                {
                    m = Regex.Match(ln, "[ \t]*<IncludePath>(.*)</IncludePath>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                    {
                        sample.IncludeDirectories = m.Groups[1].Value.Split(';').Select(FixIncludePath).ToArray();
                    }

                    m = Regex.Match(ln, "[ \t]*<Define>(.*)</Define>[ \t]*");
                    if (m.Success && m.Groups[1].Value != "")
                    {
                        sample.PreprocessorMacros = m.Groups[1].Value.Replace("&gt;", ">").Replace("&lt;", "<").Split(',').Select(t => t.Trim()).Where(t => t != "").ToArray();

                        for (int i = 0; i < sample.PreprocessorMacros.Length; i++)
                        {
                            if (sample.PreprocessorMacros[i].Contains("\"<"))
                            {
                                //This is likely the MBEDTLS_CONFIG_FILE="<mbedtls_config.h>" macro. We need to remove the quotes, as VisualGDB will automatically escape it anyway.
                                sample.PreprocessorMacros[i] = sample.PreprocessorMacros[i].Replace("\"<", "<").Replace(">\"", ">");
                            }
                        }
                    }
                }


                if (ln.Contains("</Target>") && aCntTarget == 0)
                {
                    sample.Path             = Path.GetDirectoryName(pDirPrj);
                    sample.UserFriendlyName = aNamePrj;
                    AppendSamplePrefixFromPath(ref sample.UserFriendlyName, pDirPrj);

                    sample.BoardName   = aTarget;
                    sample.SourceFiles = ToAbsolutePath(pDirPrj, topLevelDir, sourceFiles).ToArray();

                    foreach (var fl in sample.IncludeDirectories)
                    {
                        includeDirs.Add(fl);
                    }
                    includeDirs.AddRange(extraIncludeDirs);
                    sample.IncludeDirectories = ToAbsolutePath(pDirPrj, topLevelDir, includeDirs).ToArray();

                    string readmeFile = Path.Combine(pDirPrj, @"..\readme.txt");
                    if (File.Exists(readmeFile))
                    {
                        string readmeContents = File.ReadAllText(readmeFile);
                        Regex  rgTitle        = new Regex(@"@page[ \t]+[^ \t]+[ \t]+([^ \t][^@]*)\r\n *\r\n", RegexOptions.Singleline);
                        m = rgTitle.Match(readmeContents);
                        if (m.Success)
                        {
                            sample.Description = m.Groups[1].Value;
                        }
                    }

                    var fsdataCustom = sample.SourceFiles.FirstOrDefault(f => Path.GetFileName(f).ToLower() == "fsdata_custom.c");
                    if (fsdataCustom != null)
                    {
                        var lines = File.ReadAllLines(Path.Combine(Path.GetDirectoryName(fsdataCustom), "fs.c"));
                        if (lines.Contains("#include \"fsdata.c\""))
                        {
                            sample.SourceFiles = sample.SourceFiles.Except(new[] { fsdataCustom }).ToArray();
                        }
                        else
                        {
                            //Should not happen
                            Debug.Assert(false);
                        }
                    }

                    var syscallsFile = Path.Combine(sample.Path, "SW4STM32", "syscalls.c");
                    if (File.Exists(syscallsFile))
                    {
                        //This file is included in some samples to handle I/O redirection. Since it is GCC-specific, it's not referenced by the Keil project file we are parsing.
                        sample.SourceFiles = sample.SourceFiles.Concat(new[] { syscallsFile }).ToArray();
                    }

                    aLstVSampleOut.Add(sample);
                }
            }


            if (aLstVSampleOut.Count == 1)
            {
                aLstVSampleOut[0].BoardName = boardName;    //In some example projects, the target name is defined incorrectly
            }
            else
            {
                foreach (var s in aLstVSampleOut)
                {
                    s.BoardName = boardName + "-" + s.BoardName;
                }
            }

            return(aLstVSampleOut);
        }
예제 #28
0
 protected override void AdjustVendorSampleProperties(VendorSample vs)
 {
     base.AdjustVendorSampleProperties(vs);
     vs.BSPReferencesAreCopyable = true;
 }
예제 #29
0
        public void Run(string[] args)
        {
            string  SDKdir             = null;
            string  specificSampleName = null;
            RunMode mode = RunMode.Invalid;

            foreach (var arg in args)
            {
                string singlePrefix = "/single:";
                if (arg.StartsWith(singlePrefix, StringComparison.InvariantCultureIgnoreCase))
                {
                    mode = RunMode.SingleSample;
                    specificSampleName = arg.Substring(singlePrefix.Length);
                }
                else if (arg.StartsWith("/"))
                {
                    mode = Enum.GetValues(typeof(RunMode)).OfType <RunMode>().First(v => v.ToString().ToLower() == arg.Substring(1).ToLower());
                }
                else
                {
                    SDKdir = arg;
                }
            }

            if (SDKdir == null || mode == RunMode.Invalid)
            {
                Console.WriteLine($"Usage: {Path.GetFileName(Assembly.GetEntryAssembly().Location)} <mode> <SW package directory>");
                Console.WriteLine($"Modes:");
                Console.WriteLine($"       /incremental   - Only retest/rebuild previously failed samples.");
                Console.WriteLine($"                       This doesn't update the BSP archive.");
                Console.WriteLine($"       /release       - Reuse cached definitions, retest all samples. Update BSP.");
                Console.WriteLine($"       /cleanRelease  - Reparse/retest all samples. Update BSP.");
                Console.WriteLine($"       /updateErrors  - Re-categorize errors based on KnownProblems.xml");
                Console.WriteLine($"       /single:<name> - Run all phases of just one sample.");
                Console.WriteLine($"Press any key to continue...");
                Console.ReadKey();
                Environment.ExitCode = 1;
                return;
            }

            if (mode == RunMode.Incremental)
            {
                Console.WriteLine("*********************** WARNING ************************");
                Console.WriteLine("* Vendor sample parser is running in incremental mode. *");
                Console.WriteLine("* Only retested samples will be saved to BSP!          *");
                Console.WriteLine("* Re-run in /release mode to build a releasable BSP.   *");
                Console.WriteLine("********************************************************");
            }

            if (mode == RunMode.UpdateErrors)
            {
                foreach (var rec in _Report.Records)
                {
                }

                XmlTools.SaveObject(_Report, ReportFile);

                return;
            }

            string archiveName     = string.Format("{0}-{1}.vgdbxbsp", BSP.BSP.PackageID.Split('.').Last(), BSP.BSP.PackageVersion);
            string archiveFilePath = Path.Combine(BSPDirectory, archiveName);

            if (File.Exists(archiveFilePath))
            {
                File.Delete(archiveFilePath);
            }

            string sampleListFile = Path.Combine(CacheDirectory, "Samples.xml");

            var sampleDir = BuildOrLoadSampleDirectoryAndUpdateReportForFailedSamples(sampleListFile, SDKdir, mode, specificSampleName);
            Dictionary <VendorSampleID, string> encounteredIDs = new Dictionary <VendorSampleID, string>();

            foreach (var vs in sampleDir.Samples)
            {
                var id = new VendorSampleID(vs);
                if (encounteredIDs.TryGetValue(id, out var dir))
                {
                    throw new Exception("Duplicate sample for " + id);
                }
                encounteredIDs[new VendorSampleID(vs)] = vs.Path;

                var rec = _Report.ProvideEntryForSample(new VendorSampleID(vs));
                if (rec.LastSucceededPass < VendorSamplePass.InitialParse)
                {
                    rec.LastSucceededPass = VendorSamplePass.InitialParse;
                }
            }

            //We cache unadjusted sample definitions to allow tweaking the adjusting code without the need to reparse everything.
            Console.WriteLine("Adjusting sample properties...");
            foreach (var vs in sampleDir.Samples)
            {
                AdjustVendorSampleProperties(vs);
                if (vs.Path == null)
                {
                    throw new Exception("Missing sample path for " + vs.UserFriendlyName);
                }
            }

            VendorSample[] pass1Queue, insertionQueue;

            switch (mode)
            {
            case RunMode.Incremental:
                pass1Queue = insertionQueue = sampleDir.Samples.Where(s => _Report.ShouldBuildIncrementally(new VendorSampleID(s), VendorSamplePass.InPlaceBuild)).ToArray();
                break;

            case RunMode.Release:
                insertionQueue = sampleDir.Samples;
                if (sampleDir.Samples.FirstOrDefault(s => s.AllDependencies != null) == null)
                {
                    pass1Queue = sampleDir.Samples;
                }
                else
                {
                    pass1Queue = new VendorSample[0];
                }
                break;

            case RunMode.CleanRelease:
                pass1Queue = insertionQueue = sampleDir.Samples;
                break;

            case RunMode.SingleSample:
                pass1Queue = insertionQueue = sampleDir.Samples.Where(s => new VendorSampleID(s).ToString() == specificSampleName).ToArray();
                if (pass1Queue.Length == 0)
                {
                    throw new Exception("No samples match " + specificSampleName);
                }
                break;

            default:
                throw new Exception("Invalid run mode");
            }

            if (pass1Queue.Length > 0)
            {
                //Test the raw VendorSamples in-place and store AllDependencies
                TestVendorSamplesAndUpdateReportAndDependencies(pass1Queue, null, VendorSamplePass.InPlaceBuild, vs => _Report.HasSampleFailed(new VendorSampleID(vs)), validationFlags: BSPValidationFlags.ResolveNameCollisions);

                foreach (var vs in pass1Queue)
                {
                    if (vs.Path == null)
                    {
                        throw new Exception("Missing sample path for " + vs.UserFriendlyName);
                    }
                }

                sampleDir.ToolchainDirectory = ToolchainDirectory;
                sampleDir.BSPDirectory       = Path.GetFullPath(BSPDirectory);
                XmlTools.SaveObject(sampleDir, sampleListFile);
            }

            //Insert the samples into the generated BSP
            var relocator   = CreateRelocator(sampleDir);
            var copiedFiles = relocator.InsertVendorSamplesIntoBSP(sampleDir, insertionQueue, BSPDirectory);

            var bsp = XmlTools.LoadObject <BoardSupportPackage>(Path.Combine(BSPDirectory, LoadedBSP.PackageFileName));

            bsp.VendorSampleDirectoryPath = VendorSampleDirectoryName;
            bsp.VendorSampleCatalogName   = VendorSampleCatalogName;
            XmlTools.SaveObject(bsp, Path.Combine(BSPDirectory, LoadedBSP.PackageFileName));

            if (mode != RunMode.Incremental && mode != RunMode.SingleSample)
            {
                Console.WriteLine("Creating new BSP archive...");
                string statFile = Path.ChangeExtension(archiveName, ".xml");
                TarPacker.PackDirectoryToTGZ(BSPDirectory, archiveFilePath, fn => Path.GetExtension(fn).ToLower() != ".vgdbxbsp" && Path.GetFileName(fn) != statFile);
            }

            var vendorSampleListInBSP = Path.Combine(BSPDirectory, VendorSampleDirectoryName, "VendorSamples.xml");
            // Finally verify that everything builds
            var expandedSamples = XmlTools.LoadObject <VendorSampleDirectory>(vendorSampleListInBSP);

            expandedSamples.Path = Path.GetFullPath(Path.Combine(BSPDirectory, VendorSampleDirectoryName));

            var finalStats = TestVendorSamplesAndUpdateReportAndDependencies(expandedSamples.Samples, expandedSamples.Path, VendorSamplePass.RelocatedBuild);

            XmlTools.SaveObject(_Report, ReportFile);

            if (mode == RunMode.Incremental || mode == RunMode.SingleSample)
            {
                Console.WriteLine($"Deleting incomplete {vendorSampleListInBSP}...\n***Re-run in /release mode to produce a valid BSP.");
                File.Delete(vendorSampleListInBSP);   //Incremental mode only places the samples that are currently built.
            }

            if (finalStats.Failed == 0)
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"All {finalStats.Total} tests passed during final pass.");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"{finalStats.Failed} out of {finalStats.Total} tests failed during final pass.");
            }

            Console.ResetColor();
            Console.WriteLine("=============================================");
            Console.WriteLine($"Overall statistics for v{BSP.BSP.PackageVersion}:");
            List <KeyValuePair <string, string> > fields = new List <KeyValuePair <string, string> >();

            fields.Add(new KeyValuePair <string, string>("Total samples discovered:", sampleDir.Samples.Length.ToString()));

            int unparsableSamples   = _Report.Records.Count(r => r.LastSucceededPass == VendorSamplePass.None);
            int failedAtFirstBuild  = _Report.Records.Count(r => r.LastSucceededPass == VendorSamplePass.InitialParse && r.BuildFailedExplicitly);
            int failedAtSecondBuild = _Report.Records.Count(r => r.LastSucceededPass == VendorSamplePass.InPlaceBuild && r.BuildFailedExplicitly);

            fields.Add(new KeyValuePair <string, string>("Failed during initial parse attempt:", $"{unparsableSamples}/{sampleDir.Samples.Length} ({unparsableSamples * 100.0 / sampleDir.Samples.Length:f1}%)"));
            fields.Add(new KeyValuePair <string, string>("Failed during in-place build:", $"{failedAtFirstBuild}/{sampleDir.Samples.Length} ({failedAtFirstBuild * 100.0 / sampleDir.Samples.Length:f1}%)"));
            fields.Add(new KeyValuePair <string, string>("Failed during relocated build:", $"{failedAtSecondBuild}/{sampleDir.Samples.Length} ({failedAtSecondBuild * 100.0 / sampleDir.Samples.Length:f1}%)"));
            if (mode != RunMode.Incremental)
            {
                fields.Add(new KeyValuePair <string, string>("Inserted into BSP:", expandedSamples.Samples.Length.ToString()));
            }
            OutputKeyValueList(fields);

            if (finalStats.Failed > 0 && mode != RunMode.Incremental)
            {
                throw new Exception("Some of the vendor samples have failed the final test. Fix this before releasing the BSP.");
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
예제 #30
0
파일: Program.cs 프로젝트: whinis/BSPTools
            VendorSample ParseNativeBuildLog(string namelog, string SDKdir, string sampleID)
            {
                VendorSample vs = new VendorSample {
                    InternalUniqueID = sampleID
                };
                List <string> lstFileC           = new List <string>();
                List <string> lstFileInc         = new List <string>();
                List <string> splitArgs          = new List <string>();
                List <string> preprocessorMacros = new List <string>();
                string        aCurDir            = Path.GetDirectoryName(namelog);

                foreach (var ln in File.ReadAllLines(namelog))
                {
                    if (ln.Replace('\\', '/').IndexOf(ToolchainDirectory.Replace('\\', '/'), StringComparison.InvariantCultureIgnoreCase) == -1)
                    {
                        continue;
                    }
                    // Get Arguments
                    int    munArg;
                    IntPtr ptrToSplitArgs = CommandLineToArgvW(ln, out munArg);
                    if (ptrToSplitArgs == IntPtr.Zero)
                    {
                        throw new Exception("no arg");
                    }

                    for (int i = 0; i < munArg; i++)
                    {
                        string arg = Marshal.PtrToStringUni(
                            Marshal.ReadIntPtr(ptrToSplitArgs, i * IntPtr.Size));
                        if (!splitArgs.Contains(arg))
                        {
                            splitArgs.Add(arg);
                        }
                    }
                }

                // Processing arguments
                lstFileInc.AddRange(splitArgs.Where(ar => ar.StartsWith("-I")).Select(a => a.Substring(2).Trim()));
                preprocessorMacros.AddRange(splitArgs.Where(ar => ar.StartsWith("-D")).Select(a => a.Substring(2).Trim()));

                lstFileC.AddRange(splitArgs.Where(ar => (ar.EndsWith(".c") || ar.EndsWith(".s", StringComparison.InvariantCultureIgnoreCase)) && !ar.Contains(@"components/toolchain/") &&
                                                  !ar.Contains(@"gcc_startup")));
                vs.CLanguageStandard = "c99";

                //arguments from file
                var fileArg = splitArgs.SingleOrDefault(ar => ar.StartsWith("@"));

                if (fileArg != null)
                {
                    var Libs = from t in File.ReadAllText(Path.Combine(aCurDir, fileArg.Substring(1))).Split(' ') where t.EndsWith(".a") orderby t select t;
                    lstFileC.AddRange(Libs);
                }

                BuildAbsolutePath(aCurDir, ref lstFileInc);
                BuildAbsolutePath(aCurDir, ref lstFileC);

                var aProjectName = File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Single(ln => ln.StartsWith("PROJECT_NAME")).Split('=')[1].Trim(' ').ToUpper();

                vs.DeviceID = File.ReadAllLines(Path.Combine(aCurDir, "Makefile")).Single(ln => ln.StartsWith("TARGETS")).Split('=')[1].Trim(' ').ToUpper();

                var softdeviceProperty = BSP.BSP.SupportedMCUs.First(m => vs.DeviceID.StartsWith(m.ID, StringComparison.InvariantCultureIgnoreCase)).ConfigurableProperties.PropertyGroups.SelectMany(g => g.Properties).FirstOrDefault(p => p.UniqueID == "com.sysprogs.bspoptions.nrf5x.softdevice") as PropertyEntry.Enumerated;

                if (softdeviceProperty == null)
                {
                    throw new Exception("Failed to locate softdevice for property" + vs.DeviceID);
                }

                string softdevice = softdeviceProperty.SuggestionList.FirstOrDefault(e => preprocessorMacros.Contains(e.InternalValue))?.InternalValue;

                if (!preprocessorMacros.Contains("SOFTDEVICE_PRESENT"))
                {
                    //This is a special 'serialization mode' sample that defines -DSxxx, but not -DSOFTDEVICE_PRESENT, that is not supported by our BSP yet.
                    softdevice = null;
                }

                vs.Configuration.MCUConfiguration = new PropertyDictionary2
                {
                    Entries = new PropertyDictionary2.KeyValue[]
                    {
                        new PropertyDictionary2.KeyValue {
                            Key   = "com.sysprogs.bspoptions.nrf5x.softdevice",
                            Value = softdevice ?? "nosoftdev"
                        }
                    }.ToArray()
                };

                if (softdevice != null)
                {
                    var n = lstFileC.FindIndex(fi => fi.Contains("/softdevice_handler.c"));
                    if (n >= 0)
                    {
                        lstFileC.RemoveAt(n);
                    }
                }

                if (Directory.GetFiles(aCurDir, "*.ld").Count() > 0)
                {
                    vs.LinkerScript = Directory.GetFiles(aCurDir, "*.ld")[0];
                }

                vs.IncludeDirectories = lstFileInc.ToArray();
                vs.PreprocessorMacros = preprocessorMacros.ToArray();
                vs.SourceFiles        = lstFileC.ToArray();
                vs.UserFriendlyName   = aProjectName;
                vs.NoImplicitCopy     = true;
                return(vs);
            }