Hello,
for the RTEMS pre-qualification activity we need a specification of
RTEMS. I would like to use this opportunity to move structured
information which is present in hand written and hand formatted content
in the RTEMS documentation into a structured data format (YAML).
Documentation source files can be generated from the YAML files. Having
information available in an easily machine readable format with
meta-information gives us a lot of flexibility. For example to adjust
the presentation we just have to change the generator program and not
the hand written content. The presentation of things may depend on the
standard of interest, e.g. ECSS, IEC 61508, ISO 26262, DO-178C, etc.
To get started, I would like to use the glossary of terms and the
application configuration as a use case. The conversion from hand
written and hand formatted content to generated content needs three things:
1. A definition of the data format (YAML with Doorstop attributes)
2. The specification items in the defined data format.
3. A generator program which uses the specification items as input and
outputs the documentation source files.
The new build system introduced build specification items in the RTEMS
sources under "spec/build". I would like to place all of the RTEMS
specification under the "spec" directory. For the glossary I propose to
use "spec/glossary". For the application configuration categories I
propose "spec/cfg" and for the application configuration options
"spec/cfg/opt". The layout of the application configuration items
enables an easy reassignment of options to categories.
The definition of the data format should be added to the RTEMS Software
Engineering manual to the Software Requirements Engineering chapter.
The generator program should be written in Python and placed into the
rtems-tools repository. The generator program needs paths to the RTEMS
sources and the RTEMS documentation sources. The paths should be
specified via the command line.
For a proof-of-concept please have a look at the attached two patches.
What do you think of it?
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>From cfaad1b7feb8fae9dc89ffe7d245a231e9e55c7d Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.hu...@embedded-brains.de>
Date: Tue, 10 Dec 2019 14:40:08 +0100
Subject: [PATCH 1/2] spec/cfg: Add application configuration
Update #3836.
---
rtems-to-x.py | 194 +++++++++++++++++++++++++
spec/RTEMS-CONFIG.yml | 14 ++
spec/cfg/.doorstop.yml | 12 ++
spec/cfg/RTEMS-CFG-GENERAL.yml | 14 ++
spec/cfg/opt/.doorstop.yml | 13 ++
spec/cfg/opt/RTEMS-CFG-OPT-EXTRATASKSTACKS.yml | 31 ++++
6 files changed, 278 insertions(+)
create mode 100755 rtems-to-x.py
create mode 100644 spec/RTEMS-CONFIG.yml
create mode 100644 spec/cfg/.doorstop.yml
create mode 100644 spec/cfg/RTEMS-CFG-GENERAL.yml
create mode 100644 spec/cfg/opt/.doorstop.yml
create mode 100644 spec/cfg/opt/RTEMS-CFG-OPT-EXTRATASKSTACKS.yml
diff --git a/rtems-to-x.py b/rtems-to-x.py
new file mode 100755
index 0000000000..6ea44a7862
--- /dev/null
+++ b/rtems-to-x.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (C) 2019 embedded brains GmbH
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+from __future__ import print_function
+
+import os
+import stat
+import yaml
+
+
+class Item(object):
+ items = {}
+ top_level = {}
+
+ def __init__(self, uid, data):
+ self.uid = uid
+ self._data = data
+ self.links = self._init_links
+ self.children = []
+ if not self._data["links"]:
+ Item.top_level[uid] = self
+ Item.items[uid] = self
+
+ def _init_links(self):
+ self._links = []
+ for l in self._data["links"]:
+ self._links.append(Item.items[list(l.keys())[0]])
+ # self._links.sort(key=lambda x: x._data["order"])
+ self.links = self._yield_links
+ for l in self._links:
+ yield l
+
+ def _yield_links(self):
+ for l in self._links:
+ yield l
+
+ @staticmethod
+ def _is_enabled(enabled, enabled_by):
+ if enabled_by:
+ if isinstance(enabled_by, list):
+ for e in enabled_by:
+ if Item._is_enabled(enabled, e):
+ return True
+ elif isinstance(enabled_by, dict):
+ if len(enabled_by) == 1:
+ if "and" in enabled_by:
+ for e in enabled_by["and"]:
+ if not Item._is_enabled(enabled, e):
+ return False
+ return True
+ elif "not" in enabled_by:
+ return not Item._is_enabled(enabled, enabled_by["not"])
+ elif "or" in enabled_by:
+ for e in enabled_by["or"]:
+ if Item._is_enabled(enabled, e):
+ return True
+ else:
+ return enabled_by in enabled
+ return False
+ return True
+
+ def substitute(self, value):
+ return Template(value).substitute(self._data)
+
+ def get(self, name):
+ return self.substitute(self._data[name])
+
+ def __getitem__(self, name):
+ return self._data[name]
+
+
+class Content(object):
+ def __init__(self):
+ self.content = ""
+ self.copyrights = []
+
+ def addLabel(self, label):
+ self.content += ".. _" + label.strip() + ":\n"
+
+ def addHeader(self, name, level="="):
+ name = name.strip()
+ self.content += name + "\n" + level * len(name) + "\n"
+
+ def addBlankLine(self):
+ self.content += "\n"
+
+ def addLine(self, line, indent=0):
+ self.content += indent * " " + line + "\n"
+
+ def addIndexEntries(self, entries):
+ first = True
+ for entry in entries:
+ if first:
+ first = False
+ self.addBlankLine()
+ self.content += ".. index:: " + entry + "\n"
+
+ def addDefinitionItem(self, name, lines, indent=0):
+ first = True
+ for line in lines:
+ if first:
+ first = False
+ self.addBlankLine()
+ self.addLine(name, indent)
+ self.addLine(line, indent=indent + 1)
+
+
+def applicationConfigurationOptionContent(item, content):
+ content.addIndexEntries(item["index"])
+ content.addBlankLine()
+ header = item["header"]
+ content.addLabel(header)
+ content.addBlankLine()
+ content.addHeader(header)
+ content.addDefinitionItem("DESCRIPTION:", item["description"].split("\n"))
+ content.addDefinitionItem("NOTES:", item["notes"].split("\n"))
+
+
+def applicationConfigurationGroupContent(item, document):
+ content = Content()
+ for c in item.children:
+ if (
+ c["type"] == "interface"
+ and c["interface-type"] == "application-configuration-option"
+ ):
+ applicationConfigurationOptionContent(c, content)
+ else:
+ raise Exception("unexpected item type")
+ print(content.content)
+
+
+def classicAPIGuideContent(item, document):
+ for c in item.children:
+ if (
+ c["type"] == "interface"
+ and c["interface-type"] == "application-configuration-group"
+ ):
+ applicationConfigurationGroupContent(c, document)
+ else:
+ classicAPIGuideContent(c, document)
+
+
+def load(path):
+ names = os.listdir(path)
+ for name in names:
+ path2 = os.path.join(path, name)
+ if name == "build":
+ continue
+ elif name.endswith(".yml") and not name.startswith("."):
+ uid = os.path.basename(name).replace(".yml", "")
+ with open(path2, "r") as f:
+ data = yaml.safe_load(f.read())
+ Item(uid, data)
+ else:
+ mode = os.lstat(path2).st_mode
+ if stat.S_ISDIR(mode):
+ load(path2)
+
+
+def init_children():
+ for item in Item.items.values():
+ for p in item.links():
+ p.children.append(item)
+
+
+load("spec")
+init_children()
+
+for item in Item.top_level.values():
+ classicAPIGuideContent(item, "c-user")
diff --git a/spec/RTEMS-CONFIG.yml b/spec/RTEMS-CONFIG.yml
new file mode 100644
index 0000000000..24f0534208
--- /dev/null
+++ b/spec/RTEMS-CONFIG.yml
@@ -0,0 +1,14 @@
+active: true
+derived: false
+header: |
+ Application Configuration
+level: 1.1
+links: []
+normative: true
+ref: ''
+reviewed: 9csHKCHyZG6FZVXFAx4XGBlupXUClQvvKtzRX0imWoE=
+text: |
+ The system shall provide configuration options to define configurable
+ parameters.
+requirement-type: usability
+type: requirement
diff --git a/spec/cfg/.doorstop.yml b/spec/cfg/.doorstop.yml
new file mode 100644
index 0000000000..3f21cfc3a4
--- /dev/null
+++ b/spec/cfg/.doorstop.yml
@@ -0,0 +1,12 @@
+settings:
+ digits: 3
+ parent: RTEMS
+ prefix: RTEMS-CFG
+ sep: '-'
+attributes:
+ defaults:
+ enabled-by: []
+ type: configuration-group
+ reviewed:
+ - enabled-by
+ - type
diff --git a/spec/cfg/RTEMS-CFG-GENERAL.yml b/spec/cfg/RTEMS-CFG-GENERAL.yml
new file mode 100644
index 0000000000..c2a681a5f3
--- /dev/null
+++ b/spec/cfg/RTEMS-CFG-GENERAL.yml
@@ -0,0 +1,14 @@
+active: true
+derived: false
+enabled-by: []
+header: |
+ General System Configuration
+level: 1.0
+links:
+- RTEMS-CONFIG: null
+normative: true
+ref: ''
+reviewed: mnEcDbKcPQfFtABUKH287up7ae9HVAyM77Px5GywXQQ=
+text: ''
+interface-type: application-configuration-group
+type: interface
diff --git a/spec/cfg/opt/.doorstop.yml b/spec/cfg/opt/.doorstop.yml
new file mode 100644
index 0000000000..f0bb0bd0e4
--- /dev/null
+++ b/spec/cfg/opt/.doorstop.yml
@@ -0,0 +1,13 @@
+settings:
+ digits: 3
+ parent: RTEMS-CFG
+ prefix: RTEMS-CFG-OPT
+ sep: '-'
+attributes:
+ defaults:
+ enabled-by: []
+ type: configuration-option
+ reviewed:
+ - enabled-by
+ - data-type
+ - type
diff --git a/spec/cfg/opt/RTEMS-CFG-OPT-EXTRATASKSTACKS.yml b/spec/cfg/opt/RTEMS-CFG-OPT-EXTRATASKSTACKS.yml
new file mode 100644
index 0000000000..d28e10c1d9
--- /dev/null
+++ b/spec/cfg/opt/RTEMS-CFG-OPT-EXTRATASKSTACKS.yml
@@ -0,0 +1,31 @@
+active: true
+option-kind:
+ type: integer
+ default: 0
+ min: 0
+ max: SSIZE_MAX
+derived: false
+description: |
+ This configuration parameter is set to the number of bytes the applications
+ wishes to add to the task stack requirements calculated by
+ ``<rtems/confdefs.h>``.
+enabled-by: []
+header: |
+ CONFIGURE_EXTRA_TASK_STACKS
+index:
+- memory for task tasks
+level: 1.1
+links:
+- RTEMS-CFG-GENERAL: null
+normative: true
+notes: |
+ This parameter is very important. If the application creates tasks with
+ stacks larger then the minimum, then that memory is **not** accounted for by
+ ``<rtems/confdefs.h>``.
+ref: ''
+reviewed: 5-iRx9oeb96ITAYzOUVWEUvRLEha58GJl9AyFUAXM6o=
+text: |
+ The ${header} application configuration option shall add the
+ :term:`user-specified` value to the configured task stack space size.
+interface-type: application-configuration-option
+type: interface
--
2.16.4
>From b7f2abe103f56a597b56fd64153323840f053471 Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.hu...@embedded-brains.de>
Date: Wed, 8 Jan 2020 15:11:04 +0100
Subject: [PATCH 2/2] spec/glossary: Support a glossary
---
rtems-to-x.py | 20 ++++++++++++++++++++
spec/RTEMS-GLOSSARY.yml | 13 +++++++++++++
spec/glossary/.doorstop.yml | 12 ++++++++++++
spec/glossary/RTEMS-GLOSSARY-ABI.yml | 13 +++++++++++++
spec/glossary/RTEMS-GLOSSARY-ACTIVE.yml | 15 +++++++++++++++
5 files changed, 73 insertions(+)
create mode 100644 spec/RTEMS-GLOSSARY.yml
create mode 100644 spec/glossary/.doorstop.yml
create mode 100644 spec/glossary/RTEMS-GLOSSARY-ABI.yml
create mode 100644 spec/glossary/RTEMS-GLOSSARY-ACTIVE.yml
diff --git a/rtems-to-x.py b/rtems-to-x.py
index 6ea44a7862..162b54087a 100755
--- a/rtems-to-x.py
+++ b/rtems-to-x.py
@@ -164,6 +164,13 @@ def classicAPIGuideContent(item, document):
classicAPIGuideContent(c, document)
+def gatherGlossary(item, glossary):
+ for c in item.children:
+ gatherGlossary(c, glossary)
+ if item["type"] == "glossary":
+ glossary.append(item)
+
+
def load(path):
names = os.listdir(path)
for name in names:
@@ -192,3 +199,16 @@ init_children()
for item in Item.top_level.values():
classicAPIGuideContent(item, "c-user")
+
+glossary = []
+for item in Item.top_level.values():
+ gatherGlossary(item, glossary)
+glossary.sort(key=lambda x: x["header"])
+glossaryContent = Content()
+glossaryContent.addLine(".. glossary::")
+glossaryContent.addLine(":sorted:", indent=1)
+for g in glossary:
+ glossaryContent.addDefinitionItem(
+ g["header"], g["text"].split("\n"), indent=1
+ )
+print(glossaryContent.content)
diff --git a/spec/RTEMS-GLOSSARY.yml b/spec/RTEMS-GLOSSARY.yml
new file mode 100644
index 0000000000..357aabf5a7
--- /dev/null
+++ b/spec/RTEMS-GLOSSARY.yml
@@ -0,0 +1,13 @@
+active: true
+derived: false
+header: |
+ Glossary
+level: 1.2
+links: []
+normative: true
+ref: ''
+reviewed: 9csHKCHyZG6FZVXFAx4XGBlupXUClQvvKtzRX0imWoE=
+text: |
+ The system shall have a glossary of terms.
+requirement-type: documentation
+type: requirement
diff --git a/spec/glossary/.doorstop.yml b/spec/glossary/.doorstop.yml
new file mode 100644
index 0000000000..237bc65161
--- /dev/null
+++ b/spec/glossary/.doorstop.yml
@@ -0,0 +1,12 @@
+settings:
+ digits: 3
+ parent: RTEMS
+ prefix: RTEMS-GLOSSARY
+ sep: '-'
+attributes:
+ defaults:
+ enabled-by: []
+ type: glossary-term
+ reviewed:
+ - enabled-by
+ - type
diff --git a/spec/glossary/RTEMS-GLOSSARY-ABI.yml b/spec/glossary/RTEMS-GLOSSARY-ABI.yml
new file mode 100644
index 0000000000..5546d6ba3d
--- /dev/null
+++ b/spec/glossary/RTEMS-GLOSSARY-ABI.yml
@@ -0,0 +1,13 @@
+active: true
+derived: false
+enabled-by: []
+header: 'ABI'
+level: 1.1
+links:
+- RTEMS-GLOSSARY: null
+normative: true
+ref: ''
+reviewed: null
+text: 'Application Binary Interface'
+glossary-type: acronym
+type: glossary
diff --git a/spec/glossary/RTEMS-GLOSSARY-ACTIVE.yml b/spec/glossary/RTEMS-GLOSSARY-ACTIVE.yml
new file mode 100644
index 0000000000..bc787ad971
--- /dev/null
+++ b/spec/glossary/RTEMS-GLOSSARY-ACTIVE.yml
@@ -0,0 +1,15 @@
+active: true
+derived: false
+enabled-by: []
+header: 'active'
+level: 1.1
+links:
+- RTEMS-GLOSSARY: null
+normative: true
+ref: ''
+reviewed: null
+text: |
+ A term used to describe an object which has been created by an
+ application.
+glossary-type: term
+type: glossary
--
2.16.4
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel