Skip to content

Commit

Permalink
Merge branch 'develop-fprime' into develop. Close #77.
Browse files Browse the repository at this point in the history
**Description**

We have determined that supporting FPrime would generally be useful for Ogma
and related projects (e.g., FRET). a backend for FPrime should be officially
added.

**Type**

- New feature.

**Additional context**

None.

**Requester**

- Ivan Perez

**Method to check presence of bug**

The following following Dockerfile uses the accompanying FRET component
specification containing inequalities in the TL formulas to generate the FPrime
monitoring component and the Copilot monitors. The output produces a second
Dockerfile that can be used to compile the generated monitoring component as
part of FPrime's reference application. The `fprime-variables-db` file added
contains an extra variable just to add some noise to the test:

```Dockerfile
--- Dockerfile-verify-77
FROM ubuntu:trusty

RUN apt-get update

RUN apt-get install --yes software-properties-common
RUN add-apt-repository ppa:hvr/ghc
RUN apt-get update

RUN apt-get install --yes ghc-8.6.5 cabal-install-2.4
RUN apt-get install --yes libz-dev

ENV PATH=/opt/ghc/8.6.5/bin:/opt/cabal/2.4/bin:$PWD/.cabal-sandbox/bin:$PATH

RUN cabal update
RUN cabal v1-sandbox init
RUN cabal v1-install alex happy
RUN cabal v1-install copilot
RUN apt-get install --yes git

ADD file.json .
ADD fprime-variable-db .

CMD git clone $REPO && \
    cd $NAME && \
    git checkout $COMMIT && \
    cd .. && \
    cabal v1-install $NAME/$PAT**/ --enable-tests && \
    ogma fprime --app-target-dir fprime_demo --fret-file-name file.json --variable-db fprime-variable-db && \
    ogma fret-component-spec --fret-file-name file.json > Spec.hs && \
    sed -i -e 's/"fret/"copilot/g' Spec.hs && \
    cabal v1-exec -- runhaskell Spec.hs && \
    mv copilot.c copilot.h copilot_types.h fprime_demo/

--- fprime-variable-db
("pullup", "bool")
("input", "float")

--- file.json
{
  "mySpec": {
    "Internal_variables": [ ],
    "Other_variables": [ {"name":"input", "type":"real"} ],
    "Functions": [ ],
    "Requirements": [
      { "name": "REQ",
        "ptLTL": "(H (input != 30.0))",
        "CoCoSpecCode": "(H( input <> 30.0 ))",
        "fretish": "Irrelevant for the example"
      }
    ]
  }
}
```
Command (substitute variables based on new path after merge):
```sh
$ docker run -v $PWD/output:/fprime_demo -e "REPO=https://github.com/NASA/ogma" -e "NAME=ogma" -e PAT="ogma-" -e "COMMIT=<HASH>" -it ogma-verify-77
$ cd output/
$ docker build -t ogma-verify-77-fprime .
```

**Expected result**

Ogma provides a new command to generate a FPrime monitoring component, akin to
the one provided for cFS.

**Solution implemented**

Update `ogma-core` with the new command to generate FPrime package. Expose
command via `ogma-cli`.

The command produces a dockerfile, which can be used to build the generated
monitor inside FPrime's reference application (for testing purposes).

The documentation of the Main modules and Cabal files.

The README is updated with a new section explaining the backend, and providing
precise instructions to test it.

**Further notes**

None.
  • Loading branch information
ivanperez-keera committed Mar 21, 2023
2 parents 04802db + 76fc7b0 commit 07afa55
Show file tree
Hide file tree
Showing 12 changed files with 1,095 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ogma-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Revision history for ogma-cli

## [1.X.Y] - 2023-03-21

* Introduce new F' (FPrime) backend (#77).

