newt/pkg/bsp_package.go (180 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package pkg import ( "fmt" "mynewt.apache.org/newt/newt/cfgv" "runtime" "strings" "mynewt.apache.org/newt/newt/config" "mynewt.apache.org/newt/newt/flashmap" "mynewt.apache.org/newt/newt/interfaces" "mynewt.apache.org/newt/newt/ycfg" "mynewt.apache.org/newt/util" ) const BSP_YAML_FILENAME = "bsp.yml" type BspYCfgOverride struct { Pkg *LocalPackage PkgY *ycfg.YCfg } type BspPackage struct { *LocalPackage yov *BspYCfgOverride CompilerName string CompilerNamePkg *LocalPackage /* package which defines compiler name */ Arch string LinkerScripts []string Part2LinkerScripts []string /* scripts to link app to second partition */ DownloadScript string DebugScript string OptChkScript string ImageOffset int ImagePad int FlashMap flashmap.FlashMap BspV ycfg.YCfg } func (bsp *BspPackage) BspYamlPath() string { return fmt.Sprintf("%s/%s", bsp.BasePath(), BSP_YAML_FILENAME) } func (bsp *BspPackage) resolvePathSetting( settings *cfgv.Settings, key string) (string, error) { var ypkg *LocalPackage var ycfg *ycfg.YCfg proj := interfaces.GetProject() ypkg, ycfg = bsp.selectKey(key) val, err := ycfg.GetValString(key, settings) util.OneTimeWarningError(err) if val == "" { return "", nil } path, err := proj.ResolvePath(ypkg.Repo().Path(), val) if err != nil { return "", util.PreNewtError(err, "Package \"%s\" specifies invalid %s setting", ypkg.FullName(), key) } return path, nil } // Interprets a setting as either a single linker script or a list of linker // scripts. func (bsp *BspPackage) resolveLinkerScriptSetting( settings *cfgv.Settings, key string) ([]string, error) { var ypkg *LocalPackage var ycfg *ycfg.YCfg paths := []string{} // Assume config file specifies a list of scripts. ypkg, ycfg = bsp.selectKey(key) vals, err := ycfg.GetValStringSlice(key, settings) util.OneTimeWarningError(err) if vals == nil { // Couldn't read a list of scripts; try to interpret setting as a // single script. path, err := bsp.resolvePathSetting(settings, key) if err != nil { return nil, err } if path != "" { paths = append(paths, path) } } else { proj := interfaces.GetProject() // Read each linker script from the list. for _, val := range vals { path, err := proj.ResolvePath(ypkg.Repo().Path(), val) if err != nil { return nil, util.PreNewtError(err, "Package \"%s\" specifies invalid %s setting", ypkg.FullName(), key) } if path != "" { paths = append(paths, path) } } } return paths, nil } func (bsp *BspPackage) selectKey(key string) (*LocalPackage, *ycfg.YCfg) { if bsp.yov != nil && bsp.yov.PkgY.HasKey(key) { return bsp.yov.Pkg, bsp.yov.PkgY } else { return bsp.LocalPackage, &bsp.BspV } } func (bsp *BspPackage) Reload(settings *cfgv.Settings) error { var ypkg *LocalPackage var ycfg *ycfg.YCfg var err error if settings == nil { settings = cfgv.NewSettings(nil) } settings.Set(strings.ToUpper(runtime.GOOS), "1") bsp.BspV, err = config.ReadFile(bsp.BspYamlPath()) if err != nil { return err } bsp.AddCfgFilename(bsp.BspYamlPath()) ypkg, ycfg = bsp.selectKey("bsp.compiler") bsp.CompilerNamePkg = ypkg bsp.CompilerName, err = ycfg.GetValString("bsp.compiler", settings) util.OneTimeWarningError(err) bsp.Arch, err = bsp.BspV.GetValString("bsp.arch", settings) util.OneTimeWarningError(err) _, ycfg = bsp.selectKey("bsp.image_offset") bsp.ImageOffset, err = ycfg.GetValInt("bsp.image_offset", settings) util.OneTimeWarningError(err) _, ycfg = bsp.selectKey("bsp.image_pad") bsp.ImagePad, err = ycfg.GetValInt("bsp.image_pad", settings) util.OneTimeWarningError(err) bsp.LinkerScripts, err = bsp.resolveLinkerScriptSetting(settings, "bsp.linkerscript") if err != nil { return err } bsp.Part2LinkerScripts, err = bsp.resolveLinkerScriptSetting(settings, "bsp.part2linkerscript") if err != nil { return err } bsp.DownloadScript, err = bsp.resolvePathSetting( settings, "bsp.downloadscript") if err != nil { return err } bsp.DebugScript, err = bsp.resolvePathSetting( settings, "bsp.debugscript") if err != nil { return err } /* Optional Target Checker Script, not an err if not found */ bsp.OptChkScript, err = bsp.resolvePathSetting( settings, "bsp.optionalcheckscript") if bsp.CompilerName == "" { return util.NewNewtError("BSP does not specify a compiler " + "(bsp.compiler)") } if bsp.Arch == "" { return util.NewNewtError("BSP does not specify an architecture " + "(bsp.arch)") } ypkg, ycfg = bsp.selectKey("bsp.flash_map") ymlFlashMap, err := ycfg.GetValStringMap("bsp.flash_map", settings) util.OneTimeWarningError(err) if ymlFlashMap == nil { return util.NewNewtError("BSP does not specify a flash map " + "(bsp.flash_map)") } bsp.FlashMap, err = flashmap.Read(ymlFlashMap, ypkg.FullName()) if err != nil { return err } return nil } func NewBspPackage(lpkg *LocalPackage, yov *BspYCfgOverride) (*BspPackage, error) { bsp := &BspPackage{ yov: yov, CompilerName: "", DownloadScript: "", DebugScript: "", } lpkg.Load() bsp.LocalPackage = lpkg bsp.BspV = ycfg.NewYCfg(bsp.BspYamlPath()) err := bsp.Reload(nil) return bsp, err } func NewBspYCfgOverride(lpkg *LocalPackage, ycfg *ycfg.YCfg) *BspYCfgOverride { ov := &BspYCfgOverride{ Pkg: lpkg, PkgY: ycfg, } return ov }