From 103e1033c9ddcee096d56957d4ae18f3043060e9 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Sat, 13 Jan 2024 15:16:11 +0100 Subject: [PATCH 01/18] fixed indeterministic shuffle of contexts in MX_Device.h --- internal/stm32CubeMX/mxDevice.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index b30b321..f3c573f 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -13,6 +13,7 @@ import ( "path" "path/filepath" "regexp" + "strconv" "strings" "time" @@ -35,7 +36,10 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { return err } - contexts := getContexts(contextMap) + contexts, err := getContexts(contextMap) + if err != nil { + return err + } deviceFamily, err := getDeviceFamily(contextMap) if err != nil { @@ -55,7 +59,6 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { return errors.New("main location missing") } - projectIndex := 0 if len(contexts) == 0 { msp := path.Join(workDirAbs, mspFolder, mspName) fMsp, err := os.Open(msp) @@ -64,7 +67,7 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { } defer fMsp.Close() - subsystem := ¶ms.Subsystem[projectIndex] + subsystem := ¶ms.Subsystem[0] fName := "MX_Device.h" fPath := path.Join(path.Dir(workDir), "drv_cfg", subsystem.SubsystemIdx.Project) if _, err := os.Stat(fPath); err != nil { @@ -109,7 +112,7 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { CONTEXT["CortexM33NS"] = "NonSecure" CONTEXT["CortexM4"] = "CM4" CONTEXT["CortexM7"] = "CM7" - for _, context := range contexts { + for projectIndex, context := range contexts { contextFolder := CONTEXT[context] if contextFolder == "" { print("Cannot find ", mspName) @@ -237,20 +240,24 @@ func createContextMap(iocFile string) (map[string]map[string]string, error) { return pinConfigMap, nil } */ -func getContexts(contextMap map[string]map[string]string) []string { - contexts := []string{} +func getContexts(contextMap map[string]map[string]string) (map[int]string, error) { + contexts := make(map[int]string) head := contextMap["Mcu"] if len(head) > 0 { for key, content := range head { if strings.HasPrefix(key, "Context") { l := len(key) if l > 0 && key[l-1] >= '0' && key[l-1] <= '9' { - contexts = append(contexts, content) + i, err := strconv.Atoi(string(key[l-1])) + if err != nil { + return nil, err + } + contexts[i] = content } } } } - return contexts + return contexts, nil } func getDeviceFamily(contextMap map[string]map[string]string) (string, error) { From a9ad6986ab81d1d4f1ff58779c9e5ea52b21840d Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Sun, 14 Jan 2024 13:02:29 +0100 Subject: [PATCH 02/18] Added MX_Device.h path to add-path: --- internal/readFile/readFile.go | 4 +- internal/stm32CubeMX/mxDevice.go | 61 +++++++++++++++-------------- internal/stm32CubeMX/stm32CubeMX.go | 16 +++++--- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/internal/readFile/readFile.go b/internal/readFile/readFile.go index c4b3bcc..b7d1bad 100644 --- a/internal/readFile/readFile.go +++ b/internal/readFile/readFile.go @@ -84,12 +84,12 @@ func Process(inFile, inFile2, outPath string) error { return err } - err = stm32cubemx.ReadContexts(workDir+"/STM32CubeMX/STM32CubeMX.ioc", parms) + fPaths, err := stm32cubemx.ReadContexts(workDir+"/STM32CubeMX/STM32CubeMX.ioc", parms) if err != nil { return err } - err = stm32cubemx.WriteCgenYml(outPath, mxprojectAll, params) + err = stm32cubemx.WriteCgenYml(outPath, mxprojectAll, fPaths, params) if err != nil { return err } diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index f3c573f..dac2cbd 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -30,81 +30,84 @@ type PinDefinition struct { alternate string } -func ReadContexts(iocFile string, params cbuild.ParamsType) error { +func ReadContexts(iocFile string, params cbuild.ParamsType) ([]string, error) { + var fPaths []string contextMap, err := createContextMap(iocFile) if err != nil { - return err + return nil, err } contexts, err := getContexts(contextMap) if err != nil { - return err + return nil, err } deviceFamily, err := getDeviceFamily(contextMap) if err != nil { - return err + return nil, err } workDir := path.Dir(iocFile) workDirAbs, err := filepath.Abs(workDir) if err != nil { - return err + return nil, err } mspName := deviceFamily + "xx_hal_msp.c" // pinConfigMap, err := createPinConfigMap(mspName) mspFolder := contextMap["ProjectManager"]["MainLocation"] if mspFolder == "" { - return errors.New("main location missing") + return nil, errors.New("main location missing") } if len(contexts) == 0 { msp := path.Join(workDirAbs, mspFolder, mspName) fMsp, err := os.Open(msp) if err != nil { - return err + return nil, err } defer fMsp.Close() subsystem := ¶ms.Subsystem[0] + cfgPath := path.Join("drv_cfg", subsystem.SubsystemIdx.Project) fName := "MX_Device.h" - fPath := path.Join(path.Dir(workDir), "drv_cfg", subsystem.SubsystemIdx.Project) + fPath := path.Join(path.Dir(workDir), cfgPath) if _, err := os.Stat(fPath); err != nil { err = os.MkdirAll(fPath, 0750) if err != nil { - return err + return nil, err } } + fPaths = append(fPaths, cfgPath) fPath = path.Join(fPath, fName) fMxDevice, err := os.Create(fPath) if err != nil { - return err + return nil, err } defer fMxDevice.Close() err = mxDeviceWriteHeader(fMxDevice, fName) if err != nil { - return err + return nil, err } peripherals, err := getPeripherals1(contextMap) if err != nil { - return err + return nil, err } for _, peripheral := range peripherals { vmode := getVirtualMode(contextMap, peripheral) pins, err := getPins(contextMap, fMsp, peripheral) if err != nil { - return err + return nil, err } err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) if err != nil { - return err + return nil, err } } _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") if err != nil { - return err + return nil, err } } else { CONTEXT := make(map[string]string) @@ -116,65 +119,65 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { contextFolder := CONTEXT[context] if contextFolder == "" { print("Cannot find ", mspName) - return errors.New("Cannot find " + mspName) + return nil, errors.New("Cannot find " + mspName) } msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName) fMsp, err := os.Open(msp) if err != nil { - return err + return nil, err } subsystem := ¶ms.Subsystem[projectIndex] + cfgPath := path.Join("drv_cfg", subsystem.SubsystemIdx.Project) fName := "MX_Device.h" - fPath := path.Join(path.Dir(workDir), "drv_cfg", subsystem.SubsystemIdx.Project) + fPath := path.Join(path.Dir(workDir), cfgPath) if _, err := os.Stat(fPath); err != nil { err = os.MkdirAll(fPath, 0750) if err != nil { - return err + return nil, err } } + fPaths = append(fPaths, cfgPath) fPath = path.Join(fPath, fName) fMxDevice, err := os.Create(fPath) if err != nil { - return err + return nil, err } - projectIndex += 1 - err = mxDeviceWriteHeader(fMxDevice, fName) if err != nil { _ = fMxDevice.Close() - return err + return nil, err } peripherals, err := getPeripherals(contextMap, context) if err != nil { _ = fMxDevice.Close() - return err + return nil, err } for _, peripheral := range peripherals { vmode := getVirtualMode(contextMap, peripheral) pins, err := getPins(contextMap, fMsp, peripheral) if err != nil { _ = fMxDevice.Close() - return err + return nil, err } err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) if err != nil { _ = fMxDevice.Close() - return err + return nil, err } } _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") if err != nil { - return err + return nil, err } err = fMxDevice.Close() if err != nil { - return err + return nil, err } } } - return nil + return fPaths, nil } func createContextMap(iocFile string) (map[string]map[string]string, error) { diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index 085adae..16221a3 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -48,6 +48,8 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx return err } + var fPaths []string + if runCubeMx { cubeIocPath := workDir lastPath := filepath.Base(cubeIocPath) @@ -74,7 +76,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx } } - err = ReadContexts(cubeIocPath, parms) + fPaths, err = ReadContexts(cubeIocPath, parms) if err != nil { return err } @@ -87,7 +89,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx return err } - err = WriteCgenYml(workDir, mxproject, parms) + err = WriteCgenYml(workDir, mxproject, fPaths, parms) if err != nil { return err } @@ -204,7 +206,7 @@ func FindMxProject(subsystem *cbuild.SubsystemType, mxprojectAll MxprojectAllTyp return MxprojectType{}, nil } -func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, inParms cbuild.ParamsType) error { +func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, fPaths []string, inParms cbuild.ParamsType) error { for id := range inParms.Subsystem { subsystem := &inParms.Subsystem[id] @@ -212,7 +214,7 @@ func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, inParms cbuild. if err != nil { continue } - err = WriteCgenYmlSub(outPath, mxproject, subsystem) + err = WriteCgenYmlSub(outPath, mxproject, fPaths, subsystem) if err != nil { return err } @@ -221,7 +223,7 @@ func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, inParms cbuild. return nil } -func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild.SubsystemType) error { +func WriteCgenYmlSub(outPath string, mxproject MxprojectType, fPaths []string, subsystem *cbuild.SubsystemType) error { outName := subsystem.SubsystemIdx.Project + ".cgen.yml" outFile := path.Join(outPath, outName) var cgen cbuild.CgenType @@ -242,6 +244,10 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. headerPath, _ = utils.ConvertFilename(outPath, headerPath, relativePathAdd) cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, headerPath) } + for _, fPath := range fPaths { + fPath, _ = utils.ConvertFilename(outPath, fPath, "") + cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, fPath) + } var groupSrc cbuild.CgenGroupsType var groupHalDriver cbuild.CgenGroupsType From a1d95e5a6264ca58c3931624b57ab9596226198b Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Mon, 15 Jan 2024 11:18:03 +0100 Subject: [PATCH 03/18] fixed error in mxDevice_test.go --- internal/stm32CubeMX/mxDevice_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index 0762181..ef3fb2a 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -71,7 +71,11 @@ func Test_getContexts(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() - got := getContexts(tt.args.contextMap) + got, err := getContexts(tt.args.contextMap) + if (err != nil) != tt.wantErr { + t.Errorf("getContexts() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + return + } if !reflect.DeepEqual(got, tt.want1) && !reflect.DeepEqual(got, tt.want2) { t.Errorf("getContexts() %s = %v, want %v", tt.name, got, tt.want1) } From 872024d0dbcb088c9552d15a7092718e3973fc26 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Mon, 15 Jan 2024 11:31:08 +0100 Subject: [PATCH 04/18] Fixed old test --- internal/stm32CubeMX/mxDevice_test.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index ef3fb2a..5c08502 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -46,7 +46,7 @@ func Test_createContextMap(t *testing.T) { } func Test_getContexts(t *testing.T) { - t.Parallel() +// t.Parallel() var mcuContext1 = make(map[string]map[string]string) mcuContext1["Mcu"] = map[string]string{"ContextTest": "myContext"} @@ -54,23 +54,33 @@ func Test_getContexts(t *testing.T) { var mcuContext2 = make(map[string]map[string]string) mcuContext2["Mcu"] = map[string]string{"Context1": "myContext1", "Context2": "myContext2"} + var oneEmpty = make(map[int]string) + + var two1 = make(map[int]string) + two1[1] = "myContext1" + two1[2] = "myContext2" + + var two2 = make(map[int]string) + two2[2] = "myContext1" + two2[1] = "myContext2" + type args struct { contextMap map[string]map[string]string } tests := []struct { name string args args - want1 []string - want2 []string + want1 map[int]string + want2 map[int]string wantErr bool }{ - {"1 Context", args{mcuContext1}, []string{}, []string{}, false}, - {"2 Contexts", args{mcuContext2}, []string{"myContext1", "myContext2"}, []string{"myContext2", "myContext1"}, false}, + {"1 Context", args{mcuContext1}, oneEmpty, oneEmpty, false}, + {"2 Contexts", args{mcuContext2}, two1, two2, false}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - t.Parallel() +// t.Parallel() got, err := getContexts(tt.args.contextMap) if (err != nil) != tt.wantErr { t.Errorf("getContexts() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) From e7304736946b46b2b3c31a6dc4fd882e2ad758db Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Mon, 15 Jan 2024 11:36:17 +0100 Subject: [PATCH 05/18] Forgot to remove comment chars of t.Parallel --- internal/stm32CubeMX/mxDevice_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index 5c08502..a6a6017 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -46,7 +46,7 @@ func Test_createContextMap(t *testing.T) { } func Test_getContexts(t *testing.T) { -// t.Parallel() + t.Parallel() var mcuContext1 = make(map[string]map[string]string) mcuContext1["Mcu"] = map[string]string{"ContextTest": "myContext"} @@ -80,7 +80,7 @@ func Test_getContexts(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { -// t.Parallel() + t.Parallel() got, err := getContexts(tt.args.contextMap) if (err != nil) != tt.wantErr { t.Errorf("getContexts() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) From 305aed5c21db8770e4e9749e30a57b087261b6b0 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Wed, 24 Jan 2024 17:38:32 +0100 Subject: [PATCH 06/18] switched secure and non secure mode added tests added download info from global.generator.yml --- .gitignore | 3 + internal/generator/generator.go | 55 +++++++ internal/generator/generator_test.go | 7 + internal/stm32CubeMX/iniReader.go | 4 +- internal/stm32CubeMX/mxDevice.go | 224 +++++++++++--------------- internal/stm32CubeMX/mxDevice_test.go | 125 +++++++++----- internal/stm32CubeMX/stm32CubeMX.go | 46 +++++- testdata/stm32cubemx/test_msp.c | 33 ++++ 8 files changed, 322 insertions(+), 175 deletions(-) create mode 100644 internal/generator/generator.go create mode 100644 internal/generator/generator_test.go create mode 100644 testdata/stm32cubemx/test_msp.c diff --git a/.gitignore b/.gitignore index 07431cb..2b5ba44 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ # Folders .vscode /build*/ +/etc/ # others *~ +*.swp +*.swo diff --git a/internal/generator/generator.go b/internal/generator/generator.go new file mode 100644 index 0000000..783d89a --- /dev/null +++ b/internal/generator/generator.go @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package generator + +import ( + "errors" + + "github.com/open-cmsis-pack/generator-bridge/internal/common" + "github.com/open-cmsis-pack/generator-bridge/internal/utils" +) + +type ParamsType struct { + Id string + DownloadUrl string +} + +type GeneratorType struct { + Generator []struct { + Id string `yaml:"id"` + Description string `yaml:"description"` + DownloadUrl string `yaml:"download-url"` + Run string `yaml:"run"` + Path string `yaml:"path"` + } `yaml:"generator"` +} + +func Read(name string, params *ParamsType) error { + var gen GeneratorType + + if !utils.FileExists(name) { + text := "File not found: " + text += name + return errors.New(text) + } + + err := common.ReadYml(name, &gen) + if err != nil { + return err + } + for _, genx := range gen.Generator { + if genx.Id == "CubeMX" { + params.Id = genx.Id + params.DownloadUrl = genx.DownloadUrl + break + } + } + if params.Id != "CubeMX" { + return errors.New("generator CubeMX missing in global.generator.yml") + } + return nil +} diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go new file mode 100644 index 0000000..87ec970 --- /dev/null +++ b/internal/generator/generator_test.go @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2024 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package generator diff --git a/internal/stm32CubeMX/iniReader.go b/internal/stm32CubeMX/iniReader.go index 38ce6f3..5d54d50 100644 --- a/internal/stm32CubeMX/iniReader.go +++ b/internal/stm32CubeMX/iniReader.go @@ -244,8 +244,8 @@ func GetIni(path string) (*ini.File, error) { func GetSections(inidata *ini.File, iniSections *IniSectionsType) error { sectionsData := inidata.SectionStrings() - for sectionID := range sectionsData { - section := sectionsData[sectionID] + for _, section := range sectionsData { +// section := sectionsData[sectionID] var iniName string var sectionName string sectionString := strings.Split(section, ":") diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index dac2cbd..692d6af 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -60,121 +60,59 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) ([]string, error) { return nil, errors.New("main location missing") } + var cfgPath string if len(contexts) == 0 { msp := path.Join(workDirAbs, mspFolder, mspName) - fMsp, err := os.Open(msp) + cfgPath = path.Join("drv_cfg", params.Subsystem[0].SubsystemIdx.Project) + err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, "", params) if err != nil { return nil, err } - defer fMsp.Close() - - subsystem := ¶ms.Subsystem[0] - cfgPath := path.Join("drv_cfg", subsystem.SubsystemIdx.Project) - fName := "MX_Device.h" - fPath := path.Join(path.Dir(workDir), cfgPath) - if _, err := os.Stat(fPath); err != nil { - err = os.MkdirAll(fPath, 0750) - if err != nil { - return nil, err - } - } fPaths = append(fPaths, cfgPath) - fPath = path.Join(fPath, fName) - fMxDevice, err := os.Create(fPath) - if err != nil { - return nil, err - } - defer fMxDevice.Close() - - err = mxDeviceWriteHeader(fMxDevice, fName) - if err != nil { - return nil, err - } - peripherals, err := getPeripherals1(contextMap) - if err != nil { - return nil, err - } - for _, peripheral := range peripherals { - vmode := getVirtualMode(contextMap, peripheral) - pins, err := getPins(contextMap, fMsp, peripheral) - if err != nil { - return nil, err - } - err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) - if err != nil { - return nil, err - } - } - _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") - if err != nil { - return nil, err - } } else { - CONTEXT := make(map[string]string) - CONTEXT["CortexM33S"] = "Secure" - CONTEXT["CortexM33NS"] = "NonSecure" - CONTEXT["CortexM4"] = "CM4" - CONTEXT["CortexM7"] = "CM7" - for projectIndex, context := range contexts { - contextFolder := CONTEXT[context] - if contextFolder == "" { - print("Cannot find ", mspName) - return nil, errors.New("Cannot find " + mspName) - } - msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName) - fMsp, err := os.Open(msp) - if err != nil { - return nil, err + for _, context := range contexts { + var coreName string + var contextFolder string + var projectPart string + re := regexp.MustCompile("[0-9]+") + coreNameNumbers := re.FindAllString(context, -1) + if len(coreNameNumbers) == 1 { + coreName = "Cortex-M" + coreNameNumbers[0] + contextFolder = "CM" + coreNameNumbers[0] + projectPart = contextFolder } - subsystem := ¶ms.Subsystem[projectIndex] - cfgPath := path.Join("drv_cfg", subsystem.SubsystemIdx.Project) - fName := "MX_Device.h" - fPath := path.Join(path.Dir(workDir), cfgPath) - if _, err := os.Stat(fPath); err != nil { - err = os.MkdirAll(fPath, 0750) - if err != nil { - return nil, err + var trustzone string + contextLen := len(context) + if contextLen > 0 { + if strings.LastIndex(context, "S") == contextLen-1 { + if strings.LastIndex(context, "NS") == contextLen-2 { + trustzone = "NonSecure" + projectPart = "non-secure" + } else { + trustzone = "Secure" + projectPart = "secure" + } + contextFolder = trustzone } } - fPaths = append(fPaths, cfgPath) - fPath = path.Join(fPath, fName) - fMxDevice, err := os.Create(fPath) - if err != nil { - return nil, err - } - err = mxDeviceWriteHeader(fMxDevice, fName) - if err != nil { - _ = fMxDevice.Close() - return nil, err + _ = projectPart + if len(contextFolder) == 0 { + return nil, errors.New("Cannot find context " + context) } - peripherals, err := getPeripherals(contextMap, context) - if err != nil { - _ = fMxDevice.Close() - return nil, err - } - for _, peripheral := range peripherals { - vmode := getVirtualMode(contextMap, peripheral) - pins, err := getPins(contextMap, fMsp, peripheral) - if err != nil { - _ = fMxDevice.Close() - return nil, err - } - err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) - if err != nil { - _ = fMxDevice.Close() - return nil, err + msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName) + for _, subsystem := range params.Subsystem { + if subsystem.CoreName == coreName { + cfgPath = path.Join("drv_cfg", subsystem.SubsystemIdx.Project) + break } } - _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") - if err != nil { - return nil, err - } - err = fMxDevice.Close() + err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, context, params) if err != nil { return nil, err } + fPaths = append(fPaths, cfgPath) } } return fPaths, nil @@ -207,6 +145,54 @@ func createContextMap(iocFile string) (map[string]map[string]string, error) { return contextMap, nil } +func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp string, cfgPath string, context string, params cbuild.ParamsType) error { + fMsp, err := os.Open(msp) + if err != nil { + return err + } + defer fMsp.Close() + + fName := "MX_Device.h" + fPath := path.Join(path.Dir(workDir), cfgPath) + if _, err := os.Stat(fPath); err != nil { + err = os.MkdirAll(fPath, 0750) + if err != nil { + return err + } + } + fPath = path.Join(fPath, fName) + fMxDevice, err := os.Create(fPath) + if err != nil { + return err + } + defer fMxDevice.Close() + + err = mxDeviceWriteHeader(fMxDevice, fName) + if err != nil { + return err + } + peripherals, err := getPeripherals(contextMap, context) + if err != nil { + return err + } + for _, peripheral := range peripherals { + vmode := getVirtualMode(contextMap, peripheral) + pins, err := getPins(contextMap, fMsp, peripheral) + if err != nil { + return err + } + err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) + if err != nil { + return err + } + } + _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") + if err != nil { + return err + } + return nil +} + /* func createPinConfigMap(mspName string) (map[string]PinDefinition, error) { pinConfigMap := make(map[string]PinDefinition) @@ -273,43 +259,25 @@ func getDeviceFamily(contextMap map[string]map[string]string) (string, error) { return "", errors.New("missing device family") } -func getPeripherals1(contextMap map[string]map[string]string) ([]string, error) { - PERIPHERALS := [...]string{"USART", "UART", "LPUART", "SPI", "I2C", "ETH", "SDMMC", "CAN", "USB", "SDIO", "FDCAN"} - peripherals := []string{} - mcu := contextMap["Mcu"] - if mcu != nil { - for ip, peri := range mcu { - if strings.HasPrefix(ip, "IP") { - for _, peripheral := range PERIPHERALS { - if strings.HasPrefix(peri, peripheral) { - peripherals = append(peripherals, peri) - break - } - } - } - } - } else { - return nil, errors.New("peripheral not found in Mcu") - } - return peripherals, nil -} - func getPeripherals(contextMap map[string]map[string]string, context string) ([]string, error) { PERIPHERALS := [...]string{"USART", "UART", "LPUART", "SPI", "I2C", "ETH", "SDMMC", "CAN", "USB", "SDIO", "FDCAN"} var peripherals []string - contextIps := contextMap[context] - if contextIps == nil { - return nil, errors.New("context not found in ioc") - } - contextIpsLine := contextIps["IPs"] - if len(contextIpsLine) == 0 { - return nil, errors.New("IPs not found in context") + var contextIpsLine string + if len(context) > 0 { + contextIps, ok := contextMap[context] + if !ok { + return nil, errors.New("context not found in ioc") + } + contextIpsLine, ok = contextIps["IPs"] + if !ok { + return nil, errors.New("IPs not found in context") + } } mcu := contextMap["Mcu"] if mcu != nil { for ip, peri := range mcu { if strings.HasPrefix(ip, "IP") { - if strings.Contains(contextIpsLine, peri) { + if len(context) == 0 || strings.Contains(contextIpsLine, peri) { for _, peripheral := range PERIPHERALS { if strings.HasPrefix(peri, peripheral) { peripherals = append(peripherals, peri) @@ -346,8 +314,8 @@ func getPins(contextMap map[string]map[string]string, fMsp *os.File, peripheral peri := signal["Signal"] if strings.HasPrefix(peri, peripheral) { pinsName[key] = peri - label := signal["GPIO_Label"] - if len(label) > 0 { + label, ok := signal["GPIO_Label"] + if ok { label = strings.Split(label, " ")[0] label = replaceSpecialChars(label, "_") pinsLabel[key] = strings.ReplaceAll(label, ".", "_") diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index a6a6017..4749846 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -7,6 +7,7 @@ package stm32cubemx import ( + "os" "reflect" "testing" ) @@ -132,46 +133,8 @@ func Test_getDeviceFamily(t *testing.T) { } } -func Test_getPeripherals1(t *testing.T) { - t.Parallel() - - var parts = make(map[string]map[string]string) - parts["Mcu"] = map[string]string{"IP1": "UART", "IP2": "xx", "IP3": "USB3"} - - var parts1 = make(map[string]map[string]string) - parts1["xxx"] = map[string]string{} - - type args struct { - contextMap map[string]map[string]string - } - tests := []struct { - name string - args args - want1 []string - want2 []string - wantErr bool - }{ - {"test", args{parts}, []string{"UART", "USB3"}, []string{"USB3", "UART"}, false}, - {"fail", args{parts1}, nil, nil, true}, - } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - got, err := getPeripherals1(tt.args.contextMap) - if (err != nil) != tt.wantErr { - t.Errorf("getPeripherals1() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want1) && !reflect.DeepEqual(got, tt.want2) { - t.Errorf("getPeripherals1() %s = %v, want %v", tt.name, got, tt.want1) - } - }) - } -} - func Test_getPeripherals(t *testing.T) { - t.Parallel() + // t.Parallel() var parts = make(map[string]map[string]string) parts["Mcu"] = map[string]string{"IP1": "UART", "IP2": "xx", "IP3": "USB"} @@ -201,11 +164,13 @@ func Test_getPeripherals(t *testing.T) { {"fail1", args{parts1, "xxx"}, nil, nil, true}, {"fail2", args{parts2, "Context1"}, nil, nil, true}, {"fail3", args{parts3, "Context1"}, nil, nil, true}, + {"test1", args{parts, ""}, []string{"UART", "USB"}, []string{"USB", "UART"}, false}, + {"fail4", args{parts1, ""}, nil, nil, true}, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - t.Parallel() + // t.Parallel() got, err := getPeripherals(tt.args.contextMap, tt.args.context) if (err != nil) != tt.wantErr { t.Errorf("getPeripherals() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) @@ -250,7 +215,49 @@ func Test_getVirtualMode(t *testing.T) { } } +func Test_getPins(t *testing.T) { + var pins = make(map[string]map[string]string) + pins["PB8"] = map[string]string{"Mode": "MII", "Signal": "I2C1_sss", "GPIO_Label": "lab"} + + pindef := PinDefinition{p: "PB8", pin: "GPIO_PIN_8", port: "GPIOB", mode: "GPIO_MODE_AF_OD", pull: "GPIO_NOPULL", speed: "GPIO_SPEED_FREQ_LOW", alternate: "GPIO_AF4_I2C1"} + var pindefs = make(map[string]PinDefinition) + pindefs["I2C1_sss"] = pindef + + type args struct { + contextMap map[string]map[string]string + filename string + peripheral string + } + tests := []struct { + name string + args args + want map[string]PinDefinition + wantErr bool + }{ + {"test", args{pins, "../../testdata/stm32cubemx/test_msp.c", "I2C1"}, pindefs, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + file, err := os.Open(tt.args.filename) + if err != nil { + t.Errorf("getPinConfiguration() %s cannot open %s", tt.name, tt.args.filename) + return + } + got, err := getPins(tt.args.contextMap, file, tt.args.peripheral) + if (err != nil) != tt.wantErr { + t.Errorf("getPins() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getPins() %s = %v, want %v", tt.name, got, tt.want) + } + }) + } +} + func Test_replaceSpecialChars(t *testing.T) { + t.Parallel() + type args struct { label string ch string @@ -266,7 +273,9 @@ func Test_replaceSpecialChars(t *testing.T) { {"test4", args{"?bcd,", "_"}, "_bcd_"}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() if got := replaceSpecialChars(tt.args.label, tt.args.ch); got != tt.want { t.Errorf("replaceSpecialChars() = %v, want %v", got, tt.want) } @@ -296,3 +305,39 @@ func Test_getDigitAtEnd(t *testing.T) { }) } } + +func Test_getPinConfiguration(t *testing.T) { + pins := PinDefinition{p: "PB8", pin: "GPIO_PIN_8", port: "GPIOB", mode: "GPIO_MODE_AF_OD", pull: "GPIO_NOPULL", speed: "GPIO_SPEED_FREQ_LOW", alternate: "GPIO_AF4_I2C1"} + + type args struct { + filename string + peripheral string + pin string + label string + } + tests := []struct { + name string + args args + want PinDefinition + wantErr bool + }{ + {"test.ioc", args{"../../testdata/stm32cubemx/test_msp.c", "", "PB8", ""}, pins, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + file, err := os.Open(tt.args.filename) + if err != nil { + t.Errorf("getPinConfiguration() %s cannot open %s", tt.name, tt.args.filename) + return + } + got, err := getPinConfiguration(file, tt.args.peripheral, tt.args.pin, tt.args.label) + if (err != nil) != tt.wantErr { + t.Errorf("getPinConfiguration() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getPinConfiguration() %s = %v, want %v", tt.name, got, tt.want) + } + }) + } +} diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index 16221a3..468701e 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -8,6 +8,7 @@ package stm32cubemx import ( "errors" + "io/fs" "os" "os/exec" "path" @@ -17,15 +18,44 @@ import ( "github.com/open-cmsis-pack/generator-bridge/internal/cbuild" "github.com/open-cmsis-pack/generator-bridge/internal/common" + "github.com/open-cmsis-pack/generator-bridge/internal/generator" "github.com/open-cmsis-pack/generator-bridge/internal/utils" log "github.com/sirupsen/logrus" ) func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx bool) error { var projectFile string - var parms cbuild.ParamsType - err := ReadCbuildYmlFile(cbuildYmlPath, outPath, &parms) + cRoot := os.Getenv("CMSIS_COMPILER_ROOT") + if len(cRoot) == 0 { + ex, err := os.Executable() + if err != nil { + return err + } + exPath := filepath.Dir(ex) + exPath = filepath.ToSlash(exPath) + cRoot = path.Dir(exPath) + } + var generatorFile string + filepath.Walk(cRoot, func(path string, f fs.FileInfo, err error) error { + if f.Mode().IsRegular() && strings.Contains(path, "global.generator.yml") { + generatorFile = path + return nil + } + return nil + }) + if len(generatorFile) == 0 { + return errors.New("config file 'global.generator.yml' not found") + } + + var gParms generator.ParamsType + err := ReadGeneratorYmlFile(generatorFile, &gParms) + if err != nil { + return err + } + + var parms cbuild.ParamsType + err = ReadCbuildYmlFile(cbuildYmlPath, outPath, &parms) if err != nil { return err } @@ -61,7 +91,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx if utils.FileExists(cubeIocPath) { err := Launch(cubeIocPath, "") if err != nil { - return err + return errors.New("generator '" + gParms.Id + "' missing. Install from '" + gParms.DownloadUrl + "'") } } else { projectFile, err = WriteProjectFile(workDir, &parms) @@ -72,7 +102,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx err := Launch("", projectFile) if err != nil { - return err + return errors.New("generator '" + gParms.Id + "' missing. Install from '" + gParms.DownloadUrl + "'") } } @@ -102,7 +132,7 @@ func Launch(iocFile, projectFile string) error { const cubeEnvVar = "STM32CubeMX_PATH" cubeEnv := os.Getenv(cubeEnvVar) - if cubeEnv == "" { + if cubeEnv != "" { return errors.New("environment variable for CubeMX not set: " + cubeEnvVar) } @@ -167,6 +197,12 @@ func ReadCbuildYmlFile(path, outPath string, parms *cbuild.ParamsType) error { return nil } +func ReadGeneratorYmlFile(path string, parms *generator.ParamsType) error { + log.Infof("Reading generator.yml file: '%v'", path) + err := generator.Read(path, parms) + return err +} + var filterFiles = map[string]string{ "system_": "system_ file (delivered from elsewhere)", "Templates": "Templates file (mostly not present)", diff --git a/testdata/stm32cubemx/test_msp.c b/testdata/stm32cubemx/test_msp.c new file mode 100644 index 0000000..b53f94a --- /dev/null +++ b/testdata/stm32cubemx/test_msp.c @@ -0,0 +1,33 @@ +void HAL_MspInit(void) +{ +} + +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(hi2c->Instance==I2C1) + { + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1; + PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB9 ------> I2C1_SDA + PB8 ------> I2C1_SCL + */ + GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + __HAL_RCC_I2C1_CLK_ENABLE(); + } + +} From 5b210d7f06e1e04d3c696e5f8c87172d64fc8695 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Wed, 24 Jan 2024 17:55:20 +0100 Subject: [PATCH 07/18] Fixed formatting and lint complaints --- internal/generator/generator.go | 16 ++++++++-------- internal/stm32CubeMX/iniReader.go | 1 - internal/stm32CubeMX/stm32CubeMX.go | 11 +++++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/internal/generator/generator.go b/internal/generator/generator.go index 783d89a..0b2c7ee 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -14,15 +14,15 @@ import ( ) type ParamsType struct { - Id string - DownloadUrl string + ID string + DownloadURL string } type GeneratorType struct { Generator []struct { - Id string `yaml:"id"` + ID string `yaml:"id"` Description string `yaml:"description"` - DownloadUrl string `yaml:"download-url"` + DownloadURL string `yaml:"download-url"` Run string `yaml:"run"` Path string `yaml:"path"` } `yaml:"generator"` @@ -42,13 +42,13 @@ func Read(name string, params *ParamsType) error { return err } for _, genx := range gen.Generator { - if genx.Id == "CubeMX" { - params.Id = genx.Id - params.DownloadUrl = genx.DownloadUrl + if genx.ID == "CubeMX" { + params.ID = genx.ID + params.DownloadURL = genx.DownloadURL break } } - if params.Id != "CubeMX" { + if params.ID != "CubeMX" { return errors.New("generator CubeMX missing in global.generator.yml") } return nil diff --git a/internal/stm32CubeMX/iniReader.go b/internal/stm32CubeMX/iniReader.go index 5d54d50..a16757f 100644 --- a/internal/stm32CubeMX/iniReader.go +++ b/internal/stm32CubeMX/iniReader.go @@ -245,7 +245,6 @@ func GetIni(path string) (*ini.File, error) { func GetSections(inidata *ini.File, iniSections *IniSectionsType) error { sectionsData := inidata.SectionStrings() for _, section := range sectionsData { -// section := sectionsData[sectionID] var iniName string var sectionName string sectionString := strings.Split(section, ":") diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index 468701e..0805dc7 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -37,19 +37,22 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx cRoot = path.Dir(exPath) } var generatorFile string - filepath.Walk(cRoot, func(path string, f fs.FileInfo, err error) error { + err := filepath.Walk(cRoot, func(path string, f fs.FileInfo, err error) error { if f.Mode().IsRegular() && strings.Contains(path, "global.generator.yml") { generatorFile = path return nil } return nil }) + if err != nil { + return err + } if len(generatorFile) == 0 { return errors.New("config file 'global.generator.yml' not found") } var gParms generator.ParamsType - err := ReadGeneratorYmlFile(generatorFile, &gParms) + err = ReadGeneratorYmlFile(generatorFile, &gParms) if err != nil { return err } @@ -91,7 +94,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx if utils.FileExists(cubeIocPath) { err := Launch(cubeIocPath, "") if err != nil { - return errors.New("generator '" + gParms.Id + "' missing. Install from '" + gParms.DownloadUrl + "'") + return errors.New("generator '" + gParms.ID + "' missing. Install from '" + gParms.DownloadURL + "'") } } else { projectFile, err = WriteProjectFile(workDir, &parms) @@ -102,7 +105,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx err := Launch("", projectFile) if err != nil { - return errors.New("generator '" + gParms.Id + "' missing. Install from '" + gParms.DownloadUrl + "'") + return errors.New("generator '" + gParms.ID + "' missing. Install from '" + gParms.DownloadURL + "'") } } From 6feb311a759778eb98c6b735e5cc9576cb189a24 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Fri, 26 Jan 2024 11:31:53 +0100 Subject: [PATCH 08/18] corrected wrong test for not set environment variable --- internal/stm32CubeMX/stm32CubeMX.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index 0805dc7..e26d1d7 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -135,7 +135,7 @@ func Launch(iocFile, projectFile string) error { const cubeEnvVar = "STM32CubeMX_PATH" cubeEnv := os.Getenv(cubeEnvVar) - if cubeEnv != "" { + if cubeEnv == "" { return errors.New("environment variable for CubeMX not set: " + cubeEnvVar) } From 9c94c8af1a6c07eb4186b423cb657a4191168c2d Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Wed, 31 Jan 2024 13:17:40 +0100 Subject: [PATCH 09/18] Removed fPaths again, they are not necessary, can used project directly Added more tests --- cmd/version.go | 4 +- internal/common/common.go | 1 + internal/generator/generator_test.go | 38 ++++ internal/readFile/readFile.go | 12 +- internal/stm32CubeMX/mxDevice.go | 100 ++++++----- internal/stm32CubeMX/mxDevice_test.go | 249 +++++++++++++++++++++++++- internal/stm32CubeMX/stm32CubeMX.go | 28 ++- testdata/global-nix.yml | 6 + testdata/global.yml | 6 + testdata/stm32cubemx/test_msp.c | 1 + testdata/stm32cubemx/test_msp1.c | 35 ++++ testdata/wrong.yml | 2 + 12 files changed, 410 insertions(+), 72 deletions(-) create mode 100644 testdata/global-nix.yml create mode 100644 testdata/global.yml create mode 100644 testdata/stm32cubemx/test_msp1.c create mode 100644 testdata/wrong.yml diff --git a/cmd/version.go b/cmd/version.go index aa51471..f2c7aef 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,4 +8,4 @@ package main var version string -const copyright = "(C) 2023 Arm Ltd." +const copyright = "(C) 2023-2024 Arm Ltd." diff --git a/internal/common/common.go b/internal/common/common.go index 1055fc8..c811f01 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -23,6 +23,7 @@ func ReadYml(path string, out interface{}) error { err = yaml.Unmarshal(yamlFile, out) if err != nil { log.Errorf("Unmarshal: %v", err) + return err } return nil diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index 87ec970..8440a0a 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -5,3 +5,41 @@ */ package generator + +import ( + "reflect" + "testing" +) + +func TestRead(t *testing.T) { + var params ParamsType + + type args struct { + name string + params *ParamsType + } + tests := []struct { + name string + args args + want ParamsType + wantErr bool + }{ + {"wrong.yml", args{"../../testdata/wrong.yml", ¶ms}, ParamsType{}, true}, + {"global.yml", args{"../../testdata/global.yml", ¶ms}, ParamsType{ID: "CubeMX", DownloadURL: "https://nix.html"}, false}, + {"global-nix.yml", args{"../../testdata/global-nix.yml", ¶ms}, ParamsType{}, true}, + {"wrong.yml", args{"../../testdata/wrong.yml", ¶ms}, ParamsType{}, true}, + {"xxx.yml", args{"../../testdata/xxx.yml", ¶ms}, ParamsType{}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + params.ID = "" + params.DownloadURL = "" + if err := Read(tt.args.name, tt.args.params); (err != nil) != tt.wantErr { + t.Errorf("Read() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + if !reflect.DeepEqual(params, tt.want) { + t.Errorf("createContextMap() %s got = %v, want %v", tt.name, params, tt.want) + } + }) + } +} diff --git a/internal/readFile/readFile.go b/internal/readFile/readFile.go index b7d1bad..42350b1 100644 --- a/internal/readFile/readFile.go +++ b/internal/readFile/readFile.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -75,7 +75,11 @@ func Process(inFile, inFile2, outPath string) error { workDir = path.Join(workDir, parms.OutPath) } } else { - workDir = path.Join(workDir, outPath) + if filepath.IsAbs(outPath) { + workDir = outPath + } else { + workDir = path.Join(workDir, outPath) + } } workDir = filepath.Clean(workDir) workDir = filepath.ToSlash(workDir) @@ -84,12 +88,12 @@ func Process(inFile, inFile2, outPath string) error { return err } - fPaths, err := stm32cubemx.ReadContexts(workDir+"/STM32CubeMX/STM32CubeMX.ioc", parms) + err = stm32cubemx.ReadContexts(workDir+"/STM32CubeMX/STM32CubeMX.ioc", parms) if err != nil { return err } - err = stm32cubemx.WriteCgenYml(outPath, mxprojectAll, fPaths, params) + err = stm32cubemx.WriteCgenYml(outPath, mxprojectAll, params) if err != nil { return err } diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index 692d6af..129c8b7 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,34 +30,33 @@ type PinDefinition struct { alternate string } -func ReadContexts(iocFile string, params cbuild.ParamsType) ([]string, error) { - var fPaths []string +func ReadContexts(iocFile string, params cbuild.ParamsType) error { contextMap, err := createContextMap(iocFile) if err != nil { - return nil, err + return err } contexts, err := getContexts(contextMap) if err != nil { - return nil, err + return err } deviceFamily, err := getDeviceFamily(contextMap) if err != nil { - return nil, err + return err } workDir := path.Dir(iocFile) workDirAbs, err := filepath.Abs(workDir) if err != nil { - return nil, err + return err } mspName := deviceFamily + "xx_hal_msp.c" // pinConfigMap, err := createPinConfigMap(mspName) mspFolder := contextMap["ProjectManager"]["MainLocation"] if mspFolder == "" { - return nil, errors.New("main location missing") + return errors.New("main location missing") } var cfgPath string @@ -66,9 +65,8 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) ([]string, error) { cfgPath = path.Join("drv_cfg", params.Subsystem[0].SubsystemIdx.Project) err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, "", params) if err != nil { - return nil, err + return err } - fPaths = append(fPaths, cfgPath) } else { for _, context := range contexts { var coreName string @@ -97,25 +95,29 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) ([]string, error) { } } - _ = projectPart if len(contextFolder) == 0 { - return nil, errors.New("Cannot find context " + context) + return errors.New("Cannot find context " + context) } msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName) for _, subsystem := range params.Subsystem { if subsystem.CoreName == coreName { - cfgPath = path.Join("drv_cfg", subsystem.SubsystemIdx.Project) - break + if len(subsystem.TrustZone) == 0 { + cfgPath = path.Join("drv_cfg", subsystem.SubsystemIdx.Project) + break + } + if subsystem.TrustZone == projectPart { + cfgPath = path.Join("drv_cfg", subsystem.SubsystemIdx.Project) + break + } } } err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, context, params) if err != nil { - return nil, err + return err } - fPaths = append(fPaths, cfgPath) } } - return fPaths, nil + return nil } func createContextMap(iocFile string) (map[string]map[string]string, error) { @@ -167,7 +169,9 @@ func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp } defer fMxDevice.Close() - err = mxDeviceWriteHeader(fMxDevice, fName) + out := bufio.NewWriter(fMxDevice) + defer out.Flush() + err = mxDeviceWriteHeader(out, fName) if err != nil { return err } @@ -181,12 +185,12 @@ func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp if err != nil { return err } - err = mxDeviceWritePeripheralCfg(fMxDevice, peripheral, vmode, pins) + err = mxDeviceWritePeripheralCfg(out, peripheral, vmode, pins) if err != nil { return err } } - _, err = fMxDevice.WriteString("\n#endif /* __MX_DEVICE_H */\n") + _, err = out.WriteString("\n#endif /* __MX_DEVICE_H */\n") if err != nil { return err } @@ -389,7 +393,7 @@ func getPinConfiguration(fMsp *os.File, peripheral string, pin string, label str if strings.Contains(line, gpioPort) || strings.Contains(line, label+"_GPIO_Port") { values := strings.Split(pinInfo.pin, "|") for _, val := range values { - val = strings.TrimRight(strings.TrimLeft(val, " "), " ") + val = strings.TrimRight(strings.TrimLeft(val, "\t "), "\t ") if val == gpioPin || val == (label+"_Pin") { pinInfo.p = pin pinInfo.pin = gpioPin @@ -435,93 +439,93 @@ func getPinConfiguration(fMsp *os.File, peripheral string, pin string, label str return PinDefinition{}, nil } -func mxDeviceWriteHeader(fMxDevice *os.File, fName string) error { +func mxDeviceWriteHeader(out *bufio.Writer, fName string) error { now := time.Now() dtString := now.Format("02/01/2006 15:04:05") var err error - if _, err = fMxDevice.WriteString("/******************************************************************************\n"); err != nil { + if _, err = out.WriteString("/******************************************************************************\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" * File Name : " + fName + "\n"); err != nil { + if _, err = out.WriteString(" * File Name : " + fName + "\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" * Date : " + dtString + "\n"); err != nil { + if _, err = out.WriteString(" * Date : " + dtString + "\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" * Description : STM32Cube MX parameter definitions\n"); err != nil { + if _, err = out.WriteString(" * Description : STM32Cube MX parameter definitions\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" * Note : This file is generated with a generator out of the\n"); err != nil { + if _, err = out.WriteString(" * Note : This file is generated with a generator out of the\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" * STM32CubeMX project and its generated files (DO NOT EDIT!)\n"); err != nil { + if _, err = out.WriteString(" * STM32CubeMX project and its generated files (DO NOT EDIT!)\n"); err != nil { return err } - if _, err = fMxDevice.WriteString(" ******************************************************************************/\n\n"); err != nil { + if _, err = out.WriteString(" ******************************************************************************/\n\n"); err != nil { return err } - if _, err = fMxDevice.WriteString("#ifndef __MX_DEVICE_H\n"); err != nil { + if _, err = out.WriteString("#ifndef __MX_DEVICE_H\n"); err != nil { return err } - _, err = fMxDevice.WriteString("#define __MX_DEVICE_H\n\n") + _, err = out.WriteString("#define __MX_DEVICE_H\n\n") return err } -func mxDeviceWritePeripheralCfg(fMxDevice *os.File, peripheral string, vmode string, pins map[string]PinDefinition) error { +func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode string, pins map[string]PinDefinition) error { str := "\n/*------------------------------ " + peripheral if len(str) < 49 { str += strings.Repeat(" ", 49-len(str)) } str += "-----------------------------*/\n" - _, err := fMxDevice.WriteString(str) + _, err := out.WriteString(str) if err != nil { return err } - if err = writeDefine(fMxDevice, peripheral, "1\n"); err != nil { + if err = writeDefine(out, peripheral, "1\n"); err != nil { return err } if vmode != "" { - if _, err = fMxDevice.WriteString("/* Virtual mode */\n"); err != nil { + if _, err = out.WriteString("/* Virtual mode */\n"); err != nil { return err } - if err = writeDefine(fMxDevice, peripheral+"_VM", vmode); err != nil { + if err = writeDefine(out, peripheral+"_VM", vmode); err != nil { return err } - if err = writeDefine(fMxDevice, peripheral+"_"+vmode, "1"); err != nil { + if err = writeDefine(out, peripheral+"_"+vmode, "1"); err != nil { return err } } if len(pins) != 0 { - _, err = fMxDevice.WriteString("/* Pins */\n") + _, err = out.WriteString("/* Pins */\n") if err != nil { return err } for pin, pinDef := range pins { - _, err = fMxDevice.WriteString("\n/* " + pin + " */\n") + _, err = out.WriteString("\n/* " + pin + " */\n") if err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_Pin", pinDef.p); err != nil { + if err = writeDefine(out, pin+"_Pin", pinDef.p); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIO_Pin", pinDef.pin); err != nil { + if err = writeDefine(out, pin+"_GPIO_Pin", pinDef.pin); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIOx", pinDef.port); err != nil { + if err = writeDefine(out, pin+"_GPIOx", pinDef.port); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIO_Mode", pinDef.mode); err != nil { + if err = writeDefine(out, pin+"_GPIO_Mode", pinDef.mode); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIO_PuPd", pinDef.pull); err != nil { + if err = writeDefine(out, pin+"_GPIO_PuPd", pinDef.pull); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIO_Speed", pinDef.speed); err != nil { + if err = writeDefine(out, pin+"_GPIO_Speed", pinDef.speed); err != nil { return err } - if err = writeDefine(fMxDevice, pin+"_GPIO_AF", pinDef.alternate); err != nil { + if err = writeDefine(out, pin+"_GPIO_AF", pinDef.alternate); err != nil { return err } } @@ -530,7 +534,7 @@ func mxDeviceWritePeripheralCfg(fMxDevice *os.File, peripheral string, vmode str return nil } -func writeDefine(fMxDevice *os.File, name string, value string) error { +func writeDefine(out *bufio.Writer, name string, value string) error { invalidChars := [...]string{"=", " ", "/", "(", ")", "[", "]", "\\", "-"} if len(value) == 0 { @@ -544,6 +548,6 @@ func writeDefine(fMxDevice *os.File, name string, value string) error { if len(name) < 39 { name += strings.Repeat(" ", 39-len(name)) } - _, err := fMxDevice.WriteString("#define " + name + value + "\n") + _, err := out.WriteString("#define " + name + value + "\n") return err } diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index 4749846..b5d6867 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,9 +7,16 @@ package stm32cubemx import ( + "bufio" + "bytes" + "errors" + "io" "os" "reflect" "testing" + "time" + + "github.com/open-cmsis-pack/generator-bridge/internal/cbuild" ) func Test_createContextMap(t *testing.T) { @@ -46,6 +53,44 @@ func Test_createContextMap(t *testing.T) { } } +func Test_writeMXdeviceH(t *testing.T) { + var mcuContext0 = make(map[string]map[string]string) + mcuContext0["Mcu"] = map[string]string{"nixIPs": "myContext"} + var mcuContext1 = make(map[string]map[string]string) + mcuContext1["Mcu"] = map[string]string{"IPs": "myContext"} + var mcuContext2 = make(map[string]map[string]string) + mcuContext2["Mcu"] = map[string]string{"IPs": "IP1"} + mcuContext2["IP1"] = map[string]string{"IPs": "SPI2"} + + type args struct { + contextMap map[string]map[string]string + workDir string + msp string + cfgPath string + context string + params cbuild.ParamsType + } + tests := []struct { + name string + args args + wantErr bool + }{ + {"Mcu", args{mcuContext2, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "Mcu", cbuild.ParamsType{}}, false}, + {"wrong context", args{mcuContext0, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "context", cbuild.ParamsType{}}, true}, + {"Mcu Context", args{mcuContext1, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "Mcu", cbuild.ParamsType{}}, false}, + {"wrong myContext", args{mcuContext1, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "context", cbuild.ParamsType{}}, true}, + {"wrong msp", args{mcuContext1, "work", "msp", "cfg", "context", cbuild.ParamsType{}}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer os.RemoveAll(tt.args.cfgPath); + if err := writeMXdeviceH(tt.args.contextMap, tt.args.workDir, tt.args.msp, tt.args.cfgPath, tt.args.context, tt.args.params); (err != nil) != tt.wantErr { + t.Errorf("writeMXdeviceH() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + }) + } +} + func Test_getContexts(t *testing.T) { t.Parallel() @@ -321,7 +366,8 @@ func Test_getPinConfiguration(t *testing.T) { want PinDefinition wantErr bool }{ - {"test.ioc", args{"../../testdata/stm32cubemx/test_msp.c", "", "PB8", ""}, pins, false}, + {"test.msp", args{"../../testdata/stm32cubemx/test_msp.c", "", "PB8", ""}, pins, false}, + {"test1.msp", args{"../../testdata/stm32cubemx/test_msp1.c", "", "PB8", ""}, pins, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -341,3 +387,202 @@ func Test_getPinConfiguration(t *testing.T) { }) } } + +func Test_mxDeviceWriteHeader(t *testing.T) { + var b bytes.Buffer + + now := time.Now() + dtString := now.Format("02/01/2006 15:04:05") + line1 := "/******************************************************************************\n" + + " * File Name : fileName\n" + + " * Date : " + dtString + "\n" + + " * Description : STM32Cube MX parameter definitions\n" + + " * Note : This file is generated with a generator out of the\n" + + " * STM32CubeMX project and its generated files (DO NOT EDIT!)\n" + + " ******************************************************************************/\n\n" + + "#ifndef __MX_DEVICE_H\n" + + "#define __MX_DEVICE_H\n\n" + + type args struct { + out *bufio.Writer + fName string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + {"header", args{fName: "fileName"}, line1, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.args.out = bufio.NewWriter(&b) + + if err := mxDeviceWriteHeader(tt.args.out, tt.args.fName); (err != nil) != tt.wantErr { + t.Errorf("mxDeviceWriteHeader() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + tt.args.out.Flush() + str, err := b.ReadString('\000') + if err != nil && !errors.Is(err, io.EOF) { + t.Errorf("Output.print() err = %v", err) + } + if !errors.Is(err, io.EOF) && str != tt.want { + t.Errorf("Output.print() %s = %v, want %v", tt.name, str, tt.want) + } + }) + } +} + +func Test_mxDeviceWritePeripheralCfg(t *testing.T) { + var b bytes.Buffer + + var pins map[string]PinDefinition + + pins1 := make(map[string]PinDefinition) + pins1["pin1"] = PinDefinition{p: "p"} + + pins2 := make(map[string]PinDefinition) + pins2["pin2"] = PinDefinition{pin: "pin"} + + pins3 := make(map[string]PinDefinition) + pins3["pin3"] = PinDefinition{port: "port"} + + pins4 := make(map[string]PinDefinition) + pins4["pin4"] = PinDefinition{mode: "mode"} + + pins5 := make(map[string]PinDefinition) + pins5["pin5"] = PinDefinition{pull: "pull"} + + pins6 := make(map[string]PinDefinition) + pins6["pin6"] = PinDefinition{speed: "speed"} + + pins7 := make(map[string]PinDefinition) + pins7["pin7"] = PinDefinition{alternate: "alternate"} + + linev := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Virtual mode */\n" + + "#define MX_peripheral_VM vmode\n" + + "#define MX_peripheral_vmode 1\n" + + line1 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin1 */\n" + + "#define MX_pin1_Pin p\n" + + line2 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin2 */\n" + + "#define MX_pin2_GPIO_Pin pin\n\n" + + line3 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin2 */\n" + + "#define MX_pin2_GPIOx port\n\n" + + line4 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin3 */\n" + + "#define MX_pin3_GPIO_Mode mode\n\n" + + line5 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin4 */\n" + + "#define MX_pin4_GPIO_PuPd pull\n\n" + + line6 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin5 */\n" + + "#define MX_pin5_GPIO_Speed speed\n" + + line7 := "\n/*------------------------------ peripheral -----------------------------*/\n" + + "#define MX_peripheral 1\n\n" + + "/* Pins */\n\n" + + "/* pin6 */\n" + + "#define MX_pin6_GPIO_AF alternate\n\n" + + type args struct { + out *bufio.Writer + peripheral string + vmode string + pins map[string]PinDefinition + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + {"device", args{peripheral: "peripheral", vmode: "vmode", pins: pins}, linev, false}, + {"device_pin1", args{peripheral: "peripheral", pins: pins1}, line1, false}, + {"device_pin2", args{peripheral: "peripheral", pins: pins2}, line2, false}, + {"device_pin3", args{peripheral: "peripheral", pins: pins3}, line3, false}, + {"device_pin4", args{peripheral: "peripheral", pins: pins4}, line4, false}, + {"device_pin5", args{peripheral: "peripheral", pins: pins5}, line5, false}, + {"device_pin6", args{peripheral: "peripheral", pins: pins6}, line6, false}, + {"device_pin7", args{peripheral: "peripheral", pins: pins7}, line7, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.args.out = bufio.NewWriter(&b) + + if err := mxDeviceWritePeripheralCfg(tt.args.out, tt.args.peripheral, tt.args.vmode, tt.args.pins); (err != nil) != tt.wantErr { + t.Errorf("mxDeviceWritePeripheralCfg() error = %v, wantErr %v", err, tt.wantErr) + } + tt.args.out.Flush() + str, err := b.ReadString('\000') + if err != nil && !errors.Is(err, io.EOF) { + t.Errorf("Output.print() err = %v", err) + } + if !errors.Is(err, io.EOF) && str != tt.want { + t.Errorf("Output.print() %s = %v, want %v", tt.name, str, tt.want) + } + }) + } +} + +func Test_writeDefine(t *testing.T) { + var b bytes.Buffer + + line1 := "#define name value\n" + line2 := "#define na_e val_e\n" + + type args struct { + out *bufio.Writer + name string + value string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + {"test", args{name: "name", value: "value"}, line1, false}, + {"test=-", args{name: "na=e", value: "val-e"}, line2, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.args.out = bufio.NewWriter(&b) + + if err := writeDefine(tt.args.out, tt.args.name, tt.args.value); (err != nil) != tt.wantErr { + t.Errorf("writeDefine() error = %v, wantErr %v", err, tt.wantErr) + } + tt.args.out.Flush() + str, err := b.ReadString('\000') + if err != nil && !errors.Is(err, io.EOF) { + t.Errorf("Output.print() err = %v", err) + } + if !errors.Is(err, io.EOF) && str != tt.want { + t.Errorf("Output.print() %s = %v, want %v", tt.name, str, tt.want) + } + }) + } +} diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index e26d1d7..0992af0 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,8 +81,6 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx return err } - var fPaths []string - if runCubeMx { cubeIocPath := workDir lastPath := filepath.Base(cubeIocPath) @@ -109,7 +107,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx } } - fPaths, err = ReadContexts(cubeIocPath, parms) + err = ReadContexts(cubeIocPath, parms) if err != nil { return err } @@ -122,7 +120,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx return err } - err = WriteCgenYml(workDir, mxproject, fPaths, parms) + err = WriteCgenYml(workDir, mxproject, parms) if err != nil { return err } @@ -245,7 +243,7 @@ func FindMxProject(subsystem *cbuild.SubsystemType, mxprojectAll MxprojectAllTyp return MxprojectType{}, nil } -func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, fPaths []string, inParms cbuild.ParamsType) error { +func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, inParms cbuild.ParamsType) error { for id := range inParms.Subsystem { subsystem := &inParms.Subsystem[id] @@ -253,7 +251,7 @@ func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, fPaths []string if err != nil { continue } - err = WriteCgenYmlSub(outPath, mxproject, fPaths, subsystem) + err = WriteCgenYmlSub(outPath, mxproject, subsystem) if err != nil { return err } @@ -262,7 +260,7 @@ func WriteCgenYml(outPath string, mxprojectAll MxprojectAllType, fPaths []string return nil } -func WriteCgenYmlSub(outPath string, mxproject MxprojectType, fPaths []string, subsystem *cbuild.SubsystemType) error { +func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild.SubsystemType) error { outName := subsystem.SubsystemIdx.Project + ".cgen.yml" outFile := path.Join(outPath, outName) var cgen cbuild.CgenType @@ -278,15 +276,14 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, fPaths []string, s cgen.GeneratorImport.ForDevice = subsystem.Device cgen.GeneratorImport.Define = append(cgen.GeneratorImport.Define, mxproject.PreviousUsedKeilFiles.CDefines...) - for id := range mxproject.PreviousUsedKeilFiles.HeaderPath { - headerPath := mxproject.PreviousUsedKeilFiles.HeaderPath[id] + for _, headerPath := range mxproject.PreviousUsedKeilFiles.HeaderPath { headerPath, _ = utils.ConvertFilename(outPath, headerPath, relativePathAdd) cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, headerPath) } - for _, fPath := range fPaths { - fPath, _ = utils.ConvertFilename(outPath, fPath, "") - cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, fPath) - } + + cfgPath := path.Join("drv_cfg", subsystem.SubsystemIdx.Project) + cfgPath, _ = utils.ConvertFilename(outPath, cfgPath, "") + cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, cfgPath) var groupSrc cbuild.CgenGroupsType var groupHalDriver cbuild.CgenGroupsType @@ -296,8 +293,7 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, fPaths []string, s groupHalDriver.Group = "HAL Driver" groupHalFilter := "HAL_Driver" - for id := range mxproject.PreviousUsedKeilFiles.SourceFiles { - file := mxproject.PreviousUsedKeilFiles.SourceFiles[id] + for _, file := range mxproject.PreviousUsedKeilFiles.SourceFiles { if FilterFile(file) { continue } diff --git a/testdata/global-nix.yml b/testdata/global-nix.yml new file mode 100644 index 0000000..4deb411 --- /dev/null +++ b/testdata/global-nix.yml @@ -0,0 +1,6 @@ +generator: + - id: NIX + description: Global Registered Generator + download-url: https://nix.html + run: ../bin/cbridge + path: $SolutionDir()$/STM32CubeMX/$TargetType$ diff --git a/testdata/global.yml b/testdata/global.yml new file mode 100644 index 0000000..95bd24a --- /dev/null +++ b/testdata/global.yml @@ -0,0 +1,6 @@ +generator: + - id: CubeMX + description: Global Registered Generator + download-url: https://nix.html + run: ../bin/cbridge + path: $SolutionDir()$/STM32CubeMX/$TargetType$ diff --git a/testdata/stm32cubemx/test_msp.c b/testdata/stm32cubemx/test_msp.c index b53f94a..d363611 100644 --- a/testdata/stm32cubemx/test_msp.c +++ b/testdata/stm32cubemx/test_msp.c @@ -21,6 +21,7 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) PB8 ------> I2C1_SCL */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8; + GPIO_InitStruct.Port = GPIO_PORT; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; diff --git a/testdata/stm32cubemx/test_msp1.c b/testdata/stm32cubemx/test_msp1.c new file mode 100644 index 0000000..015320d --- /dev/null +++ b/testdata/stm32cubemx/test_msp1.c @@ -0,0 +1,35 @@ +void HAL_MspInit(void) +{ +} + +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(hi2c->Instance==I2C1) + { + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1; + PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB9 ------> I2C1_SDA + PB8 ------> I2C1_SCL + */ + GPIO_InitStruct.Pin = GPIO_PIN_9| + GPIO_PIN_8; + GPIO_InitStruct.Port = GPIO_PORT; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + __HAL_RCC_I2C1_CLK_ENABLE(); + } + +} diff --git a/testdata/wrong.yml b/testdata/wrong.yml new file mode 100644 index 0000000..70fcfb3 --- /dev/null +++ b/testdata/wrong.yml @@ -0,0 +1,2 @@ +invalid +yaml From f088567623be983f387b71f08b2cb0b9c579f2f5 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Wed, 31 Jan 2024 13:52:38 +0100 Subject: [PATCH 10/18] removed a ; --- internal/stm32CubeMX/mxDevice_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index b5d6867..e4b2b4a 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -83,7 +83,7 @@ func Test_writeMXdeviceH(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - defer os.RemoveAll(tt.args.cfgPath); + defer os.RemoveAll(tt.args.cfgPath) if err := writeMXdeviceH(tt.args.contextMap, tt.args.workDir, tt.args.msp, tt.args.cfgPath, tt.args.context, tt.args.params); (err != nil) != tt.wantErr { t.Errorf("writeMXdeviceH() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) } From a742897d71f7655f1a88f3e9a6a3bd812b9206af Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Fri, 2 Feb 2024 19:43:53 +0100 Subject: [PATCH 11/18] Added I2C filter extraction more Tests --- cmd/commands/commands_test.go | 59 +++++++- internal/common/common_test.go | 42 +++++- internal/stm32CubeMX/iniReader_test.go | 24 +++- internal/stm32CubeMX/mxDevice.go | 104 +++++++++++--- internal/stm32CubeMX/mxDevice_test.go | 33 +++-- internal/utils/utils_test.go | 188 ++++++++++++++++++------- testdata/stm32cubemx/main.c | 14 ++ testdata/test.yml | 2 + 8 files changed, 375 insertions(+), 91 deletions(-) create mode 100644 testdata/stm32cubemx/main.c create mode 100644 testdata/test.yml diff --git a/cmd/commands/commands_test.go b/cmd/commands/commands_test.go index 0cdb7f9..0112d6e 100644 --- a/cmd/commands/commands_test.go +++ b/cmd/commands/commands_test.go @@ -1,7 +1,62 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ -package commands_test +package commands + +import ( + "bytes" + "testing" + + "github.com/spf13/cobra" +) + +func Test_configureGlobalCmd(t *testing.T) { + type args struct { + cmd *cobra.Command + args []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + {"test", args{cmd: &cobra.Command{}}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + NewCli() + if err := configureGlobalCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr { + t.Errorf("configureGlobalCmd() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + }) + } +} + +func Test_printVersionAndLicense(t *testing.T) { + tests := []struct { + name string + version string + copyright string + wantFile string + }{ + {"test", "v1.2.3", "copy", "generator-bridge version 1.2.3 copy\n"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + file := &bytes.Buffer{} + saveVersion := Version + saveCopyright := Copyright + Version = tt.version + Copyright = tt.copyright + printVersionAndLicense(file) + if gotFile := file.String(); gotFile != tt.wantFile { + t.Errorf("printVersionAndLicense() %s = %v, want %v", tt.name, gotFile, tt.wantFile) + } + Version = saveVersion + Copyright = saveCopyright + }) + } +} diff --git a/internal/common/common_test.go b/internal/common/common_test.go index 88b0ef6..5fb3191 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -1,12 +1,46 @@ /* - * Copyright (c) 2023 Arm Limited. All rights reserved. + * Copyright (c) 2023-2024 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ -package common_test +package common -import "testing" +import ( + "reflect" + "testing" +) -func TestFoo(t *testing.T) { +func TestReadYml(t *testing.T) { + type TestYml struct { + Test []struct { + Xx string `yaml:"xx"` + } `yaml:"test"` + } + var testyml TestYml + + t1 := TestYml{Test: []struct{Xx string `yaml:"xx"`}{{Xx: "abc"}}} + + type args struct { + path string + out interface{} + } + tests := []struct { + name string + args args + want TestYml + wantErr bool + }{ + {"test", args{"../../testdata/test.yml", &testyml}, t1, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ReadYml(tt.args.path, tt.args.out); (err != nil) != tt.wantErr { + t.Errorf("ReadYml() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + if !reflect.DeepEqual(tt.args.out, &tt.want) { + t.Errorf("ReadYml() %s got = %v, want %v", tt.name, tt.args.out, tt.want) + } + }) + } } diff --git a/internal/stm32CubeMX/iniReader_test.go b/internal/stm32CubeMX/iniReader_test.go index 4d8d4da..54780bc 100644 --- a/internal/stm32CubeMX/iniReader_test.go +++ b/internal/stm32CubeMX/iniReader_test.go @@ -4,9 +4,27 @@ * SPDX-License-Identifier: Apache-2.0 */ -package stm32cubemx_test +package stm32cubemx -import "testing" +func ExamplePrintKeyValStr() { + PrintKeyValStr("key", "val") + // Output: + // + // key : val +} + +func ExamplePrintKeyValStrs() { + PrintKeyValStrs("key", []string{"val1", "val2"}) + // Output: + // + // key + // 0: val1 + // 1: val2 +} -func TestIniReader(t *testing.T) { +func ExamplePrintKeyValInt() { + PrintKeyValInt("key", 4711) + // Output: + // + // key : 4711 } diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index 129c8b7..7d65f32 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -47,23 +47,17 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { } workDir := path.Dir(iocFile) - workDirAbs, err := filepath.Abs(workDir) - if err != nil { - return err - } - mspName := deviceFamily + "xx_hal_msp.c" - // pinConfigMap, err := createPinConfigMap(mspName) - mspFolder := contextMap["ProjectManager"]["MainLocation"] - if mspFolder == "" { + mainFolder := contextMap["ProjectManager"]["MainLocation"] + if mainFolder == "" { return errors.New("main location missing") } + mspName := deviceFamily + "xx_hal_msp.c" var cfgPath string if len(contexts) == 0 { - msp := path.Join(workDirAbs, mspFolder, mspName) cfgPath = path.Join("drv_cfg", params.Subsystem[0].SubsystemIdx.Project) - err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, "", params) + err := writeMXdeviceH(contextMap, workDir, mainFolder, mspName, cfgPath, "", params) if err != nil { return err } @@ -98,7 +92,6 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { if len(contextFolder) == 0 { return errors.New("Cannot find context " + context) } - msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName) for _, subsystem := range params.Subsystem { if subsystem.CoreName == coreName { if len(subsystem.TrustZone) == 0 { @@ -111,7 +104,7 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error { } } } - err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, context, params) + err := writeMXdeviceH(contextMap, workDir, path.Join(contextFolder, mainFolder), mspName, cfgPath, context, params) if err != nil { return err } @@ -147,7 +140,20 @@ func createContextMap(iocFile string) (map[string]map[string]string, error) { return contextMap, nil } -func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp string, cfgPath string, context string, params cbuild.ParamsType) error { +func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, mainFolder string, mspName string, cfgPath string, context string, params cbuild.ParamsType) error { + workDirAbs, err := filepath.Abs(workDir) + if err != nil { + return err + } + + main := path.Join(workDirAbs, mainFolder, "main.c") + fMain, err := os.Open(main) + if err != nil { + return err + } + defer fMain.Close() + + msp := path.Join(workDirAbs, mainFolder, mspName) fMsp, err := os.Open(msp) if err != nil { return err @@ -181,11 +187,15 @@ func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp } for _, peripheral := range peripherals { vmode := getVirtualMode(contextMap, peripheral) + i2cInfo, err := getI2cInfo(fMain, peripheral) + if err != nil { + return err + } pins, err := getPins(contextMap, fMsp, peripheral) if err != nil { return err } - err = mxDeviceWritePeripheralCfg(out, peripheral, vmode, pins) + err = mxDeviceWritePeripheralCfg(out, peripheral, vmode, i2cInfo, pins) if err != nil { return err } @@ -361,6 +371,46 @@ func getDigitAtEnd(pin string) string { return "" } +// Get i2c info (filter, coefficients) +func getI2cInfo(fMain *os.File, peripheral string) (map[string]string, error) { + info := make(map[string]string) + if strings.HasPrefix(peripheral, "I2C") { + _, err := fMain.Seek(0, 0) + if err != nil { + return nil, err + } + section := false + + mainScan := bufio.NewScanner(fMain) + mainScan.Split(bufio.ScanLines) + for mainScan.Scan() { + line := mainScan.Text() + if !section { + if strings.HasPrefix(line, "static void MX_"+peripheral+"_Init") && !strings.Contains(line, ";") { + section = true // Start of section: static void MX_I2Cx_Init + } + } else { // Parse section: static void MX_I2Cx_Init + if strings.HasPrefix(line, "}") { + break // End of section: static void MX_I2Cx_Init + } + if strings.Contains(line, "HAL_I2CEx_ConfigAnalogFilter") { + if strings.Contains(line, "I2C_ANALOGFILTER_ENABLE") { + info["ANF_ENABLE"] = "1" + } else { + info["ANF_ENABLE"] = "0" + } + } + if strings.Contains(line, "HAL_I2CEx_ConfigDigitalFilter") { + dnf := strings.Split(strings.Split(line, ",")[1], ")")[0] + dnf = strings.TrimRight(strings.TrimLeft(dnf, "\t "), "\t ") + info["DNF"] = dnf + } + } + } + } + return info, nil +} + func getPinConfiguration(fMsp *os.File, peripheral string, pin string, label string) (PinDefinition, error) { var pinInfo PinDefinition @@ -473,19 +523,33 @@ func mxDeviceWriteHeader(out *bufio.Writer, fName string) error { return err } -func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode string, pins map[string]PinDefinition) error { +func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode string, i2cInfo map[string]string, pins map[string]PinDefinition) error { + var err error + str := "\n/*------------------------------ " + peripheral if len(str) < 49 { str += strings.Repeat(" ", 49-len(str)) } str += "-----------------------------*/\n" - _, err := out.WriteString(str) - if err != nil { + if _, err = out.WriteString(str); err != nil { return err } if err = writeDefine(out, peripheral, "1\n"); err != nil { return err } + if i2cInfo != nil { + if _, err = out.WriteString("/* Filter Settings */\n"); err != nil { + return err + } + for item, value := range i2cInfo { + if err = writeDefine(out, peripheral + "_" + item, value); err != nil { + return err + } + } + if _, err = out.WriteString("\n"); err != nil { + return err + } + } if vmode != "" { if _, err = out.WriteString("/* Virtual mode */\n"); err != nil { return err @@ -498,13 +562,11 @@ func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode stri } } if len(pins) != 0 { - _, err = out.WriteString("/* Pins */\n") - if err != nil { + if _, err = out.WriteString("/* Pins */\n"); err != nil { return err } for pin, pinDef := range pins { - _, err = out.WriteString("\n/* " + pin + " */\n") - if err != nil { + if _, err = out.WriteString("\n/* " + pin + " */\n"); err != nil { return err } if err = writeDefine(out, pin+"_Pin", pinDef.p); err != nil { diff --git a/internal/stm32CubeMX/mxDevice_test.go b/internal/stm32CubeMX/mxDevice_test.go index e4b2b4a..836e51e 100644 --- a/internal/stm32CubeMX/mxDevice_test.go +++ b/internal/stm32CubeMX/mxDevice_test.go @@ -59,13 +59,15 @@ func Test_writeMXdeviceH(t *testing.T) { var mcuContext1 = make(map[string]map[string]string) mcuContext1["Mcu"] = map[string]string{"IPs": "myContext"} var mcuContext2 = make(map[string]map[string]string) - mcuContext2["Mcu"] = map[string]string{"IPs": "IP1"} - mcuContext2["IP1"] = map[string]string{"IPs": "SPI2"} + mcuContext2["Mcu"] = map[string]string{"IP1": "SPI2"} + mcuContext2["SPI2"] = map[string]string{"VirtualModex": "ModeX"} + mcuContext2["P1"] = map[string]string{"Signal": "SPI2"} type args struct { contextMap map[string]map[string]string workDir string - msp string + mainFolder string + mspName string cfgPath string context string params cbuild.ParamsType @@ -75,16 +77,16 @@ func Test_writeMXdeviceH(t *testing.T) { args args wantErr bool }{ - {"Mcu", args{mcuContext2, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "Mcu", cbuild.ParamsType{}}, false}, - {"wrong context", args{mcuContext0, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "context", cbuild.ParamsType{}}, true}, - {"Mcu Context", args{mcuContext1, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "Mcu", cbuild.ParamsType{}}, false}, - {"wrong myContext", args{mcuContext1, "work", "../../testdata/stm32cubemx/test_msp.c", "../../testdata/cfg", "context", cbuild.ParamsType{}}, true}, - {"wrong msp", args{mcuContext1, "work", "msp", "cfg", "context", cbuild.ParamsType{}}, true}, + {"Mcu", args{mcuContext2, "../../testdata/stm32cubemx", "", "test_msp.c", "cfg", "", cbuild.ParamsType{}}, false}, + {"wrong context", args{mcuContext0, "../../testdata/stm32cubemx", "", "test_msp.c", "cfg", "context", cbuild.ParamsType{}}, true}, + {"Mcu Context", args{mcuContext1, "../../testdata/stm32cubemx", "", "test_msp.c", "cfg", "Mcu", cbuild.ParamsType{}}, false}, + {"wrong myContext", args{mcuContext1, "../../testdata/stm32cubemx", "", "test_msp.c", "cfg", "context", cbuild.ParamsType{}}, true}, + {"wrong msp", args{mcuContext1, "", "", "msp", "cfg", "context", cbuild.ParamsType{}}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - defer os.RemoveAll(tt.args.cfgPath) - if err := writeMXdeviceH(tt.args.contextMap, tt.args.workDir, tt.args.msp, tt.args.cfgPath, tt.args.context, tt.args.params); (err != nil) != tt.wantErr { + defer os.RemoveAll(tt.args.workDir + "/../" + tt.args.cfgPath) + if err := writeMXdeviceH(tt.args.contextMap, tt.args.workDir, tt.args.mainFolder, tt.args.mspName, tt.args.cfgPath, tt.args.context, tt.args.params); (err != nil) != tt.wantErr { t.Errorf("writeMXdeviceH() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) } }) @@ -179,7 +181,7 @@ func Test_getDeviceFamily(t *testing.T) { } func Test_getPeripherals(t *testing.T) { - // t.Parallel() + t.Parallel() var parts = make(map[string]map[string]string) parts["Mcu"] = map[string]string{"IP1": "UART", "IP2": "xx", "IP3": "USB"} @@ -215,7 +217,7 @@ func Test_getPeripherals(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - // t.Parallel() + t.Parallel() got, err := getPeripherals(tt.args.contextMap, tt.args.context) if (err != nil) != tt.wantErr { t.Errorf("getPeripherals() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) @@ -329,6 +331,8 @@ func Test_replaceSpecialChars(t *testing.T) { } func Test_getDigitAtEnd(t *testing.T) { + t.Parallel() + type args struct { pin string } @@ -343,7 +347,9 @@ func Test_getDigitAtEnd(t *testing.T) { {"test4", args{"12"}, "12"}, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() if got := getDigitAtEnd(tt.args.pin); got != tt.want { t.Errorf("getDigitAtEnd() = %v, want %v", got, tt.want) } @@ -512,6 +518,7 @@ func Test_mxDeviceWritePeripheralCfg(t *testing.T) { out *bufio.Writer peripheral string vmode string + i2cInfo map[string]string pins map[string]PinDefinition } tests := []struct { @@ -533,7 +540,7 @@ func Test_mxDeviceWritePeripheralCfg(t *testing.T) { t.Run(tt.name, func(t *testing.T) { tt.args.out = bufio.NewWriter(&b) - if err := mxDeviceWritePeripheralCfg(tt.args.out, tt.args.peripheral, tt.args.vmode, tt.args.pins); (err != nil) != tt.wantErr { + if err := mxDeviceWritePeripheralCfg(tt.args.out, tt.args.peripheral, tt.args.vmode, tt.args.i2cInfo, tt.args.pins); (err != nil) != tt.wantErr { t.Errorf("mxDeviceWritePeripheralCfg() error = %v, wantErr %v", err, tt.wantErr) } tt.args.out.Flush() diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index cb7cce3..b10cdf2 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -4,65 +4,157 @@ * SPDX-License-Identifier: Apache-2.0 */ -package utils_test +package utils import ( + "os" + "reflect" "testing" - - "github.com/open-cmsis-pack/generator-bridge/internal/utils" - "github.com/stretchr/testify/assert" ) -//var testDir string = "./Testing" - -func TestAddLine(t *testing.T) { - var text utils.TextBuilder - - text.AddLine("A line") - expected := "A line\n" - result := text.GetLine() - assert.Equal(t, expected, result) - - text.AddLine("A second line") - result = text.GetLine() - expected += "A second line\n" - assert.Equal(t, expected, result) +func TestAddQuotes(t *testing.T) { + type args struct { + text string + } + tests := []struct { + name string + args args + want string + }{ + {"test", args{"Test"}, "\"Test\""}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := AddQuotes(tt.args.text); got != tt.want { + t.Errorf("AddQuotes() = %v, want %v", got, tt.want) + } + }) + } } -func TestAddQuotes(t *testing.T) { - text := "Test" - expected := "\"" + text + "\"" - result := utils.AddQuotes(text) - assert.Equal(t, expected, result) +func TestTextBuilder_AddLine(t *testing.T) { + var builder TextBuilder + var builder1 TextBuilder + var builder2 TextBuilder + + type args struct { + args []string + } + tests := []struct { + name string + tr *TextBuilder + args args + want string + }{ + {"nix", &builder, args{}, "\n"}, + {"1", &builder1, args{[]string{"A line"}}, "A line\n"}, + {"1+", &builder2, args{[]string{"A line", "and more"}}, "A line and more\n"}, + {"2", &builder1, args{[]string{"A second line"}}, "A line\nA second line\n"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.tr.AddLine(tt.args.args...) + if !reflect.DeepEqual(tt.tr.GetLine(), tt.want) { + t.Errorf("TestTextBuilder_AddLine() %s got = %v, want %v", tt.name, tt.tr.GetLine(), tt.want) + } + }) + } } -/* Test runs when "Debug" but fails in "Run" func TestFileExists(t *testing.T) { + t.Parallel() + type args struct { + filePath string + } + tests := []struct { + name string + args args + want bool + }{ + {"file", args{"../../testdata/test.yml"}, true}, + {"dir", args{"../../testdata"}, false}, + {"nix", args{"../../testdata/nix"}, false}, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + if got := FileExists(tt.args.filePath); got != tt.want { + t.Errorf("FileExists() %s = %v, want %v", tt.name, got, tt.want) + } + }) + } +} - result := utils.DirExists(testDir) - expected := false - assert.Equal(t, expected, result) - - filename := filepath.Join(testDir, "fileexists.txt") - result = utils.FileExists(filename) - expected = false - assert.Equal(t, expected, result) - - err := os.Mkdir(testDir, 0755) - assert.Equal(t, nil, err) - - result = utils.DirExists(testDir) - expected = true - assert.Equal(t, expected, result) - - text := "Hello, World" - err = os.WriteFile(filename, []byte(text), 0755) - assert.NotEqual(t, nil, err) +func TestDirExists(t *testing.T) { + type args struct { + dirPath string + } + tests := []struct { + name string + args args + want bool + }{ + {"file", args{"../../testdata/test.yml"}, false}, + {"dir", args{"../../testdata"}, true}, + {"nix", args{"../../testdata/nix"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := DirExists(tt.args.dirPath); got != tt.want { + t.Errorf("DirExists() %s = %v, want %v", tt.name, got, tt.want) + } + }) + } +} - result = utils.FileExists(filename) - expected = true - assert.Equal(t, expected, result) +func TestEnsureDir(t *testing.T) { + type args struct { + dirName string + } + tests := []struct { + name string + args args + remove string + wantErr bool + }{ + {"test", args{"../../testdata/1/2/3"}, "../../testdata/1", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer os.RemoveAll(tt.remove) + if err := EnsureDir(tt.args.dirName); (err != nil) != tt.wantErr { + t.Errorf("EnsureDir() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + } + }) + } +} - os.RemoveAll(testDir) +func TestConvertFilename(t *testing.T) { + type args struct { + outPath string + file string + relativePathAdd string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + {"test", args{"../../testdata", "test.ioc", "stm32cubemx"}, "./stm32cubemx/test.ioc", false}, + {"nix", args{"../../testdata", "nix", "stm32cubemx"}, "./stm32cubemx/nix", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertFilename(tt.args.outPath, tt.args.file, tt.args.relativePathAdd) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertFilename() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("ConvertFilename() %s = %v, want %v", tt.name, got, tt.want) + } + }) + } } -*/ diff --git a/testdata/stm32cubemx/main.c b/testdata/stm32cubemx/main.c new file mode 100644 index 0000000..b6167fe --- /dev/null +++ b/testdata/stm32cubemx/main.c @@ -0,0 +1,14 @@ +static void MX_I2C1_Init(void) +{ + if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Digital filter + */ + if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/testdata/test.yml b/testdata/test.yml new file mode 100644 index 0000000..7c12317 --- /dev/null +++ b/testdata/test.yml @@ -0,0 +1,2 @@ +test: + - xx: abc From 533190078a2575de36001956845ca52d99495ca8 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Fri, 2 Feb 2024 20:44:58 +0100 Subject: [PATCH 12/18] changed formatting --- internal/common/common_test.go | 8 +++++--- internal/stm32CubeMX/iniReader_test.go | 6 +++--- internal/stm32CubeMX/mxDevice.go | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/internal/common/common_test.go b/internal/common/common_test.go index 5fb3191..4b56142 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -17,9 +17,11 @@ func TestReadYml(t *testing.T) { Xx string `yaml:"xx"` } `yaml:"test"` } - var testyml TestYml + var testyml TestYml - t1 := TestYml{Test: []struct{Xx string `yaml:"xx"`}{{Xx: "abc"}}} + t1 := TestYml{Test: []struct { + Xx string `yaml:"xx"` + }{{Xx: "abc"}}} type args struct { path string @@ -28,7 +30,7 @@ func TestReadYml(t *testing.T) { tests := []struct { name string args args - want TestYml + want TestYml wantErr bool }{ {"test", args{"../../testdata/test.yml", &testyml}, t1, false}, diff --git a/internal/stm32CubeMX/iniReader_test.go b/internal/stm32CubeMX/iniReader_test.go index 54780bc..eac384c 100644 --- a/internal/stm32CubeMX/iniReader_test.go +++ b/internal/stm32CubeMX/iniReader_test.go @@ -9,14 +9,14 @@ package stm32cubemx func ExamplePrintKeyValStr() { PrintKeyValStr("key", "val") // Output: - // + // // key : val } func ExamplePrintKeyValStrs() { PrintKeyValStrs("key", []string{"val1", "val2"}) // Output: - // + // // key // 0: val1 // 1: val2 @@ -25,6 +25,6 @@ func ExamplePrintKeyValStrs() { func ExamplePrintKeyValInt() { PrintKeyValInt("key", 4711) // Output: - // + // // key : 4711 } diff --git a/internal/stm32CubeMX/mxDevice.go b/internal/stm32CubeMX/mxDevice.go index 7d65f32..29e6eaf 100644 --- a/internal/stm32CubeMX/mxDevice.go +++ b/internal/stm32CubeMX/mxDevice.go @@ -373,7 +373,7 @@ func getDigitAtEnd(pin string) string { // Get i2c info (filter, coefficients) func getI2cInfo(fMain *os.File, peripheral string) (map[string]string, error) { - info := make(map[string]string) + info := make(map[string]string) if strings.HasPrefix(peripheral, "I2C") { _, err := fMain.Seek(0, 0) if err != nil { @@ -408,7 +408,7 @@ func getI2cInfo(fMain *os.File, peripheral string) (map[string]string, error) { } } } - return info, nil + return info, nil } func getPinConfiguration(fMsp *os.File, peripheral string, pin string, label string) (PinDefinition, error) { @@ -542,7 +542,7 @@ func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode stri return err } for item, value := range i2cInfo { - if err = writeDefine(out, peripheral + "_" + item, value); err != nil { + if err = writeDefine(out, peripheral+"_"+item, value); err != nil { return err } } From e7e69941cb24cb107d109b1b50a8d7408a685909 Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Fri, 2 Feb 2024 21:38:00 +0100 Subject: [PATCH 13/18] tried to fix a lint problem --- internal/common/common_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/common/common_test.go b/internal/common/common_test.go index 4b56142..de1f0f8 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -40,7 +40,8 @@ func TestReadYml(t *testing.T) { if err := ReadYml(tt.args.path, tt.args.out); (err != nil) != tt.wantErr { t.Errorf("ReadYml() %s error = %v, wantErr %v", tt.name, err, tt.wantErr) } - if !reflect.DeepEqual(tt.args.out, &tt.want) { + xx := tt.want + if !reflect.DeepEqual(tt.args.out, &xx) { t.Errorf("ReadYml() %s got = %v, want %v", tt.name, tt.args.out, tt.want) } }) From ee055f49a25ad60fa1b801bf4e70914eb4a7e93c Mon Sep 17 00:00:00 2001 From: Sourabh Mehta Date: Sun, 4 Feb 2024 19:19:00 +0100 Subject: [PATCH 14/18] fixed publish coverage step --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7bb80b2..d06b077 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -168,3 +168,4 @@ jobs: with: debug: true coverageLocations: ./cover.out:gocov + prefix: github.com/Open-CMSIS-Pack/generator-bridge From b0fc4f1ef0eecc414da800303ec3df2dd6e24308 Mon Sep 17 00:00:00 2001 From: Sourabh Mehta Date: Sun, 4 Feb 2024 19:27:27 +0100 Subject: [PATCH 15/18] fixed publish coverage step --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d06b077..76c0bb8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -168,4 +168,4 @@ jobs: with: debug: true coverageLocations: ./cover.out:gocov - prefix: github.com/Open-CMSIS-Pack/generator-bridge + prefix: github.com/open-cmsis-pack/generator-bridge From 1f30ae6dfa9238684f3f8109eb7694baa2ac096f Mon Sep 17 00:00:00 2001 From: Bernd-Gunter Nitzler Date: Wed, 14 Feb 2024 17:29:27 +0100 Subject: [PATCH 16/18] added output of command line commented out reading of packs fro cbuild-gen.yml --- cmd/main.go | 2 ++ internal/cbuild/cbuild.go | 18 +++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 45948bf..654ff77 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -22,6 +22,8 @@ func main() { utils.StartSignalWatcher() start := time.Now() + log.Println("Command line:", os.Args[1:]) + commands.Version = version commands.Copyright = copyright cmd := commands.NewCli() diff --git a/internal/cbuild/cbuild.go b/internal/cbuild/cbuild.go index 2556522..5817851 100644 --- a/internal/cbuild/cbuild.go +++ b/internal/cbuild/cbuild.go @@ -40,7 +40,7 @@ type SubsystemType struct { Compiler string TrustZone string CoreName string - Packs []PackType + // Packs []PackType } type ParamsType struct { @@ -286,14 +286,14 @@ func ReadCbuildgen(name string, subsystem *SubsystemType) error { log.Infof("Found CBuildGen: board: %v, device: %v, core: %v, TZ: %v, compiler: %v, project: %v", subsystem.Board, subsystem.Device, subsystem.CoreName, subsystem.TrustZone, subsystem.Compiler, subsystem.Project) - for id := range cbuildGen.BuildGen.Packs { - genPack := cbuildGen.BuildGen.Packs[id] - var pack PackType - pack.Pack = genPack.Pack - pack.Path = genPack.Path - log.Infof("Found Pack: #%v Pack: %v, Path: %v", id, pack.Pack, pack.Path) - subsystem.Packs = append(subsystem.Packs, pack) - } + // for id := range cbuildGen.BuildGen.Packs { + // genPack := cbuildGen.BuildGen.Packs[id] + // var pack PackType + // pack.Pack = genPack.Pack + // pack.Path = genPack.Path + // log.Infof("Found Pack: #%v Pack: %v, Path: %v", id, pack.Pack, pack.Path) + // subsystem.Packs = append(subsystem.Packs, pack) + // } return nil } From 16a10cb0f15a50924a9aa49b276d05784e6ef9bc Mon Sep 17 00:00:00 2001 From: David Lesnjak Date: Wed, 13 Mar 2024 16:38:09 +0100 Subject: [PATCH 17/18] Added support for GCC, CLAN and IAR compiler. Added startup, system and linker files (generated by CubeMX) to cgen.yml. (#32) --- internal/readFile/readFile.go | 2 +- internal/stm32CubeMX/iniReader.go | 41 +++- internal/stm32CubeMX/stm32CubeMX.go | 336 ++++++++++++++++++++++++++-- internal/utils/utils.go | 26 ++- 4 files changed, 377 insertions(+), 28 deletions(-) diff --git a/internal/readFile/readFile.go b/internal/readFile/readFile.go index 42350b1..d2749fe 100644 --- a/internal/readFile/readFile.go +++ b/internal/readFile/readFile.go @@ -54,7 +54,7 @@ func Process(inFile, inFile2, outPath string) error { } if mxprojectFile != "" { - mxprojectAll, _ := stm32cubemx.IniReader(mxprojectFile, false) + mxprojectAll, _ := stm32cubemx.IniReader(mxprojectFile, params.Subsystem[0].Compiler, false) if params.Board == "" && params.Device == "" { params.Board = "Test Board" diff --git a/internal/stm32CubeMX/iniReader.go b/internal/stm32CubeMX/iniReader.go index a16757f..3037288 100644 --- a/internal/stm32CubeMX/iniReader.go +++ b/internal/stm32CubeMX/iniReader.go @@ -30,7 +30,7 @@ type MxprojectType struct { PreviousLibFiles struct { LibFiles []string } - PreviousUsedKeilFiles struct { + PreviousUsedFiles struct { SourceFiles []string HeaderPath []string CDefines []string @@ -191,7 +191,7 @@ func AppendToCores(iniSectionCore IniSectionCore, list *[]IniSectionCore) { *list = append(*list, iniSectionCore) } -func IniReader(path string, trustzone bool) (MxprojectAllType, error) { +func IniReader(path string, compiler string, trustzone bool) (MxprojectAllType, error) { var mxprojectAll MxprojectAllType if !utils.FileExists(path) { @@ -221,7 +221,7 @@ func IniReader(path string, trustzone bool) (MxprojectAllType, error) { } coreName := core.CoreName trustzone := core.trustzone - mxproject, _ := GetData(inidata, iniName) + mxproject, _ := GetData(inidata, iniName, compiler) mxproject.CoreName = coreName mxproject.Trustzone = trustzone mxprojectAll.Mxproject = append(mxprojectAll.Mxproject, mxproject) @@ -286,20 +286,26 @@ func GetSections(inidata *ini.File, iniSections *IniSectionsType) error { return nil } -func GetData(inidata *ini.File, iniName string) (MxprojectType, error) { +func GetData(inidata *ini.File, iniName string, compiler string) (MxprojectType, error) { var mxproject MxprojectType var sectionName string - const PreviousUsedKeilFilesID = "PreviousUsedKeilFiles" + var PreviousUsedFilesID string + + PreviousUsedFilesID, err := GetPreviousUsedFilesID(compiler) + if err != nil { + return mxproject, err + } + if iniName != "" { - sectionName = iniName + ":" + PreviousUsedKeilFilesID + sectionName = iniName + ":" + PreviousUsedFilesID } else { - sectionName = PreviousUsedKeilFilesID + sectionName = PreviousUsedFilesID } section := inidata.Section(sectionName) if section != nil { - StoreItemCsv(&mxproject.PreviousUsedKeilFiles.SourceFiles, section, "SourceFiles") - StoreItemCsv(&mxproject.PreviousUsedKeilFiles.HeaderPath, section, "HeaderPath") - StoreItemCsv(&mxproject.PreviousUsedKeilFiles.CDefines, section, "CDefines") + StoreItemCsv(&mxproject.PreviousUsedFiles.SourceFiles, section, "SourceFiles") + StoreItemCsv(&mxproject.PreviousUsedFiles.HeaderPath, section, "HeaderPath") + StoreItemCsv(&mxproject.PreviousUsedFiles.CDefines, section, "CDefines") PrintItemCsv(section, "SourceFiles") PrintItemCsv(section, "HeaderPath") PrintItemCsv(section, "CDefines") @@ -346,3 +352,18 @@ func GetData(inidata *ini.File, iniName string) (MxprojectType, error) { return mxproject, nil } + +func GetPreviousUsedFilesID(compiler string) (string, error) { + var sectionMapping = map[string]string{ + "AC6": "PreviousUsedKeilFiles", + "GCC": "PreviousUsedCubeIDEFiles", + "IAR": "PreviousUsedIarFiles", + "CLANG": "PreviousUsedCubeIDEFiles", + } + + PreviousUsedFilesID, ok := sectionMapping[compiler] + if !ok { + return "", errors.New("unknown compiler") + } + return PreviousUsedFilesID, nil +} diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index 0992af0..ebb08cd 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -115,7 +115,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx tmpPath, _ := filepath.Split(cubeIocPath) mxprojectPath = path.Join(tmpPath, ".mxproject") } - mxproject, err := IniReader(mxprojectPath, false) + mxproject, err := IniReader(mxprojectPath, parms.Subsystem[0].Compiler, false) if err != nil { return err } @@ -167,7 +167,12 @@ func WriteProjectFile(workDir string, parms *cbuild.ParamsType) (string, error) text.AddLine("load", parms.Device) } text.AddLine("project name", "STM32CubeMX") - text.AddLine("project toolchain", utils.AddQuotes("MDK-ARM V5")) + + toolchain, err := GetToolchain(parms.Subsystem[0].Compiler) + if err != nil { + return "", err + } + text.AddLine("project toolchain", utils.AddQuotes(toolchain)) cubeWorkDir := workDir if runtime.GOOS == "windows" { @@ -180,7 +185,7 @@ func WriteProjectFile(workDir string, parms *cbuild.ParamsType) (string, error) os.Remove(filePath) } - err := os.WriteFile(filePath, []byte(text.GetLine()), 0600) + err = os.WriteFile(filePath, []byte(text.GetLine()), 0600) if err != nil { return "", err } @@ -205,8 +210,9 @@ func ReadGeneratorYmlFile(path string, parms *generator.ParamsType) error { } var filterFiles = map[string]string{ - "system_": "system_ file (delivered from elsewhere)", - "Templates": "Templates file (mostly not present)", + "system_": "system_ file (already added)", + "Templates": "Templates file (mostly not present)", + "/STM32CubeMX/Drivers/CMSIS/Include": "CMSIS include folder (delivered by ARM::CMSIS)", } func FilterFile(file string) bool { @@ -265,19 +271,20 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. outFile := path.Join(outPath, outName) var cgen cbuild.CgenType - lastPath := filepath.Base(outPath) - var relativePathAdd string - if lastPath != "STM32CubeMX" { - relativePathAdd = path.Join(relativePathAdd, "STM32CubeMX") + relativePathAdd, err := GetRelativePathAdd(outPath, subsystem.Compiler) + if err != nil { + return err } - relativePathAdd = path.Join(relativePathAdd, "MDK-ARM") cgen.GeneratorImport.ForBoard = subsystem.Board cgen.GeneratorImport.ForDevice = subsystem.Device - cgen.GeneratorImport.Define = append(cgen.GeneratorImport.Define, mxproject.PreviousUsedKeilFiles.CDefines...) + cgen.GeneratorImport.Define = append(cgen.GeneratorImport.Define, mxproject.PreviousUsedFiles.CDefines...) - for _, headerPath := range mxproject.PreviousUsedKeilFiles.HeaderPath { + for _, headerPath := range mxproject.PreviousUsedFiles.HeaderPath { headerPath, _ = utils.ConvertFilename(outPath, headerPath, relativePathAdd) + if FilterFile(headerPath) { + continue + } cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, headerPath) } @@ -290,15 +297,14 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. var groupTz cbuild.CgenGroupsType groupSrc.Group = "CubeMX" - groupHalDriver.Group = "HAL Driver" + groupHalDriver.Group = "STM32 HAL Driver" groupHalFilter := "HAL_Driver" - for _, file := range mxproject.PreviousUsedKeilFiles.SourceFiles { + for _, file := range mxproject.PreviousUsedFiles.SourceFiles { if FilterFile(file) { continue } file, _ = utils.ConvertFilename(outPath, file, relativePathAdd) - if strings.Contains(file, groupHalFilter) { var cgenFile cbuild.CgenFilesType cgenFile.File = file @@ -310,6 +316,43 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. } } + var cgenFile cbuild.CgenFilesType + startupFile, err := GetStartupFile(outPath, subsystem) + if err != nil { + return err + } + startupFile, err = utils.ConvertFilenameRel(outPath, startupFile) + if err != nil { + return err + } + cgenFile.File = startupFile + groupSrc.Files = append(groupSrc.Files, cgenFile) + + systemFile, err := GetSystemFile(outPath, subsystem) + if err != nil { + return err + } + systemFile, err = utils.ConvertFilenameRel(outPath, systemFile) + if err != nil { + return err + } + cgenFile.File = systemFile + groupSrc.Files = append(groupSrc.Files, cgenFile) + + linkerFiles, err := GetLinkerScripts(outPath, subsystem) + if err != nil { + return err + } + for _, file := range linkerFiles { + file, err = utils.ConvertFilenameRel(outPath, file) + if err != nil { + return err + } + var cgenFile cbuild.CgenFilesType + cgenFile.File = file + groupSrc.Files = append(groupSrc.Files, cgenFile) + } + cgen.GeneratorImport.Groups = append(cgen.GeneratorImport.Groups, groupSrc) cgen.GeneratorImport.Groups = append(cgen.GeneratorImport.Groups, groupHalDriver) @@ -325,3 +368,266 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. return common.WriteYml(outFile, &cgen) } + +func GetToolchain(compiler string) (string, error) { + var toolchainMapping = map[string]string{ + "AC6": "MDK-ARM V5", + "GCC": "STM32CubeIDE", + "IAR": "EWARM", + "CLANG": "STM32CubeIDE", + } + + toolchain, ok := toolchainMapping[compiler] + if !ok { + return "", errors.New("unknown compiler") + } + return toolchain, nil +} + +func GetRelativePathAdd(outPath string, compiler string) (string, error) { + var pathMapping = map[string]string{ + "AC6": "MDK-ARM", + "GCC": "", + "IAR": "EWARM", + "CLANG": "", + } + + folder, ok := pathMapping[compiler] + if !ok { + return "", errors.New("unknown compiler") + } + + lastPath := filepath.Base(outPath) + var relativePathAdd string + if lastPath != "STM32CubeMX" { + relativePathAdd = path.Join(relativePathAdd, "STM32CubeMX") + } + relativePathAdd = path.Join(relativePathAdd, folder) + + return relativePathAdd, nil +} + +func GetToolchainFolderPath(outPath string, compiler string) (string, error) { + var toolchainFolderMapping = map[string]string{ + "AC6": "MDK-ARM", + "GCC": "STM32CubeIDE", + "IAR": "EWARM", + "CLANG": "STM32CubeIDE", + } + + toolchainFolder, ok := toolchainFolderMapping[compiler] + if !ok { + return "", errors.New("unknown compiler") + } + + lastPath := filepath.Base(outPath) + toolchainFolderPath := outPath + if lastPath != "STM32CubeMX" { + toolchainFolderPath = path.Join(outPath, "STM32CubeMX") + } + toolchainFolderPath = path.Join(toolchainFolderPath, toolchainFolder) + + return toolchainFolderPath, nil +} + +func GetStartupFile(outPath string, subsystem *cbuild.SubsystemType) (string, error) { + var startupFolder string + var fileExtesion string + var fileFilter string + + startupFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) + if err != nil { + return "", err + } + + fileExtesion = ".s" + switch subsystem.Compiler { + case "AC6", "IAR": + if subsystem.SubsystemIdx.ProjectType == "multi-core" { + fileFilter = "_" + subsystem.SubsystemIdx.ForProjectPart + } + + case "GCC", "CLANG": + switch subsystem.SubsystemIdx.ProjectType { + case "multi-core": + startupFolder = path.Join(startupFolder, subsystem.SubsystemIdx.ForProjectPart) + case "trustzone": + if subsystem.SubsystemIdx.ForProjectPart == "secure" { + startupFolder = path.Join(startupFolder, "Secure") + } + if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { + startupFolder = path.Join(startupFolder, "NonSecure") + } + } + startupFolder = path.Join(startupFolder, "Application") + startupFolder = path.Join(startupFolder, "Startup") + + default: + return "", errors.New("unknown compiler") + } + + if !utils.DirExists(startupFolder) { + errorString := "Directory not found: " + startupFolder + log.Errorf(errorString) + return "", errors.New(errorString) + } + + var startupFile string + err = filepath.Walk(startupFolder, func(path string, f fs.FileInfo, err error) error { + if f.Mode().IsRegular() && + strings.HasSuffix(f.Name(), fileExtesion) && + strings.HasPrefix(f.Name(), "startup_") { + if fileFilter != "" { + if strings.Contains(f.Name(), fileFilter) { + startupFile = path + } + } else { + startupFile = path + } + } + return nil + }) + + if startupFile == "" { + errorString := "startup file not found" + log.Errorf(errorString) + return "", errors.New(errorString) + } + + return startupFile, err +} + +func GetSystemFile(outPath string, subsystem *cbuild.SubsystemType) (string, error) { + var toolchainFolder string + var systemFolder string + + toolchainFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) + if err != nil { + return "", err + } + + if subsystem.SubsystemIdx.ProjectType == "multi-core" { + systemFolder = filepath.Dir(toolchainFolder) + systemFolder = path.Join(systemFolder, "Common") + systemFolder = path.Join(systemFolder, "Src") + if !utils.DirExists(toolchainFolder) { + systemFolder = "" + } + } + + if systemFolder == "" { + systemFolder = filepath.Dir(toolchainFolder) + switch subsystem.SubsystemIdx.ProjectType { + case "multi-core": + systemFolder = path.Join(systemFolder, subsystem.SubsystemIdx.ForProjectPart) + case "trustzone": + if subsystem.SubsystemIdx.ForProjectPart == "secure" { + systemFolder = path.Join(systemFolder, "Secure") + } + if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { + systemFolder = path.Join(systemFolder, "NonSecure") + } + } + systemFolder = path.Join(systemFolder, "Src") + } + + if !utils.DirExists(systemFolder) { + errorString := "Directory not found: " + systemFolder + log.Errorf(errorString) + return "", errors.New(errorString) + } + + var systemFile string + err = filepath.Walk(systemFolder, func(path string, f fs.FileInfo, err error) error { + if f.Mode().IsRegular() && + strings.HasPrefix(f.Name(), "system_stm32") && + strings.HasSuffix(f.Name(), ".c") { + systemFile = path + } + return nil + }) + + if systemFile == "" { + errorString := "system file not found" + log.Errorf(errorString) + return "", errors.New(errorString) + } + + return systemFile, err +} + +func GetLinkerScripts(outPath string, subsystem *cbuild.SubsystemType) ([]string, error) { + var linkerFolder string + var fileExtesion string + var fileFilter string + + linkerFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) + if err != nil { + return nil, err + } + + switch subsystem.Compiler { + case "AC6": + fileExtesion = ".sct" + case "IAR": + fileExtesion = ".icf" + case "GCC", "CLANG": + fileExtesion = ".ld" + default: + return nil, errors.New("unknown compiler") + } + + switch subsystem.Compiler { + case "AC6", "IAR": + switch subsystem.SubsystemIdx.ProjectType { + case "single-core": + fileFilter = "" + case "multi-core": + fileFilter = "_" + subsystem.SubsystemIdx.ForProjectPart + case "trustzone": + if subsystem.SubsystemIdx.ForProjectPart == "secure" { + fileFilter = "_s." + } + if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { + fileFilter = "_ns." + } + } + + case "GCC", "CLANG": + switch subsystem.SubsystemIdx.ProjectType { + case "multi-core": + linkerFolder = path.Join(linkerFolder, subsystem.SubsystemIdx.ForProjectPart) + case "trustzone": + if subsystem.SubsystemIdx.ForProjectPart == "secure" { + linkerFolder = path.Join(linkerFolder, "Secure") + } + if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { + linkerFolder = path.Join(linkerFolder, "NonSecure") + } + } + default: + return nil, errors.New("unknown compiler") + } + + if !utils.DirExists(linkerFolder) { + errorString := "Directory not found: " + linkerFolder + log.Errorf(errorString) + return nil, errors.New(errorString) + } + + var linkerScripts []string + err = filepath.Walk(linkerFolder, func(path string, f fs.FileInfo, err error) error { + if f.Mode().IsRegular() && strings.HasSuffix(f.Name(), fileExtesion) { + if fileFilter != "" { + if strings.Contains(f.Name(), fileFilter) { + linkerScripts = append(linkerScripts, path) + } + } else { + linkerScripts = append(linkerScripts, path) + } + } + return nil + }) + + return linkerScripts, err +} diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 7e6cc77..798e777 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -70,8 +70,30 @@ func ConvertFilename(outPath, file, relativePathAdd string) (string, error) { file = filepath.Clean(file) file = filepath.ToSlash(file) - mdkarmPath := path.Join(outPath, relativePathAdd) // create the path where STCube sets it's files relative to (./STM32CubeMX/MDK-ARM/) - file = path.Join(mdkarmPath, file) + toolchainPath := path.Join(outPath, relativePathAdd) // create the path where STCube sets it's files relative to toolchain folder( example :./STM32CubeMX/MDK-ARM/) + file = path.Join(toolchainPath, file) + + if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { + log.Errorf("file or directory not found: %v", file) + } + + var err error + origfilename := file + file, err = filepath.Rel(outPath, file) + if err != nil { + log.Errorf("path error found: %v", file) + return origfilename, errors.New("path error") + } + + file = filepath.ToSlash(file) + file = "./" + file + + return file, nil +} + +func ConvertFilenameRel(outPath, file string) (string, error) { + file = filepath.Clean(file) + file = filepath.ToSlash(file) if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { log.Errorf("file or directory not found: %v", file) From 1576f171563bf245ce9708ef48ffafea11389538 Mon Sep 17 00:00:00 2001 From: Joachim Krech Date: Thu, 14 Mar 2024 07:41:22 +0100 Subject: [PATCH 18/18] =?UTF-8?q?Revert=20"Added=20support=20for=20GCC,=20?= =?UTF-8?q?CLAN=20and=20IAR=20compiler.=20Added=20startup,=20system=20a?= =?UTF-8?q?=E2=80=A6"=20(#36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 16a10cb0f15a50924a9aa49b276d05784e6ef9bc. --- internal/readFile/readFile.go | 2 +- internal/stm32CubeMX/iniReader.go | 41 +--- internal/stm32CubeMX/stm32CubeMX.go | 336 ++-------------------------- internal/utils/utils.go | 26 +-- 4 files changed, 28 insertions(+), 377 deletions(-) diff --git a/internal/readFile/readFile.go b/internal/readFile/readFile.go index d2749fe..42350b1 100644 --- a/internal/readFile/readFile.go +++ b/internal/readFile/readFile.go @@ -54,7 +54,7 @@ func Process(inFile, inFile2, outPath string) error { } if mxprojectFile != "" { - mxprojectAll, _ := stm32cubemx.IniReader(mxprojectFile, params.Subsystem[0].Compiler, false) + mxprojectAll, _ := stm32cubemx.IniReader(mxprojectFile, false) if params.Board == "" && params.Device == "" { params.Board = "Test Board" diff --git a/internal/stm32CubeMX/iniReader.go b/internal/stm32CubeMX/iniReader.go index 3037288..a16757f 100644 --- a/internal/stm32CubeMX/iniReader.go +++ b/internal/stm32CubeMX/iniReader.go @@ -30,7 +30,7 @@ type MxprojectType struct { PreviousLibFiles struct { LibFiles []string } - PreviousUsedFiles struct { + PreviousUsedKeilFiles struct { SourceFiles []string HeaderPath []string CDefines []string @@ -191,7 +191,7 @@ func AppendToCores(iniSectionCore IniSectionCore, list *[]IniSectionCore) { *list = append(*list, iniSectionCore) } -func IniReader(path string, compiler string, trustzone bool) (MxprojectAllType, error) { +func IniReader(path string, trustzone bool) (MxprojectAllType, error) { var mxprojectAll MxprojectAllType if !utils.FileExists(path) { @@ -221,7 +221,7 @@ func IniReader(path string, compiler string, trustzone bool) (MxprojectAllType, } coreName := core.CoreName trustzone := core.trustzone - mxproject, _ := GetData(inidata, iniName, compiler) + mxproject, _ := GetData(inidata, iniName) mxproject.CoreName = coreName mxproject.Trustzone = trustzone mxprojectAll.Mxproject = append(mxprojectAll.Mxproject, mxproject) @@ -286,26 +286,20 @@ func GetSections(inidata *ini.File, iniSections *IniSectionsType) error { return nil } -func GetData(inidata *ini.File, iniName string, compiler string) (MxprojectType, error) { +func GetData(inidata *ini.File, iniName string) (MxprojectType, error) { var mxproject MxprojectType var sectionName string - var PreviousUsedFilesID string - - PreviousUsedFilesID, err := GetPreviousUsedFilesID(compiler) - if err != nil { - return mxproject, err - } - + const PreviousUsedKeilFilesID = "PreviousUsedKeilFiles" if iniName != "" { - sectionName = iniName + ":" + PreviousUsedFilesID + sectionName = iniName + ":" + PreviousUsedKeilFilesID } else { - sectionName = PreviousUsedFilesID + sectionName = PreviousUsedKeilFilesID } section := inidata.Section(sectionName) if section != nil { - StoreItemCsv(&mxproject.PreviousUsedFiles.SourceFiles, section, "SourceFiles") - StoreItemCsv(&mxproject.PreviousUsedFiles.HeaderPath, section, "HeaderPath") - StoreItemCsv(&mxproject.PreviousUsedFiles.CDefines, section, "CDefines") + StoreItemCsv(&mxproject.PreviousUsedKeilFiles.SourceFiles, section, "SourceFiles") + StoreItemCsv(&mxproject.PreviousUsedKeilFiles.HeaderPath, section, "HeaderPath") + StoreItemCsv(&mxproject.PreviousUsedKeilFiles.CDefines, section, "CDefines") PrintItemCsv(section, "SourceFiles") PrintItemCsv(section, "HeaderPath") PrintItemCsv(section, "CDefines") @@ -352,18 +346,3 @@ func GetData(inidata *ini.File, iniName string, compiler string) (MxprojectType, return mxproject, nil } - -func GetPreviousUsedFilesID(compiler string) (string, error) { - var sectionMapping = map[string]string{ - "AC6": "PreviousUsedKeilFiles", - "GCC": "PreviousUsedCubeIDEFiles", - "IAR": "PreviousUsedIarFiles", - "CLANG": "PreviousUsedCubeIDEFiles", - } - - PreviousUsedFilesID, ok := sectionMapping[compiler] - if !ok { - return "", errors.New("unknown compiler") - } - return PreviousUsedFilesID, nil -} diff --git a/internal/stm32CubeMX/stm32CubeMX.go b/internal/stm32CubeMX/stm32CubeMX.go index ebb08cd..0992af0 100644 --- a/internal/stm32CubeMX/stm32CubeMX.go +++ b/internal/stm32CubeMX/stm32CubeMX.go @@ -115,7 +115,7 @@ func Process(cbuildYmlPath, outPath, cubeMxPath, mxprojectPath string, runCubeMx tmpPath, _ := filepath.Split(cubeIocPath) mxprojectPath = path.Join(tmpPath, ".mxproject") } - mxproject, err := IniReader(mxprojectPath, parms.Subsystem[0].Compiler, false) + mxproject, err := IniReader(mxprojectPath, false) if err != nil { return err } @@ -167,12 +167,7 @@ func WriteProjectFile(workDir string, parms *cbuild.ParamsType) (string, error) text.AddLine("load", parms.Device) } text.AddLine("project name", "STM32CubeMX") - - toolchain, err := GetToolchain(parms.Subsystem[0].Compiler) - if err != nil { - return "", err - } - text.AddLine("project toolchain", utils.AddQuotes(toolchain)) + text.AddLine("project toolchain", utils.AddQuotes("MDK-ARM V5")) cubeWorkDir := workDir if runtime.GOOS == "windows" { @@ -185,7 +180,7 @@ func WriteProjectFile(workDir string, parms *cbuild.ParamsType) (string, error) os.Remove(filePath) } - err = os.WriteFile(filePath, []byte(text.GetLine()), 0600) + err := os.WriteFile(filePath, []byte(text.GetLine()), 0600) if err != nil { return "", err } @@ -210,9 +205,8 @@ func ReadGeneratorYmlFile(path string, parms *generator.ParamsType) error { } var filterFiles = map[string]string{ - "system_": "system_ file (already added)", - "Templates": "Templates file (mostly not present)", - "/STM32CubeMX/Drivers/CMSIS/Include": "CMSIS include folder (delivered by ARM::CMSIS)", + "system_": "system_ file (delivered from elsewhere)", + "Templates": "Templates file (mostly not present)", } func FilterFile(file string) bool { @@ -271,20 +265,19 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. outFile := path.Join(outPath, outName) var cgen cbuild.CgenType - relativePathAdd, err := GetRelativePathAdd(outPath, subsystem.Compiler) - if err != nil { - return err + lastPath := filepath.Base(outPath) + var relativePathAdd string + if lastPath != "STM32CubeMX" { + relativePathAdd = path.Join(relativePathAdd, "STM32CubeMX") } + relativePathAdd = path.Join(relativePathAdd, "MDK-ARM") cgen.GeneratorImport.ForBoard = subsystem.Board cgen.GeneratorImport.ForDevice = subsystem.Device - cgen.GeneratorImport.Define = append(cgen.GeneratorImport.Define, mxproject.PreviousUsedFiles.CDefines...) + cgen.GeneratorImport.Define = append(cgen.GeneratorImport.Define, mxproject.PreviousUsedKeilFiles.CDefines...) - for _, headerPath := range mxproject.PreviousUsedFiles.HeaderPath { + for _, headerPath := range mxproject.PreviousUsedKeilFiles.HeaderPath { headerPath, _ = utils.ConvertFilename(outPath, headerPath, relativePathAdd) - if FilterFile(headerPath) { - continue - } cgen.GeneratorImport.AddPath = append(cgen.GeneratorImport.AddPath, headerPath) } @@ -297,14 +290,15 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. var groupTz cbuild.CgenGroupsType groupSrc.Group = "CubeMX" - groupHalDriver.Group = "STM32 HAL Driver" + groupHalDriver.Group = "HAL Driver" groupHalFilter := "HAL_Driver" - for _, file := range mxproject.PreviousUsedFiles.SourceFiles { + for _, file := range mxproject.PreviousUsedKeilFiles.SourceFiles { if FilterFile(file) { continue } file, _ = utils.ConvertFilename(outPath, file, relativePathAdd) + if strings.Contains(file, groupHalFilter) { var cgenFile cbuild.CgenFilesType cgenFile.File = file @@ -316,43 +310,6 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. } } - var cgenFile cbuild.CgenFilesType - startupFile, err := GetStartupFile(outPath, subsystem) - if err != nil { - return err - } - startupFile, err = utils.ConvertFilenameRel(outPath, startupFile) - if err != nil { - return err - } - cgenFile.File = startupFile - groupSrc.Files = append(groupSrc.Files, cgenFile) - - systemFile, err := GetSystemFile(outPath, subsystem) - if err != nil { - return err - } - systemFile, err = utils.ConvertFilenameRel(outPath, systemFile) - if err != nil { - return err - } - cgenFile.File = systemFile - groupSrc.Files = append(groupSrc.Files, cgenFile) - - linkerFiles, err := GetLinkerScripts(outPath, subsystem) - if err != nil { - return err - } - for _, file := range linkerFiles { - file, err = utils.ConvertFilenameRel(outPath, file) - if err != nil { - return err - } - var cgenFile cbuild.CgenFilesType - cgenFile.File = file - groupSrc.Files = append(groupSrc.Files, cgenFile) - } - cgen.GeneratorImport.Groups = append(cgen.GeneratorImport.Groups, groupSrc) cgen.GeneratorImport.Groups = append(cgen.GeneratorImport.Groups, groupHalDriver) @@ -368,266 +325,3 @@ func WriteCgenYmlSub(outPath string, mxproject MxprojectType, subsystem *cbuild. return common.WriteYml(outFile, &cgen) } - -func GetToolchain(compiler string) (string, error) { - var toolchainMapping = map[string]string{ - "AC6": "MDK-ARM V5", - "GCC": "STM32CubeIDE", - "IAR": "EWARM", - "CLANG": "STM32CubeIDE", - } - - toolchain, ok := toolchainMapping[compiler] - if !ok { - return "", errors.New("unknown compiler") - } - return toolchain, nil -} - -func GetRelativePathAdd(outPath string, compiler string) (string, error) { - var pathMapping = map[string]string{ - "AC6": "MDK-ARM", - "GCC": "", - "IAR": "EWARM", - "CLANG": "", - } - - folder, ok := pathMapping[compiler] - if !ok { - return "", errors.New("unknown compiler") - } - - lastPath := filepath.Base(outPath) - var relativePathAdd string - if lastPath != "STM32CubeMX" { - relativePathAdd = path.Join(relativePathAdd, "STM32CubeMX") - } - relativePathAdd = path.Join(relativePathAdd, folder) - - return relativePathAdd, nil -} - -func GetToolchainFolderPath(outPath string, compiler string) (string, error) { - var toolchainFolderMapping = map[string]string{ - "AC6": "MDK-ARM", - "GCC": "STM32CubeIDE", - "IAR": "EWARM", - "CLANG": "STM32CubeIDE", - } - - toolchainFolder, ok := toolchainFolderMapping[compiler] - if !ok { - return "", errors.New("unknown compiler") - } - - lastPath := filepath.Base(outPath) - toolchainFolderPath := outPath - if lastPath != "STM32CubeMX" { - toolchainFolderPath = path.Join(outPath, "STM32CubeMX") - } - toolchainFolderPath = path.Join(toolchainFolderPath, toolchainFolder) - - return toolchainFolderPath, nil -} - -func GetStartupFile(outPath string, subsystem *cbuild.SubsystemType) (string, error) { - var startupFolder string - var fileExtesion string - var fileFilter string - - startupFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) - if err != nil { - return "", err - } - - fileExtesion = ".s" - switch subsystem.Compiler { - case "AC6", "IAR": - if subsystem.SubsystemIdx.ProjectType == "multi-core" { - fileFilter = "_" + subsystem.SubsystemIdx.ForProjectPart - } - - case "GCC", "CLANG": - switch subsystem.SubsystemIdx.ProjectType { - case "multi-core": - startupFolder = path.Join(startupFolder, subsystem.SubsystemIdx.ForProjectPart) - case "trustzone": - if subsystem.SubsystemIdx.ForProjectPart == "secure" { - startupFolder = path.Join(startupFolder, "Secure") - } - if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { - startupFolder = path.Join(startupFolder, "NonSecure") - } - } - startupFolder = path.Join(startupFolder, "Application") - startupFolder = path.Join(startupFolder, "Startup") - - default: - return "", errors.New("unknown compiler") - } - - if !utils.DirExists(startupFolder) { - errorString := "Directory not found: " + startupFolder - log.Errorf(errorString) - return "", errors.New(errorString) - } - - var startupFile string - err = filepath.Walk(startupFolder, func(path string, f fs.FileInfo, err error) error { - if f.Mode().IsRegular() && - strings.HasSuffix(f.Name(), fileExtesion) && - strings.HasPrefix(f.Name(), "startup_") { - if fileFilter != "" { - if strings.Contains(f.Name(), fileFilter) { - startupFile = path - } - } else { - startupFile = path - } - } - return nil - }) - - if startupFile == "" { - errorString := "startup file not found" - log.Errorf(errorString) - return "", errors.New(errorString) - } - - return startupFile, err -} - -func GetSystemFile(outPath string, subsystem *cbuild.SubsystemType) (string, error) { - var toolchainFolder string - var systemFolder string - - toolchainFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) - if err != nil { - return "", err - } - - if subsystem.SubsystemIdx.ProjectType == "multi-core" { - systemFolder = filepath.Dir(toolchainFolder) - systemFolder = path.Join(systemFolder, "Common") - systemFolder = path.Join(systemFolder, "Src") - if !utils.DirExists(toolchainFolder) { - systemFolder = "" - } - } - - if systemFolder == "" { - systemFolder = filepath.Dir(toolchainFolder) - switch subsystem.SubsystemIdx.ProjectType { - case "multi-core": - systemFolder = path.Join(systemFolder, subsystem.SubsystemIdx.ForProjectPart) - case "trustzone": - if subsystem.SubsystemIdx.ForProjectPart == "secure" { - systemFolder = path.Join(systemFolder, "Secure") - } - if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { - systemFolder = path.Join(systemFolder, "NonSecure") - } - } - systemFolder = path.Join(systemFolder, "Src") - } - - if !utils.DirExists(systemFolder) { - errorString := "Directory not found: " + systemFolder - log.Errorf(errorString) - return "", errors.New(errorString) - } - - var systemFile string - err = filepath.Walk(systemFolder, func(path string, f fs.FileInfo, err error) error { - if f.Mode().IsRegular() && - strings.HasPrefix(f.Name(), "system_stm32") && - strings.HasSuffix(f.Name(), ".c") { - systemFile = path - } - return nil - }) - - if systemFile == "" { - errorString := "system file not found" - log.Errorf(errorString) - return "", errors.New(errorString) - } - - return systemFile, err -} - -func GetLinkerScripts(outPath string, subsystem *cbuild.SubsystemType) ([]string, error) { - var linkerFolder string - var fileExtesion string - var fileFilter string - - linkerFolder, err := GetToolchainFolderPath(outPath, subsystem.Compiler) - if err != nil { - return nil, err - } - - switch subsystem.Compiler { - case "AC6": - fileExtesion = ".sct" - case "IAR": - fileExtesion = ".icf" - case "GCC", "CLANG": - fileExtesion = ".ld" - default: - return nil, errors.New("unknown compiler") - } - - switch subsystem.Compiler { - case "AC6", "IAR": - switch subsystem.SubsystemIdx.ProjectType { - case "single-core": - fileFilter = "" - case "multi-core": - fileFilter = "_" + subsystem.SubsystemIdx.ForProjectPart - case "trustzone": - if subsystem.SubsystemIdx.ForProjectPart == "secure" { - fileFilter = "_s." - } - if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { - fileFilter = "_ns." - } - } - - case "GCC", "CLANG": - switch subsystem.SubsystemIdx.ProjectType { - case "multi-core": - linkerFolder = path.Join(linkerFolder, subsystem.SubsystemIdx.ForProjectPart) - case "trustzone": - if subsystem.SubsystemIdx.ForProjectPart == "secure" { - linkerFolder = path.Join(linkerFolder, "Secure") - } - if subsystem.SubsystemIdx.ForProjectPart == "non-secure" { - linkerFolder = path.Join(linkerFolder, "NonSecure") - } - } - default: - return nil, errors.New("unknown compiler") - } - - if !utils.DirExists(linkerFolder) { - errorString := "Directory not found: " + linkerFolder - log.Errorf(errorString) - return nil, errors.New(errorString) - } - - var linkerScripts []string - err = filepath.Walk(linkerFolder, func(path string, f fs.FileInfo, err error) error { - if f.Mode().IsRegular() && strings.HasSuffix(f.Name(), fileExtesion) { - if fileFilter != "" { - if strings.Contains(f.Name(), fileFilter) { - linkerScripts = append(linkerScripts, path) - } - } else { - linkerScripts = append(linkerScripts, path) - } - } - return nil - }) - - return linkerScripts, err -} diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 798e777..7e6cc77 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -70,30 +70,8 @@ func ConvertFilename(outPath, file, relativePathAdd string) (string, error) { file = filepath.Clean(file) file = filepath.ToSlash(file) - toolchainPath := path.Join(outPath, relativePathAdd) // create the path where STCube sets it's files relative to toolchain folder( example :./STM32CubeMX/MDK-ARM/) - file = path.Join(toolchainPath, file) - - if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { - log.Errorf("file or directory not found: %v", file) - } - - var err error - origfilename := file - file, err = filepath.Rel(outPath, file) - if err != nil { - log.Errorf("path error found: %v", file) - return origfilename, errors.New("path error") - } - - file = filepath.ToSlash(file) - file = "./" + file - - return file, nil -} - -func ConvertFilenameRel(outPath, file string) (string, error) { - file = filepath.Clean(file) - file = filepath.ToSlash(file) + mdkarmPath := path.Join(outPath, relativePathAdd) // create the path where STCube sets it's files relative to (./STM32CubeMX/MDK-ARM/) + file = path.Join(mdkarmPath, file) if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { log.Errorf("file or directory not found: %v", file)