## [1.0.7] - 2023-01-21
* Version bump 1.0.7 (#69).
* Replace tabs in cabal file (#69).
Expand Down
119 changes: 119 additions & 0 deletions ogma-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ verification framework that generates hard real-time C99 code.
- Generating [Robot Operating System](https://ros.org) applications that use
Copilot for monitoring data published in different topics.

- Generating [F' (FPrime)](https://github.com/nasa/fprime/) components that use
Copilot for monitoring data published in different ports.


<p align="center">
<img src="https://raw.githubusercontent.com/nasa/ogma/gh-pages/images/fret-to-c.gif" alt="Conversion of requirements into C code">
Expand All @@ -45,6 +48,7 @@ verification framework that generates hard real-time C99 code.
- [cFS Application Generation](#cfs-application-generation)
- [Struct Interface Generation](#struct-interface-generation)
- [ROS Application Generation](#ros-application-generation)
- [F' Component Generation](#f-component-generation)
- [Contributions](#contributions)
- [Acknowledgements](#acknowledgements)
- [License](#license)
Expand Down Expand Up @@ -108,6 +112,7 @@ Available commands:
structs Generate Copilot structs from C structs
handlers Generate message handlers from C structs
cfs Generate a complete cFS/Copilot application
fprime Generate a complete F' monitoring component
fret-component-spec Generate a Copilot file from a FRET Component
Specification
fret-reqs-db Generate a Copilot file from a FRET Requirements
Expand Down Expand Up @@ -442,6 +447,120 @@ be generated for any variables for which a DB entry cannot be found. At present,
Ogma will proceed without warnings if a variable is mentioned in a requirement
or variables file but a matching entry is not found in the variable DB.
## F' Component Generation
F' (FPrime) is a component-based framework for spaceflight applications.
Ogma is able to generate F' monitoring components that subscribe to obtain
the data needed by the monitors and report any violations. At present, support
for F' component generation is considered preliminary.
F' components are generated using the Ogma command `fprime`, which receives
five main arguments:
- `--app-target-dir DIR`: location where the F' application files must be
stored.
- `--fret-file-name FILENAME`: a file containing a FRET component specification.
- `--variable-file FILENAME`: a file containing a list of variables that must
be made available to the monitor.
- `--variable-db FILENAME`: a file containing a database of known variables,
and their types.
- `--handlers FILENAME`: a file containing a list of handlers used in the
specification.
Not all arguments are mandatory. You should always provide either a FRET
component specification, or both a variable file and a handlers file. If you
provide a variables file or a handler file _and_ a FRET component
specification, the variables/handlers file will always take precedence, and the
variables/requirements listed in the FRET component specification file will be
ignored.
The following execution generates an initial F' component for runtime
monitoring using Copilot:
```sh
$ ogma fprime --fret-file-name Export.json --variable-db fprime-variable-db --app-target-dir fprime_demo
```
The component generated by Ogma contains the following files:
```
fprime_demo/CMakeLists.txt
fprime_demo/Copilot.fpp
fprime_demo/Copilot.cpp
fprime_demo/Copilot.hpp
fprime_demo/Dockerfile
fprime_demo/inline-copilot
```
For completion, the following execution should compile the produced monitoring
component in a docker environment (assuming that the necessary `Export.json`,
`fprime-variable-db` files exist, they have consistent information, etc.) using
FPrime's Reference Application:
```sh
$ ogma fprime --fret-file-name Export.json --variable-db fprime-variable-db --app-target-dir fprime_demo
$ ogma fret-component-spec --fret-file-name Export.json > Spec.hs
$ sed -i -e 's/compile "fret"/compile "copilot"/g' Spec.hs
$ cd fprime_demo/
$ runhaskell ../Spec.hs
$ docker build -t fprime .
```
### File formats
The format of the variables, variable DB, and handlers file are as follows.
The variables file can contain a list of variables used in a specification, one
per line. For example, if we are working with a specification that uses three
boolean variables called `autopilot`, `sensorLimitsExceeded`, and `pullup`, we
can provide them to Ogma's `fprime` command in a file like the following:
```sh
$ cat variables
autopilot
sensorLimitsExceeded
pullup
```
The variables database file contains a list of known variables and their types.
It does not matter if there are variables that are not used for one particular
specification, FRET file, or requirement/monitor. The only thing that matters
is that the variables used, and their types, be listed in the file. Continuing
with the same example, we could have:
```sh
$ cat fprime-variable-db
("temperature", "uint8_t")
("autopilot", "bool")
("sensorLimitsExceeded", "bool")
("pullup", "bool")
("current_consumption", "float")
```
In our example, we only care about the boolean variables; it is sufficient that
they be listed in the variable DB file.
Finally, the handlers file is a list of monitor handlers that the generated
FPrime component should restrict to monitoring. They are listed one per line:
```sh
$ cat handlers
handlerpropREQ_001
```
Note that the handler name must match the one used by Copilot. Ogma transforms
requirement names to ensure that they corresponding handlers are valid C
identifiers. For example, the Ogma-generated monitor for a FRET requirement
`REQ_001` would, upon violation, call a C handler `handlerpropREQ_001`. The
transformation only applies if you are working with FRET files and not directly
with other source languages.
### Current limitations
The user must place the code generated by Copilot monitors in three files,
`fprime_demo/src/copilot.h`, `fprime_demo/src/copilot_types.h` and
`fprime_demo/src/copilot.c`. No Copilot or C code for the monitors is generated
by default by the `fprime` command.
The code generated by default assumes that handlers receive no arguments. The
user must modify the handlers accordingly if that is not the case.
## Struct Interface Generation
A lot of the information that must be monitored in real-world C applications is
Expand Down
2 changes: 2 additions & 0 deletions ogma-cli/ogma-cli.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ description: Ogma is a tool to facilitate the integration of safe runtim
> structs Generate Copilot structs from C structs
> handlers Generate message handlers from C structs
> cfs Generate a complete CFS/Copilot application
> fprime Generate a complete F' monitoring component
> fret-component-spec Generate a Copilot file from a FRET Component
> Specification
> fret-reqs-db Generate a Copilot file from a FRET Requirements
Expand Down Expand Up @@ -117,6 +118,7 @@ executable ogma
CLI.CommandCFSApp
CLI.CommandCStructs2Copilot
CLI.CommandCStructs2MsgHandlers
CLI.CommandFPrimeApp
CLI.CommandFretComponentSpec2Copilot
CLI.CommandFretReqsDB2Copilot
CLI.CommandROSApp
Expand Down
148 changes: 148 additions & 0 deletions ogma-cli/src/CLI/CommandFPrimeApp.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
-- Copyright 2022 United States Government as represented by the Administrator
-- of the National Aeronautics and Space Administration. All Rights Reserved.
--
-- Disclaimers
--
-- No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY
-- OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
-- LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
-- SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE
-- SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF
-- PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN
-- ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR
-- RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR
-- ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER,
-- GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING
-- THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES
-- IT "AS IS."
--
-- Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST
-- THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS
-- ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN
-- ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM SUCH USE,
-- INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S
-- USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS THE
-- UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY
-- PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY
-- FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS
-- AGREEMENT.
--
-- | CLI interface to the FPrimeApp subcommand.
module CLI.CommandFPrimeApp
(
-- * Direct command access
command
, CommandOpts
, ErrorCode

-- * CLI
, commandDesc
, commandOptsParser
)
where

-- External imports
import Options.Applicative ( Parser, help, long, metavar, optional, showDefault,
strOption, value )

-- External imports: command results
import Command.Result ( Result )

-- External imports: actions or commands supported
import Command.FPrimeApp ( ErrorCode, fprimeApp )

-- * Command

-- | Options needed to generate the FPrime component.
data CommandOpts = CommandOpts
{ fprimeAppTarget :: String
, fprimeAppFRETFile :: Maybe String
, fprimeAppVarNames :: Maybe String
, fprimeAppVarDB :: Maybe String
, fprimeAppHandlers :: Maybe String
}

-- | Create <https://github.com/nasa/fprime FPrime> component that subscribe
-- to obtain necessary data from the bus and call Copilot when new data
-- arrives.
--
-- This is just an uncurried version of "Command.fprimeApp".
command :: CommandOpts -> IO (Result ErrorCode)
command c =
fprimeApp
(fprimeAppTarget c)
(fprimeAppFRETFile c)
(fprimeAppVarNames c)
(fprimeAppVarDB c)
(fprimeAppHandlers c)

-- * CLI

-- | FPrime command description
commandDesc :: String
commandDesc = "Generate a complete F' monitoring component"

-- | Subparser for the @fprime@ command, used to generate an FPrime component
-- connected to Copilot monitors.
commandOptsParser :: Parser CommandOpts
commandOptsParser = CommandOpts
<$> strOption
( long "app-target-dir"
<> metavar "DIR"
<> showDefault
<> value "fprime"
<> help strFPrimeAppDirArgDesc
)
<*> optional
( strOption
( long "fret-file-name"
<> metavar "FILENAME"
<> help strFPrimeAppFRETFileNameArgDesc
)
)
<*> optional
( strOption
( long "variable-file"
<> metavar "FILENAME"
<> help strFPrimeAppVarListArgDesc
)
)
<*> optional
( strOption
( long "variable-db"
<> metavar "FILENAME"
<> help strFPrimeAppVarDBArgDesc
)
)
<*> optional
( strOption
( long "handlers-file"
<> metavar "FILENAME"
<> help strFPrimeAppHandlerListArgDesc
)
)

-- | Argument target directory to FPrime component generation command
strFPrimeAppDirArgDesc :: String
strFPrimeAppDirArgDesc = "Target directory"

-- | Argument FRET CS to FPrime component generation command
strFPrimeAppFRETFileNameArgDesc :: String
strFPrimeAppFRETFileNameArgDesc =
"File containing FRET Component Specification"

-- | Argument variable list to FPrime component generation command
strFPrimeAppVarListArgDesc :: String
strFPrimeAppVarListArgDesc =
"File containing list of F' variables to make accessible"

-- | Argument variable database to FPrime component generation command
strFPrimeAppVarDBArgDesc :: String
strFPrimeAppVarDBArgDesc =
"File containing a DB of known F' variables"

-- | Argument handler list to FPrime component generation command
strFPrimeAppHandlerListArgDesc :: String
strFPrimeAppHandlerListArgDesc =
"File containing list of Copilot handlers used in the specification"
14 changes: 14 additions & 0 deletions ogma-cli/src/CLI/CommandTop.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import Command.Result ( Result )
import qualified CLI.CommandCFSApp
import qualified CLI.CommandCStructs2Copilot
import qualified CLI.CommandCStructs2MsgHandlers
import qualified CLI.CommandFPrimeApp
import qualified CLI.CommandFretComponentSpec2Copilot
import qualified CLI.CommandFretReqsDB2Copilot
import qualified CLI.CommandROSApp
Expand All @@ -104,6 +105,7 @@ data CommandOpts =
CommandOptsCFSApp CLI.CommandCFSApp.CommandOpts
| CommandOptsCStructs2Copilot CLI.CommandCStructs2Copilot.CommandOpts
| CommandOptsCStructs2MsgHandlers CLI.CommandCStructs2MsgHandlers.CommandOpts
| CommandOptsFPrimeApp CLI.CommandFPrimeApp.CommandOpts
| CommandOptsFretComponentSpec2Copilot CLI.CommandFretComponentSpec2Copilot.CommandOpts
| CommandOptsFretReqsDB2Copilot CLI.CommandFretReqsDB2Copilot.CommandOpts
| CommandOptsROSApp CLI.CommandROSApp.CommandOpts
Expand All @@ -121,6 +123,7 @@ commandOptsParser = subparser
( subcommandCStructs
<> subcommandMsgHandlers
<> subcommandCFSApp
<> subcommandFPrimeApp
<> subcommandFretComponentSpec
<> subcommandFretReqs
<> subcommandROSApp
Expand Down Expand Up @@ -187,6 +190,15 @@ subcommandROSApp =
(CommandOptsROSApp <$> CLI.CommandROSApp.commandOptsParser)
CLI.CommandROSApp.commandDesc

-- | Modifier for the FPrime app expansion subcommand, linking the subcommand
-- options and description to the command @fprime@ at top level.
subcommandFPrimeApp :: Mod CommandFields CommandOpts
subcommandFPrimeApp =
subcommand
"fprime"
(CommandOptsFPrimeApp <$> CLI.CommandFPrimeApp.commandOptsParser)
CLI.CommandFPrimeApp.commandDesc

-- * Command dispatcher

-- | Command dispatcher that obtains the parameters from the command line and
Expand Down Expand Up @@ -215,6 +227,8 @@ command (CommandOptsCStructs2Copilot c) =
id <$> CLI.CommandCStructs2Copilot.command c
command (CommandOptsCStructs2MsgHandlers c) =
id <$> CLI.CommandCStructs2MsgHandlers.command c
command (CommandOptsFPrimeApp c) =
id <$> CLI.CommandFPrimeApp.command c
command (CommandOptsFretComponentSpec2Copilot c) =
id <$> CLI.CommandFretComponentSpec2Copilot.command c
command (CommandOptsFretReqsDB2Copilot c) =
Expand Down
2 changes: 2 additions & 0 deletions ogma-cli/src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
-- * Generate Robot Operating System (ROS) applications for runtime monitoring
-- using Copilot.
--
-- * Generate F' (FPrime) components for runtime monitoring using Copilot.
--
-- More information can be obtained by calling ogma with the argument @--help@.
module Main
( main )
Expand Down
3 changes: 2 additions & 1 deletion ogma-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Revision history for ogma-core

## [1.X.Y] - 2023-02-01
## [1.X.Y] - 2023-03-21

* Support inequality operator in SMV and CoCoSpec (#71).
* Introduce new F' (FPrime) backend (#77).

## [1.0.7] - 2023-01-21
* Version bump 1.0.7 (#69).
Expand Down
Loading

0 comments on commit 07afa55

Please sign in to comment.