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 2018/10/23 17:47:59 UTC
[mynewt-newt] 02/02: sysdown: generate package shutdown function
This is an automated email from the ASF dual-hosted git repository.
ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git
commit 6cde3237a522448062936a6815219cf43f82873e
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Thu Oct 4 18:53:19 2018 -0700
sysdown: generate package shutdown function
Allow packages to specify a function to call when the system shuts down.
The syntax is:
pkg.down:
<C-function-name>: <stage-number>
e.g.,
pkg.down:
ble_hs_shutdown: 200
Lower stages execute before greater stages. If two or more callbacks
have the same stage, they are sorted alphabetically by C function name.
---
newt/builder/targetbuild.go | 23 +++++++++++
newt/pkg/localpackage.go | 23 ++++++++++-
newt/sysdown/sysdown.go | 97 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 1c2f8ba..e4ccc21 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -45,6 +45,7 @@ import (
"mynewt.apache.org/newt/newt/resolve"
"mynewt.apache.org/newt/newt/symbol"
"mynewt.apache.org/newt/newt/syscfg"
+ "mynewt.apache.org/newt/newt/sysdown"
"mynewt.apache.org/newt/newt/sysinit"
"mynewt.apache.org/newt/newt/target"
"mynewt.apache.org/newt/newt/toolchain"
@@ -172,6 +173,10 @@ func (t *TargetBuilder) ensureResolved() error {
appSeeds = append(appSeeds, t.testPkg)
}
+ // Indicate to the apache-mynewt-core code that this version of newt
+ // supports the sysdown mechanism (generated package shutdown functions).
+ t.injectedSettings["NEWT_FEATURE_SYSDOWN"] = "1"
+
var err error
t.res, err = resolve.ResolveFull(
loaderSeeds, appSeeds, t.injectedSettings, t.bspPkg.FlashMap)
@@ -237,6 +242,20 @@ func (t *TargetBuilder) generateSysinit() error {
return nil
}
+func (t *TargetBuilder) generateSysdown() error {
+ if err := t.ensureResolved(); err != nil {
+ return err
+ }
+
+ srcDir := GeneratedSrcDir(t.target.Name())
+
+ lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.AppSet.Rpkgs)
+ sysdown.EnsureWritten(lpkgs, t.res.Cfg, srcDir,
+ pkg.ShortName(t.target.Package()))
+
+ return nil
+}
+
func (t *TargetBuilder) generateFlashMap() error {
return t.bspPkg.FlashMap.EnsureWritten(
GeneratedSrcDir(t.target.Name()),
@@ -249,6 +268,10 @@ func (t *TargetBuilder) generateCode() error {
return err
}
+ if err := t.generateSysdown(); err != nil {
+ return err
+ }
+
if err := t.generateFlashMap(); err != nil {
return err
}
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index 6927b38..d5cc9a8 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -361,9 +361,10 @@ func (pkg *LocalPackage) Load() error {
}
pkg.init[name] = int(stage)
}
+
+ // Backwards compatibility: allow old sysinit notation.
initFnName := pkg.PkgY.GetValString("pkg.init_function", nil)
initStage := pkg.PkgY.GetValInt("pkg.init_stage", nil)
-
if initFnName != "" {
pkg.init[initFnName] = initStage
}
@@ -391,6 +392,26 @@ func (pkg *LocalPackage) Init() map[string]int {
return pkg.init
}
+// DownFuncs retrieves the package's shutdown functions. The returned map has:
+// key=C-function-name, value=numeric-stage.
+func (pkg *LocalPackage) DownFuncs(
+ settings map[string]string) (map[string]int, error) {
+
+ downFuncs := map[string]int{}
+
+ down := pkg.PkgY.GetValStringMapString("pkg.down", settings)
+ for name, stageStr := range down {
+ stage, err := strconv.ParseInt(stageStr, 10, 64)
+ if err != nil {
+ return nil, util.FmtNewtError("Parsing pkg %s config: %s",
+ pkg.FullName(), err.Error())
+ }
+ downFuncs[name] = int(stage)
+ }
+
+ return downFuncs, nil
+}
+
func (pkg *LocalPackage) InjectedSettings() map[string]string {
return pkg.injectedSettings
}
diff --git a/newt/sysdown/sysdown.go b/newt/sysdown/sysdown.go
new file mode 100644
index 0000000..060130e
--- /dev/null
+++ b/newt/sysdown/sysdown.go
@@ -0,0 +1,97 @@
+/**
+ * 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 sysdown
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "mynewt.apache.org/newt/newt/newtutil"
+ "mynewt.apache.org/newt/newt/pkg"
+ "mynewt.apache.org/newt/newt/stage"
+ "mynewt.apache.org/newt/newt/syscfg"
+)
+
+// downFuncs collects the sysdown functions corresponding to the provided
+// packages.
+func downFuncs(pkgs []*pkg.LocalPackage,
+ cfg syscfg.Cfg) ([]stage.StageFunc, error) {
+
+ fns := make([]stage.StageFunc, 0, len(pkgs))
+ for _, p := range pkgs {
+ downMap, err := p.DownFuncs(cfg.AllSettingsForLpkg(p))
+ if err != nil {
+ return nil, err
+ }
+
+ for name, stageNum := range downMap {
+ fn := stage.StageFunc{
+ Name: name,
+ Stage: stageNum,
+ ReturnType: "int",
+ ArgList: "int reason",
+ Pkg: p,
+ }
+ fns = append(fns, fn)
+ }
+ }
+
+ return fns, nil
+}
+
+func sortedDownFuncs(pkgs []*pkg.LocalPackage,
+ cfg syscfg.Cfg) ([]stage.StageFunc, error) {
+
+ fns, err := downFuncs(pkgs, cfg)
+ if err != nil {
+ return nil, err
+ }
+
+ stage.SortStageFuncs(fns, "sysdown")
+ return fns, nil
+}
+
+func write(pkgs []*pkg.LocalPackage, cfg syscfg.Cfg, w io.Writer) error {
+ fmt.Fprintf(w, newtutil.GeneratedPreamble())
+
+ fns, err := sortedDownFuncs(pkgs, cfg)
+ if err != nil {
+ return err
+ }
+
+ stage.WritePrototypes(fns, w)
+
+ fmt.Fprintf(w, "\nint (* const sysdown_cbs[])(int reason) = {\n")
+ stage.WriteArr(fns, w)
+ fmt.Fprintf(w, "};\n")
+
+ return nil
+}
+
+func EnsureWritten(pkgs []*pkg.LocalPackage, cfg syscfg.Cfg, srcDir string,
+ targetName string) error {
+
+ buf := bytes.Buffer{}
+ write(pkgs, cfg, &buf)
+
+ path := fmt.Sprintf("%s/%s-sysdown.c", srcDir, targetName)
+ return stage.EnsureWritten(path, buf.Bytes())
+}