You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/10/08 19:52:55 UTC
[1/2] incubator-mynewt-newt git commit: newt - Read BSP settings from
bsp.yml.
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop 35ef6078c -> a441cdf5f
newt - Read BSP settings from bsp.yml.
Prior to this change, BSP settings were in pkg.yml.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/b6adacb0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/b6adacb0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/b6adacb0
Branch: refs/heads/develop
Commit: b6adacb05656a445330675f5456ddada180f0e4a
Parents: 35ef607
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Oct 3 16:44:17 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sat Oct 8 12:46:27 2016 -0700
----------------------------------------------------------------------
newt/builder/targetbuild.go | 6 ++++-
newt/pkg/bsp_package.go | 50 ++++++++++++++++++++++++++--------------
2 files changed, 38 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b6adacb0/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 22fd0af..288502d 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -61,7 +61,11 @@ func NewTargetBuilder(target *target.Target,
return nil, err
}
- bspPkg := pkg.NewBspPackage(target.Bsp())
+ bspPkg, err := pkg.NewBspPackage(target.Bsp())
+ if err != nil {
+ return nil, err
+ }
+
compilerPkg, err := project.GetProject().ResolvePackage(
bspPkg.Repo(), bspPkg.CompilerName)
if err != nil {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/b6adacb0/newt/pkg/bsp_package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/bsp_package.go b/newt/pkg/bsp_package.go
index 99fab5f..51f6a86 100644
--- a/newt/pkg/bsp_package.go
+++ b/newt/pkg/bsp_package.go
@@ -20,10 +20,15 @@
package pkg
import (
+ "strings"
+
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/util"
+ "mynewt.apache.org/newt/viper"
)
+const BSP_YAML_FILENAME = "bsp.yml"
+
type BspPackage struct {
*LocalPackage
CompilerName string
@@ -32,43 +37,54 @@ type BspPackage struct {
Part2LinkerScript string /* script to link app to second partition */
DownloadScript string
DebugScript string
+ BspV *viper.Viper
}
func (bsp *BspPackage) Reload(features map[string]bool) error {
- bsp.CompilerName = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.compiler")
- bsp.Arch = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.arch")
- bsp.LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.linkerscript")
- bsp.Part2LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.part2linkerscript")
- bsp.DownloadScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.downloadscript")
- bsp.DebugScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
- features, "pkg.debugscript")
+ var err error
+ bsp.BspV, err = util.ReadConfig(bsp.BasePath(),
+ strings.TrimSuffix(BSP_YAML_FILENAME, ".yml"))
+ if err != nil {
+ return err
+ }
+ bsp.AddCfgFilename(bsp.BasePath() + BSP_YAML_FILENAME)
+
+ bsp.CompilerName = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.compiler")
+ bsp.Arch = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.arch")
+ bsp.LinkerScript = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.linkerscript")
+ bsp.Part2LinkerScript = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.part2linkerscript")
+ bsp.DownloadScript = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.downloadscript")
+ bsp.DebugScript = newtutil.GetStringFeatures(bsp.BspV,
+ features, "bsp.debugscript")
if bsp.CompilerName == "" {
return util.NewNewtError("BSP does not specify a compiler " +
- "(pkg.compiler)")
+ "(bsp.compiler)")
}
if bsp.Arch == "" {
return util.NewNewtError("BSP does not specify an architecture " +
- "(pkg.arch)")
+ "(bsp.arch)")
}
return nil
}
-func NewBspPackage(lpkg *LocalPackage) *BspPackage {
+func NewBspPackage(lpkg *LocalPackage) (*BspPackage, error) {
bsp := &BspPackage{
CompilerName: "",
LinkerScript: "",
DownloadScript: "",
DebugScript: "",
+ BspV: viper.New(),
}
lpkg.Load()
bsp.LocalPackage = lpkg
- bsp.Reload(nil)
- return bsp
+ err := bsp.Reload(nil)
+
+ return bsp, err
}
[2/2] incubator-mynewt-newt git commit: Flash map config in bsp.yml.
Posted by cc...@apache.org.
Flash map config in bsp.yml.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/a441cdf5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/a441cdf5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/a441cdf5
Branch: refs/heads/develop
Commit: a441cdf5f48b0b7a5dbf198813cbf9029fcd85a8
Parents: b6adacb
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Oct 3 19:43:26 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sat Oct 8 12:47:17 2016 -0700
----------------------------------------------------------------------
newt/builder/build.go | 2 +-
newt/builder/targetbuild.go | 40 +-
newt/flash/flash.go | 401 +++++++++++++++++++
newt/newtutil/newtutil.go | 5 +
newt/pkg/bsp_package.go | 13 +
newt/resolve/resolve.go | 17 +-
newt/syscfg/restrict.go | 199 +++++++++
newt/syscfg/syscfg.go | 345 ++++++++--------
newt/sysinit/sysinit.go | 4 +-
newt/vendor/mynewt.apache.org/newt/util/util.go | 15 +
util/util.go | 15 +
11 files changed, 871 insertions(+), 185 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index 5d57153..445d9a2 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -390,7 +390,7 @@ func (b *Builder) PrepBuild() error {
}
baseCi.AddCompilerInfo(bspCi)
- // All packages have access to the generated syscfg header directory.
+ // All packages have access to the generated code header directory.
baseCi.Cflags = append(baseCi.Cflags,
"-I"+GeneratedIncludeDir(b.targetPkg.Name()))
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 288502d..ea8c0c8 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -130,7 +130,8 @@ func (t *TargetBuilder) ExportCfg() (resolve.CfgResolution, error) {
seeds = append(seeds, t.testPkg)
}
- cfgResolution, err := resolve.ResolveCfg(seeds, t.injectedSettings)
+ cfgResolution, err := resolve.ResolveCfg(seeds, t.injectedSettings,
+ t.bspPkg.FlashMap)
if err != nil {
return cfgResolution, err
}
@@ -145,6 +146,11 @@ func (t *TargetBuilder) validateAndWriteCfg(
return util.NewNewtError(errText)
}
+ warningText := strings.TrimSpace(cfgResolution.WarningText())
+ for _, line := range strings.Split(warningText, "\n") {
+ log.Warn(line)
+ }
+
if err := syscfg.EnsureWritten(cfgResolution.Cfg,
GeneratedIncludeDir(t.target.Name())); err != nil {
@@ -172,7 +178,7 @@ func (t *TargetBuilder) resolvePkgs(cfgResolution resolve.CfgResolution) (
t.target.Package())
}
-func (t *TargetBuilder) buildSysinit(
+func (t *TargetBuilder) generateSysinit(
cfgResolution resolve.CfgResolution) error {
loaderPkgs, appPkgs, err := t.resolvePkgs(cfgResolution)
@@ -193,12 +199,38 @@ func (t *TargetBuilder) buildSysinit(
return nil
}
+func (t *TargetBuilder) generateFlashMap() error {
+ return t.bspPkg.FlashMap.EnsureWritten(
+ GeneratedSrcDir(t.target.Name()),
+ GeneratedIncludeDir(t.target.Name()),
+ pkg.ShortName(t.target.Package()))
+}
+
+func (t *TargetBuilder) generateCode(
+ cfgResolution resolve.CfgResolution) error {
+
+ if err := t.generateSysinit(cfgResolution); err != nil {
+ return err
+ }
+
+ if err := t.generateFlashMap(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
func (t *TargetBuilder) PrepBuild() error {
cfgResolution, err := t.ExportCfg()
if err != nil {
return err
}
+ flashErrText := t.bspPkg.FlashMap.ErrorText()
+ if flashErrText != "" {
+ return util.NewNewtError(flashErrText)
+ }
+
if err := t.validateAndWriteCfg(cfgResolution); err != nil {
return err
}
@@ -242,7 +274,7 @@ func (t *TargetBuilder) PrepBuild() error {
t.AppList = project.ResetDeps(nil)
- if err := t.buildSysinit(cfgResolution); err != nil {
+ if err := t.generateCode(cfgResolution); err != nil {
return err
}
@@ -502,7 +534,7 @@ func (t *TargetBuilder) Test() error {
return err
}
- if err := t.buildSysinit(cfgResolution); err != nil {
+ if err := t.generateCode(cfgResolution); err != nil {
return err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/flash/flash.go
----------------------------------------------------------------------
diff --git a/newt/flash/flash.go b/newt/flash/flash.go
new file mode 100644
index 0000000..7538936
--- /dev/null
+++ b/newt/flash/flash.go
@@ -0,0 +1,401 @@
+/**
+ * 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 flash
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ log "github.com/Sirupsen/logrus"
+ "github.com/spf13/cast"
+
+ "mynewt.apache.org/newt/newt/newtutil"
+ "mynewt.apache.org/newt/util"
+)
+
+var SYSTEM_AREA_NAME_ID_MAP = map[string]int{
+ "FLASH_AREA_BOOTLOADER": 0,
+ "FLASH_AREA_IMAGE_0": 1,
+ "FLASH_AREA_IMAGE_1": 2,
+ "FLASH_AREA_IMAGE_SCRATCH": 3,
+ "FLASH_AREA_META": 4,
+}
+
+const AREA_USER_ID_MIN = 16
+
+const HEADER_PATH = "sysflash/sysflash.h"
+const C_VAR_NAME = "sysflash_map_dflt"
+const C_VAR_COMMENT = `/**
+ * This flash map definition is used for two purposes:
+ * 1. To locate the meta area, which contains the true flash map definition.
+ * 2. As a fallback in case the meta area cannot be read from flash.
+ */
+`
+
+type FlashArea struct {
+ Name string
+ Id int
+ Device int
+ Offset int
+ Size int
+}
+
+type FlashMap struct {
+ Areas map[string]FlashArea
+ Overlaps [][]FlashArea
+ IdConflicts [][]FlashArea
+}
+
+func newFlashMap() FlashMap {
+ return FlashMap{
+ Areas: map[string]FlashArea{},
+ Overlaps: [][]FlashArea{},
+ }
+}
+
+func flashAreaErr(areaName string, format string, args ...interface{}) error {
+ return util.NewNewtError(
+ "failure while parsing flash area \"" + areaName + "\": " +
+ fmt.Sprintf(format, args...))
+}
+
+func parseSize(val string) (int, error) {
+ lower := strings.ToLower(val)
+
+ multiplier := 1
+ if strings.HasSuffix(lower, "kb") {
+ multiplier = 1024
+ lower = strings.TrimSuffix(lower, "kb")
+ }
+
+ num, err := util.AtoiNoOct(lower)
+ if err != nil {
+ return 0, err
+ }
+
+ return num * multiplier, nil
+}
+
+func parseFlashArea(
+ name string, ymlFields map[string]interface{}) (FlashArea, error) {
+
+ area := FlashArea{
+ Name: name,
+ }
+
+ idPresent := false
+ devicePresent := false
+ offsetPresent := false
+ sizePresent := false
+
+ var isSystem bool
+ area.Id, isSystem = SYSTEM_AREA_NAME_ID_MAP[name]
+
+ var err error
+
+ fields := cast.ToStringMapString(ymlFields)
+ for k, v := range fields {
+ switch k {
+ case "user_id":
+ if isSystem {
+ return area, flashAreaErr(name,
+ "system areas cannot specify a user ID")
+ }
+ userId, err := util.AtoiNoOct(v)
+ if err != nil {
+ return area, flashAreaErr(name, "invalid id: %s", v)
+ }
+ area.Id = userId + AREA_USER_ID_MIN
+ idPresent = true
+
+ case "device":
+ area.Device, err = util.AtoiNoOct(v)
+ if err != nil {
+ return area, flashAreaErr(name, "invalid device: %s", v)
+ }
+ devicePresent = true
+
+ case "offset":
+ area.Offset, err = util.AtoiNoOct(v)
+ if err != nil {
+ return area, flashAreaErr(name, "invalid offset: %s", v)
+ }
+ offsetPresent = true
+
+ case "size":
+ area.Size, err = parseSize(v)
+ if err != nil {
+ return area, flashAreaErr(name, err.Error())
+ }
+ sizePresent = true
+
+ default:
+ util.StatusMessage(util.VERBOSITY_QUIET,
+ "Warning: flash area \"%s\" contains unrecognized field: %s",
+ name, k)
+ }
+ }
+
+ if !isSystem && !idPresent {
+ return area, flashAreaErr(name, "required field \"user_id\" missing")
+ }
+ if !devicePresent {
+ return area, flashAreaErr(name, "required field \"device\" missing")
+ }
+ if !offsetPresent {
+ return area, flashAreaErr(name, "required field \"offset\" missing")
+ }
+ if !sizePresent {
+ return area, flashAreaErr(name, "required field \"size\" missing")
+ }
+
+ return area, nil
+}
+
+func (flashMap FlashMap) unsortedAreas() []FlashArea {
+ areas := make([]FlashArea, 0, len(flashMap.Areas))
+ for _, area := range flashMap.Areas {
+ areas = append(areas, area)
+ }
+
+ return areas
+}
+
+func (flashMap FlashMap) sortedAreas() []FlashArea {
+ idMap := make(map[int]FlashArea, len(flashMap.Areas))
+ ids := make([]int, 0, len(flashMap.Areas))
+ for _, area := range flashMap.Areas {
+ idMap[area.Id] = area
+ ids = append(ids, area.Id)
+ }
+ sort.Ints(ids)
+
+ areas := make([]FlashArea, len(ids))
+ for i, id := range ids {
+ areas[i] = idMap[id]
+ }
+
+ return areas
+}
+
+func areasDistinct(a FlashArea, b FlashArea) bool {
+ var lo FlashArea
+ var hi FlashArea
+
+ if a.Offset < b.Offset {
+ lo = a
+ hi = b
+ } else {
+ lo = b
+ hi = a
+ }
+
+ return lo.Device != hi.Device || lo.Offset+lo.Size <= hi.Offset
+}
+
+func (flashMap *FlashMap) detectOverlaps() {
+ flashMap.Overlaps = [][]FlashArea{}
+
+ // Convert the map to a slice.
+ areas := flashMap.unsortedAreas()
+
+ for i := 0; i < len(areas)-1; i++ {
+ iarea := areas[i]
+ for j := i + 1; j < len(areas); j++ {
+ jarea := areas[j]
+
+ if !areasDistinct(iarea, jarea) {
+ flashMap.Overlaps = append(
+ flashMap.Overlaps, []FlashArea{iarea, jarea})
+ }
+
+ if iarea.Id == jarea.Id {
+ flashMap.IdConflicts = append(
+ flashMap.IdConflicts, []FlashArea{iarea, jarea})
+ }
+ }
+ }
+}
+
+func (flashMap FlashMap) ErrorText() string {
+ str := ""
+
+ if len(flashMap.IdConflicts) > 0 {
+ str += "Conflicting flash area IDs detected:\n"
+
+ for _, pair := range flashMap.IdConflicts {
+ str += fmt.Sprintf(" (%d) %s =/= %s\n",
+ pair[0].Id-AREA_USER_ID_MIN, pair[0].Name, pair[1].Name)
+ }
+ }
+
+ if len(flashMap.Overlaps) > 0 {
+ str += "Overlapping flash areas detected:\n"
+
+ for _, pair := range flashMap.Overlaps {
+ str += fmt.Sprintf(" %s =/= %s\n", pair[0].Name, pair[1].Name)
+ }
+ }
+
+ return str
+}
+
+func Read(ymlFlashMap map[string]interface{}) (FlashMap, error) {
+ flashMap := newFlashMap()
+
+ ymlAreas := ymlFlashMap["areas"]
+ if ymlAreas == nil {
+ return flashMap, util.NewNewtError(
+ "\"areas\" mapping missing from flash map definition")
+ }
+
+ areaMap := cast.ToStringMap(ymlAreas)
+ for k, v := range areaMap {
+ if _, ok := flashMap.Areas[k]; ok {
+ return flashMap, flashAreaErr(k, "name conflict")
+ }
+
+ ymlArea := cast.ToStringMap(v)
+ area, err := parseFlashArea(k, ymlArea)
+ if err != nil {
+ return flashMap, flashAreaErr(k, err.Error())
+ }
+
+ flashMap.Areas[k] = area
+ }
+
+ flashMap.detectOverlaps()
+
+ return flashMap, nil
+}
+
+func (flashMap FlashMap) varDecl() string {
+ return fmt.Sprintf("const struct flash_area %s[%d]", C_VAR_NAME,
+ len(flashMap.Areas))
+}
+
+func (area FlashArea) writeHeader(w io.Writer) {
+ fmt.Fprintf(w, "#define %-40s %d\n", area.Name, area.Id)
+}
+
+func (flashMap FlashMap) writeHeader(w io.Writer) {
+ fmt.Fprintf(w, newtutil.GeneratedPreamble())
+
+ fmt.Fprintf(w, "#ifndef H_MYNEWT_SYSFLASH_\n")
+ fmt.Fprintf(w, "#define H_MYNEWT_SYSFLASH_\n")
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "#include \"flash_map/flash_map.h\"\n")
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "%s", C_VAR_COMMENT)
+ fmt.Fprintf(w, "extern %s;\n", flashMap.varDecl())
+ fmt.Fprintf(w, "\n")
+
+ for _, area := range flashMap.sortedAreas() {
+ area.writeHeader(w)
+ }
+
+ fmt.Fprintf(w, "\n#endif\n")
+}
+
+func sizeComment(size int) string {
+ if size%1024 != 0 {
+ return ""
+ }
+
+ return fmt.Sprintf(" /* %d kB */", size/1024)
+}
+
+func (area FlashArea) writeSrc(w io.Writer) {
+ fmt.Fprintf(w, " /* %s */\n", area.Name)
+ fmt.Fprintf(w, " {\n")
+ fmt.Fprintf(w, " .fa_id = %d,\n", area.Id)
+ fmt.Fprintf(w, " .fa_device_id = %d,\n", area.Device)
+ fmt.Fprintf(w, " .fa_off = 0x%08x,\n", area.Offset)
+ fmt.Fprintf(w, " .fa_size = %d,%s\n", area.Size,
+ sizeComment(area.Size))
+ fmt.Fprintf(w, " },\n")
+}
+
+func (flashMap FlashMap) writeSrc(w io.Writer) {
+ fmt.Fprintf(w, newtutil.GeneratedPreamble())
+
+ fmt.Fprintf(w, "#include \"%s\"\n", HEADER_PATH)
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "%s", C_VAR_COMMENT)
+ fmt.Fprintf(w, "%s = {", flashMap.varDecl())
+
+ for _, area := range flashMap.sortedAreas() {
+ fmt.Fprintf(w, "\n")
+ area.writeSrc(w)
+ }
+
+ fmt.Fprintf(w, "};\n")
+}
+
+func (flashMap FlashMap) ensureWrittenGen(path string, contents []byte) error {
+ writeReqd, err := util.FileContentsChanged(path, contents)
+ if err != nil {
+ return err
+ }
+ if !writeReqd {
+ log.Debugf("flash map unchanged; not writing file (%s).", path)
+ return nil
+ }
+
+ log.Debugf("flash map changed; writing file (%s).", path)
+
+ if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ if err := ioutil.WriteFile(path, contents, 0644); err != nil {
+ return util.NewNewtError(err.Error())
+ }
+
+ return nil
+}
+
+func (flashMap FlashMap) EnsureWritten(
+ srcDir string, includeDir string, targetName string) error {
+
+ buf := bytes.Buffer{}
+ flashMap.writeSrc(&buf)
+ if err := flashMap.ensureWrittenGen(
+ fmt.Sprintf("%s/%s-sysflash.c", srcDir, targetName),
+ buf.Bytes()); err != nil {
+
+ return err
+ }
+
+ buf = bytes.Buffer{}
+ flashMap.writeHeader(&buf)
+ if err := flashMap.ensureWrittenGen(
+ includeDir+"/"+HEADER_PATH, buf.Bytes()); err != nil {
+ return err
+ }
+
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/newtutil/newtutil.go
----------------------------------------------------------------------
diff --git a/newt/newtutil/newtutil.go b/newt/newtutil/newtutil.go
index 0056201..2f52052 100644
--- a/newt/newtutil/newtutil.go
+++ b/newt/newtutil/newtutil.go
@@ -228,3 +228,8 @@ func CopyFile(dst string, src string) error {
}
return nil
}
+
+func GeneratedPreamble() string {
+ return fmt.Sprintf("/**\n * This file was generated by %s\n */\n\n",
+ NewtVersionStr)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/pkg/bsp_package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/bsp_package.go b/newt/pkg/bsp_package.go
index 51f6a86..89e9452 100644
--- a/newt/pkg/bsp_package.go
+++ b/newt/pkg/bsp_package.go
@@ -22,6 +22,7 @@ package pkg
import (
"strings"
+ "mynewt.apache.org/newt/newt/flash"
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/util"
"mynewt.apache.org/newt/viper"
@@ -37,6 +38,7 @@ type BspPackage struct {
Part2LinkerScript string /* script to link app to second partition */
DownloadScript string
DebugScript string
+ FlashMap flash.FlashMap
BspV *viper.Viper
}
@@ -71,6 +73,17 @@ func (bsp *BspPackage) Reload(features map[string]bool) error {
"(bsp.arch)")
}
+ ymlFlashMap := newtutil.GetStringMapFeatures(bsp.BspV, features,
+ "bsp.flash_map")
+ if ymlFlashMap == nil {
+ return util.NewNewtError("BSP does not specify a flash map " +
+ "(bsp.flash_map)")
+ }
+ bsp.FlashMap, err = flash.Read(ymlFlashMap)
+ if err != nil {
+ return err
+ }
+
return nil
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/resolve/resolve.go
----------------------------------------------------------------------
diff --git a/newt/resolve/resolve.go b/newt/resolve/resolve.go
index fc2f34c..b96e954 100644
--- a/newt/resolve/resolve.go
+++ b/newt/resolve/resolve.go
@@ -26,6 +26,7 @@ import (
log "github.com/Sirupsen/logrus"
+ "mynewt.apache.org/newt/newt/flash"
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
@@ -37,6 +38,7 @@ type Resolver struct {
apis map[string]*ResolvePackage
pkgMap map[*pkg.LocalPackage]*ResolvePackage
injectedSettings map[string]string
+ flashMap flash.FlashMap
cfg syscfg.Cfg
}
@@ -208,8 +210,8 @@ func (r *Resolver) loadDepsForPkg(rpkg *ResolvePackage) (bool, error) {
lpkg, ok := proj.ResolveDependency(newDep).(*pkg.LocalPackage)
if !ok {
return false,
- util.NewNewtError("Could not resolve package dependency " +
- newDep.String())
+ util.FmtNewtError("Could not resolve package dependency: "+
+ "%s; depender: %s", newDep.String(), rpkg.Name())
}
if r.pkgMap[lpkg] == nil {
@@ -277,7 +279,8 @@ func (r *Resolver) reloadCfg() (bool, error) {
// required for reloading syscfg, as features may unlock additional
// settings.
features := r.cfg.Features()
- cfg, err := syscfg.Read(lpkgs, apis, r.injectedSettings, features)
+ cfg, err := syscfg.Read(lpkgs, apis, r.injectedSettings, features,
+ r.flashMap)
if err != nil {
return false, err
}
@@ -464,11 +467,13 @@ func ResolveSplitPkgs(cfgResolution CfgResolution,
}
func ResolveCfg(seedPkgs []*pkg.LocalPackage,
- injectedSettings map[string]string) (CfgResolution, error) {
+ injectedSettings map[string]string,
+ flashMap flash.FlashMap) (CfgResolution, error) {
resolution := newCfgResolution()
r := newResolver()
+ r.flashMap = flashMap
if injectedSettings == nil {
injectedSettings = map[string]string{}
}
@@ -538,3 +543,7 @@ func (cfgResolution *CfgResolution) ErrorText() string {
return strings.TrimSpace(str)
}
+
+func (cfgResolution *CfgResolution) WarningText() string {
+ return cfgResolution.Cfg.WarningText()
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/syscfg/restrict.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/restrict.go b/newt/syscfg/restrict.go
new file mode 100644
index 0000000..5f9c0f7
--- /dev/null
+++ b/newt/syscfg/restrict.go
@@ -0,0 +1,199 @@
+/**
+ * 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 syscfg
+
+import (
+ "fmt"
+ "strings"
+
+ "mynewt.apache.org/newt/util"
+)
+
+type CfgRestrictionCode int
+
+const (
+ CFG_RESTRICTION_CODE_NOTNULL = iota
+ CFG_RESTRICTION_CODE_EXPR
+)
+
+var cfgRestrictionNameCodeMap = map[string]CfgRestrictionCode{
+ "$notnull": CFG_RESTRICTION_CODE_NOTNULL,
+}
+
+type CfgRestrictionExpr struct {
+ ReqSetting string
+ ReqVal bool
+ BaseVal bool
+}
+type CfgRestriction struct {
+ BaseSetting string
+ Code CfgRestrictionCode
+
+ // Only used if Code is CFG_RESTRICTION_CODE_EXPR
+ Expr CfgRestrictionExpr
+}
+
+func parseRestrictionExprConsequent(field string) (string, bool) {
+ var val bool
+ var name string
+
+ if strings.HasPrefix(field, "!") {
+ val = false
+ name = strings.TrimPrefix(field, "!")
+ } else {
+ val = true
+ name = field
+ }
+
+ return name, val
+}
+
+// Parses a restriction value.
+//
+// Currently, two forms of restrictions are supported:
+// 1. "$notnull"
+// 2. expression
+//
+// The "$notnull" string indicates that the setting must be set to something
+// other than the empty string.
+//
+// An expression string indicates dependencies on other settings. It would be
+// better to have a real expression parser. For now, only very simple
+// expressions are supported. A restriction expression must be of the
+// following form:
+// [!]<req-setting> [if <base-val>]
+//
+// All setting values are interpreted as booleans. If a setting is "0", "",
+// or undefined, it is false; otherwise it is true.
+//
+// Examples:
+// # Can't enable this setting unless LOG_FCB is enabled.
+// pkg.restrictions:
+// LOG_FCB
+//
+// # Can't enable this setting unless LOG_FCB is disabled.
+// pkg.restrictions:
+// !LOG_FCB
+//
+// # Can't disable this setting unless LOG_FCB is enabled.
+// pkg.restrictions:
+// LOG_FCB if 0
+func readRestrictionExpr(text string) (CfgRestrictionExpr, error) {
+ e := CfgRestrictionExpr{}
+
+ fields := strings.Fields(text)
+ switch len(fields) {
+ case 1:
+ e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0])
+ e.BaseVal = true
+
+ case 3:
+ if fields[1] != "if" {
+ return e, util.FmtNewtError("invalid restriction: %s", text)
+ }
+ e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0])
+ e.BaseVal = ValueIsTrue(fields[2])
+
+ default:
+ return e, util.FmtNewtError("invalid restriction: %s", text)
+ }
+
+ return e, nil
+}
+
+func readRestriction(baseSetting string, text string) (CfgRestriction, error) {
+ r := CfgRestriction{
+ BaseSetting: baseSetting,
+ }
+
+ var ok bool
+ if r.Code, ok = cfgRestrictionNameCodeMap[text]; !ok {
+ // If the restriction text isn't a defined string, parse it as an
+ // expression.
+ r.Code = CFG_RESTRICTION_CODE_EXPR
+
+ var err error
+ if r.Expr, err = readRestrictionExpr(text); err != nil {
+ return r, err
+ }
+ }
+
+ return r, nil
+}
+
+func (cfg *Cfg) violationText(entry CfgEntry, r CfgRestriction) string {
+ if r.Code == CFG_RESTRICTION_CODE_NOTNULL {
+ return entry.Name + " must not be null"
+ }
+
+ str := fmt.Sprintf("%s=%s ", entry.Name, entry.Value)
+ if r.Expr.ReqVal {
+ str += fmt.Sprintf("requires %s be set", r.Expr.ReqSetting)
+ } else {
+ str += fmt.Sprintf("requires %s not be set", r.Expr.ReqSetting)
+ }
+
+ str += fmt.Sprintf(", but %s", r.Expr.ReqSetting)
+ reqEntry, ok := cfg.Settings[r.Expr.ReqSetting]
+ if !ok {
+ str += "undefined"
+ } else {
+ str += fmt.Sprintf("=%s", reqEntry.Value)
+ }
+
+ return str
+}
+
+func (r *CfgRestriction) relevantSettingNames() []string {
+ switch r.Code {
+ case CFG_RESTRICTION_CODE_NOTNULL:
+ return []string{r.BaseSetting}
+
+ case CFG_RESTRICTION_CODE_EXPR:
+ return []string{r.BaseSetting, r.Expr.ReqSetting}
+
+ default:
+ panic("Invalid restriction code: " + string(r.Code))
+ }
+}
+
+func (cfg *Cfg) restrictionMet(r CfgRestriction) bool {
+ baseEntry := cfg.Settings[r.BaseSetting]
+ baseVal := baseEntry.IsTrue()
+
+ switch r.Code {
+ case CFG_RESTRICTION_CODE_NOTNULL:
+ return baseEntry.Value != ""
+
+ case CFG_RESTRICTION_CODE_EXPR:
+ if baseVal != r.Expr.BaseVal {
+ // Restriction does not apply.
+ return true
+ }
+
+ reqEntry, ok := cfg.Settings[r.Expr.ReqSetting]
+ reqVal := ok && reqEntry.IsTrue()
+
+ return reqVal == r.Expr.ReqVal
+
+ default:
+ panic("Invalid restriction code: " + string(r.Code))
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
index 14dbaf9..7b42c59 100644
--- a/newt/syscfg/syscfg.go
+++ b/newt/syscfg/syscfg.go
@@ -33,14 +33,14 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/spf13/cast"
+ "mynewt.apache.org/newt/newt/flash"
"mynewt.apache.org/newt/newt/interfaces"
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/util"
)
-const SYSCFG_INCLUDE_SUBDIR = "syscfg"
-const SYSCFG_HEADER_FILENAME = "syscfg.h"
+const HEADER_PATH = "syscfg/syscfg.h"
const SYSCFG_PREFIX_SETTING = "MYNEWT_VAL_"
@@ -50,6 +50,7 @@ const (
CFG_SETTING_TYPE_RAW CfgSettingType = iota
CFG_SETTING_TYPE_TASK_PRIO
CFG_SETTING_TYPE_INTERRUPT_PRIO
+ CFG_SETTING_TYPE_FLASH_OWNER
)
const SYSCFG_PRIO_ANY = "any"
@@ -65,6 +66,7 @@ var cfgSettingNameTypeMap = map[string]CfgSettingType{
"raw": CFG_SETTING_TYPE_RAW,
"task_priority": CFG_SETTING_TYPE_TASK_PRIO,
"interrupt_priority": CFG_SETTING_TYPE_INTERRUPT_PRIO,
+ "flash_owner": CFG_SETTING_TYPE_FLASH_OWNER,
}
type CfgPoint struct {
@@ -72,13 +74,6 @@ type CfgPoint struct {
Source *pkg.LocalPackage
}
-type CfgRestriction struct {
- ReqSetting string
- ReqVal bool
- BaseSetting string
- BaseVal bool
-}
-
type CfgEntry struct {
Name string
Value string
@@ -94,6 +89,18 @@ type CfgLateral struct {
SettingName string
}
+type CfgFlashConflictCode int
+
+const (
+ CFG_FLASH_CONFLICT_CODE_BAD_NAME CfgFlashConflictCode = iota
+ CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE
+)
+
+type CfgFlashConflict struct {
+ SettingNames []string
+ Code CfgFlashConflictCode
+}
+
type Cfg struct {
Settings map[string]CfgEntry
@@ -110,23 +117,21 @@ type Cfg struct {
// Attempted override by bottom-priority packages (libraries).
Laterals []CfgLateral
+
+ FlashConflicts []CfgFlashConflict
}
func NewCfg() Cfg {
return Cfg{
- Settings: map[string]CfgEntry{},
- Orphans: map[string][]CfgPoint{},
- Ambiguities: map[string][]CfgPoint{},
- Violations: map[string][]CfgRestriction{},
- Laterals: []CfgLateral{},
+ Settings: map[string]CfgEntry{},
+ Orphans: map[string][]CfgPoint{},
+ Ambiguities: map[string][]CfgPoint{},
+ Violations: map[string][]CfgRestriction{},
+ Laterals: []CfgLateral{},
+ FlashConflicts: []CfgFlashConflict{},
}
}
-func WritePreamble(w io.Writer) {
- fmt.Fprintf(w, "/**\n * This file was generated by %s\n */\n\n",
- newtutil.NewtVersionStr)
-}
-
func ValueIsTrue(val string) bool {
if val == "" {
return false
@@ -259,28 +264,6 @@ func (entry *CfgEntry) ambiguityText() string {
return str
}
-func (cfg *Cfg) violationText(entry CfgEntry, r CfgRestriction) string {
- str := fmt.Sprintf("%s=%s ", entry.Name, entry.Value)
-
- reqVal := ""
- if r.ReqVal {
- reqVal = "1"
- } else {
- reqVal = "0"
- }
-
- str += fmt.Sprintf("requires %s=%s, but %s", r.ReqSetting, reqVal,
- r.ReqSetting)
- reqEntry, ok := cfg.Settings[r.ReqSetting]
- if !ok {
- str += "undefined"
- } else {
- str += fmt.Sprintf("=%s", reqEntry.Value)
- }
-
- return str
-}
-
func FeatureToCflag(featureName string) string {
return fmt.Sprintf("-D%s=1", settingName(featureName))
}
@@ -289,68 +272,6 @@ func stringValue(val interface{}) string {
return strings.TrimSpace(cast.ToString(val))
}
-func parseRestrictionConsequent(field string) (string, bool) {
- var val bool
- var name string
-
- if strings.HasPrefix(field, "!") {
- val = false
- name = strings.TrimPrefix(field, "!")
- } else {
- val = true
- name = field
- }
-
- return name, val
-}
-
-// Parses a restriction expression.
-//
-// It would be better to have a real expression parser. For now, only very
-// simple expressions are supported. A restriction expression must be of the
-// following form:
-// [!]<req-setting> [if <base-val>]
-//
-// All setting values are interpreted as booleans. If a setting is "0", "",
-// or undefined, it is false; otherwise it is true.
-//
-// Examples:
-// # Can't enable this setting unless LOG_FCB is enabled.
-// pkg.restrictions:
-// LOG_FCB
-//
-// # Can't enable this setting unless LOG_FCB is disabled.
-// pkg.restrictions:
-// !LOG_FCB
-//
-// # Can't disable this setting unless LOG_FCB is enabled.
-// pkg.restrictions:
-// LOG_FCB if 0
-func readRestriction(baseSetting string, text string) (CfgRestriction, error) {
- r := CfgRestriction{
- BaseSetting: baseSetting,
- }
-
- fields := strings.Fields(text)
- switch len(fields) {
- case 1:
- r.ReqSetting, r.ReqVal = parseRestrictionConsequent(fields[0])
- r.BaseVal = true
-
- case 3:
- if fields[1] != "if" {
- return r, util.FmtNewtError("invalid restriction: %s", text)
- }
- r.ReqSetting, r.ReqVal = parseRestrictionConsequent(fields[0])
- r.BaseVal = ValueIsTrue(fields[2])
-
- default:
- return r, util.FmtNewtError("invalid restriction: %s", text)
- }
-
- return r, nil
-}
-
func readSetting(name string, lpkg *pkg.LocalPackage,
vals map[interface{}]interface{}) (CfgEntry, error) {
@@ -469,42 +390,18 @@ func (cfg *Cfg) Log() {
log.Debugf(" %s=%s %s", k, entry.Value,
historyToString(entry.History))
}
-
- keys = make([]string, len(cfg.Orphans))
- i = 0
- for k, _ := range cfg.Orphans {
- keys[i] = k
- i++
- }
- sort.Strings(keys)
-
- for _, k := range keys {
- str := fmt.Sprintf("ignoring override of undefined setting %s [", k)
- for i, p := range cfg.Orphans[k] {
- if i != 0 {
- str += ", "
- }
- str += fmt.Sprintf("%s:%s", p.Name(), p.Value)
- }
- str += "]"
-
- log.Warnf(str)
- }
}
-func (cfg *Cfg) restrictionMet(r CfgRestriction) bool {
- baseEntry := cfg.Settings[r.BaseSetting]
- baseVal := baseEntry.IsTrue()
+func (cfg *Cfg) settingsOfType(typ CfgSettingType) []CfgEntry {
+ entries := []CfgEntry{}
- if baseVal != r.BaseVal {
- // Restriction does not apply.
- return true
+ for _, entry := range cfg.Settings {
+ if entry.SettingType == typ {
+ entries = append(entries, entry)
+ }
}
- reqEntry, ok := cfg.Settings[r.ReqSetting]
- reqVal := ok && reqEntry.IsTrue()
-
- return reqVal == r.ReqVal
+ return entries
}
func (cfg *Cfg) detectViolations() {
@@ -522,19 +419,103 @@ func (cfg *Cfg) detectViolations() {
}
}
+func (cfg *Cfg) detectFlashConflicts(flashMap flash.FlashMap) {
+ entries := cfg.settingsOfType(CFG_SETTING_TYPE_FLASH_OWNER)
+
+ areaEntryMap := map[string][]CfgEntry{}
+
+ for _, entry := range entries {
+ if entry.Value != "" {
+ area, ok := flashMap.Areas[entry.Value]
+ if !ok {
+ conflict := CfgFlashConflict{
+ SettingNames: []string{entry.Name},
+ Code: CFG_FLASH_CONFLICT_CODE_BAD_NAME,
+ }
+ cfg.FlashConflicts = append(cfg.FlashConflicts, conflict)
+ } else {
+ areaEntryMap[area.Name] =
+ append(areaEntryMap[area.Name], entry)
+ }
+ }
+ }
+
+ // Settings with type flash_owner must have unique values.
+ for _, entries := range areaEntryMap {
+ if len(entries) > 1 {
+ conflict := CfgFlashConflict{
+ SettingNames: []string{},
+ Code: CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE,
+ }
+
+ for _, entry := range entries {
+ conflict.SettingNames =
+ append(conflict.SettingNames, entry.Name)
+ }
+
+ cfg.FlashConflicts = append(cfg.FlashConflicts, conflict)
+ }
+ }
+}
+
+func (cfg *Cfg) flashConflictErrorText(conflict CfgFlashConflict) string {
+ entry := cfg.Settings[conflict.SettingNames[0]]
+
+ switch conflict.Code {
+ case CFG_FLASH_CONFLICT_CODE_BAD_NAME:
+ return fmt.Sprintf("Setting %s specifies unknown flash area: %s\n",
+ entry.Name, entry.Value)
+
+ case CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE:
+ return fmt.Sprintf(
+ "Multiple flash_owner settings specify the same flash area\n"+
+ " settings: %s\n"+
+ " flash area: %s\n",
+ strings.Join(conflict.SettingNames, ", "),
+ entry.Value)
+
+ default:
+ panic("Invalid flash conflict code: " + string(conflict.Code))
+ }
+}
+
+func historyTextOnce(settingName string, points []CfgPoint) string {
+ return fmt.Sprintf(" %s: %s\n", settingName, historyToString(points))
+}
+
+func historyText(historyMap map[string][]CfgPoint) string {
+ if len(historyMap) == 0 {
+ return ""
+ }
+
+ str := "Setting history (newest -> oldest):\n"
+ names := make([]string, 0, len(historyMap))
+ for name, _ := range historyMap {
+ names = append(names, name)
+ }
+ sort.Strings(names)
+
+ for _, name := range names {
+ points := historyMap[name]
+ str += historyTextOnce(name, points)
+ }
+
+ return str
+}
+
func (cfg *Cfg) ErrorText() string {
str := ""
- interestingNames := map[string]struct{}{}
+ historyMap := map[string][]CfgPoint{}
if len(cfg.Violations) > 0 {
str += "Syscfg restriction violations detected:\n"
for settingName, rslice := range cfg.Violations {
- interestingNames[settingName] = struct{}{}
-
entry := cfg.Settings[settingName]
for _, r := range rslice {
- interestingNames[r.ReqSetting] = struct{}{}
+ for _, name := range r.relevantSettingNames() {
+ historyMap[name] = entry.History
+ }
str += " " + cfg.violationText(entry, r) + "\n"
}
}
@@ -551,7 +532,7 @@ func (cfg *Cfg) ErrorText() string {
for _, name := range settingNames {
entry := cfg.Settings[name]
- interestingNames[entry.Name] = struct{}{}
+ historyMap[entry.Name] = entry.History
str += " " + entry.ambiguityText()
}
}
@@ -560,31 +541,63 @@ func (cfg *Cfg) ErrorText() string {
str += "Lateral overrides detected (bottom-priority packages " +
"cannot override settings):\n"
for _, lateral := range cfg.Laterals {
- interestingNames[lateral.SettingName] = struct{}{}
+ entry := cfg.Settings[lateral.SettingName]
+ historyMap[lateral.SettingName] = entry.History
str += fmt.Sprintf(" Package: %s, Setting: %s\n",
lateral.PkgName, lateral.SettingName)
}
}
+ if len(cfg.FlashConflicts) > 0 {
+ str += "Flash errors detected:\n"
+ for _, conflict := range cfg.FlashConflicts {
+ for _, name := range conflict.SettingNames {
+ entry := cfg.Settings[name]
+ historyMap[name] = entry.History
+ }
+
+ str += " " + cfg.flashConflictErrorText(conflict)
+ }
+ }
+
if str == "" {
return ""
}
- str += "\nSetting history:\n"
- interestingSlice := make([]string, 0, len(interestingNames))
- for name, _ := range interestingNames {
- interestingSlice = append(interestingSlice, name)
+ str += "\n" + historyText(historyMap)
+
+ return strings.TrimSpace(str)
+}
+
+func (cfg *Cfg) WarningText() string {
+ str := ""
+
+ historyMap := map[string][]CfgPoint{}
+
+ if len(cfg.Orphans) > 0 {
+ settingNames := make([]string, len(cfg.Orphans))
+ i := 0
+ for k, _ := range cfg.Orphans {
+ settingNames[i] = k
+ i++
+ }
+ sort.Strings(settingNames)
+
+ str += "Ignoring override of undefined settings:"
+ for _, n := range settingNames {
+ historyMap[n] = cfg.Orphans[n]
+ str += fmt.Sprintf("\n %s", n)
+ }
}
- sort.Strings(interestingSlice)
- for _, name := range interestingSlice {
- entry := cfg.Settings[name]
- str += fmt.Sprintf(" %s: %s\n", name,
- historyToString(entry.History))
+ if str == "" {
+ return ""
}
- return strings.TrimSpace(str)
+ str += "\n" + historyText(historyMap)
+
+ return str
}
func escapeStr(s string) string {
@@ -663,7 +676,8 @@ func (cfg *Cfg) detectAmbiguities() {
}
func Read(lpkgs []*pkg.LocalPackage, apis []string,
- injectedSettings map[string]string, features map[string]bool) (Cfg, error) {
+ injectedSettings map[string]string, features map[string]bool,
+ flashMap flash.FlashMap) (Cfg, error) {
cfg := NewCfg()
for k, v := range injectedSettings {
@@ -707,6 +721,7 @@ func Read(lpkgs []*pkg.LocalPackage, apis []string,
cfg.detectAmbiguities()
cfg.detectViolations()
+ cfg.detectFlashConflicts(flashMap)
return cfg, nil
}
@@ -883,7 +898,7 @@ func writeSettings(cfg Cfg, w io.Writer) {
}
func write(cfg Cfg, w io.Writer) {
- WritePreamble(w)
+ fmt.Fprintf(w, newtutil.GeneratedPreamble())
fmt.Fprintf(w, "#ifndef H_MYNEWT_SYSCFG_\n")
fmt.Fprintf(w, "#define H_MYNEWT_SYSCFG_\n\n")
@@ -897,33 +912,15 @@ func write(cfg Cfg, w io.Writer) {
fmt.Fprintf(w, "#endif\n")
}
-func writeRequired(contents []byte, path string) (bool, error) {
- oldHeader, err := ioutil.ReadFile(path)
- if err != nil {
- if os.IsNotExist(err) {
- // File doesn't exist; write required.
- return true, nil
- }
-
- return true, util.NewNewtError(err.Error())
- }
-
- rc := bytes.Compare(oldHeader, contents)
- return rc != 0, nil
-}
-
-func headerPath(includeDir string) string {
- return fmt.Sprintf("%s/%s/%s", includeDir, SYSCFG_INCLUDE_SUBDIR,
- SYSCFG_HEADER_FILENAME)
-}
-
func EnsureWritten(cfg Cfg, includeDir string) error {
+ // XXX: Detect these problems at error text generation time.
if err := calcPriorities(cfg, CFG_SETTING_TYPE_TASK_PRIO,
SYSCFG_TASK_PRIO_MAX, false); err != nil {
return err
}
+ // XXX: Detect these problems at error text generation time.
if err := calcPriorities(cfg, CFG_SETTING_TYPE_INTERRUPT_PRIO,
SYSCFG_INTERRUPT_PRIO_MAX, true); err != nil {
@@ -933,9 +930,9 @@ func EnsureWritten(cfg Cfg, includeDir string) error {
buf := bytes.Buffer{}
write(cfg, &buf)
- path := headerPath(includeDir)
+ path := includeDir + "/" + HEADER_PATH
- writeReqd, err := writeRequired(buf.Bytes(), path)
+ writeReqd, err := util.FileContentsChanged(path, buf.Bytes())
if err != nil {
return err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/sysinit/sysinit.go
----------------------------------------------------------------------
diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
index 5d6d392..9835a3a 100644
--- a/newt/sysinit/sysinit.go
+++ b/newt/sysinit/sysinit.go
@@ -30,8 +30,8 @@ import (
log "github.com/Sirupsen/logrus"
+ "mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
- "mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/util"
)
@@ -89,7 +89,7 @@ func write(pkgs []*pkg.LocalPackage, isLoader bool,
}
sort.Ints(stages)
- syscfg.WritePreamble(w)
+ fmt.Fprintf(w, newtutil.GeneratedPreamble())
if isLoader {
fmt.Fprintf(w, "#if SPLIT_LOADER\n\n")
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/newt/vendor/mynewt.apache.org/newt/util/util.go
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/util/util.go b/newt/vendor/mynewt.apache.org/newt/util/util.go
index e90ddbc..2cda3e8 100644
--- a/newt/vendor/mynewt.apache.org/newt/util/util.go
+++ b/newt/vendor/mynewt.apache.org/newt/util/util.go
@@ -522,3 +522,18 @@ func IsNotExist(err error) bool {
return os.IsNotExist(err)
}
+
+func FileContentsChanged(path string, newContents []byte) (bool, error) {
+ oldContents, err := ioutil.ReadFile(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // File doesn't exist; write required.
+ return true, nil
+ }
+
+ return true, NewNewtError(err.Error())
+ }
+
+ rc := bytes.Compare(oldContents, newContents)
+ return rc != 0, nil
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/a441cdf5/util/util.go
----------------------------------------------------------------------
diff --git a/util/util.go b/util/util.go
index e90ddbc..2cda3e8 100644
--- a/util/util.go
+++ b/util/util.go
@@ -522,3 +522,18 @@ func IsNotExist(err error) bool {
return os.IsNotExist(err)
}
+
+func FileContentsChanged(path string, newContents []byte) (bool, error) {
+ oldContents, err := ioutil.ReadFile(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // File doesn't exist; write required.
+ return true, nil
+ }
+
+ return true, NewNewtError(err.Error())
+ }
+
+ rc := bytes.Compare(oldContents, newContents)
+ return rc != 0, nil
+}