fpp/docs/fpp-users-guide.html

16252 lines
597 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.23">
<title>The F Prime Prime (FPP) User&#8217;s Guide, Unreleased, after v3.0.0</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css">
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>The F Prime Prime (FPP) User&#8217;s Guide, Unreleased, after v3.0.0</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#Introduction">1. Introduction</a></li>
<li><a href="#Installing-FPP">2. Installing FPP</a></li>
<li><a href="#Defining-Constants">3. Defining Constants</a>
<ul class="sectlevel2">
<li><a href="#Defining-Constants_Writing-a-Constant-Definition">3.1. Writing a Constant Definition</a></li>
<li><a href="#Defining-Constants_Names">3.2. Names</a>
<ul class="sectlevel3">
<li><a href="#Defining-Constants_Names_Reserved-Words">3.2.1. Reserved Words</a></li>
<li><a href="#Defining-Constants_Names_Name-Clashes">3.2.2. Name Clashes</a></li>
</ul>
</li>
<li><a href="#Defining-Constants_Expressions">3.3. Expressions</a>
<ul class="sectlevel3">
<li><a href="#Defining-Constants_Expressions_Primitive-Values">3.3.1. Primitive Values</a></li>
<li><a href="#Defining-Constants_Expressions_String-Values">3.3.2. String Values</a></li>
<li><a href="#Defining-Constants_Expressions_Array-Values">3.3.3. Array Values</a></li>
<li><a href="#Defining-Constants_Expressions_Array-Elements">3.3.4. Array Elements</a></li>
<li><a href="#Defining-Constants_Expressions_Struct-Values">3.3.5. Struct Values</a></li>
<li><a href="#Defining-Constants_Expressions_Struct-Members">3.3.6. Struct Members</a></li>
<li><a href="#Defining-Constants_Expressions_Name-Expressions">3.3.7. Name Expressions</a></li>
<li><a href="#Defining-Constants_Expressions_Value-Arithmetic-Expressions">3.3.8. Value Arithmetic Expressions</a></li>
<li><a href="#Defining-Constants_Expressions_Compound-Expressions">3.3.9. Compound Expressions</a></li>
</ul>
</li>
<li><a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">3.4. Multiple Definitions and Element Sequences</a></li>
<li><a href="#Defining-Constants_Multiline-Definitions">3.5. Multiline Definitions</a></li>
<li><a href="#Defining-Constants_Framework-Constants">3.6. Framework Constants</a></li>
</ul>
</li>
<li><a href="#Writing-Comments-and-Annotations">4. Writing Comments and Annotations</a>
<ul class="sectlevel2">
<li><a href="#Writing-Comments-and-Annotations_Comments">4.1. Comments</a></li>
<li><a href="#Writing-Comments-and-Annotations_Annotations">4.2. Annotations</a></li>
</ul>
</li>
<li><a href="#Defining-Modules">5. Defining Modules</a></li>
<li><a href="#Defining-Types">6. Defining Types</a>
<ul class="sectlevel2">
<li><a href="#Defining-Types_Array-Type-Definitions">6.1. Array Type Definitions</a>
<ul class="sectlevel3">
<li><a href="#Defining-Types_Array-Type-Definitions_Writing-an-Array-Type-Definition">6.1.1. Writing an Array Type Definition</a></li>
<li><a href="#Defining-Types_Array-Type-Definitions_Type-Names">6.1.2. Type Names</a></li>
<li><a href="#Defining-Types_Array-Type-Definitions_Default-Values">6.1.3. Default Values</a></li>
<li><a href="#Defining-Types_Array-Type-Definitions_Format-Strings">6.1.4. Format Strings</a></li>
<li><a href="#Defining-Types_Array-Type-Definitions_Arrays-of-Arrays">6.1.5. Arrays of Arrays</a></li>
</ul>
</li>
<li><a href="#Defining-Types_Struct-Type-Definitions">6.2. Struct Type Definitions</a>
<ul class="sectlevel3">
<li><a href="#Defining-Types_Struct-Type-Definitions_Writing-a-Struct-Type-Definition">6.2.1. Writing a Struct Type Definition</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_Annotating-a-Struct-Type-Definition">6.2.2. Annotating a Struct Type Definition</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_Default-Values">6.2.3. Default Values</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_Member-Arrays">6.2.4. Member Arrays</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_Member-Format-Strings">6.2.5. Member Format Strings</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_Struct-Types-Containing-Named-Types">6.2.6. Struct Types Containing Named Types</a></li>
<li><a href="#Defining-Types_Struct-Type-Definitions_The-Order-of-Members">6.2.7. The Order of Members</a></li>
</ul>
</li>
<li><a href="#Defining-Types_Abstract-Type-Definitions">6.3. Abstract Type Definitions</a></li>
<li><a href="#Defining-Types_Alias-Type-Definitions">6.4. Alias Type Definitions</a></li>
<li><a href="#Defining-Types_Framework-Types">6.5. Framework Types</a></li>
</ul>
</li>
<li><a href="#Defining-Enums">7. Defining Enums</a>
<ul class="sectlevel2">
<li><a href="#Defining-Enums_Writing-an-Enum-Definition">7.1. Writing an Enum Definition</a></li>
<li><a href="#Defining-Enums_Using-an-Enum-Definition">7.2. Using an Enum Definition</a></li>
<li><a href="#Defining-Enums_Numeric-Values">7.3. Numeric Values</a></li>
<li><a href="#Defining-Enums_The-Representation-Type">7.4. The Representation Type</a></li>
<li><a href="#Defining-Enums_The-Default-Value">7.5. The Default Value</a></li>
</ul>
</li>
<li><a href="#Dictionary-Definitions">8. Dictionary Definitions</a></li>
<li><a href="#Defining-Ports">9. Defining Ports</a>
<ul class="sectlevel2">
<li><a href="#Defining-Ports_Port-Names">9.1. Port Names</a></li>
<li><a href="#Defining-Ports_Formal-Parameters">9.2. Formal Parameters</a></li>
<li><a href="#Defining-Ports_Handler-Functions">9.3. Handler Functions</a></li>
<li><a href="#Defining-Ports_Reference-Parameters">9.4. Reference Parameters</a></li>
<li><a href="#Defining-Ports_Returning-Values">9.5. Returning Values</a></li>
<li><a href="#Defining-Ports_Pass-by-Reference-Semantics">9.6. Pass-by-Reference Semantics</a></li>
<li><a href="#Defining-Ports_Annotating-a-Port-Definition">9.7. Annotating a Port Definition</a></li>
</ul>
</li>
<li><a href="#Defining-State-Machines">10. Defining State Machines</a>
<ul class="sectlevel2">
<li><a href="#Defining-State-Machines_Writing-a-State-Machine-Definition">10.1. Writing a State Machine Definition</a></li>
<li><a href="#Defining-State-Machines_States-Signals-and-Transitions">10.2. States, Signals, and Transitions</a></li>
<li><a href="#Defining-State-Machines_Actions">10.3. Actions</a>
<ul class="sectlevel3">
<li><a href="#Defining-State-Machines_Actions_Actions-in-Transitions">10.3.1. Actions in Transitions</a></li>
<li><a href="#Defining-State-Machines_Actions_Entry-and-Exit-Actions">10.3.2. Entry and Exit Actions</a></li>
<li><a href="#Defining-State-Machines_Actions_Typed-Signals-and-Actions">10.3.3. Typed Signals and Actions</a></li>
<li><a href="#Defining-State-Machines_Actions_Atomicity-of-Signal-Handling">10.3.4. Atomicity of Signal Handling</a></li>
</ul>
</li>
<li><a href="#Defining-State-Machines_More-on-State-Transitions">10.4. More on State Transitions</a>
<ul class="sectlevel3">
<li><a href="#Defining-State-Machines_More-on-State-Transitions_Guarded-Transitions">10.4.1. Guarded Transitions</a></li>
<li><a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">10.4.2. Self Transitions</a></li>
<li><a href="#Defining-State-Machines_More-on-State-Transitions_Internal-Transitions">10.4.3. Internal Transitions</a></li>
</ul>
</li>
<li><a href="#Defining-State-Machines_Choices">10.5. Choices</a></li>
<li><a href="#Defining-State-Machines_Hierarchy">10.6. Hierarchy</a>
<ul class="sectlevel3">
<li><a href="#Defining-State-Machines_Hierarchy_Substates">10.6.1. Substates</a></li>
<li><a href="#Defining-State-Machines_Hierarchy_Inherited-Transitions">10.6.2. Inherited Transitions</a></li>
<li><a href="#Defining-State-Machines_Hierarchy_Entry-and-Exit-Actions">10.6.3. Entry and Exit Actions</a></li>
<li><a href="#Defining-State-Machines_Hierarchy_Directly-Related-States">10.6.4. Directly Related States</a></li>
<li><a href="#Defining-State-Machines_Hierarchy_Choices">10.6.5. Choices</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#Defining-Components">11. Defining Components</a>
<ul class="sectlevel2">
<li><a href="#Defining-Components_Component-Definitions">11.1. Component Definitions</a></li>
<li><a href="#Defining-Components_Port-Instances">11.2. Port Instances</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Port-Instances_Basic-Port-Instances">11.2.1. Basic Port Instances</a></li>
<li><a href="#Defining-Components_Port-Instances_Rules-for-Port-Instances">11.2.2. Rules for Port Instances</a></li>
<li><a href="#Defining-Components_Port-Instances_Arrays-of-Port-Instances">11.2.3. Arrays of Port Instances</a></li>
<li><a href="#Defining-Components_Port-Instances_Priority">11.2.4. Priority</a></li>
<li><a href="#Defining-Components_Port-Instances_Queue-Full-Behavior">11.2.5. Queue Full Behavior</a></li>
<li><a href="#Defining-Components_Port-Instances_Serial-Port-Instances">11.2.6. Serial Port Instances</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Special-Port-Instances">11.3. Special Port Instances</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Special-Port-Instances_Command-Ports">11.3.1. Command Ports</a></li>
<li><a href="#Defining-Components_Special-Port-Instances_Event-Ports">11.3.2. Event Ports</a></li>
<li><a href="#Defining-Components_Special-Port-Instances_Telemetry-Ports">11.3.3. Telemetry Ports</a></li>
<li><a href="#Defining-Components_Special-Port-Instances_Parameter-Ports">11.3.4. Parameter Ports</a></li>
<li><a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports">11.3.5. Time Get Ports</a></li>
<li><a href="#Defining-Components_Special-Port-Instances_Data-Product-Ports">11.3.6. Data Product Ports</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Internal-Ports">11.4. Internal Ports</a></li>
<li><a href="#Defining-Components_Commands">11.5. Commands</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Commands_Basic-Commands">11.5.1. Basic Commands</a></li>
<li><a href="#Defining-Components_Commands_Formal-Parameters">11.5.2. Formal Parameters</a></li>
<li><a href="#Defining-Components_Commands_Opcodes">11.5.3. Opcodes</a></li>
<li><a href="#Defining-Components_Commands_Priority-and-Queue-Full-Behavior">11.5.4. Priority and Queue Full Behavior</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Events">11.6. Events</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Events_Basic-Events">11.6.1. Basic Events</a></li>
<li><a href="#Defining-Components_Events_Formal-Parameters">11.6.2. Formal Parameters</a></li>
<li><a href="#Defining-Components_Events_Identifiers">11.6.3. Identifiers</a></li>
<li><a href="#Defining-Components_Events_Throttling">11.6.4. Throttling</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Telemetry">11.7. Telemetry</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Telemetry_Basic-Telemetry">11.7.1. Basic Telemetry</a></li>
<li><a href="#Defining-Components_Telemetry_Identifiers">11.7.2. Identifiers</a></li>
<li><a href="#Defining-Components_Telemetry_Update-Frequency">11.7.3. Update Frequency</a></li>
<li><a href="#Defining-Components_Telemetry_Format-Strings">11.7.4. Format Strings</a></li>
<li><a href="#Defining-Components_Telemetry_Limits">11.7.5. Limits</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Parameters">11.8. Parameters</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Parameters_Basic-Parameters">11.8.1. Basic Parameters</a></li>
<li><a href="#Defining-Components_Parameters_Default-Values">11.8.2. Default Values</a></li>
<li><a href="#Defining-Components_Parameters_Identifiers">11.8.3. Identifiers</a></li>
<li><a href="#Defining-Components_Parameters_Set-and-Save-Opcodes">11.8.4. Set and Save Opcodes</a></li>
<li><a href="#Defining-Components_Parameters_External-Parameters">11.8.5. External Parameters</a></li>
</ul>
</li>
<li><a href="#Defining-Components_Data-Products">11.9. Data Products</a>
<ul class="sectlevel3">
<li><a href="#Defining-Components_Data-Products_Basic-Data-Products">11.9.1. Basic Data Products</a></li>
<li><a href="#Defining-Components_Data-Products_Identifiers">11.9.2. Identifiers</a></li>
<li><a href="#Defining-Components_Data-Products_Array-Records">11.9.3. Array Records</a></li>
</ul>
</li>
<li><a href="#Defining-Components_State-Machine-Instances">11.10. State Machine Instances</a></li>
<li><a href="#Defining-Components_Constants-Types-Enums-and-State-Machines">11.11. Constants, Types, Enums, and State Machines</a></li>
<li><a href="#Defining-Components_Include-Specifiers">11.12. Include Specifiers</a></li>
<li><a href="#Defining-Components_Matched-Ports">11.13. Matched Ports</a></li>
</ul>
</li>
<li><a href="#Defining-and-Using-Port-Interfaces">12. Defining and Using Port Interfaces</a>
<ul class="sectlevel2">
<li><a href="#Defining-and-Using-Port-Interfaces_Defining-Port-Interfaces">12.1. Defining Port Interfaces</a></li>
<li><a href="#Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Component-Definitions">12.2. Using Port Interfaces in Component Definitions</a></li>
<li><a href="#Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Interface-Definitions">12.3. Using Port Interfaces in Interface Definitions</a></li>
</ul>
</li>
<li><a href="#Defining-Component-Instances">13. Defining Component Instances</a>
<ul class="sectlevel2">
<li><a href="#Defining-Component-Instances_Component-Instance-Definitions">13.1. Component Instance Definitions</a>
<ul class="sectlevel3">
<li><a href="#Defining-Component-Instances_Component-Instance-Definitions_Passive-Components">13.1.1. Passive Components</a></li>
<li><a href="#Defining-Component-Instances_Component-Instance-Definitions_Queued-Components">13.1.2. Queued Components</a></li>
<li><a href="#Defining-Component-Instances_Component-Instance-Definitions_Active-Components">13.1.3. Active Components</a></li>
</ul>
</li>
<li><a href="#Defining-Component-Instances_Specifying-the-Implementation">13.2. Specifying the Implementation</a></li>
<li><a href="#Defining-Component-Instances_Init-Specifiers">13.3. Init Specifiers</a>
<ul class="sectlevel3">
<li><a href="#Defining-Component-Instances_Init-Specifiers_Execution-Phases">13.3.1. Execution Phases</a></li>
<li><a href="#Defining-Component-Instances_Init-Specifiers_Writing-Init-Specifiers">13.3.2. Writing Init Specifiers</a></li>
</ul>
</li>
<li><a href="#Defining-Component-Instances_Generation-of-Names">13.4. Generation of Names</a></li>
</ul>
</li>
<li><a href="#Defining-Topologies">14. Defining Topologies</a>
<ul class="sectlevel2">
<li><a href="#Defining-Topologies_A-Simple-Example">14.1. A Simple Example</a></li>
<li><a href="#Defining-Topologies_Connection-Graphs">14.2. Connection Graphs</a>
<ul class="sectlevel3">
<li><a href="#Defining-Topologies_Connection-Graphs_Direct-Graph-Specifiers">14.2.1. Direct Graph Specifiers</a></li>
<li><a href="#Defining-Topologies_Connection-Graphs_Pattern-Graph-Specifiers">14.2.2. Pattern Graph Specifiers</a></li>
</ul>
</li>
<li><a href="#Defining-Topologies_Port-Numbering">14.3. Port Numbering</a>
<ul class="sectlevel3">
<li><a href="#Defining-Topologies_Port-Numbering_Explicit-Numbering">14.3.1. Explicit Numbering</a></li>
<li><a href="#Defining-Topologies_Port-Numbering_Matched-Numbering">14.3.2. Matched Numbering</a></li>
<li><a href="#Defining-Topologies_Port-Numbering_General-Numbering">14.3.3. General Numbering</a></li>
</ul>
</li>
<li><a href="#Defining-Topologies_Importing-Topologies">14.4. Importing Topologies</a>
<ul class="sectlevel3">
<li><a href="#Defining-Topologies_Importing-Topologies_Importing-Instances-and-Connections">14.4.1. Importing Instances and Connections</a></li>
<li><a href="#Defining-Topologies_Importing-Topologies_Private-Instances">14.4.2. Private Instances</a></li>
<li><a href="#Defining-Topologies_Importing-Topologies_Multiple-Imports">14.4.3. Multiple Imports</a></li>
<li><a href="#Defining-Topologies_Importing-Topologies_Transitive-Imports">14.4.4. Transitive Imports</a></li>
</ul>
</li>
<li><a href="#Defining-Topologies_Include-Specifiers">14.5. Include Specifiers</a></li>
<li><a href="#Defining-Topologies_Telemetry-Packets">14.6. Telemetry Packets</a>
<ul class="sectlevel3">
<li><a href="#Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Sets">14.6.1. Telemetry Packet Sets</a></li>
<li><a href="#Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Identifiers">14.6.2. Telemetry Packet Identifiers</a></li>
<li><a href="#Defining-Topologies_Telemetry-Packets_Omitting-Channels">14.6.3. Omitting Channels</a></li>
<li><a href="#Defining-Topologies_Telemetry-Packets_Specifying-Multiple-Telemetry-Packet-Sets">14.6.4. Specifying Multiple Telemetry Packet Sets</a></li>
<li><a href="#Defining-Topologies_Telemetry-Packets_Include-Specifiers">14.6.5. Include Specifiers</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#Specifying-Models-as-Files">15. Specifying Models as Files</a>
<ul class="sectlevel2">
<li><a href="#Specifying-Models-as-Files_Dividing-Models-into-Files">15.1. Dividing Models into Files</a></li>
<li><a href="#Specifying-Models-as-Files_Include-Specifiers">15.2. Include Specifiers</a></li>
<li><a href="#Specifying-Models-as-Files_Dependencies">15.3. Dependencies</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers">15.4. Location Specifiers</a>
<ul class="sectlevel3">
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Syntax">15.4.1. Syntax</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Path-Names">15.4.2. Path Names</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Definition-Names">15.4.3. Definition Names</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Included-Files">15.4.4. Included Files</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Dictionary-Definitions">15.4.5. Dictionary Definitions</a></li>
<li><a href="#Specifying-Models-as-Files_Location-Specifiers_Repeated-Location-Specifiers">15.4.6. Repeated Location Specifiers</a></li>
</ul>
</li>
<li><a href="#Specifying-Models-as-Files_Locating-Definitions">15.5. Locating Definitions</a>
<ul class="sectlevel3">
<li><a href="#Specifying-Models-as-Files_Locating-Definitions_Running-fpp-locate-defs">15.5.1. Running fpp-locate-defs</a></li>
<li><a href="#Specifying-Models-as-Files_Locating-Definitions_Location-Paths">15.5.2. Location Paths</a></li>
<li><a href="#Specifying-Models-as-Files_Locating-Definitions_Included-Definitions">15.5.3. Included Definitions</a></li>
</ul>
</li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies">15.6. Computing Dependencies</a>
<ul class="sectlevel3">
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Running-fpp-depend">15.6.1. Running fpp-depend</a></li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Transitive-Dependencies">15.6.2. Transitive Dependencies</a></li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Missing-Dependencies">15.6.3. Missing Dependencies</a></li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Included-Files">15.6.4. Included Files</a></li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Dependencies-Between-Build-Modules">15.6.5. Dependencies Between Build Modules</a></li>
<li><a href="#Specifying-Models-as-Files_Computing-Dependencies_Framework-Dependencies">15.6.6. Framework Dependencies</a></li>
</ul>
</li>
<li><a href="#Specifying-Models-as-Files_Locating-Uses">15.7. Locating Uses</a></li>
<li><a href="#Specifying-Models-as-Files_Path-Name-Aliases">15.8. Path Name Aliases</a>
<ul class="sectlevel3">
<li><a href="#Specifying-Models-as-Files_Path-Name-Aliases_Relative-Paths-and-Symbolic-Links">15.8.1. Relative Paths and Symbolic Links</a></li>
<li><a href="#Specifying-Models-as-Files_Path-Name-Aliases_Unique-Locations">15.8.2. Unique Locations</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#Analyzing-and-Translating-Models">16. Analyzing and Translating Models</a>
<ul class="sectlevel2">
<li><a href="#Analyzing-and-Translating-Models_Checking-Models">16.1. Checking Models</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus">16.2. Generating C Plus Plus</a>
<ul class="sectlevel3">
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions">16.2.1. Constant Definitions</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Types-Ports-State-Machines-and-Components">16.2.2. Types, Ports, State Machines, and Components</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Component-Implementation-and-Unit-Test-Code">16.2.3. Component Implementation and Unit Test Code</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Topology-Definitions">16.2.4. Topology Definitions</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Compiling-the-Generated-Code">16.2.5. Compiling the Generated Code</a></li>
</ul>
</li>
<li><a href="#Analyzing-and-Translating-Models_Formatting-FPP-Source">16.3. Formatting FPP Source</a></li>
<li><a href="#Analyzing-and-Translating-Models_Visualizing-Topologies">16.4. Visualizing Topologies</a></li>
<li><a href="#Analyzing-and-Translating-Models_Generating-Ground-Dictionaries">16.5. Generating Ground Dictionaries</a></li>
<li><a href="#Analyzing-and-Translating-Models_Identifying-Generated-Files">16.6. Identifying Generated Files</a>
<ul class="sectlevel3">
<li><a href="#Analyzing-and-Translating-Models_Identifying-Generated-Files_Using-fpp-filenames">16.6.1. Using fpp-filenames</a></li>
<li><a href="#Analyzing-and-Translating-Models_Identifying-Generated-Files_Using-fpp-depend">16.6.2. Using fpp-depend</a></li>
</ul>
</li>
<li><a href="#Analyzing-and-Translating-Models_Generating-JSON-Models">16.7. Generating JSON Models</a></li>
<li><a href="#Analyzing-and-Translating-Models_Translating-Older-XML-to-FPP">16.8. Translating Older XML to FPP</a></li>
</ul>
</li>
<li><a href="#Writing-C-Plus-Plus-Implementations">17. Writing C Plus Plus Implementations</a>
<ul class="sectlevel2">
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-Abstract-Types">17.1. Implementing Abstract Types</a></li>
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-External-State-Machines">17.2. Implementing External State Machines</a></li>
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">17.3. Implementing Deployments</a>
<ul class="sectlevel3">
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments_Application-Specific-Definitions">17.3.1. Application-Specific Definitions</a></li>
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments_The-Main-Function">17.3.2. The Main Function</a></li>
<li><a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments_Public-Symbols">17.3.3. Public Symbols</a></li>
</ul>
</li>
<li><a href="#Writing-C-Plus-Plus-Implementations_Serialization-of-FPP-Values">17.4. Serialization of FPP Values</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="Introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This document describes <strong>F Prime Prime</strong>, also known as FPP or F Double Prime.
FPP is a modeling language for the
<a href="https://fprime.jpl.nasa.gov">F Prime flight software framework</a>.
For more detailed information about F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
<div class="paragraph">
<p>The goals of FPP are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>To provide a modeling language for F Prime that is simple, easy to use, and
well-tailored to its purpose.</p>
</li>
<li>
<p>To provide semantic checking and error reporting for F Prime models.</p>
</li>
<li>
<p>To generate code in the various languages that F Prime uses, e.g.,
C&#43;&#43; and JSON.
In this document, we will call these languages the <strong>target languages</strong>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Developers may combine code generated from FPP with code written by hand to
create, e.g., deployable flight software (FSW) programs and ground data environments.</p>
</div>
<div class="paragraph">
<p>The name &#8220;F Double Prime&#8221; (or F&Prime;) deliberately suggests the idea of a
&#8220;derivative&#8221;
of F Prime (or F&prime;).
By &#8220;integrating&#8221; an FPP model (i.e., running the tools) you get a partial
FSW implementation in the F Prime framework; and then by &#8220;integrating&#8221; again
(i.e., providing
the project-specific C&#43;&#43; implementation) you get a FSW application.</p>
</div>
<div class="paragraph">
<p><strong>Purpose:</strong> The purpose of this document is to describe FPP in a way that is accessible
to users, including beginning users.
A more detailed and precise description is available in
<a href="https://nasa.github.io/fpp/fpp-spec.html"><em>The FPP Language Specification</em></a>.
We recommend that you read this document before consulting that one.</p>
</div>
<div class="paragraph">
<p><strong>Overview:</strong> The rest of this document proceeds as follows.
Section 2 explains how to get up and running with FPP.
Sections 3 through 12 describe the elements of an FPP
model, starting with the simplest elements (constants
and types) and working towards the most complex (components
and topologies).
Section 13 explains how to specify a model as a collection
of files: for example, it covers the management of dependencies
between files.
Section 14 explains how to analyze FPP models and how
to translate FPP models to C&#43;&#43; and JSON.
It also explains how to translate an XML format previously used
by F Prime into FPP.
Section 15 explains how to write a C&#43;&#43; implementation
against the code generated from an FPP model.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Installing-FPP">2. Installing FPP</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Before reading the rest of this document, you should install
the latest version of FPP.
The installation instructions are available here:</p>
</div>
<div class="paragraph">
<p><a href="https://github.com/nasa/fpp/tree/main/compiler#compiler" class="bare">https://github.com/nasa/fpp/tree/main/compiler#compiler</a></p>
</div>
<div class="paragraph">
<p>Make sure that the FPP command-line tools are in your shell path.
For example, running <code>fpp-check</code> on the command line should succeed and should
prompt for standard input. You can type control-C to end
the program:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check
^C
%</pre>
</div>
</div>
<div class="paragraph">
<p><code>fpp-check</code> is the tool for checking that an FPP model is valid.
Like most FPP tools,
<code>fpp-check</code> reads either from named files or from standard input.
If one or more files are named on the command line, <code>fpp-check</code> reads those;
otherwise it reads from standard input.
As an example, the following two operations are equivalent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check &lt; file.fpp
% fpp-check file.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>The first operation redirects <code>file.fpp</code> into the standard input of
<code>fpp-check</code>.
The second operation names <code>file.fpp</code> as an input file of <code>fpp-check</code>.</p>
</div>
<div class="paragraph">
<p>Most of the examples in the following sections are complete FPP models.
You can run the models through
<code>fpp-check</code> by typing or pasting them into a file or into standard input.
We recommend that you to this for at least a few of the examples,
to get a feel for how FPP works.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Constants">3. Defining Constants</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The simplest FPP model consists of one or more <strong>constant definitions</strong>.
A constant definition associates a name with a value,
so that elsewhere you can use the name instead of re-computing or restating the
value.
Using named constants makes the model easier to understand (the name
says what the value means) and to maintain (changing a constant definition is
easy;
changing all and only the relevant uses of a repeated value is not).</p>
</div>
<div class="paragraph">
<p>This section covers the following topics:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Writing an FPP constant definition.</p>
</li>
<li>
<p>Writing an <strong>expression</strong>, which is the source text
that defines the value associated with the constant definition.</p>
</li>
<li>
<p>Writing multiple constant definitions.</p>
</li>
<li>
<p>Writing a constant definition that spans two or more lines of source text.</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Writing-a-Constant-Definition">3.1. Writing a Constant Definition</h3>
<div class="paragraph">
<p>To write a constant definition, you write the keyword <code>constant</code>,
an equals sign, and an expression.
A <a href="#Defining-Constants_Expressions">later section</a>
describes all the expressions you can write.
Here is an example that uses an integer literal expression representing
the value 42:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant ultimateAnswer = 42</code></pre>
</div>
</div>
<div class="paragraph">
<p>This definition associates the name <code>ultimateAnswer</code> with the value 42.
Elsewhere in the FPP model you can use the name <code>ultimateAnswer</code> to represent
the value.
You can also generate a C&#43;&#43; header file that defines the C&#43;&#43; constant
<code>ultimateAnswer</code> and gives it the value 42.</p>
</div>
<div class="paragraph">
<p>As an example, do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>On the command line, run <code>fpp-check</code>.</p>
</li>
<li>
<p>When the prompt appears, type the text shown above, type return, type control-D, and type return.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You should see something like the following on your console:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check
constant ultimateAnswer = 42
^D
%</pre>
</div>
</div>
<div class="paragraph">
<p>As an example of an incorrect model that produces an error message, repeat the
exercise, but omit the value 42.
You should see something like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check
constant ultimateAnswer =
^D
fpp-check
stdin: end of input
error: expression expected</pre>
</div>
</div>
<div class="paragraph">
<p>Here the <code>fpp-check</code> tool is telling you that it could not parse the input:
the input ended where it expected an expression.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Names">3.2. Names</h3>
<div class="paragraph">
<p>Names in FPP follow the usual rules for identifiers in a programming language:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A name must contain at least one character.</p>
</li>
<li>
<p>A name must start with a letter or underscore character.</p>
</li>
<li>
<p>The characters after the first may be letters, numbers, or underscores.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>name</code>, <code>Name</code>, <code>_name</code>, and <code>name1</code> are valid names.</p>
</li>
<li>
<p><code>1invalid</code> is not a valid name, because names may not start with digits.</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Names_Reserved-Words">3.2.1. Reserved Words</h4>
<div class="paragraph">
<p>Certain sequences of letters such as <code>constant</code> are called out as <strong>reserved
words</strong> (also called keywords) in FPP.
Each reserved word has a special meaning, such as introducing a constant
declaration.
<em>The FPP Language Specification</em> has a complete list of reserved words.
In this document, we will introduce reserved words as needed to explain
the language features.</p>
</div>
<div class="paragraph">
<p>Using a reserved word as a name in the ordinary way causes a parsing error.
For example, this code is incorrect:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant constant = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>To use a reserved word as a name, you must put the character <code>$</code> in
front of it with no space.
For example, this code is legal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant $constant = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>The character sequence <code>$constant</code> represents the name <code>constant</code>,
as opposed to the keyword <code>constant</code>.</p>
</div>
<div class="paragraph">
<p>You can put the character <code>$</code> in front of any identifier,
not just a keyword.
If the identifier is not a keyword, then the <code>$</code> has no effect.
For example, <code>$name</code> has the same meaning as <code>name</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Names_Name-Clashes">3.2.2. Name Clashes</h4>
<div class="paragraph">
<p>FPP will not let you define two different symbols of the same
kind with the same name.
For example, this code will produce an error:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant c = 0
constant c = 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>Two symbols can have the same unqualified name if they
reside in different
<a href="#Defining-Modules">modules</a> or
<a href="#Defining-Enums">enums</a>; these concepts
are explained below.
Two symbols can also have the same name if the analyzer
can distinguish them based on their kinds.
For example, an
<a href="#Defining-Types_Array-Type-Definitions">array type</a> (described below) and a
constant
can have the same name, but an array type and a
<a href="#Defining-Types_Struct-Type-Definitions">struct type</a> may not.
<em>The FPP Language Specification</em> has all the details.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Expressions">3.3. Expressions</h3>
<div class="paragraph">
<p>This section describes the expressions that you can write as part of a constant
definition.
Expressions appear in other FPP elements as well, so we will refer back
to this section in later sections of the manual.</p>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Primitive-Values">3.3.1. Primitive Values</h4>
<div class="paragraph">
<p>A <strong>primitive value expression</strong> represents a primitive machine value, such as an
integer.
It is one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A decimal integer literal value such as <code>1234</code>.</p>
</li>
<li>
<p>A hexadecimal integer literal value such as <code>0xABCD</code> or <code>0xabcd</code>.</p>
</li>
<li>
<p>A floating-point literal value such as <code>12.34</code> or <code>1234e-2</code>.</p>
</li>
<li>
<p>A Boolean literal expression <code>true</code> or <code>false</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As an exercise, construct some constant definitions with primitive values as their
expressions, and
feed the results to <code>fpp-check</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 1234
constant b = 0xABCD</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you get an error, make sure you understand why.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_String-Values">3.3.2. String Values</h4>
<div class="paragraph">
<p>A <strong>string value</strong> represents a string of characters.
There are two kinds of string values:
single-line strings and multiline strings.</p>
</div>
<div class="paragraph">
<p><strong>Single-line strings:</strong>
A single-line string represents a string of characters
that does not contain a newline character.
It is written as a string of characters enclosed in double quotation
marks <code>"</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = "This is a string."</code></pre>
</div>
</div>
<div class="paragraph">
<p>To put the double-quote character in a string, write the double quote
character as <code>\"</code>, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = "\"This is a quotation within a string,\" he said."</code></pre>
</div>
</div>
<div class="paragraph">
<p>To encode the character <code>\</code> followed by the character <code>"</code>, write
the backslash character as <code>\\</code>, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = "\\\""</code></pre>
</div>
</div>
<div class="paragraph">
<p>This string represents the literal character sequence <code>\</code>, <code>"</code>.</p>
</div>
<div class="paragraph">
<p>In general, the sequence <code>\</code> followed by a character <em>c</em>
is translated to <em>c</em>.
This sequence is called an <strong>escape sequence</strong>.</p>
</div>
<div class="paragraph">
<p><strong>Multiline strings:</strong>
A multiline string represents a string of characters
that may contain a newline character.
It is enclosed in a pair of sequences of three double quotation
marks <code>"""</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = """
This is a multiline string.
It has three lines.
"""</code></pre>
</div>
</div>
<div class="paragraph">
<p>When interpreting a multiline string, FPP ignores any newline
characters at the start and end of the string.
FPP also ignores any blanks to the left of the column where
the first <code>"""</code> appears.
For example, the string shown above consists of three lines and starts
with <code>This</code>.</p>
</div>
<div class="paragraph">
<p>Literal quotation marks are allowed inside a multiline string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = """
"This is a quotation within a string," he said.
"""</code></pre>
</div>
</div>
<div class="paragraph">
<p>Escape sequences work as for single-line strings.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = """
Here are three double-quote characters in a row: \"\"\"
"""</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Array-Values">3.3.3. Array Values</h4>
<div class="paragraph">
<p>An <strong>array value expression</strong> represents a fixed-size array
of values.
To write an array value expression, you write a comma-separated list of one or more values
(the array elements)
enclosed in square brackets.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code associates the name <code>a</code> with the array of
integers
<code>[ 1, 2, 3 ]</code>.</p>
</div>
<div class="paragraph">
<p>As mentioned in the introduction, an FPP model describes the structure of a FSW
application; the computations are specified in a target
language such as C&#43;&#43;.
As a result, FPP does not provide an array indexing operation.
In particular, it does not specify the index of the leftmost array element;
that is up to the target language.
For example, if the target language is C&#43;&#43;, then array indices start
at zero.</p>
</div>
<div class="paragraph">
<p>Here are some rules for writing array values:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>An array value must have at least one element.
That is, <code>[]</code> is not a valid array value.</p>
</li>
<li>
<p>The types of the elements must match.
For example, the following code is illegal, because the value <code>1</code> (which has type <code>Integer</code>)
and the value <code>"abcd"</code> (which has type <code>string</code>) are incompatible:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant mismatch = [ 1, "abcd" ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Try entering this example into <code>fpp-check</code> and see what happens.</p>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>What does it mean for types to match?
<em>The FPP Specification</em> has all the details, and we won&#8217;t attempt
to repeat them here.
In general, things work as you would expect: for example, we can convert
an integer value to a floating-point value, so the following code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2.0 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>It evaluates to an array of two floating-point values.</p>
</div>
<div class="paragraph">
<p>If you are not sure whether a type conversion is allowed, you can
ask <code>fpp-check</code>.
For example: can we convert a Boolean value to an integer value?
In older languages like C and C&#43;&#43; we can, but in many newer languages
we can&#8217;t. Here is the answer in FPP:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check
constant a = [ 1, true ]
^D
fpp-check
stdin: 1.16
constant a = [ 1, true ]
^
error: cannot compute common type of Integer and bool</pre>
</div>
</div>
<div class="paragraph">
<p>So no, we can&#8217;t.</p>
</div>
<div class="paragraph">
<p>Here are two more points about array values:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Any legal value can be an element of an array value, so in particular arrays
of arrays
are allowed. For example, this code is allowed:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ [ 1, 2 ], [ 3, 4 ] ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>It represents an array with two elements: the array <code>[ 1, 2 ]</code> and the array <code>[
3, 4 ]</code>.</p>
</div>
</li>
<li>
<p>To avoid repeating values, a numeric, string, or Boolean value is automatically promoted to an array
of appropriate size whenever necessary to make the types work.
For example, this code is allowed:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ [ 1, 2, 3 ], 0 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is equivalent to this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ [ 1, 2, 3 ], [ 0, 0, 0 ] ]</code></pre>
</div>
</div>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Array-Elements">3.3.4. Array Elements</h4>
<div class="paragraph">
<p>An <strong>array element expression</strong> represents an element of an array value.
To write an array element expression, you write an array value
followed by an index expression enclosed in square brackets.
The index expression must resolve to a number.
The number specifies the index of the array element, where the
array indices start at zero.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]
constant b = a[1]</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, the constant <code>b</code> has the value 2.</p>
</div>
<div class="paragraph">
<p>The index expression must resolve to a number that is in range
for the array.
For example, this code is incorrect, because <code>"hello"</code> is not a number:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]
constant b = a["hello"]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code is incorrect because 3 is not in the range [0, 2]:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]
constant b = a[3]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Struct-Values">3.3.5. Struct Values</h4>
<div class="paragraph">
<p>A <strong>struct value expression</strong> represents a C- or C&#43;&#43;-style structure, i.e., a
mapping
of names to values.
To write a struct value expression, you write a comma-separated list of zero or
more <strong>struct members</strong>
enclosed in curly braces.
A struct member consists of a name, an equals sign, and a value.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = { x = 1, y = "abc" }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code associates the name <code>s</code> with a struct value.
The struct value has two members <code>x</code> and <code>y</code>.
Member <code>x</code> has the integer value 1, and member <code>y</code> has the string value <code>"abc"</code>.</p>
</div>
<div class="paragraph">
<p><strong>The order of members:</strong> When writing a struct value, the order in which the
members appear does not matter.
For example, in the following code, constants <code>s1</code> and <code>s2</code> denote the same
value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s1 = { x = 1, y = "abc" }
constant s2 = { y = "abc", x = 1 }</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>The empty struct:</strong> The empty struct is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = {}</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Arrays in structs:</strong> You can write an array value as a member of a struct value.
For example, this code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = { x = 1, y = [ 2, 3 ] }</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Structs in arrays:</strong> You can write a struct value as a member of an array value.
For example, this code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ { x = 1, y = 2 }, { x = 3, y = 4 } ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code is not allowed, because the element types don&#8217;t match&#8201;&#8212;&#8201;an array is not
compatible with a struct.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ { x = 1, y = 2 }, [ 3, 4 ] ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, this code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ { x = 1, y = 2 }, { x = 3 } ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that the first member of <code>a</code> is a struct with two members <code>x</code> and <code>y</code>.
The second member of <code>a</code> is also a struct, but it has only one member <code>x</code>.
When the FPP analyzer detects that a struct type is missing a member,
it automatically adds the member, giving it a default value.
The default values are the ones you would expect: zero for numeric members, the empty
string for string members, and <code>false</code> for Boolean members.
So the code above is equivalent to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ { x = 1, y = 2 }, { x = 3, y = 0 } ]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Struct-Members">3.3.6. Struct Members</h4>
<div class="paragraph">
<p>A <strong>struct member expression</strong> represents a member of a struct value.
To write a struct member expression, you write a struct value followed
by a dot and the member name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = { x = 1, y = [ 2, 3 ] }
constant b = a.y</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here <code>a</code> is a struct value with members <code>x</code> and <code>y</code>
The constant <code>b</code> has the array value <code>[ 2, 3 ]</code>, which is the
value stored in member <code>y</code> of <code>a</code>.</p>
</div>
<div class="paragraph">
<p>This code is incorrect because <code>a</code> is not a struct value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0
constant b = a.y</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code is incorrect because <code>z</code> is not a member of <code>a</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = { x = 1, y = [ 2, 3 ] }
constant b = a.z</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Name-Expressions">3.3.7. Name Expressions</h4>
<div class="paragraph">
<p>A <strong>name expression</strong> is a use of a name appearing in a constant definition.
It stands for the associated constant value.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 1
constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this code, constant <code>b</code> has the value 1.</p>
</div>
<div class="paragraph">
<p>The order of definitions does not matter, so this code is equivalent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant b = a
constant a = 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>The only requirement is that there may not be any cycles in the graph
consisting of constant definitions and their uses.
For example, this code is illegal, because there is a cycle from <code>a</code> to <code>b</code> to
<code>c</code> and back to <code>a</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = c
constant b = a
constant c = b</code></pre>
</div>
</div>
<div class="paragraph">
<p>Try submitting this code to <code>fpp-check</code>, to see what happens.</p>
</div>
<div class="paragraph">
<p>Names like <code>a</code>, <code>b</code>, and <code>c</code> are simple or unqualified names.
Names can also be qualified: for example <code>A.a</code> is allowed.
We will discuss qualified names further when we introduce
module definitions and enum definitions below.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Value-Arithmetic-Expressions">3.3.8. Value Arithmetic Expressions</h4>
<div class="paragraph">
<p>A <strong>value arithmetic expression</strong> performs arithmetic on values.
It is one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A negation expression, for example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = -1</code></pre>
</div>
</div>
</li>
<li>
<p>A binary operation expression, where the binary operation is one of <code>+</code> (addition), <code>-</code> (subtraction),
<code>*</code> (multiplication), and <code>/</code> (division). For example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 1 + 2</code></pre>
</div>
</div>
</li>
<li>
<p>A parenthesis expression, for example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = (1)</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following rules apply to arithmetic expressions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The subexpressions must be integer or floating-point values.</p>
</li>
<li>
<p>If there are any floating-point subexpressions, then the entire expression is
evaluated using 64-bit floating-point arithmetic.</p>
</li>
<li>
<p>Otherwise the expression is evaluated using arbitrary-precision integer
arithmetic.</p>
</li>
<li>
<p>In a division operation, the second operand may not be zero or (for
floating-point values) very close to zero.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Constants_Expressions_Compound-Expressions">3.3.9. Compound Expressions</h4>
<div class="paragraph">
<p>Wherever you can write a value inside an expression, you can write
a more complex expression there, so long as the types work out.
For example, these expressions are valid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = (1 + 2) * 3
constant b = [ 1 + 2, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>The first example is a binary expression whose first operand is a parentheses
expression;
that parentheses expression in turn has a binary expression as its
subexpression.
The second example is an array expression whose first element is a binary
expression.</p>
</div>
<div class="paragraph">
<p>This expression is invalid, because <code>1 + 2.0</code> evaluates to a floating-point
value, which is incompatible with type <code>string</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1 + 2.0, "abc" ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Compound expressions are evaluated in the obvious way.
For example, the constant definitions above are equivalent to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 9
constant b = [ 3, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>For compound arithmetic expressions, the
precedence and associativity rules are the usual ones (evaluate parentheses
first, then multiplication, and so forth).</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Multiple-Definitions-and-Element-Sequences">3.4. Multiple Definitions and Element Sequences</h3>
<div class="paragraph">
<p>Typically you want to specify several definitions in a model source file, not
just one.
There are two ways to do this:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>You can separate the definitions by one or more newlines, as shown
in the examples above.</p>
</li>
<li>
<p>You can put the definitions on the same line, separated by a semicolon.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, the following two code excerpts are equivalent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 1
constant b = 2</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 1; constant b = 2</code></pre>
</div>
</div>
<div class="paragraph">
<p>More generally, a collection of several constant definitions is an example
of an <strong>element sequence</strong>, i.e., a sequence of similar syntactic elements.
Here are the rules for writing an element sequence:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Every kind of element sequence has optional <strong>terminating punctuation</strong>.
The terminating punctuation is either a semicolon or a comma, depending
on the kind of element sequence.
For constant definitions, it is a semicolon.</p>
</li>
<li>
<p>When writing elements on separate lines, the terminating punctuation is
optional.</p>
</li>
<li>
<p>When writing two or more elements on the same line, the terminating
punctuation is
required between the elements and optional after the last element.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Multiline-Definitions">3.5. Multiline Definitions</h3>
<div class="paragraph">
<p>Sometimes, especially for long definitions, it is useful to split a
definition across two or more lines.
In FPP there are several ways to do this.</p>
</div>
<div class="paragraph">
<p>First, FPP ignores newlines that follow opening symbols like <code>[</code> and precede
closing symbols like <code>]</code>.
For example, this code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [
1, 2, 3
]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Second, the elements of an array or struct form an element sequence (see
the previous section), so you can write each element on its own line,
omitting the commas if you wish:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = {
x = 1
y = 2
z = 3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is a clean way to write arrays and structs.
The assignment of each element to its own line and the lack of
terminating punctuation
make it easy to rearrange the elements.
In particular, one can do a line-by-line sort on the elements (for example, to
sort struct members alphabetically by name) without concern for messing up the
arrangement of commas.
If we assume that the example represents the first five lines of a source file,
then in vi this is easily done as <code>:2-4!sort</code>.</p>
</div>
<div class="paragraph">
<p>Third, FPP ignores newlines that follow connecting symbols such as <code>=</code> and <code>+</code>
For example, this code is allowed;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a =
1
constant b = 1 +
2</code></pre>
</div>
</div>
<div class="paragraph">
<p>Finally, you can always create an explicit line continuation by escaping
one or more newline characters with <code>\</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant \
a = 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that in this example you need the explicit continuation, i.e., this code
is not legal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant
a = 1</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Constants_Framework-Constants">3.6. Framework Constants</h3>
<div class="paragraph">
<p>Certain constants defined in FPP have a special meaning in the
F Prime framework.
These constants are called <strong>framework constants</strong>.
For example, the constant <code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code>
defines the size of the user data field in a data product container.
(Data products are an F Prime feature that we describe
<a href="#Defining-Components_Data-Products">in a later section of this manual</a>.)
You typically set these constants by overriding configuration
files provided in the directory <code>default/config</code> in the F Prime repository.
For example, the file <code>default/config/DpCfg.fpp</code> provides a default value for
<code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code>.
You can override this default value by providing your own version of
the file <code>DpCfg.fpp</code>.
The
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/configuring-fprime/">F
Prime User Manual</a>
explains how to do this configuration.</p>
</div>
<div class="paragraph">
<p>The FPP analyzer does not require that framework constants be defined
unless they are used.
For example, the following model is valid, because it neither defines nor users
<code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following model is valid because it defines and uses <code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
module DpCfg {
constant CONTAINER_USER_DATA_SIZE = 10
}
}
constant a = Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following model is invalid, because it uses <code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code>
without defining it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code></pre>
</div>
</div>
<div class="paragraph">
<p>If framework constants are defined in the FPP model, then
then they must conform to certain rules.
These rules are spelled out in detail in the
<a href="https://nasa.github.io/fpp/fpp-spec.html#Definitions_Framework-Definitions_Constant-Definitions"><em>The
FPP Language Specification</em></a>.
For example, <code>Fw.DpCfg.CONTAINER_USER_DATA_SIZE</code> must have an integer type.
So this model is invalid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
module DpCfg {
constant CONTAINER_USER_DATA_SIZE = "abc"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is what happens when you run this model through <code>fpp-check</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check
module Fw {
module DpCfg {
constant CONTAINER_USER_DATA_SIZE = "abc"
}
}
^D
fpp-check
stdin:5.5
constant CONTAINER_USER_DATA_SIZE = "abc"
^
error: the F Prime framework constant Fw.DpCfg.CONTAINER_USER_DATA_SIZE must have an integer type</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Writing-Comments-and-Annotations">4. Writing Comments and Annotations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In FPP, you can write <strong>comments</strong> that are ignored by the parser.
These are just like comments in most programming languages.
You can also write <strong>annotations</strong> that have no meaning in the FPP model
but are attached to model elements and may be carried through
to translation&#8201;&#8212;&#8201;for example, they may become comments in generated C&#43;&#43; code.</p>
</div>
<div class="sect2">
<h3 id="Writing-Comments-and-Annotations_Comments">4.1. Comments</h3>
<div class="paragraph">
<p>A comment starts with the character <code>#</code> and goes to the end of the line.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># This is a comment</code></pre>
</div>
</div>
<div class="paragraph">
<p>To write a comment that spans multiple lines, start each line with <code>#</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># This is a comment.
# It spans two lines.</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Writing-Comments-and-Annotations_Annotations">4.2. Annotations</h3>
<div class="paragraph">
<p>Annotations are attached to elements of a model, such as
<a href="#Defining-Constants">constant definitions</a>.
A model element that may have an annotation attached to it
is called an <strong>annotatable element</strong>.
Any constant definition is an annotatable element.
Other annotatable elements will be called out in future sections
of this document.</p>
</div>
<div class="paragraph">
<p>There are two kinds of annotations: <strong>pre annotations</strong> and <strong>post annotations</strong>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A pre annotation starts with the character <code>@</code> and is attached to the
annotatable element that follows it.</p>
</li>
<li>
<p>A post annotation starts with the characters <code>@&lt;</code> and is attached to
the annotatable element that precedes it.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In either case</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Any white space immediately following the <code>@</code> or <code>@&lt;</code> characters is ignored.</p>
</li>
<li>
<p>The annotation goes to the end of the line.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ This is a pre annotation
constant c = 0 @&lt; This is a post annotation</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiline annotations are allowed. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ This is a pre annotation.
@ It has two lines.
constant c = 0 @&lt; This is a post annotation.
@&lt; It also has two lines.</code></pre>
</div>
</div>
<div class="paragraph">
<p>The meaning of the annotations is tool-specific. A typical use is to
concatenate the pre and post annotations into a list of lines and emit them as
a comment. For example, if you send the code immediately above through the
tool <a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus"><code>fpp-to-cpp</code></a>,
it should generate a file <code>FppConstantsAc.hpp</code>. If you examine that file,
you should see, in relevant part, the following code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">//! This is a pre annotation.
//! It has two lines.
//! This is a post annotation.
//! It also has two lines.
enum FppConstant_c {
c = 0
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The two lines of the pre annotation and the two lines of the post
annotation have been concatenated and written out as a Doxygen
comment attached to the constant definition, represented as a C&#43;&#43; enum.</p>
</div>
<div class="paragraph">
<p>In the future, annotations may be used to provide additional capabilities, for
example timing analysis, that are not part of the FPP language specification.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Modules">5. Defining Modules</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In an FPP model, a <strong>module</strong> is a group of model elements that are all qualified
with a name, called the <strong>module name</strong>.
An FPP module corresponds to a namespace in C&#43;&#43; and a module in Python.
Modules are useful for (1) organizing a large model into a hierarchy of smaller
units and (2) avoiding
<a href="#Defining-Constants_Names_Name-Clashes">name clashes</a>
between different units.</p>
</div>
<div class="paragraph">
<p>To define a module, you write the keyword <code>module</code> followed by one
or more definitions enclosed in curly braces.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
constant a = 1
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The name of a module qualifies the names of all the definitions that the module
encloses.
To write the qualified name, you write the qualifier, a dot, and the base name:
for example <code>M.a</code>. (This is also the way that
name qualification works in Python, Java, and Scala.)
Inside the module, you can use the qualified name or the unqualified
name.
Outside the module, you must use the qualified name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
constant a = 1
constant b = a # OK: refers to M.a
constant c = M.b
}
constant a = M.a
constant c = b # Error: b is not in scope here</code></pre>
</div>
</div>
<div class="paragraph">
<p>As with namespaces in C&#43;&#43;, you can close a module definition and
reopen it later.
All the definitions enclosed by the same name go in the module
with that name.
For example, the following code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
constant a = 0
}
module M {
constant b = 1
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is equivalent to this code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
constant a = 0
constant b = 1
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can define modules inside other modules.
When you do that, the name qualification works in the obvious way.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module A {
module B {
constant c = 0
}
}
constant c = A.B.c</code></pre>
</div>
</div>
<div class="paragraph">
<p>The inside of a module definition is an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a>
with a semicolon as the optional terminating punctuation.
For example, you can write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M { constant a = 0; constant b = 1 }; constant c = M.a</code></pre>
</div>
</div>
<div class="paragraph">
<p>A module definition is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>,
so you can attach annotations to it, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ This is module M
module M {
constant a = 0
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Types">6. Defining Types</h2>
<div class="sectionbody">
<div class="paragraph">
<p>An FPP model may include one or more <strong>type definitions</strong>.
These definitions describe named types that may be used elsewhere in the
model and that may generate code in the target language.
For example,
an FPP type definition may become a class definition in C&#43;&#43;.</p>
</div>
<div class="paragraph">
<p>There are four kinds of type definitions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Array type definitions</p>
</li>
<li>
<p>Struct type definitions</p>
</li>
<li>
<p>Abstract type definitions</p>
</li>
<li>
<p>Alias type definitions</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Type definitions may appear at the top level or inside a
<a href="#Defining-Modules">module definition</a>.
A type definition is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.</p>
</div>
<div class="sect2">
<h3 id="Defining-Types_Array-Type-Definitions">6.1. Array Type Definitions</h3>
<div class="paragraph">
<p>An <strong>array type definition</strong> associates a name with an <strong>array type</strong>.
An array type describes the shape of an
<a href="#Defining-Constants_Expressions_Array-Values">array value</a>.
It specifies an element type and a size.</p>
</div>
<div class="sect3">
<h4 id="Defining-Types_Array-Type-Definitions_Writing-an-Array-Type-Definition">6.1.1. Writing an Array Type Definition</h4>
<div class="paragraph">
<p>As an example, here is an array type definition that associates
the name <code>A</code> with an array of three values, each of which is a 32-bit unsigned
integer:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32</code></pre>
</div>
</div>
<div class="paragraph">
<p>In general, to write an array type definition, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>array</code>.</p>
</li>
<li>
<p>The <a href="#Defining-Constants_Names">name</a> of the array type.</p>
</li>
<li>
<p>An equals sign <code>=</code>.</p>
</li>
<li>
<p>An <a href="#Defining-Constants_Expressions">expression</a>
enclosed in square brackets <code>[</code> &#8230;&#8203; <code>]</code> denoting the size (number of elements) of the array.</p>
</li>
<li>
<p>A type name denoting the element type.
The available type names are discussed below.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Notice that the size expression precedes the element type, and the whole
type reads left to right.
For example, you may read the type <code>[3] U32</code> as "array of 3 <code>U32</code>."</p>
</div>
<div class="paragraph">
<p>The size may be any legal expression.
It doesn&#8217;t have to be a literal integer.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant numElements = 10
array A = [numElements] U32</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Array-Type-Definitions_Type-Names">6.1.2. Type Names</h4>
<div class="paragraph">
<p>The following type names are available for the element types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The type names <code>U8</code>, <code>U16</code>, <code>U32</code>, and <code>U64</code>, denoting the type of unsigned
integers of width 8, 16, 32, and 64 bits.</p>
</li>
<li>
<p>The type names <code>I8</code>, <code>I16</code>, <code>I32</code>, and <code>I64</code>, denoting the type of signed integers
of width 8, 16, 32, and 64 bits.</p>
</li>
<li>
<p>The type names <code>F32</code> and <code>F64</code>, denoting the type of floating-point values
of width 32 and 64 bits.</p>
</li>
<li>
<p>The type name <code>bool</code>, denoting the type of Boolean values (<code>true</code> and <code>false</code>).</p>
</li>
<li>
<p>The type name <code>string</code>, denoting the type of
<a href="#Defining-Constants_Expressions_String-Values">string values</a>.
This type has a default maximum size.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># A is an array of 3 strings with default maximum size
array A = [3] string</code></pre>
</div>
</div>
</li>
<li>
<p>The type name <code>string size</code> <em>e</em>, where <em>e</em> is a numeric expression
specifying a maximum string size.</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># A is an array of 3 strings with maximum size 40
array A = [3] string size 40</code></pre>
</div>
</div>
</li>
<li>
<p>A name associated with another type definition.
In particular, an array definition may have another array definition as
its element type; this situation is discussed further below.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>An array type definition may not refer to itself (array type definitions are not
recursive). For example, this definition is illegal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] A # Illegal: the definition of A may not refer to itself</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Array-Type-Definitions_Default-Values">6.1.3. Default Values</h4>
<div class="paragraph">
<p>Optionally, you can specify a default value for an array type.
To do this, you write the keyword <code>default</code> and an expression
that evaluates to an <a href="#Defining-Constants_Expressions_Array-Values">array value</a>.
For example, here is an array type <code>A</code> with default value <code>[ 1, 2, 3 ]</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32 default [ 1, 2, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>A default value expression need not be a literal array value; it
can be any expression with the correct type.
For example, you can create a named constant with an array
value and use it multiple times, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]
array A = [3] U8 default a # default value is [ 1, 2, 3 ]
array B = [3] U16 default a # default value is [ 1, 2, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a default value, then the type gets an automatic default value,
consisting of the default value for each element.
The default numeric value is zero, the default Boolean value is <code>false</code>,
the default string value is <code>""</code>, and the default value of an array type
is specified in the type definition.</p>
</div>
<div class="paragraph">
<p>The type of the default expression must match the size and element type of the
array, with type conversions allowed as discussed for
<a href="#Defining-Constants_Expressions_Array-Values">array values</a>.
For example, this default expression is allowed, because we can convert integer
values to floating-point values, and we can promote a single value to an array
of three values:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] F32 default 1 # default value is [ 1.0, 1.0, 1.0 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, these default expressions are not allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32 default [ 1, 2 ] # Error: size does not match</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array B = [3] U32 default [ "a", "b", "c" ] # Error: element type does not match</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Array-Type-Definitions_Format-Strings">6.1.4. Format Strings</h4>
<div class="paragraph">
<p>You can specify an optional <strong>format string</strong> which says how to display
each element value and optionally provides some surrounding text.
For example, here is an array definition that interprets three integer
values as wheel speeds measured in RPMs:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array WheelSpeeds = [3] U32 format "{} RPM"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then an element with value 100 would have the format <code>100 RPM</code>.</p>
</div>
<div class="paragraph">
<p>Note that the format string specifies the format for an <em>element</em>, not the
entire array.
The way an entire array is displayed is implementation-specific.
A standard way is a comma-separated list enclosed in square brackets.
For example, a value <code>[ 100, 200, 300 ]</code> of type <code>WheelSpeeds</code> might
be displayed as <code>[ 100 RPM, 200 RPM, 300 RPM ]</code>.
Or, since the format is the same for all elements, the implementation could
display the array as <code>[ 100, 200, 300 ] RPM</code>.</p>
</div>
<div class="paragraph">
<p>The special character sequence <code>{}</code> is called a <strong>replacement field</strong>; it says
where to put the value in the format text.
Each format string must have exactly one replacement field.
The following replacement fields are allowed:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The field <code>{}</code> for displaying element values in their default format.</p>
</li>
<li>
<p>The field <code>{c}</code> for displaying a character value</p>
</li>
<li>
<p>The field <code>{d}</code> for displaying a decimal value</p>
</li>
<li>
<p>The field <code>{x}</code> for displaying a hexadecimal value</p>
</li>
<li>
<p>The field <code>{o}</code> for displaying an octal value</p>
</li>
<li>
<p>The field <code>{e}</code> for displaying a rational value in exponent notation, e.g.,
<code>1.234e2</code>.</p>
</li>
<li>
<p>The field <code>{f}</code> for displaying a rational value in fixed-point notation,
e.g., <code>123.4</code>.</p>
</li>
<li>
<p>The field <code>{g}</code> for displaying a rational value in general format
(fixed-point notation up to an implementation-dependent size and exponent
notation for larger sizes).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For field types <code>c</code>, <code>d</code>, <code>x</code>, and <code>o</code>, the element type must be an integer
type.
For field types <code>e</code>, <code>f</code>, and <code>g</code>, the element type must be a floating-point
type.
For example, the following format string is illegal, because
type <code>string</code> is not an integer type:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] string format "{d}" # Illegal: string is not an integer type</code></pre>
</div>
</div>
<div class="paragraph">
<p>For field types <code>e</code>, <code>f</code>, and <code>g</code>, you can optionally specify a precision
by writing a decimal point and an integer before the field type. For example,
the replacement field <code>{.3f}</code>, specifies fixed-point notation with a precision
of 3.</p>
</div>
<div class="paragraph">
<p>To include the literal character <code>{</code> in the formatted output, you can write
<code>{{</code>, and similarly for <code>}</code> and <code>}}</code>. For example, the following definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32 format "{{element {}}}"</code></pre>
</div>
</div>
<div class="paragraph">
<p>specifies a format string <code>element {0}</code> for element value 0.</p>
</div>
<div class="paragraph">
<p>No other use of <code>{</code> or <code>}</code> in a format string is allowed. For example, this is illegal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32 format "{" # Illegal use of { character</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can include both a default value and a format; in this case, the default
value must come first. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array WheelSpeeds = [3] U32 default 100 format "{} RPM"</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify an element format, then each element is displayed
using the default format for its type.
Therefore, omitting the format string is equivalent to writing the format
string <code>"{}"</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Array-Type-Definitions_Arrays-of-Arrays">6.1.5. Arrays of Arrays</h4>
<div class="paragraph">
<p>An array type may have another array type as its element type.
In this way you can construct an array of arrays.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32
array B = [3] A # An array of 3 A, which is an array of 3 U32</code></pre>
</div>
</div>
<div class="paragraph">
<p>When constructing an array of arrays, you may provide any legal
default expression, so long as the types are compatible.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [2] U32 default 10 # default value is [ 10, 10 ]
array B1 = [2] A # default value is [ [ 10, 10 ], [ 10, 10 ] ]
array B2 = [2] A default 1 # default value is [ [ 1, 1 ], [ 1, 1 ] ]
array B3 = [2] A default [ 1, 2 ] # default value is [ [ 1, 1 ], [ 2, 2 ] ]
array B4 = [2] A default [ [ 1, 2 ], [ 3, 4 ] ]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Types_Struct-Type-Definitions">6.2. Struct Type Definitions</h3>
<div class="paragraph">
<p>A <strong>struct type definition</strong> associates a name with a <strong>struct type</strong>.
A struct type describes the shape of a
<a href="#Defining-Constants_Expressions_Struct-Values">struct value</a>.
It specifies a mapping from element names to their types.
As discussed below, it also specifies a serialization order
for the struct elements.</p>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Writing-a-Struct-Type-Definition">6.2.1. Writing a Struct Type Definition</h4>
<div class="paragraph">
<p>As an example, here is a struct type definition that associates the name <code>S</code> with
a struct type containing two members: <code>x</code> of type <code>U32</code>, and <code>y</code> of type <code>string</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: U32, y: string }</code></pre>
</div>
</div>
<div class="paragraph">
<p>In general, to write a struct type definition, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>struct</code>.</p>
</li>
<li>
<p>The <a href="#Defining-Constants_Names">name</a> of the struct type.</p>
</li>
<li>
<p>A sequence of <strong>struct type members</strong> enclosed in curly braces <code>{</code> &#8230;&#8203; <code>}</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A struct type member consists of a name, a colon, and a
<a href="#Defining-Types_Array-Type-Definitions_Type-Names">type name</a>,
for example <code>x: U32</code>.</p>
</div>
<div class="paragraph">
<p>The struct type members form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element
sequence</a>
in which the optional terminating punctuation is a comma.
As usual for element sequences, you can omit the comma and use
a newline instead.
So, for example, we can write the definition shown above in this alternate way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S {
x: U32
y: string
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Annotating-a-Struct-Type-Definition">6.2.2. Annotating a Struct Type Definition</h4>
<div class="paragraph">
<p>As noted in the beginning of this section, a type definition is
an annotatable element, so you can attach pre and post annotations
to it.
A struct type member is also an annotatable element, so any
struct type member can have pre and post annotations as well.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ This is a pre annotation for struct S
struct S {
@ This is a pre annotation for member x
x: U32 @&lt; This is a post annotation for member x
@ This is a pre annotation for member y
y: string @&lt; This is a post annotation for member y
} @&lt; This is a post annotation for struct S</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Default-Values">6.2.3. Default Values</h4>
<div class="paragraph">
<p>You can specify an optional default value for a struct definition.
To do this, you write the keyword <code>default</code> and an expression
that evaluates to a <a href="#Defining-Constants_Expressions_Struct-Values">struct
value</a>.
For example, here is a struct type <code>S</code> with default value <code>{ x = 1, y = "abc"
}</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: U32, y: string } default { x = 1, y = "abc" }</code></pre>
</div>
</div>
<div class="paragraph">
<p>A default value expression need not be a literal struct value; it
can be any expression with the correct type.
For example, you can create a named constant with a struct
value and use it multiple times, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant s = { x = 1, y = "abc" }
struct S1 { x: U8, y: string } default s
struct S2 { x: U32, y: string } default s</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a default value, then the struct type gets an automatic default
value,
consisting of the default value for each member.</p>
</div>
<div class="paragraph">
<p>The type of the default expression must match the type of the struct, with type
conversions allowed as discussed for
<a href="#Defining-Constants_Expressions_Struct-Values">struct values</a>.
For example, this default expression is allowed, because we can convert integer
values to floating-point values, and we can promote a single value to a
struct with numeric members:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: F32, y: F32 } default 1 # default value is { x = 1.0, y = 1.0 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>And this default expression is allowed, because if we omit a member of a struct,
then FPP will fill in the member and give it the default value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: F32, y: F32 } default { x = 1 } # default value is { x = 1.0, y = 0.0 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, these default expressions are not allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S1 { x: U32, y: string } default { z = 1 } # Error: member z does not match</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S2 { x: U32, y: string } default { x = "abc" } # Error: type of member x does not match</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Member-Arrays">6.2.4. Member Arrays</h4>
<div class="paragraph">
<p>For any struct member, you can specify that the member
is an array of elements.
To do this you, write an array the size enclosed in square brackets
before the member type.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S {
x: [3] U32
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This definition says that struct <code>S</code> has one element <code>x</code>,
which is an array consisting of three <code>U32</code> values.
We call this array a <strong>member array</strong>.</p>
</div>
<div class="paragraph">
<p><strong>Member arrays vs. array types:</strong>
Member arrays let you include an array
of elements as a member of a struct type,
without defining a separate
<a href="#Defining-Types_Array-Type-Definitions">named array type</a>.
Also, member arrays generate less code than named arrays.
Whereas a member size array is a native C&#43;&#43; array,
each named array is a C&#43;&#43; class.</p>
</div>
<div class="paragraph">
<p>On the other hand, defining a named array is usually
a good choice when</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You want to use the array outside of any structure.</p>
</li>
<li>
<p>You want the convenience of a generated array class,
which has a richer interface than the bare
C&#43;&#43; array.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In particular, the generated array class provides
<strong>bounds-checked</strong> access operations:
it causes a runtime failure if an out-of-bounds access
occurs.
The bounds checking provides an additional degree of memory
safety when accessing array elements.</p>
</div>
<div class="paragraph">
<p><strong>Member arrays and default values:</strong>
FPP ignores member array sizes when checking the types of
default values.
For example, this code is accepted:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S {
x: [3] U32
} default { x = 10 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The member <code>x</code> of the struct <code>S</code> gets three copies of the value
10 specified for <code>x</code> in the default value expression.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Member-Format-Strings">6.2.5. Member Format Strings</h4>
<div class="paragraph">
<p>For any struct member, you can include an optional format.
To do this, write the keyword <code>format</code> and a format string.
The format string for a struct member has the same form as for an
<a href="#Defining-Types_Array-Type-Definitions_Format-Strings">array member</a>.
For example, the following struct definition specifies
that member <code>x</code> should be displayed as a hexadecimal value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct Channel {
name: string
offset: U32 format "offset 0x{x}"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>How the entire struct is displayed depends on the implementation.
As an example, the value of <code>S</code> with <code>name = "momentum"</code> and <code>offset = 1024</code>
might look like this when displayed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Channel { name = "momentum", offset = 0x400 }</pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a format for a struct member, then the system uses the default
format for the type of that member.</p>
</div>
<div class="paragraph">
<p>If the member has a size greater than one, then the format
is applied to each element.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct Telemetry {
velocity: [3] F32 format "{} m/s"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The format string is applied to each of the three
elements of the member <code>velocity</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_Struct-Types-Containing-Named-Types">6.2.6. Struct Types Containing Named Types</h4>
<div class="paragraph">
<p>A struct type may have an array or struct type as a member type.
In this way you can define a struct that has arrays or structs as members.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array Speeds = [3] U32
# Member speeds has type Speeds, which is an array of 3 U32 values
struct Wheel { name: string, speeds: Speeds }</code></pre>
</div>
</div>
<div class="paragraph">
<p>When initializing a struct, you may provide any legal
default expression, so long as the types are compatible.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [2] U32
struct S1 { x: U32, y: string }
# default value is { s1 = { x = 0, y = "" }, a = [ 0, 0 ] }
struct S2 { s1: S1, a: A }
# default value is { s1 = { x = 0, y = "abc" }, a = [ 5, 5 ] }
struct S3 { s1: S1, a: A } default { s1 = { y = "abc" }, a = 5 }</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Types_Struct-Type-Definitions_The-Order-of-Members">6.2.7. The Order of Members</h4>
<div class="paragraph">
<p>For <a href="#Defining-Constants_Expressions_Struct-Values">struct values</a>,
we said that the order in which the members appear in the value is not
significant.
For example, the expressions <code>{ x = 1, y = 2 }</code> and <code>{ y = 2, x = 1 }</code> denote
the same value.
For struct types, the rule is different.
The order in which the members appear is significant, because
it governs the order in which the members appear in the generated
code.</p>
</div>
<div class="paragraph">
<p>For example, the type <code>struct S1 { x: U32, y : string }</code> might generate a C&#43;&#43;
class <code>S1</code> with members <code>x</code> and <code>y</code> laid out with <code>x</code> first; while <code>struct S2
{ y : string, x : U32 }</code>
might generate a C&#43;&#43; class <code>S2</code> with members <code>x</code> and <code>y</code> laid out with <code>y</code>
first.
Since class members are generally serialized in the order in which they appear in
the class,
the members of <code>S1</code> would be serialized with <code>x</code> first, and the members of
<code>S2</code>
would be serialized with <code>y</code> first.
Serializing <code>S1</code> to data and then trying to deserialize it to <code>S2</code> would
produce garbage.</p>
</div>
<div class="paragraph">
<p>The order matters only for purposes of defining the type, not for
assigning default values to it.
For example, this code is legal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: U32, y: string } default { y = "abc", x = 5 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>FPP struct <em>values</em> have no inherent order associated with their members.
However, once those values are assigned to a named struct <em>type</em>,
the order becomes fixed.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Types_Abstract-Type-Definitions">6.3. Abstract Type Definitions</h3>
<div class="paragraph">
<p>An array or struct type definition specifies a complete type:
in addition to the name of the type, it provides the names and types
of all the members.
An <strong>abstract type</strong>, by contrast, has an incomplete or opaque definition.
It provides only a name <em>N</em>.
Its purpose is to tell the analyzer that a type with name <em>N</em> exists and will
be defined elsewhere.
For example, if the target language is C&#43;&#43;, then the type is a C&#43;&#43;
class.</p>
</div>
<div class="paragraph">
<p>To define an abstract type, you write the keyword <code>type</code> followed
by the name of the type.
For example, you can define an abstract type <code>T</code>; then you can construct
an array <code>A</code> with member type <code>T</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T # T is an abstract type
array A = [3] T # A is an array of 3 values of type T</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code says the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A type <code>T</code> exists. It is defined in the implementation,
but not in the model.</p>
</li>
<li>
<p><code>A</code> is an array of three values, each of type <code>T</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Now suppose that the target language is C&#43;&#43;.
Then the following happens when generating code:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The definition <code>type T</code> does not cause any code to be generated.</p>
</li>
<li>
<p>The definition <code>array A =</code> &#8230;&#8203; causes a C&#43;&#43; class <code>A</code>
to be generated.
By F Prime convention, the generated files are <code>AArrayAc.hpp</code> and <code>AArrayAc.cpp</code>.</p>
</li>
<li>
<p>File <code>AArrayAc.hpp</code> includes a header file <code>T.hpp</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It is up to the user to implement a C&#43;&#43; class <code>T</code> with
a header file <code>T.hpp</code>.
This header file must define <code>T</code> in a way that is compatible
with the way that <code>T</code> is used in <code>A</code>.
We will have more to say about this topic in the section on
<a href="#Writing-C-Plus-Plus-Implementations_Implementing-Abstract-Types">implementing abstract types</a>.</p>
</div>
<div class="paragraph">
<p>In general, an abstract type <code>T</code> is opaque in the FPP model
and has no values that are expressible in the model.
Thus, every use of an abstract type <code>T</code> represents the default value
for <code>T</code>.
The implementation of <code>T</code> in the target language
provides the default value.
In particular, when the target language is C&#43;&#43;, the default
value is the zero-argument constructor <code>T()</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Types_Alias-Type-Definitions">6.4. Alias Type Definitions</h3>
<div class="paragraph">
<p>An <strong>alias type definition</strong> provides an alternate name for
a type that is defined elsewhere.
The alternate name is called an <strong>alias</strong> of the original type.
For example, here is an alias type definition specifying that the type
<code>T</code> is an alias of the type <code>U32</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T = U32</code></pre>
</div>
</div>
<div class="paragraph">
<p>Wherever this definition is available, the type <code>T</code> may be used
interchangeably with the type <code>U32</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T = U32
array A = [3] T</code></pre>
</div>
</div>
<div class="paragraph">
<p>An alias type definition may refer to any type, including another
alias type, except that it may not refer to itself, either directly or through
another alias.
For example, here is an alias type definition specifying that the type
<code>T</code> is an alias of the struct type <code>S</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">struct S { x: U32, y: I32 }
type T = S</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is a pair of definitions specifying that <code>S</code> is an alias of <code>T</code>,
and <code>T</code> is an alias of <code>F32</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type S = T
type T = F32</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is a pair of alias type definitions that is illegal, because each of
the definitions indirectly refers to itself:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type S = T
type T = S</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alias type definitions are useful for specifying configurations.
Part of a model can use a type <code>T</code>, without
defining <code>T</code>; elsewhere, configuration code can define
<code>T</code> to be the alias of another type.
F Prime uses this method to provide basic type whose definitions
configure the framework.
These types are defined in the file <code>config/FpConfig.fpp</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Types_Framework-Types">6.5. Framework Types</h3>
<div class="paragraph">
<p>Certain types defined in FPP have a special meaning in the F Prime
framework.
These types are called <strong>framework types</strong>.
For example, the type <code>FwOpcodeType</code> defines the type of
a command opcode.
(Commands are an F Prime feature that we describe
<a href="#Defining-Components_Commands">in a later section of this manual</a>.)</p>
</div>
<div class="paragraph">
<p>Framework types are like <a href="#Defining-Constants_Framework-Constants">framework
constants</a>:
you typically define them by overriding configuration files
provided by F Prime, and if they are defined, then they must
conform to certain rules.
<a href="https://nasa.github.io/fpp/fpp-spec.html#Definitions_Framework-Definitions_Type-Definitions"><em>The
FPP Language Specification</em></a> has all the details.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Enums">7. Defining Enums</h2>
<div class="sectionbody">
<div class="paragraph">
<p>An FPP model may contain one or more <strong>enum definitions</strong>.
Enum is short for enumeration.
An FPP enum is similar to an enum in C or C&#43;&#43;.
It defines a named type called an <strong>enum type</strong> and a set of named constants
called <strong>enumerated constants</strong>.
The enumerated constants are the values associated with the type.</p>
</div>
<div class="paragraph">
<p>An enum definition may appear at the top level or inside a
<a href="#Defining-Modules">module definition</a>.
An enum definition is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.</p>
</div>
<div class="sect2">
<h3 id="Defining-Enums_Writing-an-Enum-Definition">7.1. Writing an Enum Definition</h3>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Decision {
YES
NO
MAYBE
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code defines an enum type <code>Decision</code> with three
enumerated constants: <code>YES</code>, <code>NO</code>, and <code>MAYBE</code>.</p>
</div>
<div class="paragraph">
<p>In general, to write an enum definition, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>enum</code>.</p>
</li>
<li>
<p>The name of the enum.</p>
</li>
<li>
<p>A sequence of enumerated constants enclosed in curly braces <code>{</code> &#8230;&#8203; <code>}</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The enumerated constants form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element
sequence</a>
in which the optional terminating punctuation is a comma.
For example, this definition is equivalent to the one above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Decision { YES, NO, MAYBE }</code></pre>
</div>
</div>
<div class="paragraph">
<p>There must be at least one enumerated constant.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Enums_Using-an-Enum-Definition">7.2. Using an Enum Definition</h3>
<div class="paragraph">
<p>Once you have defined an enum, you can use the enum as a type and the
enumerated constants as constants of that type.
The name of each enumerated constant is qualified by the enum name.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum State { ON, OFF }
constant initialState = State.OFF</code></pre>
</div>
</div>
<div class="paragraph">
<p>The constant <code>s</code> has type <code>State</code> and value <code>State.ON</code>.
Here is another example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Decision { YES, NO, MAYBE }
array Decisions = [3] Decision default Decision.MAYBE</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here we have used the enum type as the type of the array member,
and we have used the value <code>Decision.MAYBE</code> as the default
value of an array member.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Enums_Numeric-Values">7.3. Numeric Values</h3>
<div class="paragraph">
<p>As in C and C&#43;&#43;, each enumerated constant has an associated
numeric value.
By default, the values start at zero and go up by one.
For example, in the enum <code>Decision</code> defined above,
<code>YES</code> has value 0, <code>NO</code> has value 1, and <code>MAYBE</code> has value 2.</p>
</div>
<div class="paragraph">
<p>You can optionally assign explicit values to the enumerated
constants.
To do this, you write an equals sign and an expression after
each of the constant definitions.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum E { A = 1, B = 2, C = 3 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This definition creates an enum type <code>E</code> with three enumerated constants <code>E.A</code>,
<code>E.B</code>, and <code>E.C</code>. The constants have 1, 2, and 3 as their associated numeric
values.</p>
</div>
<div class="paragraph">
<p>If you provide an explicit numeric value for any of the enumerated constants,
then you must do so for all of them.
For example, this code is not allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Error: cannot provide a value for just one enumerated constant
enum E { A = 1, B, C }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Further, the values must be distinct.
For example, this code is not allowed, because
the enumerated constants <code>A</code> and <code>B</code> both have the value 2:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Error: enumerated constant values must be distinct
enum E { A = 2, B = 1 + 1 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may convert an enumerated constant to its associated numeric value.
For example, this code is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum E { A = 5 }
constant c = E.A + 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>The constant <code>c</code> has the value 6.</p>
</div>
<div class="paragraph">
<p>However, you may not convert a numeric value to an enumerated constant.
This is for type safety reasons: a value of enumeration type should have
one of the numeric values specified in the type.
Assigning an arbitrary number to an enum type would violate this rule.</p>
</div>
<div class="paragraph">
<p>For example, this code is not allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum E { A, B, C }
# Error: cannot assign integer 10 to type E
array A = [3] E default 10</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Enums_The-Representation-Type">7.4. The Representation Type</h3>
<div class="paragraph">
<p>Each enum definition has an associated <strong>representation type</strong>.
This is the primitive integer type used to represent the numeric
values associated with the enumerated constants when generating code.</p>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a representation type, then the default
type is <code>I32</code>.
For example, in the enumerations defined in the previous sections,
the representation type is <code>I32</code>.
To specify an explicit representation type, you write it after
the enum name, separated from the name by a colon, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Small : U8 { A, B, C }</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code defines an enum <code>Small</code> with three enumerated constants
<code>Small.A</code>, <code>Small.B</code>, and <code>Small.C</code>.
Each of the enumerated constants is represented as a <code>U8</code> value
in C&#43;&#43;.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Enums_The-Default-Value">7.5. The Default Value</h3>
<div class="paragraph">
<p>Every type in FPP has an associated default value.
For enum types, if you don&#8217;t specify a default value explicitly,
then the default value is the first enumerated constant
in the definition.
For example, given this definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Decision { YES, NO, MAYBE }</code></pre>
</div>
</div>
<div class="paragraph">
<p>the default value for the type <code>Decision</code> is <code>Decision.YES</code>.</p>
</div>
<div class="paragraph">
<p>That may be too permissive, say if <code>Decision</code> represents
a decision on a bank loan.
Perhaps the default value should be <code>Decision.MAYBE</code>.
To specify an explicit default value, write the keyword <code>default</code>
and the enumerated constant after the enumerated constant
definitions, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Decision { YES, NO, MAYBE } default MAYBE</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that when using the constant <code>MAYBE</code> as a default value, we
don&#8217;t need to qualify it with the enum name, because the
use appears inside the enum where it is defined.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Dictionary-Definitions">8. Dictionary Definitions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>One of the artifacts generated from an FPP model is a <strong>dictionary</strong>
that tells the ground data system how to interpret and display
the data produced by the FSW.
By default, the dictionary contains representations of the following
types and constants defined in FPP:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Types and constants that are known to the framework and that are
needed by every dictionary, e.g., <code>FwOpcodeType</code>.</p>
</li>
<li>
<p>Types and constants that appear in the definitions of the data produced
by the FSW, e.g., event specifiers or telemetry specifiers.
(In later sections of this manual we will explain how to define
<a href="#Defining-Components_Events">event reports</a> and
<a href="#Defining-Components_Telemetry">telemetry channels</a>.)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Sometimes you will need the dictionary to include the definition of a type or
constant
that does not satisfy either of these conditions.
For example, a downlink configuration parameter may be
shared by the FSW implementation and the GDS and may be otherwise unused
in the FPP model.</p>
</div>
<div class="paragraph">
<p>In this case you can mark a type or constant definition as a <strong>dictionary
definition</strong>.
A dictionary definition tells the FPP analyzer that
whenever a dictionary is generated from the model,
the definition should be included in the dictionary.</p>
</div>
<div class="paragraph">
<p>To write a dictionary definition, you write the keyword <code>dictionary</code>
before the definition.
You can do this for a constant definition, a type definition,
or an enum definition.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">dictionary constant a = 1
dictionary array A = [3] U32
dictionary struct S { x: U32, y: F32 }
dictionary type T = S
dictionary enum E { A, B }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each dictionary definition must observe the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A dictionary constant definition must have a numeric value (integer or
floating point),
a Boolean value (true or false), a string value such as <code>"abc"</code>, or an
enumerated constant value such as <code>E.A</code>.</p>
</li>
<li>
<p>A dictionary type definition must define a <strong>displayable type</strong>, i.e., a
type that the F Prime ground data system knows how to display.
For example, the type may not be an
<a href="#Defining-Types_Abstract-Type-Definitions">abstract type</a>.
Nor may it be an array or struct type that has an abstract type
as a member type.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, the following dictionary definitions are invalid:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">dictionary constant a = { x = 1, y = 2.0 } # Error: a has struct type
dictionary type T # Error: T is an abstract type</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Ports">9. Defining Ports</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A <strong>port definition</strong> defines an F Prime port.
In F Prime, a port specifies the endpoint of a connection
between two component instances.
Components are the basic units of FSW function in F Prime
and are described in the
<a href="#Defining-Components">next section</a>.
A port definition specifies (1) the name of the port, (2) the type of the data
carried
on the port, and (3) an optional return type.</p>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Port-Names">9.1. Port Names</h3>
<div class="paragraph">
<p>The simplest port definition consists of the keyword <code>port</code> followed
by a name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code defines a port named <code>P</code> that carries no data and returns
no data.
This kind of port can be useful for sending or receiving a triggering event.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Formal-Parameters">9.2. Formal Parameters</h3>
<div class="paragraph">
<p>More often, a port will carry data.
To specify the data, you write <strong>formal parameters</strong>
enclosed in parentheses.
The formal parameters of a port definition are similar to the formal parameters
of a function in a programming
language: each one has a name and a type, and you may write
zero or more of them.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P1() # Zero parameters; equivalent to port P1
port P2(a: U32) # One parameter
port P3(a: I32, b: F32, c: string) # Three parameters</code></pre>
</div>
</div>
<div class="paragraph">
<p>The type of a formal parameter may be any valid type, including an
array type, a struct type, an enum type, or an abstract type.
For example, here is some code that defines an enum type <code>E</code> and
and abstract type <code>T</code>, and then uses those types in the
formal parameters of a port:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum E { A, B }
type T
port P(e: E, t: T)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The formal parameters form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element
sequence</a> in which the optional terminating punctuation is a comma. As usual
for element sequences, you can omit the comma and use a newline instead. So,
for example, we can write the definition shown above in this alternate way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum E { A, B }
type T
port P(
e: E
t: T
)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Handler-Functions">9.3. Handler Functions</h3>
<div class="paragraph">
<p>As discussed further in the sections on
<a href="#Defining-Components">defining components</a>
and
<a href="#Defining-Component-Instances">instantiating components</a>,
when constructing an F Prime application, you
instantiate port definitions as <strong>output ports</strong> and
<strong>input ports</strong> of component instances.
Output ports are connected to input ports.
For each output port <code>pOut</code> of a component instance <code>c1</code>,
there is a corresponding auto-generated function that the
implementation of <code>c1</code> can call in order to <strong>invoke</strong> <code>pOut</code>.
If <code>pOut</code> is connected to an input
port <code>pIn</code> of component instance <code>c2</code>, then invoking <code>pOut</code> runs a
<strong>handler function</strong> <code>pIn_handler</code> associated with <code>pIn</code>.
The handler function is part of the implementation of the component
<code>C2</code> that <code>c2</code> instantiates.
In this way <code>c1</code> can send data to <code>c2</code> or request
that <code>c2</code> take some action.
Each input port may be <strong>synchronous</strong> or <strong>asynchronous</strong>.
A synchronous invocation directly calls a handler function.
An asynchronous invocation calls a short function that puts
a message on a queue for later dispatch.
Dispatching the message calls the handler function.</p>
</div>
<div class="paragraph">
<p><strong>Translating handler functions:</strong>
In FPP, each output port <code>pOut</code> or input port <code>pIn</code> has a <strong>port type</strong>.
This port type refers to an FPP port definition <code>P</code>.
In the C&#43;&#43; translation, the signature of a handler function
<code>pIn_handler</code> for <code>pIn</code>
is derived from <code>P</code>.
In particular, the C&#43;&#43; formal parameters of <code>pIn_handler</code>
correspond to the
<a href="#Defining-Ports_Formal-Parameters">FPP formal parameters</a> of <code>P</code>.</p>
</div>
<div class="paragraph">
<p>When generating the handler function <code>pIn_handler</code>, F
Prime translates each formal parameter <em>p</em> of <code>P</code> in the following way:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If <em>p</em> carries a
<a href="#Defining-Constants_Expressions_Primitive-Values">primitive value</a>,
then <em>p</em> is translated to a C&#43;&#43; value parameter.</p>
</li>
<li>
<p>Otherwise <em>p</em> is translated to a C&#43;&#43; <code>const</code> reference
parameter.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>As an example, suppose that <code>P</code> looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T
port P(a: U32, b: T)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then the signature of <code>pIn_handler</code> might look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">virtual void pIn_handler(U32 a, const T&amp; b);</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Calling handler functions:</strong>
Suppose again that output port <code>pOut</code> of component instance <code>c1</code>
is connected to input port <code>pIn</code> of component instance <code>c2</code>.
Suppose that the implementation of <code>c1</code> invokes <code>pOut</code>.
What happens next depends on whether <code>pIn</code> is synchronous
or asynchronous.</p>
</div>
<div class="paragraph">
<p>If <code>pIn</code> is synchronous, then the invocation is a direct
call of the <code>pIn</code> handler function.
Any value parameter is passed by copying the value on
the stack.
Any <code>const</code> reference parameter provides a reference to
the data passed in by <code>c1</code> at the point of invocation.
For example, if <code>pIn</code> has the port type <code>P</code> shown above,
then the implementation of <code>pIn_handler</code> might look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">// Assume pIn is a synchronous input port
void C2::pIn_handler(U32 a, const T&amp; b) {
// a is a local copy of a U32 value
// b is a const reference to T data passed in by c1
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Usually the <code>const</code> reference is what you want, for efficiency reasons.
If you want a local copy of the data, you can make one.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">// Copy b into b1
auto b1 = b</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now <code>b1</code> has the same data that the parameter <code>b</code> would have
if it were passed by value.</p>
</div>
<div class="paragraph">
<p>If <code>pIn</code> is asynchronous, then the invocation does not
call the handler directly. Instead, it calls
a function that puts a message on a queue.
The handler is called when the message is dispatched.
At this point, any value parameter is passed by
copying the value out of the queue and onto the stack.
Any <code>const</code> reference parameter is passed by
(1) copying data out of the queue and onto the stack and
(2) then providing a <code>const</code> reference to the data on the stack.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">// Assume pIn is an asynchronous input port
void C2::pIn_handler(U32 a, const T&amp; b) {
// a is a local copy of a U32 value
// b is a const reference to T data copied across the queue
// and owned by this component
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that unlike in the synchronous case, const references
in parameters refer to data owned by the handler
(residing on the handler stack),
not data owned by the invoking component.
Note also that the values must be small enough to permit
placement on the queue and on the stack.</p>
</div>
<div class="paragraph">
<p>If you want the handler and the invoking component to share data
passed in as a parameter, or if the data values are too large
for the queue and the stack, then you can use a data structure
that contains a pointer or a reference as a member.
For example, <code>T</code> could have a member that stores a reference
or a pointer to shared data.
F Prime provides a type <code>Fw::Buffer</code> that stores a
pointer to a shared data buffer.</p>
</div>
<div class="paragraph">
<p><strong>Passing string arguments:</strong>
Suppose that an input port <code>pIn</code> of a component instance <code>c</code>
has port type <code>P</code>.
If <code>P</code> has a formal parameter of type <code>string</code>,
the corresponding formal parameter in the handler for <code>pIn</code> is
a constant reference to <code>Fw::StringBase</code>, which is an abstract
supertype of all F Prime string types.
The string object referred to depends on whether <code>pIn</code> is synchronous
or asynchronous:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If <code>pIn</code> is synchronous, then the reference is
to the string object used in the invocation.
In this case the size specified in the <code>string</code> type is ignored.
For example, if a string of length 80 is bound to a port parameter
whose type is <code>string size 40</code>, the reference is to the original
string of length 80.</p>
</li>
<li>
<p>If <code>pIn</code> is asynchronous, then the reference is to
a string object on the stack whose size is bounded by
the size named in the port parameter.
For example, if a string of length 80 is bound to a port parameter
whose type is <code>string size 40</code>, then the reference is to a string
consisting of the first 40 characters of the original string.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Reference-Parameters">9.4. Reference Parameters</h3>
<div class="paragraph">
<p>You may write the keyword <code>ref</code> in front of any formal parameter <em>p</em>
of a port definition.
Doing this specifies that <em>p</em> is a <strong>reference parameter</strong>.
Each reference parameter in an FPP port becomes a mutable
C&#43;&#43; reference at the corresponding place in the
handler function signature.
For example, suppose this port definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T
port P(a: U32, b: T, ref c: T)</code></pre>
</div>
</div>
<div class="paragraph">
<p>appears as the type of an input port <code>pIn</code> of component <code>C</code>.
The generated code for <code>C</code> might contain a handler function with a
signature like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">virtual void pIn_handler(U32 a, const T&amp; b, T&amp; c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that parameter <code>b</code> is not marked <code>ref</code>, so it is
translated to <code>const T&amp; b</code>, as discussed in the previous section.
On the other hand, parameter <code>c</code> is marked ref, so it
is translated to <code>T&amp; c</code>.</p>
</div>
<div class="paragraph">
<p>Apart from the mutability, a reference parameter has the same
behavior as a <code>const</code> reference parameter, as described in
the previous section.
In particular:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When <code>pIn</code> is synchronous, a reference parameter <em>p</em> of <code>pIn_handler</code>
refers to the data passed in by the invoking component.</p>
</li>
<li>
<p>When <code>pIn</code> is asynchronous, a reference parameter <em>p</em> of <code>pIn_handler</code>
refers to data copied out of the queue and placed on the local stack.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The main reason to use a reference parameter is to
return a value to the sender by storing it through
the reference.
We discuss this pattern in the section on
<a href="#Defining-Ports_Returning-Values">returning values</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Returning-Values">9.5. Returning Values</h3>
<div class="paragraph">
<p>Optionally, you can give a port definition a return type.
To do this you write an arrow <code>-></code> and a type
after the name and the formal parameters, if any.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T
port P1 -&gt; U32 # No parameters, returns U32
port P2(a: U32, b: F32) -&gt; T # Two parameters, returns T</code></pre>
</div>
</div>
<div class="paragraph">
<p>Invoking a port with a return type is like calling a function with
a return value.
Such a port may be used only in a synchronous context (i.e.,
as a direct function call, not as a message placed
on a concurrent queue).</p>
</div>
<div class="paragraph">
<p>In a synchronous context only, <code>ref</code> parameters provide another way to return
values on the port,
by assigning to the reference, instead of executing a C&#43;&#43; <code>return</code> statement.
As an example, consider the following two port definitions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T
port P1 -&gt; T
port P2(ref t: T)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The similarities and differences are as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Both <code>P1</code> and <code>P2</code> must be used in a synchronous context,
because each returns a <code>T</code> value.</p>
</li>
<li>
<p>In the generated C&#43;&#43; code,</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The function for invoking <code>P1</code>
has no arguments and returns a <code>T</code> value.
A handler associated with <code>P1</code> returns a value of type <code>T</code>
via the C&#43;&#43; <code>return</code> statement.
For example:</p>
<div class="listingblock">
<div class="content">
<pre>T C::p1In_handler() {
...
return T(1, 2, 3);
}</pre>
</div>
</div>
</li>
<li>
<p>The function for invoking <code>P1</code> has one argument <code>t</code>
of type <code>T&amp;</code>.
A handler associated with <code>P2</code> returns a value of type <code>T</code>
by updating the reference <code>t</code> (assigning to it, or updating
its fields).
For example:</p>
<div class="listingblock">
<div class="content">
<pre>void C::p2In_handler(T&amp; t) {
...
t = T(1, 2, 3);
}</pre>
</div>
</div>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>The second way may involve less copying of data.</p>
</div>
<div class="paragraph">
<p>Finally, there can be any number of reference parameters,
but at most one return value.
So if you need to return multiple values on a port, then reference
parameters can be useful.
As an example, the following port attempts to update a result
value of type <code>U32</code>.
It does this via reference parameter.
It also returns a status value indicating whether the update
was successful.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">enum Status { SUCCEED, FAIL }
port P(ref result: U32) -&gt; Status</code></pre>
</div>
</div>
<div class="paragraph">
<p>A handler for <code>P</code> might look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>Status C::pIn_handler(U32&amp; result) {
Status status = Status::FAIL;
if (...) {
...
result = ...
status = Status::SUCCEED;
}
return status;
}</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Pass-by-Reference-Semantics">9.6. Pass-by-Reference Semantics</h3>
<div class="paragraph">
<p>Whenever a C&#43;&#43; formal parameter <em>p</em> enables sharing of data between
an invoking component and a handler function <code>pIn_handler</code>,
we say that <em>p</em> has <strong>pass-by-reference semantics</strong>.
Pass-by-reference semantics occurs in the following cases:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><em>p</em> has reference or <code>const</code> reference type,
and the port <code>pIn</code> is synchronous.</p>
</li>
<li>
<p><em>p</em> has a type <em>T</em> that contains a pointer or
a reference as a member.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>When using pass-by-reference semantics,
you must carefully manage the
use of the data to avoid concurrency bugs
such as data races.
This is especially true for references that can modify
shared data.</p>
</div>
<div class="paragraph">
<p>Except in special cases that require special expertise (e.g.,
the implementation of highly concurrent data structures),
you should enforce the rule that at most
one component may use any piece of data at any time.
In particular, if component <code>A</code> passes a reference to component <code>B</code>,
then component <code>A</code> should not use the reference while
component <code>B</code> is using it, and vice versa.
For example:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Suppose component <code>A</code> owns some data <code>D</code> and passes a reference
to <code>D</code> via a synchronous port call to component <code>B</code>.
Suppose the port handler in component <code>B</code> uses the data but
does not store the reference, so that when the handler exits,
the reference is lost.
This is a good pattern.
In this case, we may say that ownership of <code>D</code> resides in <code>A</code>, temporarily
goes to <code>B</code> for the life of the handler, and goes back to <code>A</code>
when the handler exits.
Because the port call is synchronous, the handler in <code>B</code>
never runs concurrently with any code in <code>A</code> that uses <code>D</code>.
So at most one of <code>A</code> or <code>B</code> uses <code>D</code> at any time.</p>
</li>
<li>
<p>Suppose instead that the handler in <code>B</code> stores the reference
into a member variable, so that the reference
persists after the handler exits.
If this happens, then you should make sure that <code>A</code> cannot use
<code>D</code> unless and until <code>B</code> passes ownership of <code>D</code> to <code>A</code> and vice versa.
For example, you could use state variables of enum type in <code>A</code> and in <code>B</code> to
track ownership, and you could have a port invocation from <code>A</code> to <code>B</code> pass the
reference and transfer ownership from <code>A</code> to <code>B</code> and vice versa.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Ports_Annotating-a-Port-Definition">9.7. Annotating a Port Definition</h3>
<div class="paragraph">
<p>A port definition is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.
Each formal parameter is also an annotatable element.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Pre annotation for port P
port P(
@ Pre annotation for parameter a
a: U32
@ Pre annotation for parameter b
b: F32
)</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-State-Machines">10. Defining State Machines</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A <strong>hierarchical state machine</strong> (state machine for short)
is a software subsystem that specifies the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A set of <strong>states</strong> that the system can be in.
The states can be arranged in a hierarchy (i.e.,
states may have substates).</p>
</li>
<li>
<p>A set of <strong>transitions</strong> from one state to another that
occur under specified conditions.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>State machines are important in embedded programming.
For example, F Prime components often have a concept of state
that changes as the system runs, and it is useful to model
these state changes as a state machine.</p>
</div>
<div class="paragraph">
<p>In FPP there are two ways to define a state machine:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>An <strong>external</strong> state machine definition is like
an <a href="#Defining-Types_Abstract-Type-Definitions">abstract type definition</a>:
it tells the analyzer that a state machine exists with a specified
name, but it says nothing about the state machine behavior.
An external tool must provide the state machine implementation.</p>
</li>
<li>
<p>An <strong>internal</strong> state machine definition is like an
<a href="#Defining-Types_Array-Type-Definitions">array type definition</a>
or
<a href="#Defining-Types_Struct-Type-Definitions">struct type definition</a>:
it provides a complete specification in FPP of the state machine behavior.
The FPP back end uses this specification to generate code;
no external tool is required.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The following subsections describe both kinds of state machine
definitions.</p>
</div>
<div class="paragraph">
<p>State machine definitions may appear at the top level or inside a
<a href="#Defining-Modules">module definition</a>.
A state machine definition is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.
Once you define a state machine, you can
<a href="#Defining-Components_State-Machine-Instances">instantiate it as part of a component</a>.
The component can then send the signals that cause the state
transitions.
The component also provides the functions that are called when
the state machine does actions and evaluates guards.</p>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_Writing-a-State-Machine-Definition">10.1. Writing a State Machine Definition</h3>
<div class="paragraph">
<p><strong>External state machines:</strong>
To define an external state machine, you write the keywords
<code>state</code> <code>machine</code> followed by an identifier, which is the
name of the state machine:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">state machine M</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code defines an external state machine with name <code>M</code>.</p>
</div>
<div class="paragraph">
<p>When you define an external state machine <code>M</code>, you must provide
an implementation for <code>M</code>, as discussed in the section
on <a href="#Writing-C-Plus-Plus-Implementations_Implementing-External-State-Machines">implementing external state machines</a>.
The external implementation must have a header file <code>M.hpp</code>
located in the same directory as the FPP file where
the state machine <code>M</code> is defined.</p>
</div>
<div class="paragraph">
<p><strong>Internal state machines:</strong>
In the following subsections, we explain how to define internal
state machines in FPP.
The behavior of these state machines closely follows the behavior
described for state machines in the
<a href="https://www.omg.org/spec/UML/2.5.1/PDF">Universal Modeling Language (UML)</a>.
UML is a graphical language and FPP is a textual language,
but each of the concepts in the FPP language is motivated
by a corresponding UML concept.
FPP does not represent every aspect of UML state machines:
because our goal is to support embedded and flight software,
we focus on a subset of UML state machine behavior that is
(1) simple and unambiguous and (2) sufficient for embedded
applications that use F Prime.</p>
</div>
<div class="paragraph">
<p>In this manual, we focus on the syntax and high-level behavior
of FPP state machines.
For more details about the C&#43;&#43; code generation
for state machines, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/state-machines/">F
Prime design documentation</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_States-Signals-and-Transitions">10.2. States, Signals, and Transitions</h3>
<div class="paragraph">
<p>In this and the following sections, we explain how to define
internal state machines, i.e., state machines that are fully
specified in FPP.
In these sections, when we say &#8220;state machine,&#8221;
we mean an internal state machine.</p>
</div>
<div class="paragraph">
<p>First we explain the concepts of states,
signals, and transitions.
These are the basic building blocks of FPP state machines.</p>
</div>
<div class="paragraph">
<p><strong>Basic state machines:</strong>
The simplest state machine <em>M</em> that has any useful
behavior consists of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Several <strong>state definitions</strong>.
These define the states of <em>M</em>.</p>
</li>
<li>
<p>An <strong>initial transition specifier</strong>.
This specifies the state that an instance of <em>M</em> is in when it starts up.</p>
</li>
<li>
<p>One or more <strong>signal definitions</strong>.
The external environment (typically an F Prime component)
sends signals to instances of <em>M</em>.</p>
</li>
<li>
<p>One or more <strong>state transition specifiers</strong>.
These tell each instance of <em>M</em> what to do when it receives a signal.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior
state machine Device {
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the example represented graphically, as a UML state
machine:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/Basic.png" alt="Device state machine" width="200">
</div>
</div>
<div class="paragraph">
<p>This example defines a state machine <code>Device</code> that represents
a device with on-off behavior.
There are two states, <code>ON</code> and <code>OFF</code>.
The initial transition specifier <code>initial enter OFF</code>
says that the state machine is in state <code>OFF</code> when it starts up.
There are two signals: <code>cmdOn</code> for turning the device
on and <code>cmdOff</code> for turning the device off.
There are two state transition specifiers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A specifier that says to enter state <code>OFF</code>
on receiving the <code>cmdOff</code> signal in state <code>ON</code>.</p>
</li>
<li>
<p>A specifier that says to enter state <code>ON</code>
on receiving the <code>cmdOn</code> signal in state <code>OFF</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In general, a state transition specifier causes a transition
from the state <em>S</em> in which it appears to the state <em>S'</em> that
appears after the keyword <code>enter</code>.
We say that <em>S</em> is the <strong>source</strong> of the transition,
and <em>S'</em> is the <strong>target</strong> of the transition.</p>
</div>
<div class="paragraph">
<p>If a state machine instance receives a signal <em>s</em>, and it is
in a state <em>S</em> that specifies no behavior for signal <em>s</em>
(i.e., there is no transition with source <em>S</em> and signal <em>s</em>),
then nothing happens.
In the example above, if the state machine receives signal
<code>cmdOn</code> in state <code>ON</code>
or signal <code>cmdOff</code> in state <code>OFF</code>, then it takes no action.</p>
</div>
<div class="paragraph">
<p><strong>Rules for defining state machines:</strong>
Each state machine definition must conform to the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A state machine definition and each of its members is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.
For example, you can annotate the <code>Device</code> state machine as shown above.
The members of a state machine definition form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> with a semicolon as the optional
terminating punctuation.
The same rules apply to the members of a state definition.</p>
</li>
<li>
<p>Each state machine definition must have exactly one
initial transition specifier that names a state of
the state machine.
For example, if we deleted the initial transition specifier
from the example above and passed the result through
<code>fpp-check</code>, an error would occur.</p>
</li>
<li>
<p>Every state definition must be reachable from the initial
transition specifier or from a state transition specifier.
For example, if we deleted the state transition specifier
in the state <code>ON</code> from the example above and passed
the result through <code>fpp-check</code>, an error would occur.
In this case, there would be no way to reach the <code>ON</code> state.</p>
</li>
<li>
<p>Every state name must be unique, and every signal name
must be unique.</p>
</li>
<li>
<p>Each state may have at most one state transition specifier
for each signal <em>s</em>.
For example, if we added another transition to state <code>ON</code>
on signal <code>cmdOff</code>, the FPP analyzer would report an error.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Simple state definitions:</strong>
If a state definition has no transitions, then you can omit
the braces.
For example, here is a revised version of the <code>Device</code> state
machine that has an off-on transition but no on-off transition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-only behavior
state machine Device {
@ A signal for turning the device on
signal cmdOn
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that state <code>ON</code> has a simple definition with no curly braces.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_Actions">10.3. Actions</h3>
<div class="paragraph">
<p>An <strong>action</strong> is a function that a state machine calls at a
specified point in its behavior.
In the FPP model, actions are abstract;
in the C&#43;&#43; back end they become pure virtual functions that
you implement.
When a state machine instance calls the function associated with
an action <em>A</em>, we say that it <strong>does</strong> <em>A</em>.</p>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Actions_Actions-in-Transitions">10.3.1. Actions in Transitions</h4>
<div class="paragraph">
<p>To define an action, you write the keyword <code>action</code> followed
by the name of the action.
As with <a href="#Defining-State-Machines_States-Signals-and-Transitions">signals</a>,
every action name must be unique.
To do an action, you write the keyword <code>do</code>
followed by a list of action names enclosed in curly braces.
You can do this in an initial transition specifier or in a
state transition specifier.</p>
</div>
<div class="paragraph">
<p>As an example, here is the <code>Device</code> state machine from the
previous section, with actions added:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior,
@ with actions on transitions
state machine Device {
@ Initial action 1
action initialAction1
@ Initial action 2
action initialAction2
@ An action on the transition from OFF to ON
action offOnAction
@ An action on the transition from ON to OFF
action onOffAction
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
@ Before entering the initial state, do initialAction1 and then initialAction2
initial do { initialAction1, initialAction2 } enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
@ Before entering the OFF state, do onOffAction
on cmdOff do { onOffAction } enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
@ Before entering the ON state, do offOnAction
on cmdOn do { offOnAction } enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/ActionsInTransitions.png" alt="Device state machine with actions on transitions" width="500">
</div>
</div>
<div class="paragraph">
<p>In this example there are four actions:
<code>initialAction1</code>, <code>initialAction2</code>, <code>offOnAction</code>, and <code>onOffAction</code>.
The behavior of each of these actions is specified in the C&#43;&#43;
implementation; for example, each could emit an
<a href="#Defining-Components_Events">F Prime event</a>.
The state machine has the following behavior:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>On startup, do <code>initialAction1</code>, do <code>initialAction2</code>, and
enter the <code>OFF</code> state.</p>
</li>
<li>
<p>In state <code>OFF</code>, on receiving the <code>cmdOn</code> signal, do
<code>offOnAction</code> and enter the <code>ON</code> state.</p>
</li>
<li>
<p>In state <code>ON</code>, on receiving the <code>cmdOff</code> signal, do
<code>onOffAction</code> and enter the <code>OFF</code> state.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>When multiple actions appear in an action list, as in the initial
transition specifier shown above, the actions occur in the order
listed.
Each action list is an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> with a comma as the optional
terminating punctuation.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Actions_Entry-and-Exit-Actions">10.3.2. Entry and Exit Actions</h4>
<div class="paragraph">
<p>In addition to doing actions on transitions, a state machine
can do actions on entry to or exit from a state.
To do actions like this, you write <strong>state entry specifiers</strong>
and <strong>state exit specifiers</strong>.
For example, here is the <code>Device</code> state machine from
the previous section, with state entry and exit specifiers
added to the <code>ON</code> and <code>OFF</code> states:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior,
@ with actions on transitions and on state entry and exit
state machine Device {
@ Initial action 1
action initialAction1
@ Initial action 2
action initialAction2
@ An action on the transition from OFF to ON
action offOnAction
@ An action on the transition from ON to OFF
action onOffAction
@ An action on entering the ON state
action enterOn
@ An action on exiting the ON state
action exitOn
@ An action on entering the OFF state
action enterOff
@ An action on exiting the OFF state
action exitOff
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
@ Before entering the initial state, do initialAction1 and then initialAction2
initial do { initialAction1, initialAction2 } enter OFF
@ The ON state
state ON {
@ On entering the ON state, do enterOn
entry do { enterOn }
@ In the ON state, a cmdOff signal causes a transition to the OFF state
@ Before entering the OFF state, do offAction
on cmdOff do { onOffAction } enter OFF
@ On exiting the ON state, do exitOn
exit do { exitOn }
}
@ The OFF state
state OFF {
@ On entering the OFF state, do enterOff
entry do { enterOff }
@ In the OFF state, a cmdOff signal causes a transition to the ON state
@ Before entering the ON state, do onAction
on cmdOn do { offOnAction } enter ON
@ On exiting the OFF state, do exitOff
exit do { exitOff }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/EntryAndExitActions.png" alt="Device state machine with entry and exit actions" width="500">
</div>
</div>
<div class="paragraph">
<p>As with actions on transitions, each entry or exit specifier names
a list of actions, and the actions are done in the order named.
The entry actions are done just before entering the state,
and the exit actions are done just before exiting the state.
For example, if the state machine is in state <code>OFF</code> and it
receives a <code>cmdOn</code> signal, then it runs the following behavior,
in the following order:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Exit state <code>OFF</code>. On exit, do <code>exitOff</code>.</p>
</li>
<li>
<p>Transition from <code>OFF</code> to <code>ON</code>. On the transition, do <code>offOnAction</code>.</p>
</li>
<li>
<p>Enter state <code>ON</code>. On entry, do <code>enterOn</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Each state may have at most one entry specifier and at most one
exit specifier.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Actions_Typed-Signals-and-Actions">10.3.3. Typed Signals and Actions</h4>
<div class="paragraph">
<p>Optionally, signals and actions may carry data values.
To specify that a signal or action carries a data value,
you write a colon and a data type at the end of the
signal or action specifier.
For example, here is a <code>Device</code> state machine in which
the <code>cmdOn</code> signal and the <code>offOnAction</code> each carries
a <code>U32</code> counter value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior,
@ with actions on transitions
state machine Device {
@ An action on the transition from OFF to ON
@ The value counts the number of times this action has occurred
action offOnAction: U32
@ A signal for turning the device on
@ The value counts the number of times this signal has been received
signal cmdOn: U32
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
@ Before entering the ON state, do offOnAction, passing the data from
@ the signal into the action
on cmdOn do { offOnAction } enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you send the <code>cmdOn</code> signal to an instance of
this state machine, you must provide a <code>U32</code> value.
When the state machine is in the <code>OFF</code> state and it receives
this signal, it does action <code>offOnAction</code> as shown.
The function that defines the behavior of <code>offOnAction</code> has
a single argument of type <code>U32</code>.
The value provided when the signal is sent is passed as the
argument to this function.</p>
</div>
<div class="paragraph">
<p>Here are the rules for writing typed signals and actions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When you do an action that has a type, a value
compatible with that type must be available.
For example, we can&#8217;t do the <code>offOnAction</code> in the <code>cmdOff</code> transition shown
above, because no <code>U32</code>
value is available there.
Similarly, no action done in a
<a href="#Defining-State-Machines_Actions_Entry-and-Exit-Actions">state entry or exit specifier</a> may carry a value,
because no values are available on entry to or exit
from a state.</p>
</li>
<li>
<p>The type that appears in a signal or an action can
be any FPP type.
In the example above we used a simple <code>U32</code> type;
we could have used, for example, a struct or array type.
In particular, you can use a struct type to send several
data values, with each value represented as a member
of the struct.</p>
</li>
<li>
<p>When doing an action with a value, you don&#8217;t have to
make the types exactly match.
For example, you are permitted to pass a <code>U16</code> value
to an action that requires a <code>U32</code> value.
However, the type of the value must be convertible to the type
specified in the action.
The type conversion rules are spelled out in full in
<em>The FPP Language Specification</em>.
In general, the analyzer will allow a conversion if it
can be safely done for all values of the original type.</p>
</li>
<li>
<p>If an action <em>A</em> does not carry any value, then you
can do <em>A</em> in any context, even if a value is available there.
For example, in the code shown above, the <code>cmdOn</code>
transition could do some other action that carries no value.
In this case the value is ignored when doing the action.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Actions_Atomicity-of-Signal-Handling">10.3.4. Atomicity of Signal Handling</h4>
<div class="paragraph">
<p>When an FPP state machine receives a signal, the handling of
that signal is <strong>atomic</strong>.
That means that signals may be received concurrently,
but they are handled one by one.
For example, this sequence of events cannot occur:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>In state <em>S</em><sub>1</sub>, signal <em>s</em><sub>1</sub> is handled, causing an action <em>A</em> and a
transition to state <em>S</em><sub>2</sub>.</p>
</li>
<li>
<p>After doing action <em>A</em>, but before entering state <em>S</em><sub>2</sub>,
a signal <em>s</em><sub>2</sub> is handled.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Instead, <em>s</em><sub>2</sub> will be handled either before the handling of <em>s</em><sub>1</sub>
starts or after the handling of <em>s</em><sub>1</sub> is complete.
This atomicity guarantee is achieved by putting the signals on
an input queue and using the queue to serialize the signal handler
functions.</p>
</div>
<div class="paragraph">
<p>Because of the atomicity guarantee, the C&#43;&#43; implementation of an FPP state machine
can safely send a signal <em>s</em> as part of its implementation for an action <em>A</em>.
The action <em>A</em> will be run during the handling of a signal <em>s'</em>.
When <em>s'</em> is handled and <em>A</em> is run, <em>s</em> is placed on the queue.
After <em>s'</em> is complete, <em>s</em> is dispatched from the queue and handled.</p>
</div>
<div class="paragraph">
<p>For more details on sending signals to an FPP state machine, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/state-machines/">F
Prime design documentation</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_More-on-State-Transitions">10.4. More on State Transitions</h3>
<div class="paragraph">
<p>In this section, we provide more details on how to write
<a href="#Defining-State-Machines_States-Signals-and-Transitions">state transitions</a>
in FPP state machines.</p>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_More-on-State-Transitions_Guarded-Transitions">10.4.1. Guarded Transitions</h4>
<div class="paragraph">
<p>Sometimes it is useful to specify that a transition should occur
only if a certain condition is true.
For example, you may want to turn on a device, but only if
it is safe to do so.
We call this kind of transition a <strong>guarded transition</strong>.
To specify this transition, you define a <strong>guard</strong>, which
is an abstract function that returns a Boolean value.
Then you use the guard in a transition.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A device state machine with a guarded transition
state machine Device {
@ A guard for checking whether the device is in a safe state for power-on
guard powerOnIsSafe
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
@ if powerOnIsSafe evaluates to true. Otherwise no transition occurs.
on cmdOn if powerOnIsSafe enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/GuardedTransitions.png" alt="Device state machine with a guarded transition" width="400">
</div>
</div>
<div class="paragraph">
<p>In this example, there is one guard, <code>powerOnIsSafe</code>.
The implementation of this function will return true
if it is safe to power on the device; otherwise it will
return false.
In state <code>OFF</code>, the transition on signal <code>cmdOn</code> is
now guarded: when the signal is received in this state,
the transition occurs if and only if <code>powerOnIsSafe</code>
evaluates to <code>true</code>.</p>
</div>
<div class="paragraph">
<p>As with actions, each guard must have a unique name.
Also as with actions, a guard can have a type; if it does,
the type must match the type of the signal at the point
where the guard is evaluated.
For example, here is a revised version of the previous
state machine that adds a value of type <code>DeviceStatus</code>
to the guard <code>powerOnIsSafe</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A type representing the status of a device
type DeviceStatus
@ A device state machine with a guarded transition
state machine Device {
@ A guard for checking whether the device is in a safe state for power-on
@ The DeviceStatus value provides the current device status
guard powerOnIsSafe: DeviceStatus
@ A signal for turning the device on
@ The DeviceStatus value provides the current device status
signal cmdOn: DeviceStatus
@ A signal for turning the device off
signal cmdOff
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
@ if powerOnIsSafe evaluates to true. Otherwise no transition occurs.
on cmdOn if powerOnIsSafe enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you send the signal <code>cmdOn</code> to an instance of this state
machine, you must provide a value of type <code>DeviceStatus</code>.
When the state machine instance evaluates the guard <code>powerOnIsSafe</code>,
it passes in the value as an argument to the function.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_More-on-State-Transitions_Self-Transitions">10.4.2. Self Transitions</h4>
<div class="paragraph">
<p>When a state transition has the same state <em>S</em> as its source
and its target, and <em>S</em> has no substates, we call the transition
a <strong>self transition</strong>.
In this case the following behavior occurs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The state machine does the exit actions for <em>S</em>, if any.</p>
</li>
<li>
<p>The state machine does the actions specified in the transition, if any.</p>
</li>
<li>
<p>The state machine does the entry actions for <em>S</em>, if any.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Note that on a self transition, the state machine exits and
reenters <em>S</em>.
This behavior is a special case of a more general behavior that we will
discuss
<a href="#Defining-State-Machines_Hierarchy_Entry-and-Exit-Actions">below</a>
in connection with state hierarchy.
<a href="#Defining-State-Machines_Hierarchy_Directly-Related-States">Below</a>
we will also generalize the concept of a self transition to
the case of a state with substates.</p>
</div>
<div class="paragraph">
<p>As an example, consider the following state machine:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior,
@ with a self transition
state machine Device {
@ An action on entering the ON state
action enterOn
@ An action to perform on reset
action reset
@ An action on exiting the ON state
action exitOn
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ A signal for resetting the device
signal cmdReset
@ The initial state is OFF
@ Before entering the initial state, do initialAction1 and then initialAction2
initial enter OFF
@ The ON state
state ON {
@ On entering the ON state, do enterOn
entry do { enterOn }
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
@ In the ON state, a cmdReset signal causes a self transition
on cmdReset do { reset } enter ON
@ On exiting the ON state, do exitOn
exit do { exitOn }
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/SelfTransitions.png" alt="Device state machine with a self transition" width="400">
</div>
</div>
<div class="paragraph">
<p>In this example, when the state machine is in the <code>ON</code> state and
it receives a <code>cmdReset</code> signal, the following behavior occurs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Do action <code>exitOn</code>.</p>
</li>
<li>
<p>Do action <code>reset</code>.</p>
</li>
<li>
<p>Do action <code>enterOn</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_More-on-State-Transitions_Internal-Transitions">10.4.3. Internal Transitions</h4>
<div class="paragraph">
<p>An <strong>internal transition</strong> is like a
<a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">self transition</a>,
except that there is no exit and reentry.
To write an internal transition, you write the <code>on</code> and <code>do</code>
parts of a transition and omit the <code>enter</code> part.
For example, here is a device state machine with a <code>reset</code>
action that causes an internal transition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A state machine representing a device with on-off behavior,
@ with an internal transition
state machine Device {
@ An action on entering the ON state
action enterOn
@ An action to perform on reset
action reset
@ An action on exiting the ON state
action exitOn
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ A signal for resetting the device
signal cmdReset
@ The initial state is OFF
@ Before entering the initial state, do initialAction1 and then initialAction2
initial enter OFF
@ The ON state
state ON {
@ On entering the ON state, do enterOn
entry do { enterOn }
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
@ In the ON state, a cmdReset signal causes an internal transition
on cmdReset do { reset }
@ On exiting the ON state, do exitOn
exit do { exitOn }
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/InternalTransitions.png" alt="Device state machine with an internal transition" width="200">
</div>
</div>
<div class="paragraph">
<p>In this example, when the state machine is in state <code>ON</code> and it
receives a <code>cmdReset</code> signal, it does the <code>reset</code> action and
performs no other behavior.</p>
</div>
<div class="paragraph">
<p>An internal transition may have a guard.
For example, we could define a guard <code>resetIsSafe</code> and
write the internal transition as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">on cmdReset if resetIsSafe do { reset }</code></pre>
</div>
</div>
<div class="paragraph">
<p>As with other transitions, if the signal carries data, then
any actions and guards named in an internal transition may
carry data of a compatible type.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_Choices">10.5. Choices</h3>
<div class="paragraph">
<p>A <strong>choice definition</strong> is a state machine member that
defines a branch point for one or more transitions.
In this section we explain how to write and use
choice definitions.</p>
</div>
<div class="paragraph">
<p><strong>Basic choice definitions:</strong>
The most basic choice definition consists of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A name. Like a state name, this name can be the target
of a transition.</p>
</li>
<li>
<p>The name of a
<a href="#Defining-State-Machines_More-on-State-Transitions_Guarded-Transitions">guard</a>
<em>G</em>.
The evaluation of <em>G</em> selects which branch of the choice to
follow.</p>
</li>
<li>
<p>An <strong>if transition</strong> that specifies what to do if <em>G</em>
evaluates to <code>true</code>.</p>
</li>
<li>
<p>An <strong>else transition</strong> that specifies what to do if <em>G</em>
evaluates to <code>false</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Each of the if and else transitions has a target,
which can be a state or a choice.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A device state machine with a choice
state machine Device {
@ A guard for checking whether the device is in a safe state for power-on
guard powerOnIsSafe
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ A signal for resetting the device
signal cmdReset
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ In the OFF state, a cmdOff signal causes a transition to the choice ON_OR_ERROR
on cmdOn enter ON_OR_ERROR
}
@ The ON_OR_ERROR choice
choice ON_OR_ERROR {
if powerOnIsSafe enter ON else enter ERROR
}
@ The ERROR state
state ERROR {
@ In the ERROR state, a cmdReset signal causes a transition to the OFF state
on cmdReset enter OFF
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/Choices.png" alt="Device state machine with a choice" width="450">
</div>
</div>
<div class="paragraph">
<p>This version of the <code>Device</code> state machine has three states:
<code>ON</code>, <code>OFF</code>, and <code>ERROR</code>.
It also has a choice <code>ON_OR_ERROR</code>.
Each instance of the state machine has the following behavior:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The initial state is <code>OFF</code>.</p>
</li>
<li>
<p>On receiving the signal <code>cmdOn</code> in the <code>OFF</code> state, it
enters the choice <code>ON_OR_ERROR</code>.
At that point, if <code>powerOnIsSafe</code> evaluates to <code>true</code>, then
it enters then <code>ON</code> state.
Otherwise it enters the <code>ERROR</code> state.</p>
</li>
<li>
<p>On receiving the signal <code>cmdReset</code> in the <code>ERROR</code> state,
it enters the <code>OFF</code> state.</p>
</li>
<li>
<p>On receiving the signal <code>cmdOff</code> in the <code>ON</code> state,
it enters the <code>OFF</code> state.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The text inside the curly braces of a choice consists
of a single line.
To write the text on multiple lines, you can use an
<a href="#Defining-Constants_Multiline-Definitions">explicit line
continuation</a>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">choice ON_OR_ERROR {
if powerOnIsSafe \
enter ON \
else enter ERROR
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Initial transitions to choices:</strong>
An initial transition can go to a choice.
This pattern can express conditional behavior on state
machine startup.
For example, in the <code>Device</code> state machine shown above,
we could have the initial transition go to a choice
that checks a safety condition and then enters either
the <code>OFF</code> state or an error state.</p>
</div>
<div class="paragraph">
<p><strong>Choice transitions to choices:</strong>
An if transition or an else transition of a choice
(or both) can enter another choice.
For example, it is permissible to write a chain of
choices like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">choice C {
if g1 enter C1 else enter C2
}
choice C1 {
if g2 enter S1 else enter S2
}
choice C2 {
if g3 enter S3 else enter S4
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Effectively this is a four-way choice; it is a two-way
choice, each branch of which leads to a two way choice.
By having the if or else branch of <code>C1</code> go directly
to a state, you could get a three-way choice.
And by adding more levels, you can create an <em>n</em> -way
choice for any <em>n</em>.
In this way you can use choices to create arbitrarily
complex branching patterns.
Note though, that it is usually a good idea not to have
more than a few levels of choices; otherwise the state
machine can be complex and hard to understand.</p>
</div>
<div class="paragraph">
<p><strong>The type associated with a choice:</strong>
Like initial transitions and state transitions, the
transitions out of a choice may
<a href="#Defining-State-Machines_Actions_Typed-Signals-and-Actions">carry a value</a>.
To determine whether the transitions of a choice <em>C</em> carry a value,
and if so what type that value has, we use the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If any transition into <em>C</em> carries no value,
then transitions out of <em>C</em> carry no value.</p>
</li>
<li>
<p>Otherwise if all of the transitions into <em>C</em> carry
a value of the same type <em>T</em>, then each of the
transitions out of <em>C</em> carries a value of type <em>T</em>.</p>
</li>
<li>
<p>Otherwise if the incoming types can be resolved to
a common type <em>T</em>, then each of the transitions out of <em>C</em>
carries a value of type <em>T</em>.
The rules for resolving common types are given in
<em>The FPP Language Specification</em>.
The basic idea is to find a type to which it is always
safe to cast all the incoming types.</p>
</li>
<li>
<p>Otherwise the analyzer reports an error.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Actions in choice transitions:</strong>
You can do actions in choice transitions just as for
<a href="#Defining-State-Machines_Actions">initial transitions and
state transitions</a>.
For example, suppose we add the definitions of actions <code>onAction</code> and
<code>errorAction</code> to the <code>Device</code> state machine shown above.
Then we could revise the <code>ON_OR_ERROR</code> choice to read as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">choice ON_OR_ERROR {
if powerOnIsSafe do onAction enter ON else do errorAction enter ERROR
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As for other kinds of transitions, the actions done in choice
transitions may carry values.
If an action <em>A</em> done in a transition of a choice <em>C</em> carries a value,
the type named in the definition of <em>A</em> must be
compatible with the type associated with <em>C</em>, as discussed above.</p>
</div>
<div class="paragraph">
<p><strong>Entry and exit actions:</strong>
When a transition <em>T</em> of a state machine <em>M</em>
goes to or from a choice, entry and
exit actions are done as if each choice were a state with
no entry and or exit actions.
For example, let <em>I</em> be an instance of <em>M</em>, and
suppose <em>I</em> is carrying out a transition <em>T</em>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If <em>T</em> goes from a choice <em>C</em> to a state <em>S</em>,
then <em>I</em>
does the actions of <em>T</em> followed by the entry actions of <em>S</em>.</p>
</li>
<li>
<p>If <em>T</em> goes from a state <em>S</em> to a choice <em>C</em>,
then <em>I</em>
does the exit actions of <em>S</em> followed by the actions of <em>T</em>.</p>
</li>
<li>
<p>If <em>T</em> goes from a choice <em>C</em><sub>1</sub> to a choice <em>C</em><sub>2</sub>,
then <em>I</em> does the actions of <em>T</em>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>Rules for choice definitions:</strong>
Choice definitions must conform to the following rules:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>No state or choice may have the same name as any other
state or choice.</p>
</li>
<li>
<p>Every choice must be reachable from the initial transition
or from a state transition.</p>
</li>
<li>
<p>There may be no cycles of choice transitions.
For example, it is not permitted for a choice <code>C1</code> to
have a transition to a choice <code>C2</code> that has a transition
back to <code>C1</code>.
Nor is it permissible for <code>C1</code> to go to <code>C2</code>, <code>C2</code> to
go to <code>C3</code>, and <code>C3</code> to go to <code>C1</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="Defining-State-Machines_Hierarchy">10.6. Hierarchy</h3>
<div class="paragraph">
<p>As with UML state machines, FPP state machines can have <strong>hierarchy</strong>.
That is, we can do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Define states within other states.
When a state <em>T</em> is defined within a state <em>S</em>, <em>S</em> is called the
<strong>parent</strong> of <em>T</em>, and <em>T</em> is called a <strong>substate</strong> or <strong>child</strong> of <em>S</em>.</p>
</li>
<li>
<p>Define choices within states.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Using hierarchy, we can do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Group related substates under a single parent.
This grouping lets us express the state machine structure in a
disciplined and modular way.</p>
</li>
<li>
<p>Define behaviors of a parent state that are inherited
by its substates.
The parent behavior saves having to redefine the behavior for each
substate.</p>
</li>
<li>
<p>Control the way that entry and exit actions occur
when transitions cross state boundaries.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A state machine with hierarchy is called a
<strong>hierarchical state machine</strong>.
In the following subsections, we explain how to define
hierarchical state machines in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Hierarchy_Substates">10.6.1. Substates</h4>
<div class="paragraph">
<p>In this section we explain how to define and use substates.</p>
</div>
<div class="paragraph">
<p><strong>An example:</strong>
Here is an example of a state machine with substates:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A device state machine with substates
state machine Device {
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ A signal for indicating that the device is in an unsafe state
signal cmdUnsafe
@ A signal for indicating that the device is in a safe state
signal cmdSafe
@ The initial state is OFF
initial enter OFF
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
@ In the ON state, a cmdUnsafe signal causes a transition to OFF.UNSAFE
on cmdUnsafe enter OFF.UNSAFE
}
@ The OFF state
state OFF {
@ The initial state is SAFE
initial enter SAFE
@ The state OFF.SAFE
@ In this state, it is safe to turn on the device
state SAFE {
@ In the SAFE state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
@ In the SAFE state, a cmdUnsafe signal causes a transition to the UNSAFE state
on cmdUnsafe enter UNSAFE
}
@ The state OFF.UNSAFE
@ In this state, it is not safe to turn on the device
state UNSAFE {
@ In the UNSAFE state, a cmdSafe signal causes a transition to the SAFE state
on cmdSafe enter SAFE
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/Substates.png" alt="Device state machine with substates" width="500">
</div>
</div>
<div class="paragraph">
<p>This state machine has four states: <code>ON</code>, <code>OFF</code>, <code>OFF.SAFE</code>, and <code>OFF.UNSAFE</code>.
The last two states are substates of <code>OFF</code>.
Notice the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The substates are defined syntactically within the parent state.</p>
</li>
<li>
<p>The full names of the substates are qualified by the name of the parent state.</p>
</li>
<li>
<p>Inside the scope of the parent state, you can refer
to the substates by the shorter name that omits the implied qualifier.
The way the qualification works for state names is identical to the
way it works for <a href="#Defining-Modules">module names</a>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>An instance <em>m</em> of this state machine has the following behavior:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>When <em>m</em> starts up, it runs its initial transition specifier, just as for
<a href="#Defining-State-Machines_States-Signals-and-Transitions">a state machine
without hierarchy</a>.
The state machine enters state <code>OFF</code>.
<code>OFF</code> is a parent state, so it in turn has an initial transition
specifier which is run.
The state machine enters <code>OFF.SAFE</code>.</p>
</li>
<li>
<p>In state <code>ON</code>, the following behavior occurs:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>When <em>m</em> receives signal <code>cmdOff</code>, it enters state
<code>OFF</code>. This entry causes it to enter state <code>OFF.SAFE</code> as discussed above.</p>
</li>
<li>
<p>When <em>m</em> receives signal <code>cmdUnsafe</code>, it goes
directly to <code>OFF.UNSAFE</code>, bypassing the <code>OFF</code> state and its initial
transition.</p>
</li>
</ol>
</div>
</li>
<li>
<p>In state <code>OFF.SAFE</code>, the following behavior occurs:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>When <em>m</em> receives signal <code>cmdOn</code>, it enters
the <code>ON</code> state.</p>
</li>
<li>
<p>When <em>m</em> receives signal <code>cmdUnsafe</code>, it
enters the <code>OFF.UNSAFE</code> state.</p>
</li>
</ol>
</div>
</li>
<li>
<p>In state <code>OFF.UNSAFE</code>, when <em>m</em> receives signal
<code>cmdSafe</code>, it enters the <code>OFF.SAFE</code> state.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Rules for substates:</strong>
Here are the rules for defining substates:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Each parent state <em>S</em> must have exactly one initial transition
specifier that enters a substate of <em>S</em>.</p>
</li>
<li>
<p>Each state, including parents and substates, must be reachable
from the initial transition of the state machine or from
a state transition.</p>
</li>
<li>
<p>Substates may themselves be parents (i.e., may have substates),
to any depth.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Rule 1 ensures that the final target of every transition,
after following all initial transition specifiers, is a
<strong>leaf state</strong>, i.e., a state that has no substates.</p>
</div>
<div class="paragraph">
<p><strong>The hierarchy tree:</strong>
When a state <em>S</em> is a parent of a state <em>S'</em>, we say that <em>S</em> is an
<strong>ancestor</strong> of <em>S'</em> in the state hierarchy.
We also say that <em>S</em> is an ancestor of <em>S'</em> if it is a parent of
an ancestor of <em>S'</em>.
For example, if <em>S</em> is a parent of a parent of <em>S'</em>, then
<em>S</em> is an ancestor of <em>S'</em>.
Note that a state is never an ancestor of itself.</p>
</div>
<div class="paragraph">
<p>When a state <em>S</em> is a an ancestor of a state <em>S'</em>, we
say that <em>S'</em> is a <strong>descendant</strong> of <em>S</em>.
For example, <em>S'</em> is a descendant of <em>S</em> if <em>S'</em>
is a child of <em>S</em>, or if <em>S'</em> is a child of a child of
<em>S</em>.
Note that a state is never a descendant of itself.</p>
</div>
<div class="paragraph">
<p>In order to make the state hierarchy into a tree, we also
say that the entire state machine <em>M</em> is a parent of every top-level
state in the state machine.
This means that (1) <em>M</em> is an ancestor of every
state in <em>M</em> and (2) every state in <em>M</em> is a descendant of <em>M</em>.
We will say that the tree constructed in this way is the
<strong>hierarchy tree</strong> for <em>M</em>, and that each of <em>M</em> and every state
in <em>M</em> is a <strong>node</strong> in the hierarchy tree.
In particular, <em>M</em> is the root node of the hierarchy tree.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Hierarchy_Inherited-Transitions">10.6.2. Inherited Transitions</h4>
<div class="paragraph">
<p>In general, when a transition <em>T</em> is defined in a parent state <em>S</em>,
<em>T</em> behaves as if it were defined in each of the
<a href="#Defining-State-Machines_Hierarchy_Substates">leaf states</a> that is a
<a href="#Defining-State-Machines_Hierarchy_Substates">descendant of <em>T</em></a>.
In this case we say that <em>T</em> is <strong>inherited</strong> by each of the leaf states.
There is an important exception to this rule:
When a state <em>S</em> defines a transition <em>T</em> on a signal <em>s</em>,
and a descendant <em>S'</em> of <em>S</em> defines another transition <em>T'</em>
on the same signal <em>s</em>, the behavior of <em>T'</em> takes precedence
over the inherited transition <em>T</em> in the behavior of <em>S'</em>.
This rule is called <strong>behavioral polymorphism</strong> for transitions.</p>
</div>
<div class="paragraph">
<p><strong>Example:</strong>
Here is an example that illustrates inherited transitions
and behavioral polymorphism:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A device state machine with inherited transitions and behavioral polymorphism
state machine Device {
@ A signal for turning the device on
signal cmdOn
@ A signal for turning the device off
signal cmdOff
@ A signal for indicating that the device is in an unsafe state
signal cmdUnsafe
@ A signal for indicating that the device is in a safe state
signal cmdSafe
@ The initial state is DEVICE
initial enter DEVICE
@ The DEVICE state
state DEVICE {
@ The initial state is OFF
initial enter OFF
@ In the DEVICE state, a cmdUnsafe signal causes a transition to OFF.UNSAFE
on cmdUnsafe enter OFF.UNSAFE
@ The ON state
state ON {
@ In the ON state, a cmdOff signal causes a transition to the OFF state
on cmdOff enter OFF
}
@ The OFF state
state OFF {
@ The initial state is SAFE
initial enter SAFE
@ The state OFF.SAFE
@ In this state, it is safe to turn on the device
state SAFE {
@ In the SAFE state, a cmdOff signal causes a transition to the ON state
on cmdOn enter ON
}
@ The state OFF.UNSAFE
@ In this state, it is not safe to turn on the device
state UNSAFE {
@ In the UNSAFE state, a cmdSafe signal causes a transition to the SAFE state
on cmdSafe enter SAFE
@ In the UNSAFE state, a cmdUnsafe signal causes no action
on cmdUnsafe do { }
}
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is the graphical representation:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="users-guide/diagrams/state-machine/InheritedTransitions.png" alt="Device state machine with inherited transitions" width="600">
</div>
</div>
<div class="paragraph">
<p>Here we have rewritten the
<a href="#Defining-State-Machines_Hierarchy_Substates"><code>Device</code> state machine from the previous section</a>
so that all the states in that example are descendants of a single state
<code>DEVICE</code>.
By doing this, we can have a single transition out of <code>DEVICE</code> on signal
<code>cmdUnsafe</code>.
Before we had to write out the same transition twice,
once in the state <code>ON</code> and once in the state <code>OFF.SAFE</code>.
Here we can write the transition once in the ancestor state, and
it is inherited by all the descendants.</p>
</div>
<div class="paragraph">
<p>There is one catch, though: in the previous example, we did not define
the transition on <code>cmdUnsafe</code> in the state <code>OFF.UNSAFE</code>.
Here, if we use inheritance in the obvious way, the transition will
be inherited by all the descendants of <code>DEVICE</code>, including <code>OFF.UNSAFE</code>,
so the behavior will not be exactly the same as for the previous
state machine.
This may not matter much in this example, but it would matter if the
the state <code>DEVICE.OFF.UNSAFE</code> had entry or exit actions; in this case
transition from <code>UNSAFE</code> to itself (which is a
<a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">self transition</a>)
would cause an exit from and reentry to the state, which we may not want.</p>
</div>
<div class="paragraph">
<p>To remedy this situation, we use behavioral polymorphism.
In the state <code>DEVICE.OFF.UNSAFE</code>, we define an
<a href="#Defining-State-Machines_More-on-State-Transitions_Internal-Transitions">internal
transition</a>
that has an empty list of actions and so does nothing.
This transition overrides the transition provided in the ancestor state,
so it restores the behavior that, on receipt of the signal
<code>cmdUnsafe</code> in the state <code>DEVICE.OFF.UNSAFE</code>, nothing happens.</p>
</div>
<div class="paragraph">
<p><strong>Syntactic and flattened state transitions:</strong>
Once we introduce substates and inheritance, it is useful to
distinguish <strong>syntactic state transitions</strong> from <strong>flattened state transitions</strong>.
A syntactic state transition is a state transition in the FPP source
for a state machine <em>M</em>.
A flattened state transition is a transition that results from
applying the rules for transition inheritance to a syntactic
state transition.
We say the transition is &#8220;flattened&#8221; because we create
it by moving the left side of the transition down to a leaf state.
This move flattens the hierarchy on the left
side of the transition.</p>
</div>
<div class="paragraph">
<p>When there is no hierarchy, a syntactic transition from state
<em>S</em><sub>1</sub> to <em>S</em><sub>2</sub> generates exactly one flattened transition,
also from <em>S</em><sub>1</sub> to <em>S</em><sub>2</sub>.
Once we have hierarchy, however, syntactic and flattened
state transitions may be different.
For example, suppose that <em>S</em><sub>1</sub> is a parent state,
and let <em>T</em> be a syntactic transition from <em>S</em><sub>1</sub> to <em>S</em><sub>2</sub>.
Then for each descendant <em>L</em> of <em>S</em><sub>1</sub> that is a leaf state, there is a flattened
state transition from <em>L</em> to <em>S</em><sub>2</sub>.
Note in particular that whereas a syntactic state transition may
have a parent state as its source, a flattened state transition always
has a leaf state as its source.
This distinction between syntactic and flattened state transitions
will be useful when we discuss entry and exit actions
in the following sections.</p>
</div>
<div class="paragraph">
<p><strong>Internal transitions:</strong>
<a href="#Defining-State-Machines_More-on-State-Transitions_Internal-Transitions">Internal transitions</a> are flattened and inherited like other transitions,
except that there is no target state.
When a parent state <em>S</em> defines an internal transition, the following occurs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>There is one flattened transition for each leaf state that
that is a descendant of <em>S</em>.</p>
</li>
<li>
<p>The behavior of each flattened transition is to stay in <em>S</em>
and do the actions listed in the transition.
There is no state change, and no entry or exit actions are done.</p>
</li>
<li>
<p>As usual, any of these flattened transitions may be overridden
by behavioral polymorphism.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Hierarchy_Entry-and-Exit-Actions">10.6.3. Entry and Exit Actions</h4>
<div class="paragraph">
<p>In previous sections on
<a href="#Defining-State-Machines_Actions_Entry-and-Exit-Actions">entry and exit actions</a> and on
<a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">self transitions</a>,
we explained the order in which actions occur during a transition between
states without hierarchy.
Each of the behaviors described there is a special case of a more general
behavior for state machines with hierarchy, which we now describe.</p>
</div>
<div class="paragraph">
<p><strong>General behavior:</strong>
Suppose, in the course of running an instance of a state machine <em>M</em>,
a <a href="#Defining-State-Machines_Hierarchy_Inherited-Transitions">flattened state transition</a> <em>T</em>
occurs from state <em>L</em> to state <em>S</em>.
By the definition of a flattened state transition, we know
that <em>L</em> is a leaf state.
When carrying out the transition <em>T</em>, the state machine instance will do
actions as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Compute the <strong>least common ancestor</strong> of <em>L</em> and <em>S</em>.
This is the unique node <em>N</em> of the <a href="#Defining-State-Machines_Hierarchy_Substates">hierarchy tree</a> of <em>M</em> such that (a) <em>N</em> is an ancestor of <em>L</em>,
(b) <em>N</em> is an ancestor of <em>S</em>, and (c) there is no node <em>N'</em>
that is a descendant of <em>N</em> and that satisfies properties (a) and (b).</p>
</li>
<li>
<p>Traverse the hierarchy tree upwards from <em>L</em> to <em>N</em>.
At each point where the traversal passes out of a state <em>S'</em>, in the
order of the traversal, do the exit actions of <em>S'</em>, if any.</p>
</li>
<li>
<p>Do the actions specified in <em>T</em>, if any.</p>
</li>
<li>
<p>Traverse the hierarchy tree downwards from <em>N</em> to <em>S</em>.
At each point where the traversal enters a state <em>S'</em>, in the
order of the traversal, do the entry actions of <em>S'</em>, if any.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, suppose that <em>M</em> has a state <em>A</em> with substates
<em>B</em> and <em>C</em>, <em>B</em> has substate <em>D</em>, and <em>C</em> has substate <em>E</em>.
Suppose that <em>T</em> goes from <em>D</em> to <em>E</em>.
Then least common ancestor is <em>A</em>, and the following actions
would be done, in the following order:
the exit actions of <em>D</em>, the exit actions of <em>B</em>,
the actions of <em>T</em>, the entry actions of <em>C</em>, and the
entry actions of <em>E</em>.</p>
</div>
<div class="paragraph">
<p>Remember also that if <em>E</em> is not a leaf state, then <em>T</em> will
<a href="#Defining-State-Machines_Hierarchy_Substates">follow
one or more transitions to go to a leaf state</a>.
In this case, any actions specified in those transitions are
done as well,
after the transitions described above, and in the order that
the initial transitions are run.</p>
</div>
<div class="paragraph">
<p>Finally, the algorithm above is described in a way
that emphasizes ease of understanding.
As stated, it is inefficient because it
recomputes the least common ancestor every time a flattened state
transition occurs.
In fact all the sequences of exit and entry actions for flattened
state transitions can be computed before generating code, and
it is more efficient to do this.
This is how the FPP code generator works.
For more details, see the algorithm descriptions on the
<a href="https://github.com/nasa/fpp/wiki/Compute-Flattened-State-Transition-Map">FPP wiki</a>.</p>
</div>
<div class="paragraph">
<p><strong>The special case of no hierarchy:</strong>
The general behavior described above agrees with the special-case
behavior that we described in the section on
<a href="#Defining-State-Machines_Actions_Entry-and-Exit-Actions">entry and exit actions for state machines without hierarchy</a>.
When a state machine <em>M</em> has no hierarchy, a every state transition <em>T</em>
is a flattened transition that goes from a leaf state <em>L</em> to a leaf
state <em>S</em>, both of which are children of <em>M</em> in the hierarchy tree.
So we always exit <em>L</em>, do the actions of <em>T</em>, and enter <em>S</em>.</p>
</div>
<div class="paragraph">
<p>In particular,
the general behavior agrees with the behavior that we previously
described for
<a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">self transitions</a>.
When <em>L</em> and <em>S</em> are the same leaf state, the least common
ancestor of <em>L</em> and <em>S</em> is the parent <em>P</em> of <em>S</em>.
So we exit <em>S</em> to go up to <em>P</em>, do the actions of <em>T</em>, and
reenter <em>S</em>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Hierarchy_Directly-Related-States">10.6.4. Directly Related States</h4>
<div class="paragraph">
<p>Let <em>S</em><sub>1</sub> and <em>S</em><sub>2</sub> be states.
If <em>S</em><sub>1</sub> is equal to S<sub>2</sub>, or <em>S</em><sub>1</sub> is an ancestor of S<sub>2</sub>, or S<sub>2</sub>
is an ancestor of <em>S</em><sub>1</sub>, then we say that <em>S</em><sub>1</sub> and S<sub>2</sub> are
<strong>directly related</strong> in the hierarchy tree.</p>
</div>
<div class="paragraph">
<p>In this section we describe the behavior of transitions between
directly related states.
Each of the behaviors described below follows from the general behavior
presented in the previous section.
However, in some cases the behavior may be subtle or surprising.</p>
</div>
<div class="paragraph">
<p><strong>Flattened transitions to ancestors:</strong>
When a transition <em>T</em> goes from a leaf state <em>L</em> to a state <em>A</em>
that is an ancestor of <em>L</em>, we call <em>T</em> a
<strong>flattened transition to an ancestor</strong>.
The least common ancestor
of <em>L</em> and <em>A</em> is the parent <em>P</em> of <em>A</em>.
Therefore the following behavior occurs:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Do exit actions to get from <em>L</em> to <em>P</em>. The last actions will
be the exit actions of <em>A</em>, if any.</p>
</li>
<li>
<p>Do the actions of <em>T</em>, if any.</p>
</li>
<li>
<p>Do the entry actions of <em>A</em>, if any.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Syntactic transitions to ancestors:</strong>
Consider a state transition <em>T</em> of the form
<code>on</code> <em>s</em> <code>enter</code> <em>A</em> that is defined in the state <em>S</em>,
where <em>A</em> is an ancestor of <em>S</em>.
We call this kind of state transition a
<strong>syntactic transition to an ancestor</strong>.
If <em>S</em> is a leaf state, then it represents
a flattened transition to the ancestor <em>A</em>.
Otherwise it represents one flattened transition
to the ancestor <em>A</em> for each descendant of <em>S</em> that
is a leaf state.
Because of
<a href="#Defining-State-Machines_Hierarchy_Inherited-Transitions">behavioral polymorphism</a>, any of the flattened transitions may
be overridden.</p>
</div>
<div class="paragraph">
<p><strong>Flattened transitions to self:</strong>
A <strong>flattened transition to self</strong> is a transition
from a leaf state <em>L</em> to itself.
This is what we previously called a
<a href="#Defining-State-Machines_More-on-State-Transitions_Self-Transitions">self
transition</a>.</p>
</div>
<div class="paragraph">
<p><strong>Syntactic transitions to self:</strong>
Consider a state transition <em>T</em> of the form
<code>on</code> <em>s</em> <code>enter</code> <em>S</em> that is defined in the state <em>S</em>.
In general we call this kind of state transition a
<strong>syntactic transition to self</strong>.
If <em>S</em> is a leaf state, then <em>T</em> a flattened
transition to self.
In particular, when there is no hierarchy, every syntactic
transition to self is a self transition.
If <em>S</em> is not a leaf state, then <em>T</em> is flattened
to one or more transitions from leaf states <em>L</em> that are
descendants of <em>S</em>.
Each of these transitions is a flattened transition
to the ancestor <em>S</em>.
Because of
<a href="#Defining-State-Machines_Hierarchy_Inherited-Transitions">behavioral polymorphism</a>, any of the flattened transitions may
be overridden.</p>
</div>
<div class="paragraph">
<p><strong>Flattened transitions to descendants:</strong>
In theory, a <strong>flattened transition to a descendant</strong> would
be a transition from a leaf node <em>L</em> to a descendant <em>D</em> of <em>L</em>.
However, leaf nodes have no descendants, so no such transition
is possible.
We include the category for completeness.
It has no members.</p>
</div>
<div class="paragraph">
<p><strong>Syntactic transitions to descendants:</strong>
Consider a state transition <em>T</em> of the form
<code>on</code> <em>s</em> <code>enter</code> <em>D</em> that is defined in the state <em>S</em>,
where <em>D</em> is a descendant of <em>S</em>.
We call this kind of state transition a
<strong>syntactic transition to a descendant</strong>.
By symmetry with syntactic transitions to ancestors,
you might expect that the first behavior when
making such a transition is to exit and reenter <em>S</em>.
However, this is not what happens.
Instead, <em>T</em> represents one flattened transition
from each leaf state that is a descendant of <em>S</em>.
The flattened transitions have the following properties:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If <em>D</em> is a leaf state, then the flattened
transition out of <em>D</em> (and only that transition)
is a flattened transition to self.</p>
</li>
<li>
<p>Otherwise (a) none of the flattened transitions
is a flattened transition to self, and (b) the
flattened transitions out of the descendants of <em>D</em>
are flattened transitions to the ancestor <em>D</em>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In either case, because of
<a href="#Defining-State-Machines_Hierarchy_Inherited-Transitions">behavioral polymorphism</a>, any of the flattened transitions may
be overridden.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-State-Machines_Hierarchy_Choices">10.6.5. Choices</h4>
<div class="paragraph">
<p>Like state definitions, choice definitions are hierarchical.
That is, you may define a choice inside a state.
The names of choices are qualified by the enclosing
state names
<a href="#Defining-State-Machines_Hierarchy_Substates">as for the
names of substates</a>.
For example, you can write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">state machine M {
...
state S {
...
choice C { ... }
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The dots represent omitted text needed to make the state machine valid.
In this example, the qualified name of the choice is <code>S.C</code>.
Inside state <code>S</code>, you can refer to the choice as <code>S.C</code> or <code>C</code>.
Outside state <code>S</code>, you must refer to it as <code>S.C</code>.</p>
</div>
<div class="paragraph">
<p><strong>Initial transitions to choices:</strong>
When an initial transition <em>I</em> goes to a choice <em>C</em>,
<em>C</em> and <em>I</em> must have the same parent <em>P</em> in the
<a href="#Defining-State-Machines_Hierarchy_Substates">hierarchy tree</a>.
In addition, each transition out of <em>C</em> must go to a state
or choice with parent <em>P</em>; and if it goes
to a choice, then each transition out of that choice must
go to a state or choice with parent <em>P</em>, and so forth.
Another way to say this is that (since no cycles of transitions
through choices are allowed) each transition
path out of <em>I</em> must go through zero or more choices with parent <em>P</em>
to a state with parent <em>P</em>.</p>
</div>
<div class="paragraph">
<p>For example, this state machine is allowed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">state machine ValidInitialChoice {
guard g
initial enter S1
state S1 {
@ This initial transition is valid: C, S2, and S3 all have parent S1
initial enter C
choice C { if g enter S2 else enter S3 }
state S2
state S3
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>But this one is not:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">state machine InvalidInitialChoice {
guard g
initial enter S1
state S1 {
@ This initial transition is invalid: C has parent S1,
@ but S2 and S3 have parent InvalidInitialChoice
initial enter C
choice C { if g enter S2 else enter S3 }
}
state S2
state S3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Entry and exit actions:</strong>
As in the <a href="#Defining-State-Machines_Choices">non-hierarchical case</a>,
when a transition <em>T</em> of a state machine <em>M</em>
goes to or from a choice, entry and
exit actions occur as if each choice were a leaf state with
no entry or exit actions.
For example, suppose that <em>M</em> has a state <em>S</em> with substates
<em>A</em> and <em>B</em>, <em>A</em> has a choice <em>C</em>, and <em>B</em> has substate <em>B'</em>.
Suppose that <em>T</em> goes from <em>C</em> to <em>B'</em>.
Then least common ancestor is <em>S</em>, and the following actions
would be done, in the following order:
the exit actions of <em>A</em>, the actions of <em>T</em>, the entry actions of <em>B</em>, and the
entry actions of <em>B'</em>.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Components">11. Defining Components</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In F Prime, the <strong>component</strong> is the basic unit of FSW function.
An F Prime component is similar to a class in an object-oriented language.
An F Prime FSW application is divided into several
<strong>component instances</strong>, each of which instantiates a component.
The component instances communicate by sending and receiving
invocations on their
<a href="#Defining-Ports">ports</a>.</p>
</div>
<div class="paragraph">
<p>In F Prime, there are three kinds of components:
active, queued, and passive.
An active component has a thread of control
and a message queue.
A queued component has a message queue, but no thread
of control; control runs on another thread, such as
a rate group thread.
A passive component has no thread of control and no
message queue; it is like a non-threaded function library.</p>
</div>
<div class="sect2">
<h3 id="Defining-Components_Component-Definitions">11.1. Component Definitions</h3>
<div class="paragraph">
<p>An FPP <strong>component definition</strong> defines an F Prime component.
To write a component definition, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The component kind: one of <code>active</code>, <code>passive</code>,
or <code>queued</code>.</p>
</li>
<li>
<p>The keyword <code>component</code>.</p>
</li>
<li>
<p>The <a href="#Defining-Constants_Names">name</a> of the component.</p>
</li>
<li>
<p>A sequence of <strong>component members</strong> enclosed in curly braces
<code>{</code> &#8230;&#8203; <code>}</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>C</code> with no members:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An empty passive component
passive component C {
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A component definition and each of its members is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.
For example, you can annotate the component as shown above.
The members of a component form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> with a semicolon as the optional
terminating punctuation.
The following sections describe the available component members
except for importing port interfaces, which we describe in
<a href="#Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Interface-Definitions">a separate section</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Port-Instances">11.2. Port Instances</h3>
<div class="paragraph">
<p>A <strong>port instance</strong> is a component member that specifies an instance of an FPP
<a href="#Defining-Ports">port</a> used by the instances of the component.
Component instances use their port instances to communicate
with other component instances.</p>
</div>
<div class="paragraph">
<p>A port instance instantiates a port.
The port definition provides information common to all uses of the port, such as
the kind of data carried on the port.
The port instance provides use-specific information, such
as the name of the instance and the direction of invocation
(input or output).</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Basic-Port-Instances">11.2.1. Basic Port Instances</h4>
<div class="paragraph">
<p>The simplest port instance specifies a kind, a name, and a type.
The kind is one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>async</code> <code>input</code>: Input to this component that arrives on a message queue, to
be dispatched on this component&#8217;s thread (if this component is active)
or on the thread of another port invocation (if this component is queued).</p>
</li>
<li>
<p><code>sync</code> <code>input</code>: Input that invokes a handler defined in this component,
and run on the thread of the caller.</p>
</li>
<li>
<p><code>guarded</code> <code>input</code>: Similar to sync input, but the handler is
guarded by a mutual exclusion lock.</p>
</li>
<li>
<p><code>output</code>: Output transmitted by this component.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The name is the name of the port instance.
The type refers to a <a href="#Defining-Ports">port definition</a>.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>F32Adder</code> that
adds two <code>F32</code> values and produces an <code>F32</code> value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ A passive component for adding two F32 values
passive component F32Adder {
@ Input 1
sync input port f32ValueIn1: F32Value
@ Input 2
sync input port f32ValueIn2: F32Value
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are two sync input port instances and one output port
instance.
The kind appears first, followed by the keyword <code>port</code>, the port instance
name, a colon, and the type.
Each port instance is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>,
so you can annotate the instances as shown.</p>
</div>
<div class="paragraph">
<p>As another example, here is an active version of <code>F32Adder</code>
with <code>async</code> input ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ An active component for adding two F32 values
active component ActiveF32Adder {
@ Input 1
async input port f32ValueIn1: F32Value
@ Input 2
async input port f32ValueIn2: F32Value
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In each case, the adding is done in the target language.
For example, in the C&#43;&#43; implementation, you would generate a
base class with a virtual handler function, and then override that virtual
function in a derived class that you write.
For further details about implementing F Prime components, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
<div class="paragraph">
<p><strong>Note on terminology:</strong> As explained above, there is a technical
distinction between a <em>port type</em> (defined outside any component, and providing
the type of a port instance)
and a <em>port instance</em> (specified inside a component and instantiating
a port type).
However, it is sometimes useful to refer to a port instance with
the shorter term &#8220;port&#8221; when there is no danger of confusion.
We will do that in this manual.
For example, we will say that the <code>F32Adder</code> component has three
ports: two async input ports of type <code>F32Value</code> and one output port
of type <code>F32Value</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Rules-for-Port-Instances">11.2.2. Rules for Port Instances</h4>
<div class="paragraph">
<p>The port instances appearing in a component definition must
satisfy certain rules.
These rules ensure that the FPP model makes sense.</p>
</div>
<div class="paragraph">
<p>First, no passive component may have an <code>async</code> <code>input</code>
port.
This is because a passive component has no message queue,
so asynchronous input is not possible.
As an example, if we modify the input ports of our <code>F32Adder</code>
to make them <code>async</code>, we get an error.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port F32Value(value: F32)
# Error: Passive component may not have async input
passive component ErroneousF32Adder {
async input port f32ValueIn1: F32Value
async input port f32ValueIn2: F32Value
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Try presenting this code to <code>fpp-check</code> and observe what happens.</p>
</div>
<div class="paragraph">
<p>Second, an active or queued component <em>must</em> have asynchronous input.
That means it must have at least one async input port;
or it must have an internal port;
or it must have at least one async command; or it must have
at least one state machine instance.
Internal ports, async commands, and state machine instances
are described below.
As an example, if we modify the input ports of our <code>ActiveF32Adder</code>
to make them <code>sync</code>, we get an error, because
there is no async input.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port F32Value(value: F32)
# Error: Active component must have async input
active component ErroneousActiveF32Adder {
sync input port f32ValueIn1: F32Value
sync input port f32ValueIn2: F32Value
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Third, a port type appearing in an <code>async</code> <code>input</code> port
may not have a return type.
This is because returning a value
makes sense only for synchronous input.
As an example, this component definition is illegal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P -&gt; U32
active component Error {
# Error: port instance p: P is async input and
# port P has a return type
async input port p: P
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Arrays-of-Port-Instances">11.2.3. Arrays of Port Instances</h4>
<div class="paragraph">
<p>When you specify a port instance as part of an FPP component, you
are actually specifying an <em>array</em> of port instances.
Each instance has a <strong>port number</strong>, where the port numbers start at zero
and go up by one at each successive element.
(Another way to say this is that the port numbers are the array indices,
and the indices start at zero.)</p>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a size for the array, as shown in
the previous sections, then the array has size one, and there is a single port
instance with port number zero.
Thus a port instance specifier with no array size acts like a singleton
element.
Alternatively, you can specify an explicit array size.
You do that by writing an <a href="#Defining-Constants_Expressions">expression</a>
enclosed in square brackets <code>[</code> &#8230;&#8203; <code>]</code> denoting the size (number of elements)
of the array.
The size expression must evaluate to a numeric value.
As with
<a href="#Defining-Types_Array-Type-Definitions_Writing-an-Array-Type-Definition">array type definitions</a>,
the size goes before the element type.
As an example, here is another version of the <code>F32Adder</code> component, this time
using a single array of two input ports instead of two named ports.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ A passive component for adding two F32 values
passive component F32Adder {
@ Inputs 0 and 1
sync input port f32ValueIn: [2] F32Value
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Priority">11.2.4. Priority</h4>
<div class="paragraph">
<p>For <code>async</code> <code>input</code> ports, you may specify a priority.
The priority specification is not allowed for other kinds of ports.
To specify a priority, you write the keyword <code>priority</code> and an
expression that evaluates to a numeric value after the port type.
As an example, here is a modified version of the <code>ActiveF32Adder</code>
with specified priorities:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ An active component for adding two F32 values
@ Uses specified priorities
active component ActiveF32Adder {
@ Input 1 at priority 10
async input port f32ValueIn1: F32Value priority 10
@ Input 2 at priority 20
async input port f32ValueIn2: F32Value priority 20
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If an <code>async</code> <code>input</code> port has no specified priority, then the
translator uses a default priority.
The precise meaning of the default priority and of the numeric priorities is
implementation-specific.
In general the priorities regulate the order in which elements are dispatched
from the message queue.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Queue-Full-Behavior">11.2.5. Queue Full Behavior</h4>
<div class="paragraph">
<p>By default, if an invocation of an <code>async</code> <code>input</code> port causes
a message queue to overflow, then a <strong>FSW assertion</strong> fails.
A FSW assertion is a condition that must be true in order
for FSW execution to proceed safely.
The behavior of a FSW assertion failure is configurable in the C&#43;&#43;
implementation of the F Prime framework; typically it causes a FSW
abort and system reset.</p>
</div>
<div class="paragraph">
<p>Optionally, you can specify the behavior when a message
received on an <code>async</code> <code>input</code> port causes a queue overflow.
There are three possible behaviors:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><code>assert</code>: Fail a FSW assertion (the default behavior).</p>
</li>
<li>
<p><code>block</code>: Block the sender until the queue is available.</p>
</li>
<li>
<p><code>drop</code>: Drop the incoming message and proceed.</p>
</li>
<li>
<p><code>hook</code>: Call a user-specified function and proceed.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>To specify queue full behavior, you write one of the keywords <code>assert</code>,
<code>block</code>, <code>drop</code>, or <code>hook</code> after the port type and after the priority
(if any).
As an example, here is the <code>ActiveF32Adder</code> updated with explicit
queue full behavior.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ An active component for adding two F32 values
@ Uses specified priorities
active component ActiveF32Adder {
@ Input 1 at priority 10: Block on queue full
async input port f32ValueIn1: F32Value priority 10 block
@ Input 2: Drop on queue full
async input port f32ValueIn2: F32Value drop
@ Input 3: Call hook function on queue full
async input port f32ValueIn3: F32Value hook
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As for priority specifiers, queue full specifiers are allowed only
for <code>async</code> <code>input</code> ports.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Port-Instances_Serial-Port-Instances">11.2.6. Serial Port Instances</h4>
<div class="paragraph">
<p>When writing a port instance, instead of specifying a named port type,
you may write the keyword <code>serial</code>.
Doing this specifies a <strong>serial port instance</strong>.
A serial port instance does not specify the type of data that it carries.
It may be connected to a port of any type.
Serial data passes through the port; the data may be converted to or from a
specific type at the other end of the connection.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component for taking a stream
of serial data and splitting it (i.e., repeating it by copy)
onto several streams:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Split factor
constant splitFactor = 10
@ Component for splitting a serial data stream
passive component SerialSplitter {
@ Input
sync input port serialIn: serial
@ Output
output port serialOut: [splitFactor] serial
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>By using serial ports, you can send several unrelated types
of data over the same port connection.
This technique is useful when communicating across
a network: on each side of the network connection, a single component
can act as a hub that routs all data to and from components
on that side.
This flexibility comes at the cost that you lose the type
compile-time type checking provided by port connections with named types.
For more information about serial ports and their use, see
the <a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Special-Port-Instances">11.3. Special Port Instances</h3>
<div class="paragraph">
<p>A <strong>special port instance</strong> is a port instance that has a special
behavior in F Prime.
As discussed <a href="#Defining-Components_Port-Instances">above</a>,
when writing a general port instance,
you specify a port kind, a port type, and possibly other
information such as array size and priority.
Writing a special port instance is a bit different.
In this case you specify a predefined behavior
provided by the F Prime framework.
The special port behaviors fall into six groups:
commands, events, telemetry, parameters, time,
and data products.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Command-Ports">11.3.1. Command Ports</h4>
<div class="paragraph">
<p>A <strong>command</strong> is an instruction to the spacecraft to perform an action.
Each component instance <em>C</em> that specifies commands has the following
high-level behaviors:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>At FSW startup time, <em>C</em> registers its commands with a component
instance called the <strong>command dispatcher</strong>.</p>
</li>
<li>
<p>During FSW execution, <em>C</em> receives commands from the command
dispatcher.
For each command received, <em>C</em> executes the command and
sends a response back to the command dispatcher.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In FPP, the keywords for the special command behaviors are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>command</code> <code>reg</code>: A port for sending command registration requests.</p>
</li>
<li>
<p><code>command</code> <code>recv</code>: A port for receiving commands.</p>
</li>
<li>
<p><code>command</code> <code>resp</code>: A port for sending command responses.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Collectively, these ports are known as <strong>command ports</strong>.
To specify a command port, you write one of the keyword pairs
shown above followed by the keyword <code>port</code> and the port name.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>CommandPorts</code> with each
of the command ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating command ports
passive component CommandPorts {
@ A port for receiving commands
command recv port cmdIn
@ A port for sending command registration requests
command reg port cmdRegOut
@ A port for sending command responses
command resp port cmdResponseOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one of each kind of command
port.
If a component receives commands (more on this below),
then all three ports are required.
The port names shown in the example above are standard but not
required; you can use any names you wish.</p>
</div>
<div class="paragraph">
<p>During translation, each command port is converted into
a typed port instance with a predefined port type, as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>command</code> <code>recv</code> uses the port <code>Fw.Cmd</code></p>
</li>
<li>
<p><code>command</code> <code>reg</code> uses the port <code>Fw.CmdReg</code></p>
</li>
<li>
<p><code>command</code> <code>resp</code> uses the port <code>Fw.CmdResponse</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The F Prime framework provides definitions for these ports
in the directory <code>Fw/Cmd</code>.
For checking simple examples, you can use the following
simplified definitions of these ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port Cmd
port CmdReg
port CmdResponse
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For example, to check the <code>CommandPorts</code> component, you can
add these lines before the component definition.
If you don&#8217;t do this, or something similar, then the component
definition won&#8217;t pass through <code>fpp-check</code> because of the missing ports.
(Try it and see.)</p>
</div>
<div class="paragraph">
<p>Note that the port definitions shown above are for conveniently checking
simple examples only.
They are not correct for the F Prime framework and will not work
properly with F Prime C&#43;&#43; code generation.</p>
</div>
<div class="paragraph">
<p>For further information about command registration, receipt, and
response, and implementing command handlers, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Event-Ports">11.3.2. Event Ports</h4>
<div class="paragraph">
<p>An <strong>event</strong> is a report that something happened, for example,
that a file was successfully uplinked.
The special event behaviors, and their keywords, are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>event</code>: A port for emitting events as serialized bytes.</p>
</li>
<li>
<p><code>text</code> <code>event</code>: A port for emitting events as human-readable
text (usually used for testing and debugging on the ground).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Collectively, these ports are known as <strong>event ports</strong>.
To specify an event port, you write one of the keyword groups
shown above followed by the keyword <code>port</code> and the port name.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>EventPorts</code> with each
of the event ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating event ports
passive component EventPorts {
@ A port for emitting events
event port eventOut
@ A port for emitting text events
text event port textEventOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one of each kind of event
port.
If a component emits events (more on this below),
then both event ports are required.</p>
</div>
<div class="paragraph">
<p>During translation, each event port is converted into
a typed port instance with a predefined port type, as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>event</code> uses the port <code>Fw.Log</code></p>
</li>
<li>
<p><code>text</code> <code>event</code> uses the port <code>Fw.LogText</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The name <code>Log</code> refers to an event log.
The F Prime framework provides definitions for these ports
in the directory <code>Fw/Log</code>.
For checking simple examples, you can use the following
simplified definitions of these ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port Log
port LogText
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For further information about events in F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Telemetry-Ports">11.3.3. Telemetry Ports</h4>
<div class="paragraph">
<p><strong>Telemetry</strong> is data regarding the state of the system.
A <strong>telemetry port</strong> allows a component to emit telemetry.
To specify a telemetry port, you write the keyword <code>telemetry</code>,
the keyword <code>port</code>, and the port name.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>TelemetryPorts</code> with
a telemetry port:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating telemetry ports
passive component TelemetryPorts {
@ A port for emitting telemetry
telemetry port tlmOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one telemetry port.
If a component emits telemetry (more on this below),
then a telemetry port is required.</p>
</div>
<div class="paragraph">
<p>During translation, each telemetry port is converted into
a typed port instance with the predefined port type
<code>Fw.Tlm</code>.
The F Prime framework provides a definition for this port
in the directory <code>Fw/Tlm</code>.
For checking simple examples, you can use the following
simplified definition of this port:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port Tlm
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For further information about telemetry in F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Parameter-Ports">11.3.4. Parameter Ports</h4>
<div class="paragraph">
<p>A <strong>parameter</strong> is a configurable constant that may be updated
from the ground.
The current parameter values are stored in an F Prime component
called the <strong>parameter database</strong>.</p>
</div>
<div class="paragraph">
<p>The special parameter behaviors, and their keywords, are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>param</code> <code>get</code>: A port for getting the current value of a parameter
from the parameter database.</p>
</li>
<li>
<p><code>param</code> <code>set</code>: A port for setting the current value of a parameter
in the parameter database.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Collectively, these ports are known as <strong>parameter ports</strong>.
To specify a parameter port, you write one of the keyword groups
shown above followed by the keyword <code>port</code> and the port name.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>ParamPorts</code> with each
of the parameter ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating parameter ports
passive component ParamPorts {
@ A port for getting parameter values
param get port prmGetOut
@ A port for setting parameter values
param set port prmSetOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one of each kind of parameter
port.
If a component has parameters (more on this below),
then both parameter ports are required.</p>
</div>
<div class="paragraph">
<p>During translation, each parameter port is converted into
a typed port instance with a predefined port type, as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>param</code> <code>get</code> uses the port <code>Fw.PrmGet</code></p>
</li>
<li>
<p><code>param</code> <code>set</code> uses the port <code>Fw.PrmSet</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The F Prime framework provides definitions for these ports
in the directory <code>Fw/Prm</code>.
For checking simple examples, you can use the following
simplified definitions of these ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port PrmGet
port PrmSet
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For further information about parameters in F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Time-Get-Ports">11.3.5. Time Get Ports</h4>
<div class="paragraph">
<p>A <strong>time get port</strong> allows a component to get the system time from a
time component.
To specify a time get port, you write the keywords <code>time</code> <code>get</code>,
the keyword <code>port</code>, and the port name.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>TimeGetPorts</code> with
a time get port:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating time get ports
passive component TimeGetPorts {
@ A port for getting the time
time get port timeGetOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one time get port.
If a component emits events or telemetry (more on this below),
then a time get port is required, so that the events
and telemetry points can be time stamped.</p>
</div>
<div class="paragraph">
<p>During translation, each time get port is converted into
a typed port instance with the predefined port type
<code>Fw.Time</code>.
The F Prime framework provides a definition for this port
in the directory <code>Fw/Time</code>.
For checking simple examples, you can use the following
simplified definition of this port:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port Time
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For further information about time in F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Special-Port-Instances_Data-Product-Ports">11.3.6. Data Product Ports</h4>
<div class="paragraph">
<p>A <strong>data product</strong> is a collection of data that can be stored to an
onboard file system, given a priority, and downlinked in priority
order.
For example, a data product may be an image or a unit of
science data.
Data products are stored in <strong>containers</strong> that contain
<strong>records</strong>.
A record is a unit of data.
A container stores (1) a header that describes the container
and (2) a list of records.</p>
</div>
<div class="paragraph">
<p>The special data product behaviors, and their keywords, are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>product</code> <code>get</code>: A port for synchronously requesting a
memory buffer to store a container.</p>
</li>
<li>
<p><code>product</code> <code>request</code>: A port for asynchronously requesting
a buffer to store a container.</p>
</li>
<li>
<p><code>product</code> <code>recv</code>: A port for receiving a response to an
asynchronous buffer request.</p>
</li>
<li>
<p><code>product</code> <code>send</code>: A port for sending a buffer that stores
a container, after the container has been filled with data.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Collectively, these ports are known as <strong>data product ports</strong>.
To specify a data product port, you write one of the keyword groups
shown above followed by the keyword <code>port</code> and the port name.
To specify a product receive port, you must first write
<code>async</code>, <code>sync</code> or <code>guarded</code> to specify whether the input port
is asynchronous, synchronous, or guarded, as described in
the section on <a href="#Defining-Components_Port-Instances_Basic-Port-Instances">basic port instances</a>.
When specifying an <code>async</code> product receive port, you may
specify a <a href="#Defining-Components_Port-Instances_Priority">priority behavior</a>
or <a href="#Defining-Components_Port-Instances_Queue-Full-Behavior">queue full behavior</a>.</p>
</div>
<div class="paragraph">
<p>As an example, here is a passive component <code>DataProductPorts</code> with each
of the data product ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating data product ports
active component DataProductPorts {
@ A port for getting a data product container
product get port productGetOut
@ A port for requesting a data product container
product request port productRequestOut
@ An async port for receiving a requested data product container
async product recv port productRecvIn priority 10 assert
@ A port for sending a filled data product container
product send port productSendOut
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Any component may have at most one of each kind of data product
port.
If a component defines data products (more on this below),
then there must be (1) a product get port or a product request port
and (2) a product send port.
If there is a product request port, then there must be a product
receive port.</p>
</div>
<div class="paragraph">
<p>During translation, each data product port is converted into
a typed port instance with a predefined port type, as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>product</code> <code>get</code> uses the port <code>Fw.DpGet</code></p>
</li>
<li>
<p><code>product</code> <code>request</code> uses the port <code>Fw.DpRequest</code></p>
</li>
<li>
<p><code>product</code> <code>recv</code> uses the port <code>Fw.DpResponse</code></p>
</li>
<li>
<p><code>product</code> <code>send</code> uses the port <code>Fw.DpSend</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The F Prime framework provides definitions for these ports
in the directory <code>Fw/Dp</code>.
For checking simple examples, you can use the following
simplified definitions of these ports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Fw {
port DpGet
port DpRequest
port DpResponse
port DpSend
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For further information about data products in F Prime, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/data-products/">F
Prime design documentation</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Internal-Ports">11.4. Internal Ports</h3>
<div class="paragraph">
<p>An <strong>internal port</strong> is a port that a component can use to send a
message to itself.
In the ordinary case, when a component sends a message, it invokes an
output port that is connected to an async input port.
When the output port and input port reside in the same component,
it is simpler to use an internal port.</p>
</div>
<div class="paragraph">
<p>As an example, suppose we have a component
that needs to send a message to itself.
We could construct such a component in the following way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A data type T
type T
@ A port for sending data of type T
port P(t: T)
@ A component that sends data to itself on an async input port
active component ExternalSelfMessage {
@ A port for sending data of type T
async input port pIn: P
@ A port for receiving data of type T
output port pOut: P
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This works, but if the only user of <code>pIn</code> is
<code>ExternalSelfMessage</code>, it is cumbersome.
We need to declare two ports and connect them.
Instead, we can use an internal port, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A data type T
type T
@ A component that sends data to itself on an internal port
active component InternalSelfMessage {
@ An internal port for sending data of type T
internal port pInternal(t: T)
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the implementation of <code>InternalSelfMessage</code> invokes
the port <code>pInternal</code>, a message goes on its queue.
This corresponds to the behavior of <code>pOut</code> in
<code>ExternalSelfMessage</code>.
Later, when the framework dispatches the message, it
calls a handler function associated with the port.
This corresponds to the behavior of <code>pIn</code> in
<code>ExternalSelfMessage</code>.
So an internal port is like two ports (an output port
and an async input port) fused into one.</p>
</div>
<div class="paragraph">
<p>When writing an internal port, you do not use a named
port definition.
Instead, you provide the formal parameters directly.
Notice that when defining <code>ExternalSelfMessage</code> we
defined and used the port <code>P</code>, but when defining
<code>InternalSelfMessage</code> we did not.
The formal parameters of an internal port work in the same way
as for a <a href="#Defining-Ports_Formal-Parameters">port definition</a>,
except that none of the parameters may be a
<a href="#Defining-Ports_Reference-Parameters">reference parameter</a>.</p>
</div>
<div class="paragraph">
<p>When specifying an internal port, you may specify
<a href="#Defining-Components_Port-Instances_Priority">priority</a> and
<a href="#Defining-Components_Port-Instances_Queue-Full-Behavior">queue full behavior</a>
as for an async input port.
For example, we can add priority and queue full behavior
to <code>pInternal</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A data type T
type T
@ A component that sends data to itself on an internal port,
@ with priority and queue full behavior
active component InternalSelfMessage {
@ An internal port for sending data of type T
internal port pInternal(t: T) priority 10 drop
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Internal ports generate async input, so they make sense
only for <code>active</code> and <code>queued</code> components.
As an example, consider the following component
definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T
passive component PassiveInternalPort {
# Internal ports don't make sense for passive components
internal port pInternal(t: T)
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>What do you think will happen if you run <code>fpp-check</code>
on this code?
Try it and see.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Commands">11.5. Commands</h3>
<div class="paragraph">
<p>When defining an F Prime component, you may specify one or more commands.
When you are operating the FSW, you use the F Prime Ground Data System
or another ground data system to send commands to the FSW.
On receipt of a command <em>C</em>, a Command Dispatcher component instance
dispatches <em>C</em> to the component instance where that command is implemented.
The command is handled in a C&#43;&#43; command handler that you write
as part of the component implementation.</p>
</div>
<div class="paragraph">
<p>For complete information about F Prime command dispatch and
handling, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.
Here we concentrate on how to specify commands in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Commands_Basic-Commands">11.5.1. Basic Commands</h4>
<div class="paragraph">
<p>The simplest command consists of a kind followed by the keyword
<code>command</code> and a name.
The kind is one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>async</code>: The command arrives on a message queue, to
be dispatched on this component&#8217;s thread (if this component is active)
or on the thread of a port invocation (if this component is queued).</p>
</li>
<li>
<p><code>sync</code>: The command invokes a handler defined in this component,
and run on the thread of the caller.</p>
</li>
<li>
<p><code>guarded</code>: Similar to sync input, but the handler is
guarded by a mutual exclusion lock.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Notice that the kinds of commands are similar to the kinds of
<a href="#Defining-Components_Port-Instances_Basic-Port-Instances">input ports</a>.
The name is the name of the command.</p>
</div>
<div class="paragraph">
<p>As an example, here is an active component called <code>Action</code>
with two commands: an async command <code>START</code> and a sync
command <code>STOP</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An active component for performing an action
active component Action {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Start the action
async command START
@ Stop the action
sync command STOP
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Command <code>START</code> is declared <code>async</code>.
That means that when a <code>START</code> command is dispatched
to an instance of this component, it arrives on a queue.
Later, the F Prime framework takes the message off the queue
and calls the corresponding handler on the thread
of the component.</p>
</div>
<div class="paragraph">
<p>Command <code>STOP</code> is declared <code>sync</code>.
That means that the command runs immediately on the
thread of the invoking component (for example,
a command dispatcher component).
Because the command runs immediately, its handler
should be very short.
For example, it could set a stop flag and then exit.</p>
</div>
<div class="paragraph">
<p>Notice that we defined the three
<a href="#Defining-Components_Special-Port-Instances_Command-Ports">command ports</a>
for this component.
All three ports are required for any component that has commands.
As an example, try deleting one or more of the command ports from the
code above and running the result through <code>fpp-check</code>.</p>
</div>
<div class="paragraph">
<p><code>async</code> commands require a message queue, so
they are allowed only for active and queued
components.
As an example, try making the <code>Action</code> component passive and
running the result through <code>fpp-check</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Commands_Formal-Parameters">11.5.2. Formal Parameters</h4>
<div class="paragraph">
<p>When specifying a command, you may specify one or more
formal parameters.
The parameters are bound to arguments when the command
is sent to the spacecraft.
Different uses of the same command can have different
argument values.</p>
</div>
<div class="paragraph">
<p>The formal parameters of a command are the same
as for a <a href="#Defining-Ports_Formal-Parameters">port definition</a>, except
for the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>None of the parameters may be a
<a href="#Defining-Ports_Reference-Parameters">reference parameter</a>.</p>
</li>
<li>
<p>Each parameter must have a <a href="#Dictionary-Definitions">displayable type</a>, i.e.,
a
type that the F Prime ground data system knows how to display.
For example, the type may not be an
<a href="#Defining-Types_Abstract-Type-Definitions">abstract type</a>.
Nor may it be an array or struct type that has an abstract type
as a member type.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>As an example, here is a <code>Switch</code> component that has
two states, <code>ON</code> and <code>OFF</code>.
The component has a <code>SET_STATE</code> command for
setting the state.
The command has a single argument <code>state</code>
that specifies the new state.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ The state enumeration
enum State {
OFF @&lt; The off state
ON @&lt; The on state
}
@ A switch with on and off state
active component Switch {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Set the state
async command SET_STATE(
$state: State @&lt; The new state
)
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, the enum type <code>State</code> is a displayable type because
its definition is known to FPP.
Try replacing the enum definition with the
abstract type definition <code>type S</code> and see what happens when
you run the model through <code>fpp-check</code>.
Remember to <a href="#Defining-Components_Special-Port-Instances_Command-Ports">provide
stubs for the special command ports</a> that are required by
<code>fpp-check</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Commands_Opcodes">11.5.3. Opcodes</h4>
<div class="paragraph">
<p>Every command in an F Prime FSW application has an <strong>opcode</strong>.
The opcode is a number that uniquely identifies the command.
The F Prime framework uses the opcode when dispatching commands
because it is a more compact identifier than the name.
The name is mainly for human interaction on the ground.</p>
</div>
<div class="paragraph">
<p>The opcodes associated with each component <em>C</em>
are relative to the component.
Typically the opcodes start at zero: that is, the
opcodes are 0, 1, 2, etc.
When constructing an instance <em>I</em> of component <em>C</em>,
the framework adds a base opcode for <em>I</em> to each relative opcode
associated with <em>C</em> to form
the global opcodes associated with <em>I</em>.
That way different instances of <em>C</em> can have different opcodes
for the same commands defined in <em>C</em>.
We will have more to say about base and relative opcodes
when we describe component instances and topologies.</p>
</div>
<div class="paragraph">
<p>If you specify a command <em>c</em> with no explicit opcode, as in the examples
shown in the previous sections, then FPP assigns a default opcode
to <em>c</em>.
The default opcode for the first command in a component is zero.
Otherwise the default opcode for any command is one more than
the opcode of the previous command.</p>
</div>
<div class="paragraph">
<p>It is usually convenient to rely on the default opcodes.
However, you may wish to specify one or more opcodes explicitly.
To do this, you write the keyword <code>opcode</code> followed
by a numeric expression after the command name and after the
formal parameters, if any.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating command opcodes
active component CommandOpcodes {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ This command has default opcode 0x0
async command COMMAND_1
@ This command has explicit opcode 0x10
async command COMMAND_2(a: F32, b: U32) opcode 0x10
@ This command has default opcode 0x11
sync command COMMAND_3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Within a component, the command opcodes must be unique.
For example, this component is incorrect because
the opcode zero appears twice:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating a duplicate opcode
active component DuplicateOpcode {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ This command has opcode 0x0
async command COMMAND_1
@ Oops! This command also has opcode 0x0
async command COMMAND_2 opcode 0x0
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Commands_Priority-and-Queue-Full-Behavior">11.5.4. Priority and Queue Full Behavior</h4>
<div class="paragraph">
<p>When specifying an async command, you may specify
<a href="#Defining-Components_Port-Instances_Priority">priority</a> and
<a href="#Defining-Components_Port-Instances_Queue-Full-Behavior">queue full behavior</a>
as for an async input port.
You put the priority and queue full information after the command name
and after the formal parameters and opcode, if any.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating priority and queue full behavior for async
@ commands
active component PriorityQueueFull {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Command with priority
async command COMMAND_1 priority 10
@ Command with formal parameters and priority
async command COMMAND_2(a: U32, b: F32) priority 20
@ Command with formal parameters, opcode, priority, and queue full behavior
async command COMMAND_3(a: string) opcode 0x10 priority 30 drop
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Priority and queue full behavior are allowed only for
<code>async</code> commands.
Try changing one of the commands in the previous example
to <code>sync</code> and see what <code>fpp-check</code> has to say about it.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Events">11.6. Events</h3>
<div class="paragraph">
<p>When defining an F Prime component, you may specify one or more events.
The F Prime framework converts each event into a C&#43;&#43;
function that you can call from the component implementation.
Calling the function emits a serialized event report that
you can store in an on-board file system or send to the ground.</p>
</div>
<div class="paragraph">
<p>For complete information about F Prime event
handling, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.
Here we concentrate on how to specify events in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Events_Basic-Events">11.6.1. Basic Events</h4>
<div class="paragraph">
<p>The simplest event consists of the keyword <code>event</code>, a name, a severity,
and a format string.
The name is the name of the event.
A severity is the keyword <code>severity</code> and one of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>activity</code> <code>high</code>: Spacecraft activity of greater importance.</p>
</li>
<li>
<p><code>activity</code> <code>low</code>: Spacecraft activity of lesser importance.</p>
</li>
<li>
<p><code>command</code>: An event related to commanding.
Primarily used by the command dispatcher.</p>
</li>
<li>
<p><code>diagnostic</code>: An event relating to system diagnosis
and debugging.</p>
</li>
<li>
<p><code>fatal</code>: An event that causes the system to abort.</p>
</li>
<li>
<p><code>warning</code> <code>high</code>: A warning of greater importance.</p>
</li>
<li>
<p><code>warning</code> <code>low</code>: A warning of lesser importance.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A format is the keyword <code>format</code> and a literal string for
use in a formatted real-time display or event log.</p>
</div>
<div class="paragraph">
<p>As an example, here is an active component called <code>BasicEvents</code>
with a few basic events.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating basic events
passive component BasicEvents {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Event port
event port eventOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Activity low event
event Event1 severity activity low format "Event 1 occurred"
@ Warning low event
event Event2 severity warning low format "Event 2 occurred"
@ Warning high event
event Event3 severity warning high format "Event 3 occurred"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that we defined the two
<a href="#Defining-Components_Special-Port-Instances_Event-Ports">event ports</a>
and a
<a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports">time get port</a>
for this component.
All three ports are required for any component that has events.
As an example, try deleting one or more of these ports from the
code above and running the result through <code>fpp-check</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Events_Formal-Parameters">11.6.2. Formal Parameters</h4>
<div class="paragraph">
<p>When specifying an event, you may specify one or more
formal parameters.
The parameters are bound to arguments when the component
instance emits the event.
The argument values appear in the formatted text
that describes the event.</p>
</div>
<div class="paragraph">
<p>You specify the formal parameters of an event in the same
way as for a <a href="#Defining-Components_Commands_Formal-Parameters">command
specifier</a>.
For each formal parameter, there must be a corresponding
replacement field in the format string.
The replacement fields for event format strings are the same as for
format strings in
<a href="#Defining-Types_Array-Type-Definitions_Format-Strings">type definitions</a>.
The replacement fields in the format string match the event
parameters, one for one and in the same order.</p>
</div>
<div class="paragraph">
<p>As an example, here is a component with two events,
each of which has formal parameters.
Notice how the replacement fields in the event format
strings correspond to the formal parameters.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An enumeration of cases
enum Case { A, B, C }
@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating event formal parameters
passive component EventParameters {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Event port
event port eventOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Event 1
@ Sample output: "Event 1 occurred with argument 42"
event Event1(
arg1: U32 @&lt; Argument 1
) \
severity activity high \
format "Event 1 occurred with argument {}"
@ Event 2
@ Sample output: "Saw value [ 0.001, 0.002, 0.003 ] for case A"
event Event2(
case: Case @&lt; The case
value: F64x3 @&lt; The value
) \
severity warning low \
format "Saw value {} for case {}"
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Events_Identifiers">11.6.3. Identifiers</h4>
<div class="paragraph">
<p>Every event in an F Prime FSW application has a unique
numeric identifier.
As for
<a href="#Defining-Components_Commands_Opcodes">command opcodes</a>,
the event identifiers for a component are specified
relative to the component, usually starting from
zero and counting up by one.
If you omit the identifier, then
FPP assigns a default identifier: zero for the first
event in the component; otherwise one more than the
identifier of the previous event.</p>
</div>
<div class="paragraph">
<p>If you wish, you may explicitly specify one or more event
identifiers.
To do this, you write the keyword <code>id</code> followed
by a numeric expression immediately before the keyword <code>format</code>.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating event identifiers
passive component EventIdentifiers {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Event port
event port eventOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Event 1
@ Its identifier is 0x00
event Event1 severity activity low \
id 0x10 \
format "Event 1 occurred"
@ Event 2
@ Its identifier is 0x10
event Event2(
count: U32 @&lt; The count
) \
severity activity high \
id 0x11 \
format "The count is {}"
@ Event 3
@ Its identifier is 0x11
event Event3 severity activity high \
format "Event 3 occurred"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Within a component, the event identifiers must be unique.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Events_Throttling">11.6.4. Throttling</h4>
<div class="paragraph">
<p>Sometimes it is necessary to throttle events, to ensure that
they do not flood the system.
For example, suppose that the FSW requests some resource <em>R</em>
at a rate <em>r</em> of several times per second.
Suppose further that if <em>R</em> is unavailable, then the FSW
emits a warning event.
In this case, we typically do not want the FSW to emit an unbounded number
of warnings at rate <em>r</em>; instead, we want it to emit a single warning
or a few warnings.</p>
</div>
<div class="paragraph">
<p>To achieve this behavior, you can write the keyword <code>throttle</code> and a
numeric expression after the format string.
The expression must evaluate to a constant value <em>n</em>, where <em>n</em> is a number
greater than zero.
<em>n</em> is called the <strong>maximum throttle count</strong>.
After an instance of the component has emitted the event <em>n</em> times, it will
stop emitting the event.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating event throttling
passive component EventThrottling {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Event port
event port eventOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Event 1
event Event1 severity warning high \
format "Event 1 occurred" \
throttle 10
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, event <code>Event1</code> will be throttled after the component
instance has emitted it ten times.</p>
</div>
<div class="paragraph">
<p>Once an event is throttled, the component
instance will no longer emit the event until the throttling is reset.
There are two ways to reset the throttling of an event: manually and
automatically.</p>
</div>
<div class="paragraph">
<p><strong>Manual reset:</strong>
To manually reset throttling for events,
you can use a <a href="#Defining-Components_Commands">command</a>.
For example, you can define a command <code>CLEAR_EVENT_THROTTLE</code>
that resets throttling for all throttled events.
You can implement this command by calling functions
that reset the throttle counts to zero.
The auto-generated C&#43;&#43; code provides one such function for
each event with throttling.
For details, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
<div class="paragraph">
<p><strong>Automatic reset:</strong>
You can also specify in FPP that the throttling for an event should be reset
automatically after a specified amount of time.
To do this, you write <code>every</code> and a time interval after the maximum throttle
count.
The time interval is a <a href="#Defining-Constants_Expressions_Struct-Values">struct
value expression</a> with two members: <code>seconds</code> and <code>useconds</code>.
<code>useconds</code> is short for &#8220;microseconds.&#8221;
Each member must evaluate to an integer value.
Either or both of the members can be omitted; an omitted member evaluates to
zero.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating event throttling with timeouts
passive component EventThrottlingWithTimeout {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Event port
event port eventOut
@ Text event port
text event port textEventOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Events
# ----------------------------------------------------------------------
@ Event 1
event Event1 severity warning high \
format "Event 1 occurred" \
throttle 10 every { seconds = 2 }
@ Event 2
event Event2 severity warning high \
format "Event 2 occurred" \
throttle 10 every { seconds = 2, useconds = 500000 }
@ Event 3
event Event3 severity warning high \
format "Event 3 occurred" \
throttle 10 every { useconds = 500000 }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, an instance of <code>EventThrottlingWithTimeout</code> will emit events
at the following rates:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Event1</code>: Up to 10 events every 2 seconds.</p>
</li>
<li>
<p><code>Event2</code>: Up to 10 events every 2.5 seconds.</p>
</li>
<li>
<p><code>Event3</code>: Up to 10 events every 0.5 seconds.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Telemetry">11.7. Telemetry</h3>
<div class="paragraph">
<p>When defining an F Prime component, you may specify one or more
<strong>telemetry channels</strong>.
A telemetry channel consists of a data type and an identifier.
The F Prime framework converts each telemetry into a C&#43;&#43;
function that you can call from the component implementation.
Calling the function emits a value on the channel.
Each emitted value is called a
<strong>telemetry point</strong>.
You can store the telemetry points in an on-board file system
or send them the ground.</p>
</div>
<div class="paragraph">
<p>For complete information about F Prime telemetry
handling, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.
Here we concentrate on how to specify telemetry channels in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Telemetry_Basic-Telemetry">11.7.1. Basic Telemetry</h4>
<div class="paragraph">
<p>The simplest telemetry channel consists of the keyword <code>telemetry</code>,
a name, and a data type.
The name is the name of the channel.
The data type is the type of data carried on the channel.
The data type must be a
<a href="#Defining-Components_Commands_Formal-Parameters">displayable type</a>.</p>
</div>
<div class="paragraph">
<p>As an example, here is an active component called <code>BasicTelemetry</code>
with a few basic events.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating basic telemetry channels
passive component BasicTelemetry {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Telemetry channel 1
telemetry Channel1: U32
@ Telemetry channel 2
telemetry Channel2: F64
@ Telemetry channel 3
telemetry Channel3: F64x3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that we defined a
<a href="#Defining-Components_Special-Port-Instances_Telemetry-Ports">telemetry port</a>
and a
<a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports">time get port</a>
for this component.
Both ports are required for any component that has telemetry.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Telemetry_Identifiers">11.7.2. Identifiers</h4>
<div class="paragraph">
<p>Every telemetry channel in an F Prime FSW application has a unique
numeric identifier.
As for
<a href="#Defining-Components_Commands_Opcodes">command opcodes</a>
and
<a href="#Defining-Components_Events_Identifiers">event identifiers</a>,
the telemetry channel identifiers for a component are specified
relative to the component, usually starting from
zero and counting up by one.
If you omit the identifier, then
FPP assigns a default identifier: zero for the first
event in the component; otherwise one more than the
identifier of the previous channel.</p>
</div>
<div class="paragraph">
<p>If you wish, you may explicitly specify one or more
telemetry channel identifiers.
To do this, you write the keyword <code>id</code> followed
by a numeric expression immediately after the data type.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ Component for illustrating telemetry channel identifiers
passive component TlmIdentifiers {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Telemetry channel 1
@ Its implied identifier is 0x00
telemetry Channel1: U32
@ Telemetry channel 2
@ Its identifier is 0x10
telemetry Channel2: F64 id 0x10
@ Telemetry channel 3
@ Its implied identifier is 0x11
telemetry Channel3: F64x3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Within a component, the telemetry channel identifiers must be unique.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Telemetry_Update-Frequency">11.7.3. Update Frequency</h4>
<div class="paragraph">
<p>You can specify how often the telemetry is emitted on a channel <em>C</em>.
There are two possibilities:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>always</code>: Emit a telemetry point on <em>C</em>
whenever the component implementation calls the
auto-generated function <em>F</em> that emits telemetry on <em>C</em>.</p>
</li>
<li>
<p><code>on</code> <code>change</code>: Emit a telemetry point whenever
(1) the implementation calls <em>F</em> and (2) either (a)
<em>F</em> has not been called before or
(b) the last time that <em>F</em> was called, the argument
to <em>F</em> had a different value.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Emitting telemetry on change can reduce unnecessary
activity in the system.
For example, suppose a telemetry channel <em>C</em> counts
the number of times that some event <em>E</em> occurs
in a periodic task,
and suppose that <em>E</em> does not occur on every cycle.
If you declare channel <em>C</em> <code>on</code> <code>change</code>, then your implementation
can call the telemetry emit function for <em>C</em> on every
cycle, and telemetry will be emitted only when
<em>E</em> occurs.</p>
</div>
<div class="paragraph">
<p>To specify an update frequency, you write the keyword <code>update</code>
and one of the frequency selectors shown above.
The update specifier goes after
the type name and after the channel identifier, if any.
If you don&#8217;t specify an update frequency, then the default
value is <code>always</code>.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ Component for illustrating telemetry channel update specifiers
passive component TlmUpdate {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Telemetry channel 1
@ Always emitted
telemetry Channel1: U32
@ Telemetry channel 2
@ Emitted on change
telemetry Channel2: F64 id 0x10 update on change
@ Telemetry channel 3
@ Always emitted
telemetry Channel3: F64x3 update always
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Telemetry_Format-Strings">11.7.4. Format Strings</h4>
<div class="paragraph">
<p>You may specify how a telemetry channel is formatted in the
ground display.
To do this, you write the keyword <code>format</code> and a format string
with one
<a href="#Defining-Types_Array-Type-Definitions_Format-Strings">replacement field</a>.
The replacement field must match the type of the telemetry
channel.
The format specifier comes after the type name, after the
channel identifier, and after the update specifier.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating telemetry channel format specifiers
passive component TlmFormat {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Telemetry channel 1
telemetry Channel1: U32 format "{x}"
@ Telemetry channel 2
telemetry Channel2: F64 id 0x10 \
update on change \
format "{.3f}"
@ Telemetry channel 3
telemetry Channel3: F64\
update always \
format "{e}"
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Telemetry_Limits">11.7.5. Limits</h4>
<div class="paragraph">
<p>You may specify <strong>limits</strong>, or bounds, on the expected values
carried on a telemetry channel.
There are two kinds of limits: <code>low</code> (meaning that the
values on the channel should stay above the limit) and <code>high</code>
(meaning that the values should stay below the limit).
Within each kind, there are three levels of severity:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>yellow</code>: Crossing the limit is of low concern.</p>
</li>
<li>
<p><code>orange</code>: Crossing the limit is of medium concern.</p>
</li>
<li>
<p><code>red</code>: Crossing the limit is of high concern.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The F Prime ground data system displays an appropriate warning
when a telemetry point crosses a limit.</p>
</div>
<div class="paragraph">
<p>The limit specifiers come after the type name, identifier,
update specifier, and format string.
You specify the low limits (if any) first, and then the high limits.
For the low limits, you write the keyword <code>low</code> followed by a
list of limits in curly braces <code>{ &#8230;&#8203; }</code>.
For the high limits, you do the same thing but use the keyword
<code>high</code>.
Each limit is a severity keyword followed by a numeric expression.
Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for illustrating telemetry channel limits
passive component TlmLimits {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Telemetry
# ----------------------------------------------------------------------
@ Telemetry channel 1
telemetry Channel1: U32 \
low { red 0, orange 1, yellow 2 }
@ Telemetry channel 2
telemetry Channel2: F64 id 0x10 \
update on change \
format "{.3f}" \
low { red -3, orange -2, yellow -1 } \
high { red 3, orange 2, yellow 1 }
@ Telemetry channel 3
telemetry Channel3: F64 \
update always \
format "{e}" \
high { red 3, orange 2, yellow 1 }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each limit must be a numeric value.
The type of the telemetry channel must be (1) a numeric
type; or (2) an array or struct type each of whose members
has a numeric type; or (3) an array or struct type
each of whose members satisfies condition (1) or
condition (2).</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Parameters">11.8. Parameters</h3>
<div class="paragraph">
<p>When defining an F Prime component, you may specify one or more
<strong>parameters</strong>.
A parameter is a typed constant value that you can update
by command.
For example, it could be a configuration constant
for a hardware device or a software algorithm.</p>
</div>
<div class="paragraph">
<p>F Prime has special support for parameters, including a parameter
database component for storing parameters in a non-volatile
manner (e.g., on a file system).
For complete information about F Prime parameters, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.
Here we concentrate on how to specify parameters in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Parameters_Basic-Parameters">11.8.1. Basic Parameters</h4>
<div class="paragraph">
<p>The simplest parameter consists of the keyword <code>param</code>,
a name, and a data type.
The name is the name of the parameter.
The data type is the type of data stored in the parameter.
The data type must be a
<a href="#Defining-Components_Commands_Formal-Parameters">displayable type</a>.</p>
</div>
<div class="paragraph">
<p>As an example, here is an active component called <code>BasicParams</code>
with a few basic parameters.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating basic parameters
passive component BasicParams {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp port cmdResponseOut
@ Parameter get port
param get port prmGetOut
@ Parameter set port
param set port prmSetOut
# ----------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------
@ Parameter 1
param Param1: U32
@ Parameter 2
param Param2: F64
@ Parameter 3
param Param3: F64x3
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that we defined the two
<a href="#Defining-Components_Special-Port-Instances_Parameter-Ports">parameter ports</a>
for this component.
Both ports are required for any component that has parameters.</p>
</div>
<div class="paragraph">
<p>Notice also that we defined the
<a href="#Defining-Components_Special-Port-Instances_Command-Ports">command ports</a>
for this component.
When you add one or more parameters to a component,
F Prime automatically generates commands for (1)
setting the local parameter in the component and (2) saving
the local parameter to a system-wide parameter database.
Therefore, any component that has parameters must have
the command ports.
Try deleting one or more of the command ports from the example
above and see what <code>fpp-check</code> does.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Parameters_Default-Values">11.8.2. Default Values</h4>
<div class="paragraph">
<p>You can specify a default value for any parameter.
This is the value that F Prime will use if no value is
available in the parameter database.
If you don&#8217;t specify a default value, and no value is
available in the database, then attempting to get
the parameter produces an invalid value.
What happens then is up to the FSW implementation.
By providing default values for your parameters,
you can avoid handling this case.</p>
</div>
<div class="paragraph">
<p>Here is the example from the previous section, updated
to include default values for the parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating default parameter values
passive component ParamDefaults {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp port cmdResponseOut
@ Parameter get port
param get port prmGetOut
@ Parameter set port
param set port prmSetOut
# ----------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------
@ Parameter 1
param Param1: U32 default 1
@ Parameter 2
param Param2: F64 default 2.0
@ Parameter 3
param Param3: F64x3 default [ 1.0, 2.0, 3.0 ]
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Parameters_Identifiers">11.8.3. Identifiers</h4>
<div class="paragraph">
<p>Every parameter in an F Prime FSW application has a unique
numeric identifier.
As for
<a href="#Defining-Components_Commands_Opcodes">command opcodes</a>,
<a href="#Defining-Components_Events_Identifiers">event identifiers</a>,
and
<a href="#Defining-Components_Telemetry_Identifiers">telemetry channel identifiers</a>,
the parameter identifiers for a component are specified
relative to the component, usually starting from
zero and counting up by one.
If you omit the identifier, then
FPP assigns a default identifier: zero for the first
parameter in the component; otherwise one more than the
identifier of the previous parameter.</p>
</div>
<div class="paragraph">
<p>If you wish, you may explicitly specify one or more
parameter identifiers.
To do this, you write the keyword <code>id</code> followed
by a numeric expression after the data type
and after the default value, if any.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating default parameter identifiers
passive component ParamIdentifiers {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp port cmdResponseOut
@ Parameter get port
param get port prmGetOut
@ Parameter set port
param set port prmSetOut
# ----------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------
@ Parameter 1
@ Its implied identifier is 0x00
param Param1: U32 default 1
@ Parameter 2
@ Its identifier is 0x10
param Param2: F64 default 2.0 id 0x10
@ Parameter 3
@ Its implied identifier is 0x11
param Param3: F64x3 default [ 1.0, 2.0, 3.0 ]
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Within a component, the parameter identifiers must be unique.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Parameters_Set-and-Save-Opcodes">11.8.4. Set and Save Opcodes</h4>
<div class="paragraph">
<p>Each parameter that you specify has two implied commands: one
for setting the value bound to the parameter locally in the
component, and one for saving the current local value
to the system-wide parameter database.
The opcodes for these implied commands are called the <strong>set and
save opcodes</strong> for the parameter.</p>
</div>
<div class="paragraph">
<p>By default, FPP generates set and save opcodes for a
parameter <em>P</em> according to the following rules:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If no command or parameter appears before <em>P</em> in the
component, then the set opcode is 0, and the save opcode is 1.</p>
</li>
<li>
<p>Otherwise, let <em>o</em> be the previous opcode defined
in the component
(either a command opcode or a parameter save opcode).
Then the set opcode is <em>o</em> + 1, and the save opcode is
<em>o</em> + 2.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you wish, you may specify either or both of the set and
save opcodes explicitly.
To specify the set opcode, you write the keywords <code>set</code> <code>opcode</code>
and a numeric expression.
To specify the save opcode, you write the keywords <code>save</code> <code>opcode</code>
and a numeric expression.
The set and save opcodes come after the type name, default
parameter value, and parameter identifier.
If both are present, the set opcode comes first.</p>
</div>
<div class="paragraph">
<p>When you specify an explicit set or save opcode <em>o</em>, the
default value for the next opcode is <em>o</em> + 1.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An array of 3 F64 values
array F64x3 = [3] F64
@ A component for illustrating parameter set and save opcodes
passive component ParamOpcodes {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp port cmdResponseOut
@ Parameter get port
param get port prmGetOut
@ Parameter set port
param set port prmSetOut
# ----------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------
@ Parameter 1
@ Its implied set opcode is 0x00
@ Its implied save opcode is 0x01
param Param1: U32 default 1
@ Parameter 2
@ Its set opcode is 0x10
@ Its save opcode is 0x11
param Param2: F64 \
default 2.0 \
id 0x10 \
set opcode 0x10 \
save opcode 0x11
@ Parameter 3
@ Its set opcode is 0x12
@ Its save opcode is 0x20
param Param3: F64x3 \
default [ 1.0, 2.0, 3.0 ] \
save opcode 0x20
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Parameters_External-Parameters">11.8.5. External Parameters</h4>
<div class="paragraph">
<p>In the default case, when you specify a parameter <em>P</em> in a component
<em>C</em>, the FPP code generator produces code for storing
and managing <em>P</em> as part of the auto-generated
code for <em>C</em>.
Sometimes it is more convenient to store and manage parameters separately.
For example, you may wish to integrate an F Prime component with a library
that stores and manages its own parameters.
In this case you can specify an <strong>external</strong> parameter.
An external parameter is like an ordinary parameter (also called
an internal parameter), except that its specifier begins
with the keyword <code>external</code>.</p>
</div>
<div class="paragraph">
<p>Here is an example component definition that specifies two parameters,
an internal parameter <code>Param1</code> and an external parameter <code>Param2</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A component for illustrating internal and external parameters
passive component ParamExternal {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command receive port
command recv port cmdIn
@ Command registration port
command reg port cmdRegOut
@ Command response port
command resp port cmdResponseOut
@ Parameter get port
param get port prmGetOut
@ Parameter set port
param set port prmSetOut
# ----------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------
@ Param1 is an internal parameter
param Param1: U32
@ Param2 is an external parameter
external param Param2: F64 \
default 2.0 \
id 0x10 \
set opcode 0x10 \
save opcode 0x11
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you specify an external parameter, you are responsible for
providing the C&#43;&#43; code that stores and maintains the parameter.
The
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/autocoded-functions/#parameters">F
Prime User Manual</a> explains how to do this.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Data-Products">11.9. Data Products</h3>
<div class="paragraph">
<p>When defining an F Prime component, you may specify the <strong>data products</strong>
produced by that component.
A data product is a collection of related data that is stored onboard
and transmitted to the ground.
F Prime has special support for data products, including components
for (1) managing buffers that can store data products in memory;
(2) writing data products to the file system; and (3)
cataloging stored data products for downlink in priority order.
For more information about these F Prime features, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/data-products/">F
Prime User Manual</a>.</p>
</div>
<div class="sect3">
<h4 id="Defining-Components_Data-Products_Basic-Data-Products">11.9.1. Basic Data Products</h4>
<div class="paragraph">
<p>In F Prime, a data product is represented as a <strong>container</strong>.
One container holds one data product, and each data product
is typically stored in its own file.
A container consists of a header, which provides information about
the container (e.g., the size of the data payload), and binary data
representing a list of serialized <strong>records</strong>.
A record is a unit of data.
For a complete specification of the container format, see the
<a href="https://fprime.jpl.nasa.gov/devel/Fw/Dp/docs/sdd/">F Prime design
documentation</a>.</p>
</div>
<div class="paragraph">
<p>In an F Prime component, you can specify one or more containers
and one or more records.
The simplest container specification consists of the keywords <code>product</code> <code>container</code>
and a name.
The name is the name of the container.
The simplest record specification consists of the keywords <code>product</code> <code>record</code>,
a name, and a data type.
The name is the name of the record.
The data type is the type of the data that the record holds.
The data type must be a
<a href="#Defining-Components_Commands_Formal-Parameters">displayable type</a>.</p>
</div>
<div class="paragraph">
<p>As an example, here is a component called <code>BasicDataProducts</code> that specifies
two records and two containers.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A struct type defining some data
struct Data { a: U32, b: F32 }
@ A component for illustrating basic data products
passive component BasicDataProducts {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Product get port
product get port productGetOut
@ Product send port
product send port productSendOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Records
# ----------------------------------------------------------------------
@ Record 1
product record Record1: I32
@ Record 2
product record Record2: Data
# ----------------------------------------------------------------------
# Containers
# ----------------------------------------------------------------------
@ Container 1
product container Container1
@ Container 2
product container Container2
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The FPP back end uses this specification to generate code for requesting
buffers to hold containers and for serializing records into containers.
See the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/data-products/">F
Prime design documentation</a> for the details.</p>
</div>
<div class="paragraph">
<p>Note the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Records are not specific to containers.
For example, with the specification shown above, you can serialize instances of
<code>Record1</code> and <code>Record2</code> into either or both of <code>Container1</code> and <code>Container2</code>.</p>
</li>
<li>
<p>Like telemetry channels, F Prime containers are component-centric.
A component can request containers that it defines, and it can fill those
containers with records that it defines.
It cannot use records or containers defined by another component.</p>
</li>
<li>
<p>If a component has container specifier, then it must have at least one record
specifier, and vice versa.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Data-Products_Identifiers">11.9.2. Identifiers</h4>
<div class="paragraph">
<p>Every record in an F Prime FSW application has a unique
numeric identifier.
As for
<a href="#Defining-Components_Commands_Opcodes">command opcodes</a>,
<a href="#Defining-Components_Events_Identifiers">event identifiers</a>,
<a href="#Defining-Components_Telemetry_Identifiers">telemetry channel identifiers</a>, and
<a href="#Defining-Components_Parameters">parameters</a>,
the record identifiers for a component are specified
relative to the component, usually starting from
zero and counting up by one.
If you omit the identifier, then
FPP assigns a default identifier: zero for the first
event in the component; otherwise one more than the
identifier of the previous parameter.
The same observations apply to containers and container
identifiers.</p>
</div>
<div class="paragraph">
<p>If you wish, you may explicitly specify one or more
container or record identifiers.
To do this, you write the keyword <code>id</code> followed
by a numeric expression at the end of the container
or record specifier.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A struct type defining some data
struct Data { a: U32, b: F32 }
@ A component for illustrating data product identifiers
passive component DataProductIdentifiers {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Product get port
product get port productGetOut
@ Product send port
product send port productSendOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Records
# ----------------------------------------------------------------------
@ Record 1
@ Its implied identifier is 0x00
product record Record1: I32
@ Record 2
@ Its identifier is 0x10
product record Record2: Data id 0x10
# ----------------------------------------------------------------------
# Containers
# ----------------------------------------------------------------------
@ Container 1
@ Its identifier is 0x10
product container Container1 id 0x10
@ Container 2
@ Its implied identifier is 0x11
product container Container2
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Within a component, the record identifiers must be unique,
and the container identifiers must be unique.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Components_Data-Products_Array-Records">11.9.3. Array Records</h4>
<div class="paragraph">
<p>In the basic form of a record described above, each record that
does not have
<a href="#Defining-Types_Array-Type-Definitions_Type-Names">string type</a>
has a fixed, statically-specified size.
The record may contain an array (e.g., an
<a href="#Defining-Types_Array-Type-Definitions">array type</a>
or a struct type with a
<a href="#Defining-Types_Struct-Type-Definitions_Member-Arrays">member array</a>),
but the size of the array must be specified in the model.
To specify a record that is a dynamically-sized array, you put
the keyword <code>array</code> after the type specifier for the record.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A struct type defining some data
struct Data { a: U32, b: F32 }
@ A component for illustrating array records
passive component ArrayRecords {
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Product get port
product get port productGetOut
@ Product send port
product send port productSendOut
@ Time get port
time get port timeGetOut
# ----------------------------------------------------------------------
# Records
# ----------------------------------------------------------------------
@ A data record
@ It holds one element of type Data
product record DataRecord: Data
@ A data array record
@ It holds an array of elements of type Data
product record DataArrayRecord: Data array
# ----------------------------------------------------------------------
# Containers
# ----------------------------------------------------------------------
@ A container
product container Container
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, a record with name <code>DataArrayRecord</code> holds
an array of elements of type <code>Data</code>.
The number of elements is unspecified in the model;
it is provided when the record is serialized into a container.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_State-Machine-Instances">11.10. State Machine Instances</h3>
<div class="paragraph">
<p>A <strong>state machine instance</strong> is a component member that instantiates
an FPP <a href="#Defining-State-Machines">state machine</a>.
The state machine instance becomes part of the component implementation.</p>
</div>
<div class="paragraph">
<p>For example, here is a simple async component that has
one state machine instance and one async input port
for driving the state machine:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An external state machine
state machine M
@ A component with a state machine
active component StateMachine {
@ A port for driving the state machine
async input port schedIn: Svc.Sched
@ An instance of state machine M
state machine instance m: M
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When a state machine instance <em>m</em> is part of a component <em>C</em>,
each instance <em>c</em> of <em>C</em> sends <em>m</em> <strong>signals</strong> to process as it runs.
Signals occur in response to commands or port
invocations received by <em>c</em>, and they tell <em>m</em> when to change state.
<em>c</em> puts the signals on its queue, and <em>m</em> dispatches them.
Therefore, if a component <em>C</em> has a state machine instance member <em>m</em>,
then its instances <em>c</em> must have queues, i.e., <em>C</em> must be active or queued.</p>
</div>
<div class="paragraph">
<p>As with <a href="#Defining-Components_Internal-Ports">internal ports</a>,
you may specify priority and queue full behavior associated
with the signals dispatched by a state machine instance.
For example, we can revise the example above as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An external state machine
state machine M
@ A component with a state machine
active component StateMachine {
@ A port for driving the state machine
async input port schedIn: Svc.Sched
@ An instance of state machine M
state machine instance m: M priority 10 drop
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As discussed
<a href="#Defining-State-Machines_Writing-a-State-Machine-Definition">above</a>, state
machine definitions may be internal (specified in FPP) or external (specified
by an external tool). For more details about the C&#43;&#43; code generation for
instances of internal state machines, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/state-machines/">F
Prime design documentation</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Constants-Types-Enums-and-State-Machines">11.11. Constants, Types, Enums, and State Machines</h3>
<div class="paragraph">
<p>You can write a <a href="#Defining-Constants">constant definition</a>,
<a href="#Defining-Types">type definition</a>,
<a href="#Defining-Enums">enum definition</a>,
or
<a href="#Defining-State-Machines">state machine definition</a>
as a component member.
When you do this, the component qualifies
the name of the constant or type, similarly to the way that a
<a href="#Defining-Modules">module</a> qualifies the names of the
definitions it contains.
For example, if you define a type <code>T</code> inside a component
<code>C</code>, then</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Inside the definition of <code>C</code>, you can refer to the
type as <code>T</code>.</p>
</li>
<li>
<p>Outside the definition of <code>C</code>, you must refer to the
type as <code>C.T</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As an example, here is the <code>SerialSplitter</code> component
from the section on
<a href="#Defining-Components_Port-Instances_Serial-Port-Instances">serial port instances</a>, where we have moved the
definition of the constant <code>splitFactor</code>
into the definition of the component.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Component for splitting a serial data stream
passive component SerialSplitter {
# ----------------------------------------------------------------------
# Constants
# ----------------------------------------------------------------------
@ Split factor
constant splitFactor = 10
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Input
sync input port serialIn: serial
@ Output
output port serialOut: [splitFactor] serial
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As another example, here is the <code>Switch</code> component from the section on
<a href="#Defining-Components_Commands_Formal-Parameters">command formal parameters</a>, where we have moved the definition of
the enum <code>State</code> into the component:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A switch with on and off state
active component Switch {
# ----------------------------------------------------------------------
# Types
# ----------------------------------------------------------------------
@ The state enumeration
enum State {
OFF @&lt; The off state
ON @&lt; The on state
}
# ----------------------------------------------------------------------
# Ports
# ----------------------------------------------------------------------
@ Command input
command recv port cmdIn
@ Command registration
command reg port cmdRegOut
@ Command response
command resp port cmdResponseOut
# ----------------------------------------------------------------------
# Commands
# ----------------------------------------------------------------------
@ Set the state
async command SET_STATE(
$state: State @&lt; The new state
)
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In general, it is a good idea to state a definition inside a component
when the definition logically belongs to the component.
The name scoping mechanism emphasizes the hierarchical relationship
and prevents name clashes.</p>
</div>
<div class="paragraph">
<p>In most cases, a qualified name such as <code>Switch.State</code>
in FPP becomes a qualified name such as <code>Switch::State</code> when translating
to C&#43;&#43;.
However, the current C&#43;&#43; code generation strategy does not
support the definition
of constants and types as members of C&#43;&#43; components.
Therefore, when translating the previous example to C&#43;&#43;,
the following occurs:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The component <code>Switch</code> becomes an auto-generated C&#43;&#43; class
<code>SwitchComponentBase</code>.</p>
</li>
<li>
<p>The type <code>State</code> becomes a C&#43;&#43; class <code>Switch_State</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Similarly, the FPP constant <code>SerialSplitter.splitFactor</code>
becomes a C&#43;&#43; constant <code>SerialSplitter_SplitFactor</code>.
We will have more to say about this issue in the section on
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus">generating C&#43;&#43;</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Include-Specifiers">11.12. Include Specifiers</h3>
<div class="paragraph">
<p>Component definitions can become long, especially when there
are many commands, events, telemetry channels, and parameters.
In this case it is useful to break up the component
definition into several files.</p>
</div>
<div class="paragraph">
<p>For example, suppose you are defining a component with
many commands, and you wish to place the commands in a
separate file <code>Commands.fppi</code>.
The suffix <code>.fppi</code> is conventional for included FPP files.
Inside the component definition, you can write the
following component member:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">include "Commands.fppi"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This construct is called an <strong>include specifier</strong>.
During analysis and translation, the include specifier
is replaced with the commands specified
in <code>Commands.fppi</code>, just as if you had written them
at the point where you wrote the include specifier.
This replacement is called expanding or resolving the
include specifier.
You can use the same technique for events, telemetry,
parameters, or any other component members.</p>
</div>
<div class="paragraph">
<p>The text enclosed in quotation marks after the keyword
<code>include</code> is a path name relative to the directory of the
file in which the include specifier appears.
The file must exist and must contain component members
that can validly appear at the point where the include
specifier appears.
For example, if <code>Commands.fppi</code> contains invalid syntax
or syntax that may not appear inside a component,
or if the file <code>Commands.fppi</code> does not exist, then
the specifier <code>include "Commands.fppi"</code> is not valid.</p>
</div>
<div class="paragraph">
<p>Include specifiers are perhaps most useful when defining
components, but they can also appear at the top level of a
model, inside a module definition, or inside a
topology definition.
We discuss include specifiers further in the section on
<a href="#Specifying-Models-as-Files_Include-Specifiers">specifying models as files</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Components_Matched-Ports">11.13. Matched Ports</h3>
<div class="paragraph">
<p>Some F Prime components employ the following pattern:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The component has a pair of port arrays, say <code>p1</code> and <code>p2</code>.
The two arrays have the same number of ports.</p>
</li>
<li>
<p>For every connection between <code>p1</code> and another component
instance, there must be a matching connection between that
component instance and <code>p2</code>.</p>
</li>
<li>
<p>The matched pairs in item 2 must be connected to the
same port numbers at <code>p1</code> and <code>p2</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In this case we call <code>p1</code> and <code>p2</code> a pair of
<strong>matched ports</strong>.
For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The standard Command Dispatcher component has matched ports
<code>compCmdReg</code> for receiving command registration and
<code>compCmdSend</code> for sending commands.</p>
</li>
<li>
<p>The standard Health component has matched ports
<code>PingSend</code> for sending health ping messages and
<code>PingReturn</code> for receiving responses to the ping messages.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>FPP provides special support for matched ports.
Inside a component definition, you can write
<code>match p1 with p2</code>, where <code>p1</code> and <code>p2</code> are the names of
<a href="#Defining-Components_Port-Instances">port instances</a>
defined in the component.
When you do this, the following occurs:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The FPP translator checks that <code>p1</code> and <code>p2</code> have
the same number of ports.
If not, an error occurs.</p>
</li>
<li>
<p>When
<a href="#Defining-Topologies_Port-Numbering_Matched-Numbering">automatically numbering a topology</a>, the
translator ensures that the port numbers match in the manner
described above.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, here is a simplified version of the Health
component:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Number of health ping ports
constant numPingPorts = 10
queued component Health {
@ Ping output port
output port pingOut: [numPingPorts] Svc.Ping
@ Ping input port
async input port pingIn: [numPingPorts] Svc.Ping
@ Corresponding port numbers of pingOut and pingIn must match
match pingOut with pingIn
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This component defines a pair of matched ports
<code>pingOut</code> and <code>pingIn</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-and-Using-Port-Interfaces">12. Defining and Using Port Interfaces</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A common pattern in F Prime is to use an identical set of
<a href="#Defining-Components_Port-Instances">port instances</a>
in the definitions of each of several components.
For example, each of several driver components may specify
an identical set of ports for sending and receiving data.
Such a set of port instances is called a <strong>port interface</strong>
(interface for short).
FPP has special support for defining and using port interfaces,
which we describe in this section.</p>
</div>
<div class="sect2">
<h3 id="Defining-and-Using-Port-Interfaces_Defining-Port-Interfaces">12.1. Defining Port Interfaces</h3>
<div class="paragraph">
<p>A <strong>port interface definition</strong> defines a port interface.
To write a port interface definition, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>interface</code>.</p>
</li>
<li>
<p>The <a href="#Defining-Constants_Names">name</a> of the interface.</p>
</li>
<li>
<p>A sequence of <strong>port interface members</strong> enclosed in curly braces
<code>{</code> &#8230;&#8203; <code>}</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A port interface member may directly specify a
<a href="#Defining-Components_Port-Instances">general port instance</a> or a
<a href="#Defining-Components_Special-Port-Instances">special port instance</a>.
For example, here is a port interface representing a binary operation
that takes two <code>F32</code> inputs and produces an <code>F32</code> output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ A port for carrying an F32 value
port F32Value(value: F32)
@ A priority constant for async F32 binary operation input
constant AsyncF32BinopInputPriority = 10
@ An active component for adding two F32 values with specified priorities
interface AsyncF32Binop {
@ Input 1 at priority 10
async input port f32ValueIn1: F32Value priority AsyncF32BinopInputPriority
@ Input 2 at priority 20
async input port f32ValueIn2: F32Value priority AsyncF32BinopInputPriority
@ Output
output port f32ValueOut: F32Value
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This interface represents the input and output ports for any
binary operation: addition, multiplication, etc.
An interface member may also import the definition of another interface;
we describe this option
<a href="#Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Interface-Definitions">below</a>.</p>
</div>
<div class="paragraph">
<p>An interface definition and each of its members is an
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable element</a>.
For example, you can annotate the interface as shown above.
The members of a interface form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> with a semicolon as the optional
terminating punctuation.</p>
</div>
<div class="paragraph">
<p>In general, port instances that appear in port interfaces must follow the same rules
as
<a href="#Defining-Components_Port-Instances">port instances that appear in
components</a>.
For example, each port name appearing in the interface must
be distinct.
The rules specific to active, passive, and queued components
do not apply to interfaces; those are checked when the interface
is used in a component, as described in the next section.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Component-Definitions">12.2. Using Port Interfaces in Component Definitions</h3>
<div class="paragraph">
<p>Once you have defined a port interface, you can use it in a component definition.
To do this you write a <a href="#Defining-Components_Component-Definitions">component
member</a> consisting of the keyword <code>import</code> followed by the interface name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An active component for adding two F32 values
active component ActiveF32Adder {
@ Import the AsyncF32Binop interface
import AsyncF32Binop
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This component is identical to the <code>ActiveF32Adder</code> component
that we defined in the section on
<a href="#Defining-Components_Port-Instances_Basic-Port-Instances">basic port instances</a>, except that we have factored the input
and output ports into an interface.
We can then use the same interface to define an <code>ActiveF32Multiplier</code>
component:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ An active component for multiplying two F32 values
active component ActiveF32Multiplier {
@ Import the AsyncF32Binop interface
import AsyncF32Binop
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This component is identical to <code>ActiveF32Adder</code>, except
that it performs multiplication instead of addition.</p>
</div>
<div class="paragraph">
<p>In general, a component member <code>import</code> <em>I</em> member is analyzed by (1)
resolving the interface <em>I</em> to a set of port instances
and (2) adding each of the port instances to the component.
After this resolution, all the rules for component definition
must be obeyed.
For example, this component definition is illegal,
because it has a duplicate port name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P
interface I {
sync input port p: P
}
passive component C {
@ Port instance p is imported here
import I
@ Port instance name p is a duplicate here
sync input port p: P
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-and-Using-Port-Interfaces_Using-Port-Interfaces-in-Interface-Definitions">12.3. Using Port Interfaces in Interface Definitions</h3>
<div class="paragraph">
<p>You can import a port interface into another interface.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P
interface I1 {
sync input port p1: P
}
interface I2 {
import I1
sync input port p2: P
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Either <code>I1</code> or <code>I2</code> may be imported into a component
or into another interface.
Interface <code>I2</code> is functionally equivalent to the
following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P
interface I2 {
sync input port p1: P
sync input port p2: P
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Component-Instances">13. Defining Component Instances</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As discussed in the section on <a href="#Defining-Components">defining-components</a>,
in F Prime you define components and instantiate them.
Then you construct a <strong>topology</strong>, which is a graph
that specifies the connections between the components.
This section explains how to define component instances.
In the next section, we will explain how to
construct topologies.</p>
</div>
<div class="sect2">
<h3 id="Defining-Component-Instances_Component-Instance-Definitions">13.1. Component Instance Definitions</h3>
<div class="paragraph">
<p>To instantiate a component, you write a <strong>component instance definition</strong>.
The form of a component instance definition depends on the kind
of the component you are instantiating: passive, queued, or active.</p>
</div>
<div class="sect3">
<h4 id="Defining-Component-Instances_Component-Instance-Definitions_Passive-Components">13.1.1. Passive Components</h4>
<div class="paragraph">
<p>To instantiate a passive component, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>instance</code>.</p>
</li>
<li>
<p>The <a href="#Defining-Constants_Names">name</a> of the instance.</p>
</li>
<li>
<p>A colon <code>:</code>.</p>
</li>
<li>
<p>The name of a <a href="#Defining-Components_Component-Definitions">component definition</a>.</p>
</li>
<li>
<p>The keywords <code>base</code> <code>id</code>.</p>
</li>
<li>
<p>An <a href="#Defining-Constants_Expressions">expression</a> denoting
the <strong>base identifier</strong> associated with the component instance.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The base identifier must resolve to a number.
The FPP translator adds this number to each of the component-relative
<a href="#Defining-Components_Commands_Opcodes">command opcodes</a>,
<a href="#Defining-Components_Events_Identifiers">event identifiers</a>,
<a href="#Defining-Components_Telemetry_Identifiers">telemetry channel identifiers</a>,
and
<a href="#Defining-Components_Parameters_Identifiers">parameter identifiers</a>
specified in the component, as discussed in the previous section.
The base identifier for the instance plus the component-relative
opcode or identifier for the component gives the corresponding
opcode or identifier for the instance.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Sensors {
@ A component for sensing engine temperature
passive component EngineTemp {
@ Schedule input port
sync input port schedIn: Svc.Sched
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
@ Impulse engine temperature
telemetry ImpulseTemp: F32
@ Warp core temperature
telemetry WarpTemp: F32
}
}
module FSW {
@ Engine temperature instance
instance engineTemp: Sensors.EngineTemp base id 0x100
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We have defined a passive component <code>Sensors.EngineTemp</code> with three ports:
a schedule input port for driving the component periodically on a rate group,
a time get port for getting the time, and a telemetry port
for reporting telemetry.
(For more information on rate groups and the use of <code>Svc.Sched</code>
ports, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/design-patterns/rate-group/">F
Prime documentation</a>.)
We have given the component two telemetry channels:
<code>ImpulseTemp</code> for reporting the temperature of the impulse engine,
and <code>WarpTemp</code> for reporting the temperature of the warp core.</p>
</div>
<div class="paragraph">
<p>Next we have defined an instance <code>FSW.engineTemp</code> of component <code>Sensors.EngineTemp</code>.
Because the instance definition is in a different module from the
component definition, we must refer to the component by its
qualified name <code>Sensors.EngineTemp</code>.
If we wrote</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance engineTemp: EngineTemp base id 0x100</code></pre>
</div>
</div>
<div class="paragraph">
<p>the FPP compiler would complain that the symbol <code>EngineTemp</code> is undefined
(try it and see).</p>
</div>
<div class="paragraph">
<p>We have specified that the base identifier of instance <code>FSW.engineTemp</code>
is the hexadecimal number 0x100 (256 decimal).
In the component definition, the telemetry channel <code>ImpulseTemp</code>
has relative identifier 0, and the telemetry channel <code>WarpTemp</code>
has relative identifier 1.
Therefore the corresponding telemetry channels for the instance
<code>FSW.engineTemp</code> have identifiers 0x100 and 0x101 (256 and 257)
respectively.</p>
</div>
<div class="paragraph">
<p>For consistency, the base identifier is required for all component instances,
even instances that define no dictionary elements (commands, events, telemetry,
or parameters).
For each component instance <em>I</em>, the range of numbers between the base
identifier and the base identifier plus the largest relative identifier
is called the <strong>identifier range</strong> of <em>I</em>.
If a component instance defines no dictionary elements, then the
identifier range is empty.
All the numbers in the identifier range of <em>I</em> are reserved for
instance <em>I</em> (even if they are not all used).
No other component instance may have a base identifier that lies within the
identifier range of <em>I</em>.</p>
</div>
<div class="paragraph">
<p>For example, this code is illegal:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module FSW {
@ Temperature sensor for the left engine
instance leftEngineTemp: Sensors.EngineTemp base id 0x100
@ Temperature sensor for the right engine
instance rightEngineTemp: Sensors.EngineTemp base id 0x101
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The base identifier 0x101 for <code>rightEngineTemp</code> is inside the
identifier range for <code>leftEngineTemp</code>, which goes from
0x100 to 0x101, inclusive.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Component-Instances_Component-Instance-Definitions_Queued-Components">13.1.2. Queued Components</h4>
<div class="paragraph">
<p>Instantiating a queued component is just like instantiating
a passive component, except that you must also specify
a queue size for the instance.
You do this by writing the keywords <code>queue</code> <code>size</code> and
the queue size after the base identifier.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Sensors {
@ A port for calibration input
port Calibration(cal: F32)
@ A component for sensing engine temperature
queued component EngineTemp {
@ Schedule input port
sync input port schedIn: Svc.Sched
@ Calibration input
async input port calibrationIn: Calibration
@ Telemetry port
telemetry port tlmOut
@ Time get port
time get port timeGetOut
@ Impulse engine temperature
telemetry ImpulseTemp: F32
@ Warp core temperature
telemetry WarpTemp: F32
}
}
module FSW {
@ Engine temperature sensor
instance engineTemp: Sensors.EngineTemp base id 0x100 \
queue size 10
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the component definition, we have revised the example from the previous
section so that
the <code>EngineTemp</code> component is queued instead of passive,
and we have added an async input port for calibration input.
In the component instance definition, we have specified a queue size of 10.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Component-Instances_Component-Instance-Definitions_Active-Components">13.1.3. Active Components</h4>
<div class="paragraph">
<p>Instantiating an active component is like instantiating a queued
component, except that you may specify additional parameters
that configure the OS thread associated with each component instance.</p>
</div>
<div class="paragraph">
<p><strong>Queue size, stack size, and priority:</strong>
When instantiating an active component, you <em>must</em>
specify a queue size, and you <em>may</em> specify either or both of
a stack size and priority.
You specify the queue size in the same way as for a queued component.
You specify the stack size by writing the keywords <code>stack</code> <code>size</code>
and the desired stack size in bytes.
You specify the priority by writing the keyword <code>priority</code>
and a numeric priority.
The priority number is passed to the OS operation for creating
the thread, and its meaning is OS-specific.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Utils {
@ A component for compressing data
active component DataCompressor {
@ Uncompressed input data
async input port bufferSendIn: Fw.BufferSend
@ Compressed output data
output port bufferSendOut: Fw.BufferSend
}
}
module FSW {
module Default {
@ Default queue size
constant queueSize = 10
@ Default stack size
constant stackSize = 10 * 1024
}
@ Data compressor instance
instance dataCompressor: Utils.DataCompressor base id 0x100 \
queue size Default.queueSize \
stack size Default.stackSize \
priority 30
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We have defined an active component <code>Utils.DataCompressor</code>
for compressing data.
We have defined an instance of this component called
<code>FSW.dataCompressor</code>.
Our instance has base identifier 0x100, the default
queue size, the default stack size, and priority 30.
We have used
<a href="#Defining-Constants">constant definitions</a> for
the default queue and stack sizes.</p>
</div>
<div class="paragraph">
<p>We could also have omitted either or both of the stack size and priority
specifiers.
When you omit the stack size or priority from a component instance
definition, F Prime supplies a default value appropriate to the
target platform.
With implicit stack size and priority, the <code>dataCompressor</code>
instance looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance dataCompressor: Utils.DataCompressor base id 0x100 \
queue size Default.queueSize</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>CPU affinity:</strong>
When defining an active component, you may specify
a <strong>CPU affinity</strong>.
The CPU affinity is a number whose meaning depends on
the platform.
Usually it is an instruction to the operating system
to run the thread of the active component on a particular
CPU, identified by number.</p>
</div>
<div class="paragraph">
<p>To specify CPU affinity, you write the keyword <code>cpu</code>
and the CPU number after the queue size, the stack size (if any),
and the priority specifier (if any).
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance dataCompressor: Utils.DataCompressor base id 0x100 \
queue size Default.queueSize \
stack size Default.stackSize \
priority 30 \
cpu 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example is the same as the previous <code>dataCompressor</code>
instance, except that we have specified that the thread
associated with the instance should run on CPU 0.</p>
</div>
<div class="paragraph">
<p>With implicit stack size and priority, the example looks like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance dataCompressor: Utils.DataCompressor base id 0x100 \
queue size Default.queueSize \
cpu 0</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Component-Instances_Specifying-the-Implementation">13.2. Specifying the Implementation</h3>
<div class="paragraph">
<p>When you define a component instance <em>I</em>, the FPP translator needs
to know the following information about the C&#43;&#43; implementation of <em>I</em>:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The type (i.e., the name of the C&#43;&#43; class) that defines the
implementation.</p>
</li>
<li>
<p>The location of the C&#43;&#43; header file that declares the implementation
class.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In most cases, the translator can infer this information.
However, in some cases you must specify it manually.</p>
</div>
<div class="paragraph">
<p><strong>The implementation type:</strong>
The FPP translator can automatically infer the implementation
type if its qualified C&#43;&#43; class name matches the qualified
name of the FPP component.
For example, the C&#43;&#43; class name <code>A::B</code> matches the FPP component
name <code>A.B</code>.
More generally, modules in FPP become namespaces in C&#43;&#43;, so
dot qualifiers in FPP become double-colon qualifiers in C&#43;&#43;.</p>
</div>
<div class="paragraph">
<p>If the names do not match, then you must provide the type
associated with the implementation.
You do this by writing the keyword <code>type</code> after the base identifier,
followed by a <a href="#Defining-Constants_Expressions_String-Values">string</a>
specifying the implementation type.</p>
</div>
<div class="paragraph">
<p>For example, suppose we have a C&#43;&#43; class <code>Utils::SpecialDataCompressor</code>,
which is a specialized implementation of the FPP component
<code>Utils.DataCompressor</code>.
By default, when we specify <code>Utils.DataCompressor</code> as the component name, the
translator infers <code>Utils::DataCompressor</code> as the implementation type.
Here is how we specify the implementation type <code>Utils::SpecialDataCompressor</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance dataCompressor: Utils.DataCompressor base id 0x100 \
type "Utils::SpecialDataCompressor" \
queue size Default.queueSize \
cpu 0</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>The header file:</strong>
The FPP translator can automatically locate the header file for <em>I</em>
if it conforms to the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The name of the header file is <code>Name.hpp</code>, where <code>Name</code>
is the name of the component in the FPP model, without
any module qualifiers.</p>
</li>
<li>
<p>The header file is located in the same directory as the FPP
source file that defines the component.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, the F Prime repository contains a reference FSW implementation
with instances defined in the file <code>Ref/Top/instances.fpp</code>.
One of the instances is <code>SG1</code>.
Its definition reads as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance SG1: Ref.SignalGen base id 0x2100 \
queue size Default.queueSize</code></pre>
</div>
</div>
<div class="paragraph">
<p>The FPP component <code>Ref.SignalGen</code> is
defined in the directory <code>Ref/SignalGen/SignalGen.fpp</code>,
and the implementation class <code>Ref::SignalGen</code> is declared in
the header file <code>Ref/SignalGen/SignalGen.hpp</code>.
In this case, the header file follows rules (1) and (2)
stated above, so the FPP translator can automatically locate
the file.</p>
</div>
<div class="paragraph">
<p>If the implementation header file does not follow
rules (1) and (2) stated above, then you must specify
the name and location of the header file by hand.
You do that by writing the keyword <code>at</code> followed by
a <a href="#Defining-Constants_Expressions_String-Values">string</a>
specifying the header file path.
The header file path is relative to the directory
containing the source file that defines the component
instance.</p>
</div>
<div class="paragraph">
<p>For example, the F Prime repository has a directory
<code>Svc/Time</code> that contains an FPP model for a component <code>Svc.Time</code>.
Because the C&#43;&#43; implementation for this component
is platform-specific, the directory <code>Svc/Time</code> doesn&#8217;t
contain any implementation.
Instead, when instantiating the component, you have to
provide the header file to an implementation located
in a different directory.</p>
</div>
<div class="paragraph">
<p>The F Prime repository also provides a Linux-specific implementation
of the <code>Time</code> component in the directory <code>Svc/LinuxTime</code>.
The file <code>Ref/Top/instances.fpp</code> contains an instance definition
<code>linuxTime</code> that reads as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance linuxTime: Svc.Time base id 0x4500 \
type "Svc::LinuxTime" \
at "../../Svc/LinuxTime/LinuxTime.hpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This definition says to use the implementation of the component
<code>Svc.Time</code> with C&#43;&#43; type name <code>Svc::LinuxTime</code> defined in the header
file <code>../../Svc/LinuxTime/LinuxTime.hpp</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Component-Instances_Init-Specifiers">13.3. Init Specifiers</h3>
<div class="paragraph">
<p>In an F Prime FSW application, each component instance <em>I</em>
has some associated C&#43;&#43; code
for setting up <em>I</em> when FSW starts up
and tearing down <em>I</em> when FSW exits.
Much of this code can be inferred from the FPP model,
but some of it is implementation-specific.
For example, each instance of the standard F Prime command sequencer
component has a method <code>allocateBuffer</code> that the FSW must
call during setup to allocate the sequence buffer
for that instance.
The FPP model does not represent this function;
instead, you have to provide
the function call directly in C&#43;&#43;.</p>
</div>
<div class="paragraph">
<p>To do this, you write one or more <strong>init specifiers</strong>
as part of a component instance definition.
An init specifier names a phase
of the setup or teardown process and
provides a snippet of literal C&#43;&#43; code.
The FPP translator pastes the snippet into the setup
or teardown code according to the phase named in
the specifier.
(Strictly speaking, the init specifier should be called
a "setup or teardown specifier."
However, most of the code is in fact initialization code,
and so FPP uses "init" as a shorthand name.)</p>
</div>
<div class="sect3">
<h4 id="Defining-Component-Instances_Init-Specifiers_Execution-Phases">13.3.1. Execution Phases</h4>
<div class="paragraph">
<p>The FPP translator uses init specifiers when it generates
code for an F Prime topology.
We will have more to say about topology generation in the
next section.
For now, you just need to know the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A topology is a unit of an FPP model that specifies the top-level
structure of an F Prime application (the component instances
and their connections).</p>
</li>
<li>
<p>Each topology has a name, which we will refer to here generically as <em>T</em>.</p>
</li>
<li>
<p>When generating C&#43;&#43; code for topology <em>T</em>, the code generator produces
files <em>T</em> <code>TopologyAc.hpp</code> and <em>T</em> <code>TopologyAc.cpp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The generated code in <em>T</em> <code>TopologyAc.hpp</code> and <em>T</em> <code>TopologyAc.cpp</code>
is divided into several phases of execution.
Table <a href="#execution-phases">Execution Phases</a> shows the execution phases
recognized by the FPP code generator.
In this table, <em>T</em> is the name of a topology and <em>I</em> is the
name of a component instance.
The columns of the table have the following meanings:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Phase:</strong> The symbol denoting the execution phase.
These symbols are the enumerated constants of the
<a href="#Defining-Enums">enum</a> <code>Fpp.ToCpp.Phases</code> defined in
<code>Fpp/ToCpp.fpp</code> in the F Prime repository.</p>
</li>
<li>
<p><strong>Generated File:</strong> The generated file for topology <em>T</em>
that contains the definition:
either <em>T</em> <code>TopologyAc.hpp</code> (for compile-time symbols)
or <em>T</em> <code>TopologyAc.cpp</code> (for link-time symbols).</p>
</li>
<li>
<p><strong>Intended Use:</strong> The intended use of the C&#43;&#43; code snippet
associated with the instance <em>I</em> and the phase.</p>
</li>
<li>
<p><strong>Where Placed:</strong> Where FPP places the code snippet
in the generated file.</p>
</li>
<li>
<p><strong>Default Code:</strong> Whether FPP generates default code if
there is no init specifier for instance <em>I</em>
and for this phase.
If there is an init specifier, then it replaces any
default code.</p>
</li>
</ul>
</div>
<table id="execution-phases" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 1. Execution Phases</caption>
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Phase</th>
<th class="tableblock halign-left valign-top">Generated File</th>
<th class="tableblock halign-left valign-top">Intended Use</th>
<th class="tableblock halign-left valign-top">Where Placed</th>
<th class="tableblock halign-left valign-top">Default Code</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>configConstants</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.hpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">C&#43;&#43; constants for use in constructing and
initializing an instance <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the namespace <code>ConfigConstants::</code> <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>configObjects</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Statically declared C&#43;&#43; objects for use in
constructing and initializing instance <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the namespace <code>ConfigObjects::</code> <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>instances</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A constructor for an instance <em>I</em> that has a non-standard
constructor format.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In an anonymous (file-private) namespace.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard constructor call for <em>I</em>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>initComponents</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Initialization code for an instance <em>I</em> that has a non-standard
initialization format.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>initComponents</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>init</code> for <em>I</em>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>configComponents</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementation-specific configuration code for an instance <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>configComponents</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>regCommands</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for registering the commands of <em>I</em> (if any)
with the command dispatcher.
Required only if <em>I</em> has a
non-standard command registration format.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>regCommands</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>regCommands</code> if <em>I</em> has commands;
otherwise none.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>readParameters</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for reading parameters from a file.
Ordinarily used only when <em>I</em> is the parameter database.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>readParameters</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>loadParameters</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for loading parameter values from the parameter database.
Required only if <em>I</em> has a non-standard parameter-loading
format.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>loadParameters</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>loadParameters</code> if <em>I</em>
has parameters; otherwise none.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>startTasks</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for starting the task (if any) of <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>startTasks</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>startTasks</code> if <em>I</em>
is an active component; otherwise none.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>stopTasks</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for stopping the task (if any) of <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>stopTasks</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>exit</code> if <em>I</em>
is an active component; otherwise none.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>freeThreads</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for freeing the thread associated with <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>freeThreads</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The standard call to <code>join</code> if <em>I</em> is an
active component; otherwise none.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>tearDownComponents</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.cpp</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Code for deallocating the allocated memory
(if any) associated with <em>I</em>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In the file-private function <code>tearDownComponents</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You will most often need to write code for <code>configConstants</code>,
<code>configObjects</code>, and <code>configComponents</code>.
These phases often require implementation-specific input that
cannot be provided in any other way, except to write an init specifier.</p>
</div>
<div class="paragraph">
<p>In theory you should never have to write code for <code>instances</code>
or <code>initComponents</code>&#8201;&#8212;&#8201;this code can be be standardized&#8201;&#8212;&#8201;but in practice not all F Prime components conform to the standard,
so you may have to override the default.</p>
</div>
<div class="paragraph">
<p>You will typically not have to write code for <code>regCommands</code>,
<code>readParameters</code>, and <code>loadParameters</code>&#8201;&#8212;&#8201;the framework can generate
this code automatically&#8201;&#8212;&#8201;except that the parameter database
instance needs one line of special code for reading its parameters.</p>
</div>
<div class="paragraph">
<p>Code for <code>startTasks</code>, <code>stopTasks</code>,
and <code>freeThreads</code> is required only if the user-written implementation of
a component instance manages its own F Prime task.
If you use a standard F Prime active component, then the framework
manages the task, and this code is generated automatically.</p>
</div>
<div class="paragraph">
<p>Code for <code>tearDownComponents</code> is required only if a component
instance needs to deallocate memory or release resources on program exit.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Component-Instances_Init-Specifiers_Writing-Init-Specifiers">13.3.2. Writing Init Specifiers</h4>
<div class="paragraph">
<p>You may write one or more init specifiers as part of a component
instance definition.
The init specifiers, if any, come at the end of the
definition and must be enclosed in curly braces.
The init specifiers form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a>
with a semicolon as the optional terminating punctuation.</p>
</div>
<div class="paragraph">
<p>To write an init specifier, you write the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The keyword <code>phase</code>.</p>
</li>
<li>
<p>The
<a href="#Defining-Component-Instances_Init-Specifiers_Execution-Phases">execution phase</a>
of the init specifier.</p>
</li>
<li>
<p>A
<a href="#Defining-Constants_Expressions_String-Values">string</a>
that provides the code snippet.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It is usually convenient, but not required, to use a multiline string
for the code snippet.</p>
</div>
<div class="paragraph">
<p>As an example, here is the component instance definition for the
command sequencer instance <code>cmdSeq</code> from the
<a href="https://github.com/fprime-community/fprime-system-reference/blob/main/SystemReference/Top/instances.fpp">F Prime system reference deployment</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance cmdSeq: Svc.CmdSequencer base id 0x0700 \
queue size Default.queueSize \
stack size Default.stackSize \
priority 100 \
{
phase Fpp.ToCpp.Phases.configConstants """
enum {
BUFFER_SIZE = 5*1024
};
"""
phase Fpp.ToCpp.Phases.configComponents """
cmdSeq.allocateBuffer(
0,
Allocation::mallocator,
ConfigConstants::SystemReference_cmdSeq::BUFFER_SIZE
);
"""
phase Fpp.ToCpp.Phases.tearDownComponents """
cmdSeq.deallocateBuffer(Allocation::mallocator);
"""
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The code for <code>configConstants</code> provides a constant <code>BUFFER_SIZE</code>
that is used in the <code>configComponents</code> phase.
The code generator places this code snippet in the
namespace <code>ConfigConstants::SystemReference_cmdSeq</code>.
Notice that the second part of the namespace uses the
fully qualified name <code>SystemReference::cmdSeq</code>, and it replaces
the double colon <code>::</code> with an underscore <code>_</code> to generate
the name.
We will explain this behavior further in the section on
<a href="#Defining-Component-Instances_Generation-of-Names">generation of names</a>.</p>
</div>
<div class="paragraph">
<p>The code for <code>configComponents</code> calls <code>allocateBuffer</code>, passing
in an allocator object that is declared elsewhere.
(In the section on
<a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">implementing deployments</a>, we will explain where this allocator
object is declared.)
The code for <code>tearDownComponents</code> calls <code>deallocateBuffer</code> to
deallocate the sequence buffer, passing in the allocator
object again.</p>
</div>
<div class="paragraph">
<p>As another example, here is the instance definition for the parameter
database instance <code>prmDb</code> from the system reference deployment:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance prmDb: Svc.PrmDb base id 0x0D00 \
queue size Default.queueSize \
stack size Default.stackSize \
priority 96 \
{
phase Fpp.ToCpp.Phases.instances """
Svc::PrmDb prmDb(FW_OPTIONAL_NAME("prmDb"), "PrmDb.dat");
"""
phase Fpp.ToCpp.Phases.readParameters """
prmDb.readParamFile();
"""
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here we provide code for the <code>instances</code> phase because the constructor
call for this component is nonstandard&#8201;&#8212;&#8201;it takes the parameter
file name as an argument.
In the <code>readParameters</code> phase, we provide the code for reading the parameters
from the file.
As discussed above, this code is needed only for the parameter database
instance.</p>
</div>
<div class="paragraph">
<p>When writing init specifiers, you may read (but not modify) a special value
<code>state</code> that you define in a handwritten main function.
This value lets you pass application-specific information from the
handwritten code to the auto-generated code.
We will explain the special <code>state</code> value further in the
section on <a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">implementing deployments</a>.</p>
</div>
<div class="paragraph">
<p>For more examples of init specifiers in action, see the rest of
the file <code>SystemReference/Top/instances.fpp</code> in the F Prime repository.
In particular, the init specifiers for the <code>comDriver</code> instance
use the <code>state</code> value that we just mentioned.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Component-Instances_Generation-of-Names">13.4. Generation of Names</h3>
<div class="paragraph">
<p>FPP uses the following rules to generate the names associated with
component instances.
First, as explained in the section on
<a href="#Defining-Component-Instances_Specifying-the-Implementation">specifying the implementation</a>,
a component type <code>M.C</code> in FPP becomes the type <code>M::C</code> in C&#43;&#43;.
Here <code>C</code> is a C&#43;&#43; class defined in namespace <code>M</code> that
implements the behavior of component <code>C</code>.</p>
</div>
<div class="paragraph">
<p>Second, a component instance <em>I</em> defined in module <em>N</em> becomes
a C&#43;&#43; variable <em>I</em> defined in namespace <em>N</em>.
For example, this FPP code</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module N {
instance i: M.C base id 0x100
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>becomes this code in the generated C&#43;&#43;:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="c++">namespace N {
M::C i;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>So the fully qualified name of the instance is <code>N.i</code> in FPP and <code>N::i</code>
in C&#43;&#43;.</p>
</div>
<div class="paragraph">
<p>Third, all other code related to instances is generated in the namespace of the
top-level implementation.
For example, in the System Reference example from the previous section,
the top-level implementation is in the namespace <code>SystemReference</code>, so
the code for configuring constants is generated in that namespace.
We will have more to say about the top-level implementation in
the section on <a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">implementing deployments</a>.</p>
</div>
<div class="paragraph">
<p>Fourth, when generating the name of a constant associated with an instance,
FPP uses the fully-qualified name of the instance, and it replaces
the dots (in FPP) or the colons (in C&#43;&#43;) with underscores.
For example, as discussed in the previous section, the configuration
constants for the instance <code>SystemReference::cmdSeq</code> are placed in
the namespace <code>ConfigConstants::SystemReference_cmdSeq</code>.
This namespace, in turn, is placed in the namespace <code>SystemReference</code>
according to the previous paragraph.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Defining-Topologies">14. Defining Topologies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In F Prime, a <strong>topology</strong> or connection graph is the
highest level of software architecture in a FSW application.
A topology specifies what
<a href="#Defining-Component-Instances">component instances</a>
are used in the application and how their
<a href="#Defining-Components_Port-Instances">port instances</a>
are connected.</p>
</div>
<div class="paragraph">
<p>An F Prime FSW application consists of a topology <em>T</em>;
all the types, ports, and components used by <em>T</em>;
and a small amount of top-level C&#43;&#43; code that you write by hand.
In the section on
<a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">implementing deployments</a>, we will explain more about the top-level
C&#43;&#43; code.
In this section we explain how to define a topology in FPP.</p>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_A-Simple-Example">14.1. A Simple Example</h3>
<div class="paragraph">
<p>We begin with a simple example that shows how many of the pieces
fit together.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">port P
passive component C {
sync input port pIn: P
output port pOut: P
}
instance c1: C base id 0x100
instance c2: C base id 0x200
@ A simple topology
topology Simple {
@ This specifier says that instance c1 is part of the topology
instance c1
@ This specifier says that instance c2 is part of the topology
instance c2
@ This code specifies a connection graph C1
connections C1 {
c1.pOut -&gt; c2.pIn
}
@ This code specifies a connection graph C2
connections C2 {
c2.pOut -&gt; c1.pIn
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, we define a <a href="#Defining-Ports">port</a> <code>P</code>.
Then we define a <a href="#Defining-Components">passive component</a> <code>C</code>
with an input port and an output port, both of type <code>P</code>.
We define two <a href="#Defining-Component-Instances">instances</a> of
<code>C</code>, <code>c1</code> and <code>c2</code>.
We put these instances into a topology called <code>Simple</code>.</p>
</div>
<div class="paragraph">
<p>As shown, to define a topology, you write the keyword <code>topology</code>,
the name of the topology, and the members of the topology
definition enclosed in curly braces.
In this case, the topology has two kinds of members:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Two <strong>instance specifiers</strong> specifying that instances
<code>c1</code> and <code>c2</code> are part of the topology.</p>
</li>
<li>
<p>Two <strong>graph specifiers</strong> that specify connection graphs
named <code>C1</code> and <code>C2</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>As shown, to write an instance specifier, you write the
keyword <code>instance</code> and the name of a component instance
definition.
In general the name may be a qualified name such as <code>A.B</code>.
if the instance is defined inside a
<a href="#Defining-Modules">module</a>; in this simple
example it is not.
Each instance specifier states that the instance it names
is part of the topology.
The instances appearing in the list must be distinct.
For example, this is not correct:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology T {
instance c1
instance c1 # Error: duplicate instance c1
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A graph specifier specifies one or more connections
between component instances.
Each graph specifier has a name.
By dividing the connections of a topology into named
graphs, you can organize the connections in a meaningful way.
For example you can have one graph group
for connections that send commands, another one
for connections that send telemetry, and so forth.
We will have more to say about this in a later section.</p>
</div>
<div class="paragraph">
<p>As shown, to write a graph specifier, you may write the keyword <code>connections</code>
followed by the name of the graph; then you may list
the connections inside curly braces.
(In the next section, we will explain another way to write a graph specifier.)
Each connection consists of an endpoint, an arrow <code>-></code>,
and another endpoint.
An endpoint is the name of a component instance
(which in general may be a qualified name), a dot,
and the name of a port of that component instance.</p>
</div>
<div class="paragraph">
<p>In this example there are two connection graphs, each containing
one connection:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A connection graph <code>C1</code> containing a connection from <code>c1.pOut</code> to <code>c2.pIn</code>.</p>
</li>
<li>
<p>A connection graph <code>C2</code> containing a connection from <code>c2.pOut</code> to <code>c1.pIn</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>As shown, topologies and their members are
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable elements</a>.
The topology members form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> in which the optional
terminating punctuation is a semicolon.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_Connection-Graphs">14.2. Connection Graphs</h3>
<div class="paragraph">
<p>In general, an FPP topology consists of a list of instances
and a set of named connection graphs.
There are two ways to specify connection graphs:
<strong>direct graph specifiers</strong> and <strong>pattern graph specifiers</strong>.</p>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Connection-Graphs_Direct-Graph-Specifiers">14.2.1. Direct Graph Specifiers</h4>
<div class="paragraph">
<p>A direct graph specifier provides a name and a list
of connections.
We illustrated direct graph specifiers in the
previous section, where the simple topology example
included direct graph specifiers for graphs named
<code>C1</code> and <code>C2</code>.
Here are some more details about direct graph specifiers.</p>
</div>
<div class="paragraph">
<p>As shown in the previous section, each connection consists
of an output port specifier, followed by an arrow, followed
by an input port specifier.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections C {
a.p -&gt; b.p
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each of the two port specifiers consists of a component
instance name, followed by a dot, followed the name of a port instance.
The component instance name must refer to a
<a href="#Defining-Component-Instances">component instance definition</a>
and may be qualified by a module name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections C {
M.a.p -&gt; N.b.p
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here component instance <code>a</code> is defined in module <code>M</code> and component
instance <code>b</code> is defined in module <code>N</code>.
In a port specifier <code>a.p</code>, the port instance name <code>p</code> must refer to a
<a href="#Defining-Components_Port-Instances">port instance</a> of the
component definition associated with the component instance <code>a</code>.</p>
</div>
<div class="paragraph">
<p>Each component instance named in a connection must be part of the
instance list in the topology.
For example, if you write a connection <code>a.b -> c.d</code> inside
a topology <code>T</code>, and the specifier <code>instance a</code> does not
appear inside topology <code>T</code>, then you will get an error&#8201;&#8212;&#8201;even if <code>a</code> is a valid instance name for the FPP model.
The reason for this rule is that in flight code we need
to be very careful about which instances are included
in the application.
Naming all the instances also lets us check for
<a href="#Analyzing-and-Translating-Models_Checking-Models">unconnected ports</a>.</p>
</div>
<div class="paragraph">
<p>You may use the same name in more than one direct
graph specifier in the same topology.
If you do this, then all specifiers with the same
name are combined into a single graph with that name.
For example, this code</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections C {
a.p -&gt; b.p
}
connections C {
c.p -&gt; d.p
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>is equivalent to this code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections C {
a.p -&gt; b.p
c.p -&gt; d.p
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The members of a direct graph specifier form an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> in which the optional
terminating punctuation is a comma.
For example, you can write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections C { a.p -&gt; b.p, c.p -&gt; d.p }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The connections appearing in direct graph specifiers must obey the
following rules:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Each connection must go from an output port instance to
an input port instance.</p>
</li>
<li>
<p>The types of the ports must match, except that a
<a href="#Defining-Components_Port-Instances_Serial-Port-Instances">serial port instance</a> may be connected to a port of any
type.
In particular, serial to serial connections are allowed.</p>
</li>
<li>
<p>If a typed port <em>P</em> is connected to a serial port in either direction,
then the port type of <em>P</em> may not specify a
<a href="#Defining-Ports_Returning-Values">return type</a>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Connection-Graphs_Pattern-Graph-Specifiers">14.2.2. Pattern Graph Specifiers</h4>
<div class="paragraph">
<p>A few connection patterns are so common in F Prime that they
get special treatment in FPP.
For example, an F Prime topology typically includes an
instance of the component <code>Svc.Time</code>.
This component has a port <code>timeGetPort</code>
of type <code>Fw.Time</code> that other components can use to get the system
time.
Any component that gets the system time
(and there are usually several) has a connection to
the <code>timeGetPort</code> port of the <code>Svc.Time</code> instance.</p>
</div>
<div class="paragraph">
<p>Suppose you are constructing a topology in which
(1) <code>sysTime</code> is an instance of <code>Svc.Time</code>; and (2)
each of the instances
<code>a</code>, <code>b</code>, <code>c</code>, etc., has a
<a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports">time get port</a>
<code>timeGetOut</code> port connected to <code>sysTime.timeGetPort</code>,
If you used a direct graph specifier to write all these connections,
the result might look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections Time {
a.timeGetOut -&gt; sysTime.timeGetPort
b.timeGetOut -&gt; sysTime.timeGetPort
c.timeGetOut -&gt; sysTime.timeGetPort
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This works, but it is tedious and repetitive. So FPP provides
a better way: you can use a <strong>pattern graph specifier</strong>
to specify this common pattern.
You can write</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">time connections instance sysTime</code></pre>
</div>
</div>
<div class="paragraph">
<p>This code says the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Use the instance <code>sysTime</code> as the instance of <code>Fw.Time</code>
for the time connection pattern.</p>
</li>
<li>
<p>Automatically construct a direct graph specifier named <code>Time</code>.
In this direct graph specifier, include one connection
from each component instance that has a time get port
to the input port of <code>sysTime</code> of type <code>Fw.Time</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The result is as if you had written the direct graph specifier
yourself.
All the other rules for direct graph specifiers apply: for example,
if you write another direct graph specifier with name <code>Time</code>, then
the connections in that specifier are merged with the connections
generated by the pattern specifier.</p>
</div>
<div class="paragraph">
<p>In the example above, we call <code>time</code> the <strong>kind</strong> of the pattern
graph specifier.
We call <code>sysTime</code> the <strong>source instance</strong> of the pattern.
It is the source of all the time pattern connections
in the topology.
We call the instances that have time get ports (and so contribute
connections to the pattern) the <strong>target instances</strong>.
They are the instances targeted by the pattern once the source
instance is named.</p>
</div>
<div class="paragraph">
<p>Table <a href="#pattern-graph-specifiers">Pattern Graph Specifiers</a> shows the pattern graph
specifiers allowed in FPP.
The columns of the table have the following meanings:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Kind:</strong> The keyword or keywords denoting the kind.
When writing the specifier, these appear just before
the keyword <code>connections</code>, as shown above for the time example.</p>
</li>
<li>
<p><strong>Source Instance:</strong> The source instance for the pattern.</p>
</li>
<li>
<p><strong>Target Instances:</strong> The target instances for the pattern.</p>
</li>
<li>
<p><strong>Graph Name:</strong> The name of the connection graph
generated by the pattern.</p>
</li>
<li>
<p><strong>Connections:</strong> The connections generated by the pattern.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The command pattern specifier generates three connection graphs:
<code>Command</code>, <code>CommandRegistration</code>, and <code>CommandResponse</code>.</p>
</div>
<table id="pattern-graph-specifiers" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 2. Pattern Graph Specifiers</caption>
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Kind</th>
<th class="tableblock halign-left valign-top">Source Instance</th>
<th class="tableblock halign-left valign-top">Target Instances</th>
<th class="tableblock halign-left valign-top">Graph Name</th>
<th class="tableblock halign-left valign-top">Connections</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Command</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the unique output port of type <code>Fw::Cmd</code>
of the source instance to the
<a href="#Defining-Components_Special-Port-Instances_Command-Ports"><code>command</code> <code>recv</code> port</a>
of each target instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>command</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.CommandDispatcher</code> or a similar component for
dispatching commands.
The instance must have a unique output port of type <code>Fw.Cmd</code>,
a unique input port of type <code>Fw.CmdReg</code>, and a unique
input port of type <code>Fw.CmdResponse</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has
<a href="#Defining-Components_Special-Port-Instances_Command-Ports">command ports</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CommandRegistration</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Command-Ports"><code>command</code> <code>reg</code> port</a> of each target instance to the
unique input port of type <code>Fw.CmdReg</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CommandResponse</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Command-Ports"><code>command</code> <code>resp</code> port</a> of each target instance to the
unique input port of type <code>Fw.CmdResponse</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>event</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.ActiveLogger</code> or a similar component for
logging event reports.
The instance must have a unique input port of type
<code>Fw.Log</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has an
<a href="#Defining-Components_Special-Port-Instances_Event-Ports"><code>event</code> port</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Events</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Event-Ports"><code>event</code> port</a> of each target instance to the unique
input port of type <code>Fw.Log</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>health</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.Health</code> or a similar component for
health monitoring.
The instance must have a unique output port of type
<code>Svc.Ping</code> and a unique input port of type <code>Svc.Ping</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance other than the source instance
that has a unique output port of type
<code>Svc.Ping</code> and a unique input port of type <code>Svc.Ping</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Health</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(1) All connections from the unique output port of type
<code>Svc.Ping</code> of each target instance to the unique input
port of type <code>Svc.Ping</code> of the source instance.
(2) All connections from the unique output port of type
<code>Svc.Ping</code> of the source instance to the unique
input port of type <code>Svc.Ping</code> of each target instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>param</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.PrmDb</code> or a similar component representing
a database of parameters.
The instance must have a unique input port of type <code>Fw.PrmGet</code>
and a unique input port of type <code>Fw.PrmSet</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has
<a href="#Defining-Components_Special-Port-Instances_Parameter-Ports">parameter ports</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Parameters</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(1) All connections from the
<a href="#Defining-Components_Special-Port-Instances_Parameter-Ports"><code>param</code> <code>get</code> port</a> of each target instance
to the unique input port of type <code>Fw.PrmGet</code> of the source instance.
(2) All connections from the
<a href="#Defining-Components_Special-Port-Instances_Parameter-Ports"><code>param</code> <code>set</code> port</a> of each target instance
to the unique input port of type <code>Fw.PrmSet</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>telemetry</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.TlmChan</code> or a similar component for
storing channelized telemetry.
The instance must have a unique input port of type <code>Fw.Tlm</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has a <a href="#Defining-Components_Special-Port-Instances_Telemetry-Ports">telemetry port</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Telemetry</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Telemetry-Ports"><code>telemetry</code> port</a> of each target instance to the unique input
port of type <code>Fw.Tlm</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>text</code> <code>event</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.PassiveTextLogger</code> or a similar component
for logging event reports in textual form.
The instance must have a unique input port of type <code>Fw.LogText</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has a <a href="#Defining-Components_Special-Port-Instances_Event-Ports"><code>text</code> <code>event</code> port</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>TextEvents</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Event-Ports"><code>text</code> <code>event</code> port</a> of each target instance to the unique
input port of type <code>Fw.LogText</code> of the source instance.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>time</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An instance of <code>Svc.Time</code> or a similar component for providing
the system time.
The instance must have a unique input port of type <code>Fw.Time</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each instance that has a
<a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports"><code>time</code> <code>get</code> port</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Time</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All connections from the
<a href="#Defining-Components_Special-Port-Instances_Time-Get-Ports"><code>time</code> <code>get</code> port</a> of each target instance to the unique
input port of type <code>Fw.Time</code> of the source instance.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Here are some rules for writing graph pattern specifiers:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>At most one occurrence of each pattern kind is allowed in
each topology.</p>
</li>
<li>
<p>For each pattern, the required ports shown in the table
must exist and must be unambiguous.
For example, if you write a time pattern</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">time connections instance sysTime</code></pre>
</div>
</div>
<div class="paragraph">
<p>then you will get an error if <code>sysTime</code> has no
input ports of type <code>Fw.Time</code>,
You will also get an error if <code>sysTime</code> has two or more
such ports.</p>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>The default behavior for a pattern is
to generate the connections for all target instances
as shown in the table.
If you wish, you may generate connections for a selected
set of target instances.
To do this, you write a list of target instances enclosed in
curly braces after the source instance.
For example, suppose a topology contains instances
<code>a</code>, <code>b</code>, and <code>c</code> each of which has an output port
that satisfies the time pattern.
And suppose that <code>sysTime</code> is an instance of <code>Svc.Time</code>.
Then if you write this pattern</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">time connections instance sysTime</code></pre>
</div>
</div>
<div class="paragraph">
<p>you will get a connection graph <code>Time</code> containing
time connections from each of <code>a</code>, <code>b</code>, and <code>c</code> to <code>sysTime</code>.
But if you write this pattern</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">time connections instance sysTime {
a
b
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>then you will just get the connections from <code>a</code> and <code>b</code>
to <code>sysTime</code>.
The instances <code>a</code> and <code>b</code> must be valid target instances
for the pattern.</p>
</div>
<div class="paragraph">
<p>As with connections, you can write the instances <code>a</code> and <code>b</code>
each on its own line, or you can separate them with commas:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">time connections instance sysTime { a, b }</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_Port-Numbering">14.3. Port Numbering</h3>
<div class="paragraph">
<p>As discussed in the
<a href="#Defining-Components_Port-Instances_Arrays-of-Port-Instances">section on defining components</a>,
each named port instance is actually an array of
one or more port instances.
When the size of the array exceeds one, you
must specify the port number (i.e., the array index)
of each connection going into or out of the port instance.
In FPP, there are three ways to specify port numbers:
explicit numbering, matched numbering, and general numbering.</p>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Port-Numbering_Explicit-Numbering">14.3.1. Explicit Numbering</h4>
<div class="paragraph">
<p>To use explicit numbering, you provide an explicit port number
for a connection endpoint.
You write the port number as a
<a href="#Defining-Constants_Expressions">numeric expression</a>
in square brackets, immediately following the port name.
The port numbers start at zero.</p>
</div>
<div class="paragraph">
<p>For example, the <code>RateGroups</code> graph of the Ref (reference) topology in the F Prime
repository defines the rate group connections.
It contains the following connection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">rateGroupDriverComp.CycleOut[Ports.RateGroups.rateGroup1] -&gt; rateGroup1Comp.CycleIn
rateGroup1Comp.RateGroupMemberOut[0] -&gt; SG1.schedIn
rateGroup1Comp.RateGroupMemberOut[1] -&gt; SG2.schedIn
rateGroup1Comp.RateGroupMemberOut[2] -&gt; chanTlm.Run
rateGroup1Comp.RateGroupMemberOut[3] -&gt; fileDownlink.Run</code></pre>
</div>
</div>
<div class="paragraph">
<p>The first line says to connect the port at index
<code>Ports.RateGroups.rateGroup1</code> of <code>rateGroupDriverComp.CycleOut</code>
to <code>rateGroup1Comp.CycleIn</code>.
The symbol <code>Ports.RateGroups.rateGroup1</code> is an enumerated constant, defined
like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module Ports {
enum RateGroups {
rateGroup1
rateGroup2
rateGroup3
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The second and following lines say to connect the ports of
<code>rateGroup1Comp.RateGroupMemberOut</code> at the indices 0, 1, 2, and 3
in the manner shown.</p>
</div>
<div class="paragraph">
<p>As another example, the <code>Downlink</code> graph of the reference topology
contains the following connection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">downlink.framedAllocate -&gt; staticMemory.bufferAllocate[Ports.StaticMemory.downlink]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This line says to connect <code>downlink.framedAllocate</code> to
<code>staticMemory.bufferAllocate</code> at index
<code>Port.StaticMemory.downlink</code>.
Again the port index is a symbolic constant.</p>
</div>
<div class="paragraph">
<p>If you wish, you may write two explicit port numbers,
one at each endpoint.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">a.b[0] -&gt; c.d[1]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here are some rules to keep in mind when using explicit numbering:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>You can write any numeric expression as a port number.
Each port number must be in bounds for the port (greater than
or equal to zero and less than the size of the port array).
If you write a port number that is out of bounds, you will get an error.</p>
</li>
<li>
<p>Use symbolic constants judiciously.
Avoid scattering "magic" literal
constants throughout the topology definition.
For example:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The Ref topology uses the symbolic constants
<code>Ports.RateGroups.rateGroup1</code> and <code>Ports.StaticMemory.downlink</code>, as shown
above.
Because these constants appear in several different places, it is
better to use symbolic constants here.
Using literal constants would decrease readability and increase
the chance of using incorrect or inconsistent numbers.</p>
</li>
<li>
<p>The Ref topology uses the literal constants 0, 1, 2, and 3
to connect the ports of <code>rateGroup1Comp.RateGroupMemberOut</code>.
Here there are no obvious names to associate with the numbers,
the numbers go in sequence, and all the numbers appear together in one place.
So there is no clear benefit to giving them names.</p>
</li>
</ol>
</div>
</li>
<li>
<p>Remember that in F Prime, multiple connections can go to the same
input port, but only one connection can go from each output port.
For example, this code is allowed:</p>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">c1.p1 -&gt; c2.p[0]
c1.p2 -&gt; c2.p[0] # OK: Two connections into c2.p[0]</code></pre>
</div>
</div>
<div class="paragraph">
<p>But this code is incorrect:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">c1.p[0] -&gt; c2.p1
c1.p[0] -&gt; c2.p2 # Error: Two connections out of c1.p[0]</code></pre>
</div>
</div>
</li>
<li>
<p>Use explicit numbering as little as possible.
Instead, use matched numbering or general numbering
(described in the next sections) and let FPP
do the numbering for you.
In particular, avoid writing zero indices such as
<code>c.p[0]</code> except in cases where you need to control the assignment
of numbers, such as in the rate group example shown above.
In other cases, write <code>c.p</code> and let FPP infer
the zero index.
For example, this is what we did in the section on
<a href="#Defining-Topologies_Connection-Graphs_Direct-Graph-Specifiers">direct graph specifiers</a>.</p>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Port-Numbering_Matched-Numbering">14.3.2. Matched Numbering</h4>
<div class="paragraph">
<p><strong>Automatic matching:</strong>
After resolving
<a href="#Defining-Topologies_Port-Numbering_Explicit-Numbering">explicit numbering</a>, the FPP translator applies
<strong>matched numbering</strong>.
In this step, the translator numbers all pairs of
<a href="#Defining-Components_Matched-Ports">matched ports</a>.</p>
</div>
<div class="paragraph">
<p>Matched numbering is essential for resolving the command and health
<a href="#Defining-Topologies_Connection-Graphs_Pattern-Graph-Specifiers">patterns</a>, each of which has matched ports.
You can also use matched numbering in conjunction with direct
graph specifiers.
For example, the Ref topology contains the following connections:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">connections Sequencer {
cmdSeq.comCmdOut -&gt; cmdDisp.seqCmdBuff
cmdDisp.seqCmdStatus -&gt; cmdSeq.cmdResponseIn
}
connections Uplink {
...
uplink.comOut -&gt; cmdDisp.seqCmdBuff
cmdDisp.seqCmdStatus -&gt; uplink.cmdResponseIn
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The port <code>cmdDisp.seqCmdBuff</code> port of the command dispatcher receives
command input from the command sequencer or from the ground.
The corresponding command response goes out on
port <code>cmdDisp.seqCmdStatus</code>.
These two ports are matched in the definition of the Command
Sequencer component.</p>
</div>
<div class="paragraph">
<p>When you use matched numbering with direct graph specifiers, you
must obey the following rules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>When a component has the matching specifier
<code>match p1 with p2</code>, for every connection between <code>p1</code>
and another component, there must be a corresponding
connection between that other component and <code>p2</code>.</p>
</li>
<li>
<p>You can use explicit numbering, and the automatic matching
will work around the numbers you supply if it can.
However, you may not do this in a way that makes the matching impossible.
For example, you may not connect <code>p1[0]</code> to another component
and <code>p2[1]</code> to the same component, because this connection
forces a mismatch.</p>
</li>
<li>
<p>Duplicate connections at the same port number of <code>p1</code> or
<code>p2</code> are not allowed, even if <code>p1</code> or <code>p2</code> are input ports.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>If you violate these rules, you will get an error during
analysis.
You can relax these rules by writing unmatched connections,
as described below.</p>
</div>
<div class="paragraph">
<p><strong>Unmatched connections:</strong>
Occasionally you may need to relax the rules for using matched ports.
For example, you may need to match pairs of connections that use
the F Prime hub pattern to cross a network boundary.
In this case, although the connections are logically matched
at the endpoints, they all go through a single hub instance
on the side of the boundary that has the matched ports, and so they do not obey the
simple rules for matching given here.</p>
</div>
<div class="paragraph">
<p>When a connection goes to or from a matched port,
we say that it is <strong>match constrained</strong>.
Ordinarily a match constrained connection must obey the
rules for matching stated above.
To relax the rules, you can write an <strong>unmatched</strong> connection.
To do this, write the keyword <code>unmatched</code> at the start of the connection
specifier.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">Port P
passive component Source {
sync input port pIn: [2] P
output port pOut: [2] P
match pOut with pIn
}
passive component Target {
sync input port pIn: [2] P
output port pOut: [2] P
}
instance source: Source base id 0x100
instance target: Target base id 0x200
topology T {
instance source
instance target
connections C {
unmatched source.pOut[0] -&gt; target.pIn[0]
unmatched target.pOut[0] -&gt; source.pIn[0]
unmatched source.pOut[1] -&gt; target.pIn[1]
unmatched target.pOut[1] -&gt; source.pIn[1]
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, there are two pairs of connections between the
<code>pIn</code> and <code>pOut</code> connections of the instances <code>source</code> and <code>target</code>.
The ports of <code>source</code> are match constrained, so ordinarily
the connections would need to obey the matching rules.
The connections do partially obey the rules: for example,
there are no duplicate numbers, and the numbers match.
However, both pairs of connections go to and from the same
instance <code>target</code>; ordinarily this is not allowed for
match constrained connections.
To allow it, we need to use unmatched ports as shown.</p>
</div>
<div class="paragraph">
<p>Note the following about using unmatched ports:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>When connections are marked <code>unmatched</code>, the analyzer cannot check that the
port numbers assigned to the connections conform to any particular pattern.
If you need the port numbers to follow a pattern, as in the example shown
above, then you must use explicit numbering.
For a suggestion on how to do this, see the discussion of manual matching
below.</p>
</li>
<li>
<p>Unmatched ports must still obey the rule that distinct
connections at a matched port must have distinct port numbers.</p>
</li>
<li>
<p>The <code>unmatched</code> keyword is allowed only for connections that
are match constrained, i.e., that go to or from a matched port.
If you try to write an unmatched connection and the connection
is not match constrained, then you will get an error.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Manual matching:</strong>
Port matching specifiers work well when each matched pair of connections
goes between the same two components, one of which
has a matched pair of ports.
If the matching does not follow this pattern, then automatic matched
numbering will not work, and it is usually better not to
use a port matching specifier at all.
Instead, you can use explicit port numbers to express the matching.
For example, the Ref topology contains these connections:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">comm.allocate -&gt; staticMemory.bufferAllocate[Ports.StaticMemory.uplink]
comm.$recv -&gt; uplink.framedIn
uplink.framedDeallocate -&gt; staticMemory.bufferDeallocate[Ports.StaticMemory.uplink]</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the <code>staticMemory</code> instance requires that pairs of
allocation and deallocation requests for the same memory
go to the same port.
But the allocation request comes from <code>comm</code>,
and the deallocation request comes from <code>uplink</code>.
Since the allocation and deallocation connections go to different
component instances, we can&#8217;t used automatic matched numbering.
Instead we define a symbolic constant <code>Ports.StaticMemory.uplink</code>
and use that twice to do the matching by hand.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Port-Numbering_General-Numbering">14.3.3. General Numbering</h4>
<div class="paragraph">
<p>After resolving
<a href="#Defining-Topologies_Port-Numbering_Explicit-Numbering">explicit numbering</a> and
<a href="#Defining-Topologies_Port-Numbering_Matched-Numbering">matched numbering</a>,
the FPP translator applies
<strong>general numbering</strong>.
In this step, the translator uses the following algorithm to
fill in any remaining unassigned
port numbers:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Traverse the connections in a deterministic order.
The order is fully described in <em>The FPP Language Specification</em>.</p>
</li>
<li>
<p>For each connection</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>If the output port number is unassigned, then set it to the
lowest available port number.</p>
</li>
<li>
<p>If the input port number is unassigned, then set it to zero.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, consider the following connections:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">a.p -&gt; b.p
a.p -&gt; c.p</code></pre>
</div>
</div>
<div class="paragraph">
<p>After general numbering, the connections could be numbered
as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">a.p[0] -&gt; b.p[0]
a.p[1] -&gt; c.p[0]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_Importing-Topologies">14.4. Importing Topologies</h3>
<div class="paragraph">
<p>It is often useful to decompose a flight software project
into several topologies.
For example, a project might have the following topologies:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A topology for command and data handling (CDH) with
components such as a command dispatcher, an event logger, a telemetry data
base,
a parameter database, and components for managing files.</p>
</li>
<li>
<p>Various subsystem topologies, for example power, thermal,
attitude control, etc.</p>
</li>
<li>
<p>A release topology.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Each of the subsystem topologies might include the CDH topology.
The release topology might include the CDH topology
and each of the subsystem topologies.
Further, to enable modular testing, it is useful for
each topology to be able to run on its own.</p>
</div>
<div class="paragraph">
<p>In FPP, the way we accomplish these goals is to <strong>import</strong>
one topology into another one.
In this section of the User Guide, we explain how to do that.</p>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Importing-Topologies_Importing-Instances-and-Connections">14.4.1. Importing Instances and Connections</h4>
<div class="paragraph">
<p>To import a topology <code>A</code> into a topology <code>B</code>, you write
<code>import A</code> inside topology <code>B</code>, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology B {
import A
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may add instances and connections as usual to <code>B</code>, as shown
by the dots.</p>
</div>
<div class="paragraph">
<p>When you do this, the FPP translator does the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><strong>Resolve <code>A</code>:</strong> Resolve all pattern graph
specifiers in <code>A</code>, and resolve all explicit port numbers in <code>A</code>.
Call the resulting topology <code>T</code>.</p>
</li>
<li>
<p><strong>Form the instances of <code>B</code>:</strong>
Take the union of the instances specified in <code>T</code> and
the instances specified in <code>B</code>, counting any duplicates once.
These are the instances of <code>B</code>.</p>
</li>
<li>
<p><strong>Form the connections of <code>B</code>:</strong>
Take the union of the connection graphs specified in <code>T</code> and
the connection graphs specified in <code>B</code>.
If each of <code>T</code> and <code>B</code> has a connection between the same
ports, then each becomes a separate connection in <code>B</code>.</p>
</li>
<li>
<p><strong>Resolve <code>B</code>:</strong> Resolve the pattern graph specifies of <code>B</code>.
Apply matched numbering and general numbering to <code>B</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, suppose topologies <code>A</code> and <code>B</code> are defined
as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology A {
instance a
instance b
connections C1 {
a.p1 -&gt; b.p
}
}
topology B {
import A
instance c
connections C1 {
a.p1 -&gt; c.p
}
connections C2 {
a.p2 -&gt; c.p
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>After import resolution, <code>B</code> is equivalent to this topology:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology B {
instance a
instance b
instance c
connections C1 {
a.p1 -&gt; b.p
a.p1 -&gt; c.p
}
connections C2 {
a.p2 -&gt; c.p
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that the <code>C1</code> connections of <code>A</code> are merged with the <code>C1</code>
connections of <code>B</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Importing-Topologies_Private-Instances">14.4.2. Private Instances</h4>
<div class="paragraph">
<p>Often when importing topology <code>A</code> into topology <code>B</code>, you
want to include one or more instances in <code>A</code> that exist just
for running <code>A</code>, but that you don&#8217;t want imported into <code>B</code>.
For example, <code>A</code> could have an instance <code>cStub</code> which is a stub version of
a component <code>c</code> that is fully implemented in <code>B</code>.
In this case</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When running <code>A</code> you may need <code>cStub</code>; the topology
may not run or may not even compile without it.</p>
</li>
<li>
<p>When importing <code>A</code> into <code>B</code> you don&#8217;t want to import
<code>cStub</code>, because it is superseded by the real implementation <code>c</code> in <code>B</code>.
Also, any connections to <code>cStub</code> in <code>A</code> should be replaced
by connections to <code>c</code> in <code>B</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To handle this case, you can make <code>cStub</code> a <strong>private</strong> instance
of <code>A</code> and <code>c</code> an instance of <code>B</code>.
When you import <code>B</code> into <code>A</code>, <code>cStub</code> will not become an instance
of <code>B</code>.
Further, no connections in <code>A</code> involving <code>cStub</code> will be imported
into <code>B</code>.</p>
</div>
<div class="paragraph">
<p>As an example, suppose we revise topology <code>A</code> from the previous
section as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology A {
instance a
instance b
private instance d
connections C1 {
a.p1 -&gt; b.p
}
connections C2 {
a.p1 -&gt; d.p
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that we have added an instance <code>d</code> to topology
<code>A</code>, and we have declared <code>d</code> private to <code>A</code>.
We have also added a new connection to <code>d</code> in the
connection graph <code>C2</code>.</p>
</div>
<div class="paragraph">
<p>Now suppose that we use the same definition of <code>B</code> given
in the previous section.
After import resolution, <code>B</code> will still be equivalent
to the topology shown at the end of the last section:
we have added an instance and a connection to <code>A</code>,
but the instance is private and the connection goes
from a private instance, so neither the instance nor
the connection is imported into <code>B</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Importing-Topologies_Multiple-Imports">14.4.3. Multiple Imports</h4>
<div class="paragraph">
<p>Multiple imports are allowed.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology A {
import B
import C
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This has the obvious meaning: both topology <code>B</code> and
topology <code>C</code> are imported into topology <code>A</code>, according
to the rules described above.</p>
</div>
<div class="paragraph">
<p>Each topology may appear at most once in the import list.
For example, this is incorrect:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology A {
import B
import B # Error: B imported twice
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Importing-Topologies_Transitive-Imports">14.4.4. Transitive Imports</h4>
<div class="paragraph">
<p>In general, transitive imports are allowed.
For example, topology <code>A</code> may import topology <code>B</code>,
and topology <code>B</code> may import topology <code>C</code>.
Resolution works bottom-up on the import graph:
for example, first we resolve <code>C</code>, and then we resolve <code>B</code>,
and then we resolve <code>A</code>.</p>
</div>
<div class="paragraph">
<p>Cycles in the import graph are not allowed.
For example, if <code>A</code> imports <code>B</code> and <code>B</code> imports <code>C</code>
and <code>C</code> imports <code>A</code>, you will get an error.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_Include-Specifiers">14.5. Include Specifiers</h3>
<div class="paragraph">
<p>You can include code from another file in a topology definition.
You do this by writing an <strong>include specifier</strong>.
Here is a simple example, in which the body of a topology
definition is specified in a file <code>T.fppi</code> and then included
in a topology definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">topology T {
include "T.fppi"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>We will explain more about this feature in the section on
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifiers</a>
below.</p>
</div>
</div>
<div class="sect2">
<h3 id="Defining-Topologies_Telemetry-Packets">14.6. Telemetry Packets</h3>
<div class="paragraph">
<p>When defining a topology, you may (but are not required to)
specify how the <a href="#Defining-Components_Telemetry">telemetry channels</a>
defined in the topology are grouped into <strong>telemetry packets</strong>.
If you do this, then you can use an F Prime component called
the Telemetry Packetizer to construct telemetry packets and transmit
them to the ground.
This approach is usually more space efficient than transmitting
individual channels.
In this section we explain how to specify telemetry packets in FPP.</p>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Sets">14.6.1. Telemetry Packet Sets</h4>
<div class="paragraph">
<p>To group the channels of a topology <em>T</em> into packets, you write a
<strong>telemetry packet set</strong> as part of the definition of <em>T</em>.
Here is a simple example showing a complete topology with a
telemetry packet set:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">passive component C {
telemetry port tlmOut
time get port timeGetOut
telemetry T1: U32
telemetry T2: F32
}
instance c1: C base id 0x100
instance c2: C base id 0x200
topology T {
instance c1
instance c2
@ Telemetry packet set PacketSet
telemetry packets PacketSet {
@ Packet P1
packet P1 group 0 {
c1.T1
c2.T1
c1.T1
}
@ Packet P2
packet P2 group 1 {
c1.T2
c2.T2
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, we have defined a passive component <code>C</code> with two telemetry
channels, <code>T1</code> and <code>T2</code>.
We have defined two instances of <code>C</code>, <code>c1</code> and <code>c2</code>, so that there
are four telemetry channels overall: <code>c1.T1</code>, <code>c1.T2</code>, <code>c2.T1</code>, and <code>c2.T2</code>.
We have defined a topology <code>T</code> that uses the instances <code>c1</code> and <code>c2</code>
and defines a telemetry packet set <code>PacketSet</code>.
(In a realistic topology, there would be other instances and connections,
for example the telemetry packetizer instance and the ground interface
component. Here we have omitted these instances
and connections to focus on illustrating the FPP features.)</p>
</div>
<div class="paragraph">
<p>Notice the following about this example:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>To write a telemetry packet set, you write the keywords <code>telemetry</code> <code>packets</code>
followed by the name of the packet set, here <code>PacketSet</code>.
Then you write the body of the telemetry packet set inside curly braces
<code>{ &#8230;&#8203; }</code>.</p>
</li>
<li>
<p>In the body of the packet set, you specify packets.
The packet specifiers are
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable elements</a>.
The body of the packet set is an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> in which the optional
terminating punctuation is a comma.</p>
</li>
<li>
<p>Each packet specifier consists of the keyword <code>packet</code>, the packet
name, the keyword <code>group</code>, a group identifier, and the body of the packet.
Within a telemetry packet set, the packet names must be distinct.
The group identifiers must be numeric values.
In particular they can be
<a href="#Defining-Constants_Writing-a-Constant-Definition">defined constants</a>,
<a href="#Defining-Enums">enumerated constants</a>, or
<a href="#Defining-Constants_Expressions_Value-Arithmetic-Expressions">arithmetic expressions</a>.
The Telemetry Packetizer uses the group identifiers to select
which packets get transmitted.
For example, it is possible to transmit packets from group 0 but not group 1.
More than one packet may have the same group identifier.</p>
</li>
<li>
<p>Inside each packet, you specify telemetry channels
enclosed in curly braces <code>{ &#8230;&#8203; }</code>.
The channel specifiers are
<a href="#Writing-Comments-and-Annotations_Annotations">annotatable elements</a>.
The body of the packet is an
<a href="#Defining-Constants_Multiple-Definitions-and-Element-Sequences">element sequence</a> in which the optional
terminating punctuation is a comma.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>When the packets are serialized and transmitted, each packet with name
<em>P</em> contains data from
the channels listed in the specification for <em>P</em>, in the order that
the channels are specified.
As shown for packet <code>P1</code>, a single channel may appear more than
once in a packet; that means that data from that channel appears at
two or more offsets in that packet.</p>
</div>
<div class="paragraph">
<p>The form of a telemetry channel specifier
is an instance name followed by a dot and a channel name.
The instance name must refer to an instance of the topology.
The channel name must refer to a channel of that instance.
For example, in the model above, <code>c1.T</code> is a valid channel
for topology <code>T</code> because <code>c1</code> is an instance of <code>T</code>,
<code>c1</code> has type <code>C</code>, and <code>T</code> is a channel of <code>C</code>.</p>
</div>
<div class="paragraph">
<p>The instance name may be a qualified name containing a dot,
as discussed in
the section on <a href="#Defining-Modules">defining modules</a>.
For example, if we had written</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
instance c1: C base id 0x100
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>instead of</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">instance c1: C base id 0x100</code></pre>
</div>
</div>
<div class="paragraph">
<p>to define instance <code>c1</code> in the model shown above,
then in the topology <code>T</code> we would write
<code>instance M.c1</code> instead of <code>instance c</code>, and we would write
channel <code>M.c1.T</code> instead of channel <code>c1.T</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Telemetry-Packets_Telemetry-Packet-Identifiers">14.6.2. Telemetry Packet Identifiers</h4>
<div class="paragraph">
<p>Within a telemetry packet set, every packet has a unique numeric identifier.
Typically the identifiers start at zero and count up by one.
If you don&#8217;t specify an identifier, as in the example shown in the previous
section, then FPP assigns a default identifier: zero for the first packet in the set;
otherwise one more than the identifier of the previous packet.</p>
</div>
<div class="paragraph">
<p>If you wish, you may explicitly specify one or more packet identifiers. To do
this, you write the keyword <code>id</code> followed by a numeric expression immediately
after the packet name.
For example, in the model shown in the previous section, we
could have written</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">@ Packet P1
packet P1 id 0 group 0 {
c1.T1
c2.T1
c1.T1
}
@ Packet P2
packet P2 id 1 group 1 {
c1.T2
c2.T2
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>for the packet specifiers, and this would have equivalent behavior.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Telemetry-Packets_Omitting-Channels">14.6.3. Omitting Channels</h4>
<div class="paragraph">
<p>By default, every telemetry channel in the topology must appear
in at least one telemetry packet.
For example, in the model shown above, if we comment out the definition
of packet <code>P2</code> and run the result through <code>fpp-check</code>, then an error will result,
because neither channel
<code>c1.T2</code> nor channel <code>c2.T2</code> appears in any packet.
The purpose of this behavior is to ensure that you don&#8217;t omit
any channels from the telemetry by mistake.</p>
</div>
<div class="paragraph">
<p>If you do want to omit channels from the telemetry packets,
then you can do so explicitly by writing the keyword <code>omit</code> and listing
those channels after the main specification of the packet set.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">passive component C {
telemetry port tlmOut
time get port timeGetOut
telemetry T1: U32
telemetry T2: F32
}
instance c1: C base id 0x100
instance c2: C base id 0x200
topology T {
instance c1
instance c2
@ Telemetry packet set PacketSet
telemetry packets PacketSet {
@ Packet P1
packet P1 group 0 {
c1.T1
c2.T1
c1.T1
}
} omit {
c1.T2
c2.T2
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The form of the list of omitted channels is the same as the
form of the list of channels in a telemetry packet.
It is an error for any channel to appear in a telemetry
packet and also to appear in the omitted list.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Telemetry-Packets_Specifying-Multiple-Telemetry-Packet-Sets">14.6.4. Specifying Multiple Telemetry Packet Sets</h4>
<div class="paragraph">
<p>You may specify more than one telemetry packet set in a topology.
Each telemetry packet set must have a distinct name.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">passive component C {
telemetry port tlmOut
time get port timeGetOut
telemetry T: U32
}
instance c1: C base id 0x100
instance c2: C base id 0x200
topology T {
instance c1
instance c2
@ Telemetry packet set PacketSet1
telemetry packets PacketSet1 {
@ Packet P
packet P1 group 0 {
c1.T
}
} omit {
c2.T
}
@ Telemetry packet set PacketSet2
telemetry packets PacketSet2 {
@ Packet P
packet P1 group 0 {
c2.T
}
} omit {
c1.T
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you run the F Prime ground data system, you can tell it which
telemetry packet set to use to decode the packets.</p>
</div>
</div>
<div class="sect3">
<h4 id="Defining-Topologies_Telemetry-Packets_Include-Specifiers">14.6.5. Include Specifiers</h4>
<div class="paragraph">
<p>When writing a telemetry packet set, you can
<a href="#Defining-Topologies_Include-Specifiers">include code
from another file</a> in the following places:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>You can include code inside a packet set specifier.
The code must contain packet specifiers.</p>
</li>
<li>
<p>You can include code inside a packet specifier.
The code must list telemetry channels.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">telemetry packets PacketSet {
@ Include some packets
include "packets.fppi"
packet P group 0 {
c1.T1
# Include some channels
include "channels.fppi"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The files that you include can themselves include code
from other files, if you wish.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Specifying-Models-as-Files">15. Specifying Models as Files</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The previous sections have explained the syntactic and semantic elements
of FPP models.
This section takes a more file-centric view:
it explains how to assemble a collection of elements specified in
several files into a model.</p>
</div>
<div class="paragraph">
<p>We discuss several tools for specifying and analyzing dependencies between
model files.
We focus on how to use the tools, and we summarize their most important
features.
We do not attempt to cover every feature of every tool.
For more comprehensive coverage, see
<a href="https://github.com/nasa/fpp/wiki/Tools">the FPP wiki</a>.</p>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Dividing-Models-into-Files">15.1. Dividing Models into Files</h3>
<div class="paragraph">
<p>FPP does not require any particular division of model
elements into files.
For example, there is no requirement that each
type definition reside in its own file.
Nor is there any requirement that the names of files correspond
to the names of the definitions they contain.</p>
</div>
<div class="paragraph">
<p>Of course you should try to adhere to good style when decomposing a large model
into many files.
For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Group related model elements into files, and name the files
according to the purpose of the grouping.</p>
</li>
<li>
<p>Choose meaningful module names, and group all files in a single module
in single directory (including its subdirectories).
In the F Prime distribution, the <code>Fw</code> and <code>Svc</code> directories
follow this pattern, where the C&#43;&#43; namespaces <code>Fw</code> and <code>Svc</code>
correspond to FPP modules.</p>
</li>
<li>
<p>Group files into modules and directories logically according to their function.</p>
<div class="ulist">
<ul>
<li>
<p>You can group files according to their role in the FPP model.
For example, group types separately from ports.</p>
</li>
<li>
<p>You can group files according to their role in the FSW.
For example, group framework files separately from application files.</p>
</li>
</ul>
</div>
</li>
<li>
<p>If the definition of a constant or type is logically part of a component,
then make the definition a member of the component.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>There is still the usual requirement that a syntactic unit must begin and end
in the same file.
For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Each type definition is a syntactic unit, so each type definition must begin
and end in the same file.</p>
</li>
<li>
<p>A module definition may span several syntactic units of the form
<code>module { &#8230;&#8203; }</code>,
so a module definition may span multiple files (with each unit of the form
<code>module { &#8230;&#8203; }</code> residing in a single file).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These rules are similar to the way that C&#43;&#43; requires a class definition
<code>class C { &#8230;&#8203; }</code> or a namespace block <code>namespace N { &#8230;&#8203; }</code> to reside in a
single file, but it allows the definition of a single namespace <code>N</code> to span
multiple blocks
<code>namespace N { &#8230;&#8203; }</code> that can be in different files.</p>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Include-Specifiers">15.2. Include Specifiers</h3>
<div class="paragraph">
<p>As part of an FPP model, you can write one or more <strong>include specifiers</strong>.
An include specifier is an instruction to include FPP source elements
from one file into another file.
Include specifiers may occur at the top level of a model,
inside a <a href="#Defining-Modules">module definition</a>,
inside a <a href="#Defining-Components">component definition</a>,
or inside a <a href="#Defining-Topologies">topology definition</a>.</p>
</div>
<div class="paragraph">
<p>The main purpose of include specifiers is to split up large syntactic units
into several files.
For example, a component definition may include a telemetry dictionary
from a separate file.</p>
</div>
<div class="paragraph">
<p>To write an include specifier, you write the keyword <code>include</code>
followed by string denoting a file path.
The path is relative to the file in which the include specifier appears.
By convention, included FPP files end in <code>.fppi</code> to distinguish
them from <code>.fpp</code> files that are directly analyzed and translated.</p>
</div>
<div class="paragraph">
<p>For example, suppose that the file <code>a.fppi</code> contains the definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>In a file <code>b.fppi</code> in the same directory, you could write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">include "a.fppi"
constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>After resolving the include specifier, the model is equivalent
to the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0
constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>To see this, do the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Create files <code>a.fppi</code> and <code>b.fpp</code> as described
above.</p>
</li>
<li>
<p>Run <code>fpp-format -i b.fpp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><code>fpp-format</code> is a tool for formatting FPP source files.
It also can expand include specifiers.
<code>fpp-format</code> is discussed further in the section on
<a href="#Analyzing-and-Translating-Models_Formatting-FPP-Source">formatting FPP source</a>.</p>
</div>
<div class="paragraph">
<p>As mentioned above, the path is relative to the directory
of the file containing the include specifier.
So if <code>a.fppi</code> is located in a subdirectory <code>A</code>, you could write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">include "A/a.fppi"
constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>And if <code>a.fppi</code> is located in the parent directory, you could write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">include "../a.fppi"
constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can write an include specifier inside a module.
In this case, any definitions in the included file are treated as occurring
inside the module.
For example, if <code>a.fppi</code> contains the definition <code>constant a = 0</code>,
then this source text</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M { include "a.fppi" }</code></pre>
</div>
</div>
<div class="paragraph">
<p>defines the constant <code>M.a</code>.
As an exercise, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo "module M { constant a = 0 }" &gt; a.fppi
% fpp-check
include "a.fppi"
constant b = M.a
^D
%</pre>
</div>
</div>
<div class="paragraph">
<p>The check should pass.</p>
</div>
<div class="paragraph">
<p>In any case, an included file must contain complete syntactic
units that may legally appear at the point where the include specifier appears.
For example, an included file may contain one or more constant
definitions or type definitions.
It may not contain a bare identifier <code>a</code>, as this is not a valid top-level
or module-level syntactic unit.
Nor is it valid to write an include specifier in a place where an identifier
like <code>a</code>
is expected.</p>
</div>
<div class="paragraph">
<p>For example, here is the result of a failed attempt to include
an identifier into a constant definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo a &gt; a.fppi
% fpp-check
module M { constant include "a.fppi" = 0 }
constant b = M.a
^D
fpp-check
stdin: 1.21
module M { constant include "a.fppi" = 0 }
^
error: identifier expected
%</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Dependencies">15.3. Dependencies</h3>
<div class="paragraph">
<p>Whenever a model spans two or more files, one file <em>F</em> may use
one or more definitions appearing in other files.
In order to analyze <em>F</em>, the tools must extract
the definitions from these other files, called the <strong>dependencies</strong> of <em>F</em>.</p>
</div>
<div class="paragraph">
<p>For example, suppose the file <code>a.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>And suppose the file <code>b.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you present both files to <code>fpp-check</code>, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check a.fpp b.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>the check will pass.
However, if you present just <code>b.fpp</code>, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check b.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>you will get an error stating that the symbol <code>a</code> is undefined. (Try it and
see.)
The error occurs because the definition of <code>a</code> is located in <code>a.fpp</code>,
which was not included in the input to the analysis.
In this case we say that <code>a.fpp</code> is a <strong>dependency</strong> of <code>b.fpp</code>.
In order to analyze a file <em>F</em> (for example, <code>b.fpp</code>), the analyzer
needs to be told where to find all the dependencies of <em>F</em> (for example,
<code>a.fpp</code>).</p>
</div>
<div class="paragraph">
<p>For simple models, we can manage the dependencies by hand, as we
did for the example above.
However, for even moderately complex models, this kind of hand management
becomes difficult.
Therefore FPP has a set of tools and features for automatic dependency
management.</p>
</div>
<div class="paragraph">
<p>In summary, dependency management in FPP works as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>You run a tool called <code>fpp-locate-defs</code> to generate <strong>location specifiers</strong>
for all the definitions <em>that could be used</em> in a set of files <em>F</em>.</p>
</li>
<li>
<p>You run a tool called <code>fpp-depend</code>, passing it the files <em>F</em>
and the location specifiers generated in step 1.
It emits a list of files containing definitions <em>that are actually used</em> in <em>F</em>
(i.e., the dependencies of <em>F</em>).</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>These steps may occur in separate phases of development.
For example:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You may run step 1 to locate all the type definitions
available for use in the model.</p>
</li>
<li>
<p>You may run step 2 to develop ports that depend on the types.
Typically you would run this step as part of a build process, e.g.,
the CMake build process included in the F Prime distribution.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Below we explain these steps in more detail.</p>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Location-Specifiers">15.4. Location Specifiers</h3>
<div class="paragraph">
<p>A location specifier is a unit of syntax in an FPP model.
It specifies the location of a definition used in the model.</p>
</div>
<div class="paragraph">
<p>Although it is possible to write location specifiers by hand,
you should usually not do so.
Instead, you should write definitions and let the tools discover their
locations, as described
in the section on <a href="#Specifying-Models-as-Files_Locating-Definitions">locating
definitions</a>.</p>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Syntax">15.4.1. Syntax</h4>
<div class="paragraph">
<p>In general, a location specifier consists of the keyword <code>locate</code>, a kind of
definition,
the name of a definition, and a string representing a file path.
For type and constant specifiers, there is also an optional <code>dictionary</code>
specifier, which we will describe
<a href="#Specifying-Models-as-Files_Location-Specifiers_Dictionary-Definitions">below</a>.</p>
</div>
<div class="paragraph">
<p>For example, to locate the definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>appearing in the file <code>a.fpp</code>, we would write</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Locating a constant definition
locate constant a at "a.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The kind of definition must be one of the following:</p>
</div>
<table id="location-specifier-kinds" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 3. Location Specifier Kinds</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Keyword</th>
<th class="tableblock halign-left valign-top">Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>component</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Components">component definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>constant</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Constants">constant definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>instance</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Component-Instances">component instance definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>interface</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-and-Using-Port-Interfaces_Defining-Port-Interfaces">port interface definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>port</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Ports">port definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>state</code> <code>machine</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-State-Machines">state machine definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>topology</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Topologies">topology definition</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>type</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A <a href="#Defining-Types">type</a> or <a href="#Defining-Enums">enum</a> definition</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>As a further example, to locate a type <code>T</code> in a file <code>T.fpp</code>, we would write the
following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Locating a type definition
locate type T at "T.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>To locate a port <code>P</code> in a file <code>P.fpp</code>, we write the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Locating a port definition
locate port P at "P.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>To locate an enum, we locate the type; the location of the enumerated
constants are then implied:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Locating an enum definition,
# including the enumerated constant definitions
locate type E at "E.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The other kinds operate similarly.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Path-Names">15.4.2. Path Names</h4>
<div class="paragraph">
<p>As with
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifiers</a>,
the path name in a location specifier <em>L</em> is relative to the
location of the file where <em>L</em> appears.
For example, suppose the file <code>b.fpp</code> appears in the file system in some
directory <em>D</em>.
Suppose also that <em>D</em> has a subdirectory <code>Constants</code>, <code>Constants</code> contains a
file <code>a.fpp</code>,
and <code>a.fpp</code> defines the constant <code>a</code>.
Then in <code>b.fpp</code> we could write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "Constants/a.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>If, instead of residing in a subdirectory, <code>a.fpp</code> were located one directory above
<code>b.fpp</code> in the file system, we could write this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "../a.fpp"</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Definition-Names">15.4.3. Definition Names</h4>
<div class="paragraph">
<p>The definition name appearing after the keyword <code>locate</code>
may be a qualified name.
For example, suppose the file <code>M.fpp</code> contains the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M { constant a = 0 }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then in file <code>b.fpp</code> we could write this:</p>
</div>
<div class="listingblock fpp">
<div class="content">
<pre class="prettyprint highlight"><code>locate constant M.a at "M.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Optionally, we may enclose the location specifier in the module <code>M</code>, like
this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M { locate constant a at "M.fpp" }</code></pre>
</div>
</div>
<div class="paragraph">
<p>A location specifier written inside a module this way has its definition name
implicitly qualified with the module name.
For example, the name <code>a</code> appearing in the example above is automatically
resolved to <code>M.a</code>.</p>
</div>
<div class="paragraph">
<p>Note that this rule is different than for other uses of definitions.
For example, when using the constant <code>M.a</code> in an expression inside module <code>M</code>,
you may spell the constant either <code>a</code> or <code>M.a</code>;
but when referring to the same constant <code>M.a</code> in a location specifier inside
module <code>M</code>, you must write <code>a</code> and not <code>M.a</code>.
(If you wrote <code>M.a</code>, it would be incorrectly resolved to <code>M.M.a</code>.)
The purpose of this rule is to facilitate dependency analysis,
which occurs before the analyzer has complete information about
definitions and their uses.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Included-Files">15.4.4. Included Files</h4>
<div class="paragraph">
<p>When you write a file that contains definitions and you
<a href="#Specifying-Models-as-Files_Include-Specifiers">include that file in another file</a>,
the location of each definition is the file where the definition is
included, not the file where the definition appears.
For example, suppose that file <code>a.fppi</code> contains the
definition <code>constant a = 0</code>,
and suppose that file <code>b.fpp</code> contains the include specifier <code>include "a.fppi"</code>.
When analyzing <code>b.fpp</code>, the location of the definition of the constant <code>a</code>
is <code>b.fpp</code>, not <code>a.fppi</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Dictionary-Definitions">15.4.5. Dictionary Definitions</h4>
<div class="paragraph">
<p>For type and constant specifiers only, if the definition being located
is a
<a href="#Dictionary-Definitions">dictionary definition</a>, then you must
write the keyword <code>dictionary</code> after the keyword <code>locate</code>
and before the definition kind.
For example, to locate the dictionary definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">dictionary constant b = 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>appearing in the file <code>b.fpp</code>, we would write</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp"># Locating a dictionary constant definition
locate dictionary constant b at "b.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>dictionary</code> keyword tells the analyzer that the definition is a dictionary
definition and so should be included in the dependency files of the model,
regardless of whether the definition is used in the model.</p>
</div>
<div class="paragraph">
<p>If a definition is a dictionary definition and the corresponding location
specifier does not specify <code>dictionary</code> (or vice versa), then the analyzer
will report an error.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Location-Specifiers_Repeated-Location-Specifiers">15.4.6. Repeated Location Specifiers</h4>
<div class="paragraph">
<p>An FPP model may contain any number of location specifiers for the same
definition, so long as the following conditions are met:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>All the specifiers must be consistent.
This means that all the specifiers for the same definition
provide the same location, and either they all specify <code>dictionary</code>
or none of them does.</p>
</li>
<li>
<p>All the specifiers must agree with the definition, if it exists
in the model.
This means that the location specifiers specify the location
of the definition, and the specifiers specify <code>dictionary</code>
if and only if the definition is a dictionary definition.</p>
</li>
</ol>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Locating-Definitions">15.5. Locating Definitions</h3>
<div class="paragraph">
<p>Given a collection of FPP source files <em>F</em>, you can generate location specifiers
for all the definitions in <em>F</em>.
The tool for doing this analysis is called <code>fpp-locate-defs</code>.
As example, you can run <code>fpp-locate-defs</code> to report the locations of all
the definitions in a subdirectory called <code>Constants</code> that contains constant
definitions for your model.
When analyzing other files that use the constants, you can use the location
specifiers to discover dependencies on individual files within <code>Constants</code>.</p>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Locating-Definitions_Running-fpp-locate-defs">15.5.1. Running fpp-locate-defs</h4>
<div class="paragraph">
<p>To locate definitions, do the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Collect all the FPP source files containing the definitions you want to
locate.
For example, run <code>find Constants -name '*.fpp'</code>.</p>
</li>
<li>
<p>Run <code>fpp-locate-defs</code> with the result of step 1 as the command-line
arguments.
The result will be a list of location specifiers.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, suppose the file <code>Constants/a.fpp</code> defines the constant <code>a</code>.
Running</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-locate-defs `find Constants -name '*.fpp'`</pre>
</div>
</div>
<div class="paragraph">
<p>generates the location specifier</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "Constants/a.fpp"</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Locating-Definitions_Location-Paths">15.5.2. Location Paths</h4>
<div class="paragraph">
<p>By default, the location path is relative to the current
directory.
To specify a different base directory, use the option <code>-d</code>.
For example, running</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-locate-defs -d Constants `find Constants -name '*.fpp'`</pre>
</div>
</div>
<div class="paragraph">
<p>generates the location specifier</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "a.fpp"</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Locating-Definitions_Included-Definitions">15.5.3. Included Definitions</h4>
<div class="paragraph">
<p>Consider the case where you write a definition in one file and
include that file in another file via an
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifier</a>.
For example, suppose file <code>Constants.fpp</code> looks like this:</p>
</div>
<div class="listingblock fpp">
<div class="content">
<pre class="prettyprint highlight"><code>module Constants {
constant a = 0
include "b.fppi"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Suppose <code>b.fppi</code> contains the definition <code>constant b = 1</code>.
If you run <code>find</code> on this directory as described above and provide
the output to <code>fpp-locate-defs</code>, then you will get the following output:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The definition of constant <code>a</code> is located at <code>Constants.fpp</code>.</p>
</li>
<li>
<p>The definition of constant <code>b</code> is also located at <code>Constants.fpp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For purposes of dependency analysis, this is what you want.
You want uses of <code>b</code> to depend on <code>Constants.fpp</code> (where the
definition
of <code>b</code> is included) rather than <code>b.fpp</code> (where the definition of <code>b</code> is
stated).</p>
</div>
<div class="paragraph">
<p>When running a <code>find</code> command to find files containing definitions,
you should exclude any files that are included in other files.
If your main FPP files end with <code>.fpp</code> and your included FPP files end with
<code>.fppi</code>, then running</p>
</div>
<div class="listingblock">
<div class="content">
<pre>find . -name '*.fpp'</pre>
</div>
</div>
<div class="paragraph">
<p>will pick up just the main files.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Computing-Dependencies">15.6. Computing Dependencies</h3>
<div class="paragraph">
<p>Given files <em>F</em> and location specifiers <em>L</em> that locate the definitions used in
<em>F</em>, you can
generate the dependencies of <em>F</em>.
The tool for doing this is called <code>fpp-depend</code>.</p>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Running-fpp-depend">15.6.1. Running fpp-depend</h4>
<div class="paragraph">
<p>To run <code>fpp-depend</code>, you pass it as input (1) files <em>F</em> that you want to
analyze
and (2) a superset of the location specifiers for the definitions used in that
code.
The tool extracts the location specifiers for the definitions used in <em>F</em>, resolves
them to absolute path names (the dependencies of <em>F</em>), and writes the
dependencies to standard output.</p>
</div>
<div class="paragraph">
<p>For example, suppose the file <code>a.fpp</code> contains the following
definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>Suppose the file <code>b.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant b = 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>Suppose the file <code>locations.fpp</code> contains the following location
specifiers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "a.fpp"
locate constant b at "b.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>And suppose the file <code>c.fpp</code> contains the following definition of <code>c</code>,
which uses the definition of <code>b</code> but not the definition of <code>a</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant c = b + 1</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then running <code>fpp-depend locations.fpp c.fpp</code> produces the output
<code>[path-prefix]/b.fpp</code>.
The dependency output contains absolute path names, which will vary from system
to system.
Here we represent the system-dependent part of the path as <code>[path-prefix]</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-depend locations.fpp c.fpp
[path-prefix]/b.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>As usual with FPP tools, you can provide input as a set of files
or on standard input.
So the following is equivalent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat locations.fpp c.fpp | fpp-depend
[path-prefix]/b.fpp</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Transitive-Dependencies">15.6.2. Transitive Dependencies</h4>
<div class="paragraph">
<p><code>fpp-depend</code> computes dependencies transitively.
This means that if <em>A</em> depends on <em>B</em> and <em>B</em>
depends on <em>C</em>, then <em>A</em> depends on <em>C</em>.</p>
</div>
<div class="paragraph">
<p>For example, suppose again that <code>locations.fpp</code>
contains the following location specifiers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">locate constant a at "a.fpp"
locate constant b at "b.fpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Suppose the file <code>a.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = 0</code></pre>
</div>
</div>
<div class="paragraph">
<p>Suppose the file <code>b.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant b = a</code></pre>
</div>
</div>
<div class="paragraph">
<p>And suppose that file <code>c.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant c = b</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that there is a direct dependency of <code>c.fpp</code> on <code>b.fpp</code>
and a transitive dependency of <code>c.fpp</code> on <code>a.fpp</code>.
The transitive dependency occurs because there is a direct dependency
of <code>c.fpp</code> on <code>b.fpp</code> and a direct dependency of <code>b.fpp</code> on <code>a.fpp</code>.</p>
</div>
<div class="paragraph">
<p>Running <code>fpp-depend</code> on <code>locations.fpp</code> and <code>c.fpp</code>
produces both dependencies:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-depend locations.fpp c.fpp
[path-prefix]/a.fpp
[path-prefix]/b.fpp</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Missing-Dependencies">15.6.3. Missing Dependencies</h4>
<div class="paragraph">
<p>Suppose we construct the files <code>locations.fpp</code> and <code>a.fpp</code>, <code>b.fpp</code>, and <code>c.fpp</code>
as described in the previous section, but then we temporarily remove <code>b.fpp</code>.
Then the following facts are true:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><code>fpp-depend</code> can see the direct dependency of <code>c.fpp</code> on <code>b.fpp</code>.</p>
</li>
<li>
<p><code>fpp-depend</code> can see that <code>b.fpp</code> does not exist.
In this case we say that <code>b.fpp</code> is a <strong>missing dependency</strong>.</p>
</li>
<li>
<p><code>fpp-depend</code> cannot see that <code>b.fpp</code> depends on <code>a.fpp</code> (that dependency
occurred in the missing file) and therefore it cannot see that
<code>c.fpp</code> depends on <code>a.fpp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>In this case, by default, <code>fpp-depend</code> does the best that it can:
it reports the dependency of <code>c.fpp</code> on <code>b.fpp</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-depend locations.fpp c.fpp
[path-prefix]/b.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>The philosophy behind <code>fpp-depend</code> is to be as permissive and enabling as
possible.
It doesn&#8217;t assume that something is wrong because a dependency is missing:
for example, that dependency could be created later, as part of a code-generation
step.</p>
</div>
<div class="paragraph">
<p>However, you may want to know about missing dependencies, either to issue
a warning or error because something really is wrong, or to identify files to
generate.
To record missing dependencies, use the <code>-m</code> option.
It takes as an argument the name of a file, and it writes missing dependencies
(if any)
to that file.</p>
</div>
<div class="paragraph">
<p>For example, the command</p>
</div>
<div class="listingblock">
<div class="content">
<pre>fpp-depend -m missing.txt locations.fpp c.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>writes the missing dependency <code>[path-prefix]/b.fpp</code> to <code>missing.txt</code> in
addition to writing
the dependency <code>[path-prefix]/b.fpp</code> to standard output.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Included-Files">15.6.4. Included Files</h4>
<div class="paragraph">
<p>Suppose file <code>a.fpp</code> contains the
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifier</a>
<code>include "b.fppi"</code>.
Then there are two options for computing the dependencies of <code>a.fpp</code>:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><code>a.fpp</code> does not depend on <code>b.fppi</code>.</p>
</li>
<li>
<p><code>a.fpp</code> does depend on <code>b.fppi</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Option 1 is what you want for assembling the input
to FPP analysis and translation tools such as <code>fpp-check</code>.
In this case, when analyzing <code>a.fpp</code>, the tool will resolve the include
specifier and include the contents of <code>b.fppi</code>. So <code>b.fppi</code> should
not be included as a separate input to the analysis.</p>
</div>
<div class="paragraph">
<p>On the other hand, suppose you are constructing a list of dependencies
for a build system such as the F Prime CMake system.
In this case, the build system doesn&#8217;t know anything about FPP include specifiers.
However, it needs to know that <code>a.fpp</code> does depend on <code>b.fppi</code> in the sense that
if <code>b.fppi</code> is modified, then <code>a.fpp</code> should be analyzed or translated again.
So in this case we want option 2.</p>
</div>
<div class="paragraph">
<p>By default, <code>fpp-depend</code> provides option 1:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo 'include "b.fppi"' &gt; a.fpp
% rm -f b.fppi
% touch b.fppi
% fpp-depend a.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>To get option 2, use the <code>-i</code> option to <code>fpp-depend</code>.
It takes as an argument the name of a file, and it writes the included dependencies
(if any) to that file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo 'include "b.fppi"' &gt; a.fpp
% rm -f b.fppi
% touch b.fppi
% fpp-depend -i included.txt a.fpp
% cat included.txt
[path-prefix]/b.fppi</pre>
</div>
</div>
<div class="paragraph">
<p>In practice, you usually run <code>fpp-depend</code> with the <code>-i</code> <em>file</em> option
enabled.
Then option 1 corresponds to the output of the tool, and option 2 corresponds
to the output plus the contents of <em>file</em>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Dependencies-Between-Build-Modules">15.6.5. Dependencies Between Build Modules</h4>
<div class="paragraph">
<p>As discussed
<a href="#Specifying-Models-as-Files_Computing-Dependencies_Transitive-Dependencies">above</a>, the standard output of <code>fpp-depend</code> reports transitive dependencies.
This is ordinarily what you want (a) for computing the input to an FPP
analysis tool and (b) for managing dependencies between files in a build.
For example, suppose that <code>a.fpp</code> depends on <code>b.fpp</code> and <code>b.fpp</code> depends on <code>c.fpp</code>.
When running analysis or code generation on <code>a.fpp</code>, you will need to import
<code>b.fpp</code> and <code>c.fpp</code> (see the
<a href="#Specifying-Models-as-Files_Locating-Uses">next section</a>
for an example).
Further, if you have a build rule for translating <code>a.fpp</code> to C&#43;&#43;, then you probably want to
re-run that rule if <code>c.fpp</code> changes.
Therefore you need to report a dependency of <code>a.fpp</code> on <code>c.fpp</code>.</p>
</div>
<div class="paragraph">
<p>However, suppose that your build system divides the FPP files into groups
of files called <strong>build modules</strong>, and it manages dependencies between
the modules.
This is how the F Prime CMake system works.
In this case, assuming there is no direct dependency from <code>a.fpp</code> to <code>c.fpp</code>,
you may <em>not</em> want to report a dependency from <code>a.fpp</code> to <code>c.fpp</code>
to the build system:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If <code>a.fpp</code> and <code>c.fpp</code> are in the same build module, then they
are in the same node of the dependency graph.
So there is no dependency to manage.</p>
</li>
<li>
<p>Otherwise, it suffices to report the file dependencies (a) from <code>a.fpp</code>
to <code>b.fpp</code> and (b) from <code>b.fpp</code> to <code>c.fpp</code>.
We can let the build system infer (a) the direct dependency from the module
containing <code>a.fpp</code> to the module containing <code>b.fpp</code>; (b) the direct
dependency from the module
containing <code>b.fpp</code> to the module containing <code>c.fpp</code>; and (c)
the transitive dependency from the module containing <code>a.fpp</code>
to the module containing <code>c.fpp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>To compute direct dependencies, run <code>fpp-depend</code> with the option
<code>-d</code> <em>file</em>.
The tool will write a list of direct dependencies to <em>file</em>.
Because direct dependencies are build dependencies,
any
<a href="#Specifying-Models-as-Files_Computing-Dependencies_Included-Files">included files</a>
will appear in the list.
For this purpose, an included file is (a) any file included by an
input file to <code>fpp-depend</code>; or (b) any file included
by such a file, and so forth.</p>
</div>
<div class="paragraph">
<p>When setting up a build based on build modules, you will typically
use <code>fpp-depend</code> as follows, for each module <em>M</em> in the build:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Let <em>S</em> be the list of source files in <em>M</em>.</p>
</li>
<li>
<p>Run <code>fpp-depend -m missing.txt -d direct.txt</code> <em>S</em> and use the
output as follows:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The standard output reports the FPP source files to import
when running FPP analysis tools on the module.</p>
</li>
<li>
<p><code>missing.txt</code> reports missing dependencies.</p>
</li>
<li>
<p><code>direct.txt</code> reports direct dependencies.
Use those to construct module dependencies for the build system.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>You can also use the <code>-g</code> option to identify generated files;
we discuss this option
<a href="#Analyzing-and-Translating-Models_Identifying-Generated-Files">below</a>.
Note that we do not use the <code>-i</code> option to <code>fpp-depend</code>, because the relevant
included files are already present in <code>direct.txt</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Computing-Dependencies_Framework-Dependencies">15.6.6. Framework Dependencies</h4>
<div class="paragraph">
<p>Certain FPP constructs imply dependencies on parts of the F Prime framework
that may not be available on all platforms.
For example, use of a
<a href="#Defining-Components_Port-Instances_Basic-Port-Instances">guarded input port</a>
requires that an operating system provides a mutex lock.</p>
</div>
<div class="paragraph">
<p>To report framework dependencies, run <code>fpp-depend</code> with the option
<code>-f</code> <em>file</em>, where <em>file</em> is the name of an output file.
The currently recognized framework dependencies are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Fw_Comp</code> if the FPP model defines a passive component.</p>
</li>
<li>
<p><code>Fw_CompQueued</code> if the model defines a queued or active component.</p>
</li>
<li>
<p><code>Os</code> if the model defines a queued or active component or
uses a guarded input port specifier.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Each dependency corresponds to a build module (i.e., a
statically compiled library) of the F Prime framework.
<code>fpp-depend</code> writes the dependencies in the order that they must
be provided to the linker.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Locating-Uses">15.7. Locating Uses</h3>
<div class="paragraph">
<p>Given a collection of files <em>F</em> and their dependencies <em>D</em>, you can generate
the locations of the definitions appearing in <em>D</em> and used in <em>F</em>.
This information is not necessary for doing analysis and translation&#8201;&#8212;&#8201;for
that it is sufficient to know the file dependencies <em>D</em>.
However, by reporting dependencies on individual definitions,
this analysis provides an additional level of detail that may be helpful.</p>
</div>
<div class="paragraph">
<p>The tool for doing this analysis is called <code>fpp-locate-uses</code>.
As an example, you can run <code>fpp-locate-uses</code> to report the locations of all the
type definitions used in a port definition.</p>
</div>
<div class="paragraph">
<p>To locate uses, run <code>fpp-locate-uses -i</code> <em>D</em> <em>F</em>, where <em>D</em> is a comma-separated
list and <em>F</em> is a space-separated list.
The <code>-i</code> option stands for <em>import</em>: it says that the files <em>D</em> are to be read
for their
definitions, but not to be included in the results of the analysis.</p>
</div>
<div class="paragraph">
<p>For example, suppose <code>a.fpp</code> defines constant <code>a</code>, <code>b.fpp</code> defines constant
<code>b</code>,
and <code>c.fpp</code> uses <code>a</code> but not <code>b</code>.
Then <code>fpp-locate-uses -i a.fpp,b.fpp c.fpp</code> generates the output <code>locate a at
"a.fpp"</code></p>
</div>
<div class="paragraph">
<p>Note that unlike in the case of
<a href="#Specifying-Models-as-Files_Computing-Dependencies">dependency analysis</a>,
the inputs <em>D</em> and <em>F</em> to <code>fpp-locate-uses</code> must form a complete model.
There must be no name used in <em>D</em> or in <em>F</em> that is not defined somewhere in
<em>D</em> or in <em>F</em>.
If <em>D</em> is the output of running <code>fpp-depend</code> on <em>F</em>, and there are no
<a href="#Specifying-Models-as-Files_Computing-Dependencies_Missing-Dependencies">missing dependencies</a>,
then this property should hold.</p>
</div>
<div class="paragraph">
<p>With <code>fpp-locate-uses</code>, you can automatically derive the equivalent of the
<code>include</code>
declarations that you would normally write by hand when programming in C&#43;&#43;.
For example, suppose you have specified a port <em>P</em> that uses a type <em>T</em>.
To bring <em>P</em> into a C&#43;&#43; translation context, you would write an <code>include</code>
directive that
includes <em>T</em> into <em>P</em>. In FPP you don&#8217;t do this.
Instead, you can do the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Run <code>fpp-locate-defs</code> to generate location specifiers <em>L</em> for all the type
definitions.
You can do this as needed, or you can do it once and check it in as part of
the module that defines the types.</p>
</li>
<li>
<p>Run <code>fpp-depend</code> on <em>L</em> and <em>P</em> to generate the dependencies <em>D</em> of <em>P</em>.</p>
</li>
<li>
<p>Run <code>fpp-locate-uses -i</code> <em>D</em> <em>P</em>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The result is a location specifier that gives the location of <em>T</em>.
If you wish, you can check the result in as part of the source code that
defines <em>P</em>.
Doing this provide as a kind of &#8220;import statement,&#8221; if that is desired
to make the dependencies explicit in the code.
Or you can just use the procedure given above to generate the "import
statement"
whenever desired, and see the dependencies that way.</p>
</div>
<div class="paragraph">
<p>As with <code>fpp-locate-defs</code>, you can use <code>-d</code> to specify a base directory
for the location specifiers.</p>
</div>
</div>
<div class="sect2">
<h3 id="Specifying-Models-as-Files_Path-Name-Aliases">15.8. Path Name Aliases</h3>
<div class="paragraph">
<p>Because FPP associates locations with symbols, and the locations
are path names, care is required when using path names that are
aliases of other path names, via symbolic links or hard links.
There are two issues to consider:
relative paths and unique locations.</p>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Path-Name-Aliases_Relative-Paths-and-Symbolic-Links">15.8.1. Relative Paths and Symbolic Links</h4>
<div class="paragraph">
<p>A <strong>relative path</strong> is a path that does not start with a slash and is
relative to the current directory path, which is
set by the environment in which an FPP tool is run.
For example, the command sequence</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="bash">% cd /home/user/dir
% fpp-check file.fpp</code></pre>
</div>
</div>
<div class="paragraph">
<p>sets the current directory path to <code>/home/user/dir</code> and then runs
<code>fpp-check file.fpp</code>.
In this case, the relative path <code>file.fpp</code> is resolved to
<code>/home/user/dir/file.fpp</code>.
An <strong>absolute path</strong> is a path that starts with a slash and specifies
a complete path from the root of the file system, e.g.,
<code>/home/user/dir/file.fpp</code>.</p>
</div>
<div class="paragraph">
<p>Because FPP is implemented in Scala, relative paths are resolved by
the Java Virtual Machine (JVM).
When the current directory path contains a symbolic link,
this resolution may not work in the way that you expect.
For example, suppose the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>D</em> is an absolute path to a directory.
<em>D</em> is a &#8220;real&#8221; path, i.e., none of the path elements in <em>D</em> is a symbolic
link to a directory.</p>
</li>
<li>
<p><em>S</em> is an absolute path in which one or more of the path elements is a symbolic
link to a directory.
After resolving all symbolic links, <em>S</em> points to <em>D</em>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Suppose that <em>D</em> contains a file <code>file.fpp</code>, and that the
current directory path is <em>D</em>.
In this case, when you run an FPP tool with <code>file.fpp</code> as input,
any symbols defined in <code>file.fpp</code> will have location
<em>D</em> <code>/file.fpp</code>, as expected.</p>
</div>
<div class="paragraph">
<p>Now suppose that the current directory path is <em>S</em>.
In this case, when you run an FPP tool with <code>file.fpp</code> as input,
the symbols defined in <code>file.fpp</code> again have location <em>D</em> <code>/file.fpp</code>,
when you might expect them to have location <em>S</em> <code>/file.fpp</code>.
This is because the JVM resolves all symbolic links before computing
relative path names.</p>
</div>
<div class="paragraph">
<p>This behavior can cause problems when using the <code>-p</code> (path prefix)
option with FPP code generation tools, as described in the section on
<a href="#Analyzing-and-Translating-Models">analyzing and translating models</a>.
See that section for details, and for suggested workarounds.</p>
</div>
</div>
<div class="sect3">
<h4 id="Specifying-Models-as-Files_Path-Name-Aliases_Unique-Locations">15.8.2. Unique Locations</h4>
<div class="paragraph">
<p>The FPP analyzers assume that each symbol <em>s</em> has
a unique path defining the location of the source file where
<em>s</em> is defined.
If paths contain names that are aliased via symbolic links or hard links, then
this may not be true:
for example, <em>P<sub>1</sub></em> and <em>P<sub>2</sub></em> may be syntactically different
absolute paths that represent the same physical location in the file system.
In this case it may be possible for the tools to associate two different locations
with the same FPP symbol definition.</p>
</div>
<div class="paragraph">
<p>You must ensure that this doesn&#8217;t happen.
If you present the same file <em>F</em> to the FPP tools several times,
for example to locate definitions and to compute dependencies,
you must ensure that the path describing <em>F</em> is the same each
time, after resolving relative paths as described above.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Analyzing-and-Translating-Models">16. Analyzing and Translating Models</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The previous section explained how to specify an FPP model
as a collection of files:
how to divide a model into source files and how to compute the
dependencies of one or more files on other files.
This section explains the next step: how to perform analysis and
translation on part or all of an FPP model, after specifying
the model and computing its dependencies.</p>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Checking-Models">16.1. Checking Models</h3>
<div class="paragraph">
<p>It is often useful to check a model for correctness, without
doing any translation.
The tool for checking models is called <code>fpp-check</code>.
If you provide one or more files as arguments, <code>fpp-check</code>
will attempt to read those files.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-check file1.fpp file2.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>If there are no arguments, then <code>fpp-check</code> reads from standard input.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat file1.fpp file2.fpp | fpp-check</pre>
</div>
</div>
<div class="paragraph">
<p>If you run <code>fpp-check</code> with no arguments on the command line,
it will block and wait for standard input.
This is useful for interactive sessions, where you want
to type simple model text into the console and immediately check it.
<code>fpp-check</code> will keep reading input until (1) it encounters a parse error (more
on this below); or (2) you terminate the input with control-D (which must be
the first character in a line); or (3)
you terminate the program with control-C.</p>
</div>
<div class="paragraph">
<p>For larger models, the usual procedure for running <code>fpp-check</code> is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Identify one or more files <em>F</em> that you want to check.</p>
</li>
<li>
<p><a href="#Specifying-Models-as-Files_Computing-Dependencies">Compute the dependencies</a> <em>D</em> of <em>F</em>.</p>
</li>
<li>
<p>Run <code>fpp-check</code> <em>D</em> <em>F</em>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>All the files <em>D</em> and all the files <em>F</em> are specified as file arguments,
separated by spaces.</p>
</div>
<div class="paragraph">
<p>When you run <code>fpp-check</code>, the following occurs:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The tool parses all the input files, recursively resolving
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifiers</a> as it goes.
If there are any parse errors or any problems resolving include files (for
example, a missing file), it prints an error message to standard error and
halts with nonzero status.</p>
</li>
<li>
<p>If parsing succeeds, then the tool runs semantic analysis.
If everything checks out, the tool silently returns zero status.
Otherwise it prints an error message to standard error and
halts with nonzero status.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Checking for unconnected port instances:</strong>
It is often useful to check for port instances that appear
in a topology but that have no connections.
For example, the following is a useful procedure for adding component instances
and connections to a topology:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Add the component instances.
In general this will introduce new port instances,
which will initially be unconnected.</p>
</li>
<li>
<p>Check for unconnected port instances.</p>
</li>
<li>
<p>Add some or all of the connections identified
in step 2.</p>
</li>
<li>
<p>Rerun steps 2 and 3 until there are no more
missing connections, or you are certain that the
missing connections are valid for your design.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>To check for unconnected port instances (step 2 in the procedure above),
run <code>fpp-check</code> with the option <code>-u</code> <em>file</em>, where <em>file</em> is
the name of an output file.
<code>fpp-check</code> will write the names of all unconnected port instances
to the file.
For this purpose, a port instance array is considered unconnected
if none of its port numbers are connected.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code>% fpp-check -u unconnected.txt
port P
passive component C {
sync input port pIn: P
output port pOut: [2] P
}
instance c: C base id 0x100
topology T1 {
instance c
}
topology T2 {
instance c
connections C {
c.pOut -&gt; c.pIn
}
}
^D
% cat unconnected.txt
Topology T1:
c.pIn
c.pOut</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, component instance <code>c</code> has the following port instances:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Two output port instances <code>c.pOut[0]</code> and <code>c.pOut[1]</code>.</p>
</li>
<li>
<p>One input port instance <code>c.pIn</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Topology <code>T1</code> uses instance <code>c</code> and does not connect any port number of
<code>c.pOut</code> or <code>c.pIn</code>.
So the output written to <code>unconnected.txt</code> reports that fact.
On the other hand, in topology <code>T2</code>, both <code>c.pOut</code> and <code>c.pIn</code>
are considered connected (so not reported as unconnected)
even though <code>c.Out</code> has two ports and only one of them is connected.</p>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus">16.2. Generating C Plus Plus</h3>
<div class="paragraph">
<p>This section describes how to generate C&#43;&#43; from FPP.</p>
</div>
<div class="paragraph">
<p><strong>Tool name:</strong> The tool for translating FPP to C&#43;&#43; is called
<code>fpp-to-cpp</code>.</p>
</div>
<div class="paragraph">
<p><strong>Procedure:</strong>
The usual procedure for running <code>fpp-to-cpp</code> is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Identify one or more files <em>F</em> that you want to translate.</p>
</li>
<li>
<p><a href="#Specifying-Models-as-Files_Computing-Dependencies">Compute the dependencies</a> <em>D</em> of <em>F</em>.</p>
</li>
<li>
<p>If <em>D</em> is empty, then run <code>fpp-to-cpp</code> <em>F</em>.</p>
</li>
<li>
<p>Otherwise run <code>fpp-to-cpp -i</code> <em>D<sub>1</sub></em> <code>,</code> &#8230;&#8203; <code>,</code> <em>D<sub>n</sub></em> <em>F</em>, where <em>D<sub>i</sub></em> are the
names of the dependencies.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, suppose you want to generate C&#43;&#43; for the definitions in <code>c.fpp</code>,
If <code>c.fpp</code> has no dependencies, then run</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-to-cpp c.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>On the other hand, if <code>c.fpp</code> depends on <code>a.fpp</code> and <code>b.fpp</code>, then run</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-to-cpp -i a.fpp,b.fpp c.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>Notice that you provide the dependencies as a comma-separated list of
arguments to the option <code>-i</code>.
<code>-i</code> stands for <em>import</em>.
This option tells the tool that you want to read the files in <em>D</em> for their symbols,
but you don&#8217;t want to translate them.
Only the files <em>F</em> provided as arguments are translated.</p>
</div>
<div class="paragraph">
<p><strong>Tool behavior:</strong> When you run <code>fpp-to-cpp</code>, the following occurs:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The tool runs the same analysis
<a href="#Analyzing-and-Translating-Models_Checking-Models">as for <code>fpp-check</code></a>.
If there is any problem, the tool prints an error message to
standard error and halts with nonzero status.</p>
</li>
<li>
<p>If the analysis succeeds, then the tool generates C&#43;&#43;files, one
for each definition appearing in <em>F</em>, with names as shown in the table above.
The files are written to the current directory.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Standard input:</strong> Instead of providing named files as arguments,
you can provide FPP source on standard input, as described
for <a href="#Analyzing-and-Translating-Models_Checking-Models"><code>fpp-check</code></a>.</p>
</div>
<div class="paragraph">
<p><strong>C&#43;&#43; file names:</strong> The table <a href="#cpp-file-names">C&#43;&#43; File Names</a> shows how FPP definitions are
translated to C&#43;&#43; files.</p>
</div>
<table id="cpp-file-names" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 4. C&#43;&#43; File Names</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">FPP Definition</th>
<th class="tableblock halign-left valign-top">C&#43;&#43; Files</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Constants</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FppConstantsAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Array <em>A</em> outside any component</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>A</em> <code>ArrayAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Array <em>A</em> in component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code><em></code> _A</em> <code>ArrayAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enum <em>E</em> outside any component</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>E</em> <code>EnumAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enum <em>E</em> in component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code><em></code> _E</em> <code>EnumAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">State machine <em>M</em> outside any component</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>M</em> <code>StateMachineAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">State machine <em>M</em> in component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code><em></code> _M</em> <code>StateMachineAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Struct <em>S</em> outside any component</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>S</em> <code>SerializableAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Struct <em>S</em> in component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code><em></code> _S</em> <code>SerializableAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Alias type <em>A</em> outside any component</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>A</em> <code>AliasAc.{hpp,h,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Alias type <em>A</em> in component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code><em></code> _A</em> <code>AliasAc.{hpp,h,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Port <em>P</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>P</em> <code>PortAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Component <em>C</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>C</em> <code>ComponentAc.{hpp,cpp}</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Topology <em>T</em></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><em>T</em> <code>TopologyAc.{hpp,cpp}</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>For example, consider the FPP array definition</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] U32</code></pre>
</div>
</div>
<div class="paragraph">
<p>Outside of any component definition, this definition is translated to
a C&#43;&#43; class with name <code>A</code> defined in a files <code>AArrayAc.hpp</code>
and <code>AArray.cpp</code>.
Inside the definition of component <code>C</code>, it is translated to
a class with name <code>C_A</code> defined in the files <code>C_AArrayAc.hpp</code>
and <code>C_AArray.cpp</code>.
In either case the C&#43;&#43; namespace is given by the enclosing
FPP modules, if any.
For example, the following code</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
array A = [3] U32
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>generates an array class <code>M::A</code> in files <code>AArrayAc.hpp</code>
and <code>AArrayAc.cpp</code>.</p>
</div>
<div class="paragraph">
<p><strong>Headers for alias types:</strong>
For alias types, a C&#43;&#43; header with suffix <code>.hpp</code> is always generated.
A C header with suffix <code>.h</code> is also generated if the alias type
is C-compatible.
This means (1) the underlying
type is a signed or unsigned integer type or a floating-point type,
and (2) the alias type definition does not appear in an FPP module
or component, and (3) if the alias type refers to another alias
type <em>T</em>, then <em>T</em> is C-compatible.
For example, the following alias types are C-compatible
and cause <code>.h</code> headers to be generated:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T1 = U32
type T2 = T1</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following alias types are not C-compatible, so
they do not cause <code>.h</code> headers to be generated:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">module M {
type T1 = U32 # Definition is in a module
}
type T2 = M.T1 # M.T1 is not C-compatible
array A = [3] U32
type T3 = A # A is not C-compatible</code></pre>
</div>
</div>
<div class="paragraph">
<p>When both headers are generated, you should include the <code>.h</code> header in your
C programs and the <code>.hpp</code> header in your C&#43;&#43; programs.</p>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions">16.2.1. Constant Definitions</h4>
<div class="paragraph">
<p><code>fpp-to-cpp</code> extracts <a href="#Defining-Constants">constant definitions</a>
from the source files <em>F</em>.
It generates files <code>FppConstantsAc.hpp</code> and <code>FppConstantsAc.cpp</code>
containing C&#43;&#43; translations of the constants.
By including and/or linking against these files,
you can use constants defined in the FPP model
in your FSW implementation code.</p>
</div>
<div class="paragraph">
<p>To keep things simple, only numeric, string, and Boolean constants are
translated;
struct and array constants are ignored.
For example, the following constant is not translated, because
it is an array:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a = [ 1, 2, 3 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>To translate array constants, you must expand them to values
that are translated, like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">constant a0 = 1
constant a1 = 2
constant a2 = 3
constant a = [ a0, a1, a2 ]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Constants are translated as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Integer constants become enumeration constants.</p>
</li>
<li>
<p>Floating-point constants become <code>const</code> floating-point variables.</p>
</li>
<li>
<p><code>bool</code> point constants become <code>const bool</code> variables.</p>
</li>
<li>
<p><code>string</code> constants become <code>const char* const</code> variables initialized
with string literals.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As an example, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-to-cpp
@ Constant a
constant a = 1
@ Constant b
constant b = 2.0
@ Constant c
constant c = true
@ Constant d
constant d = "abcd"
^D</pre>
</div>
</div>
<div class="paragraph">
<p>You should see files <code>FppConstantsAc.hpp</code> and <code>FppConstantsAc.cpp</code>
in the current directory.
Examine them to confirm your understanding of how the translation
works.
Notice how the FPP annotations are translated to comments.
(We also remarked on this in the section on
<a href="#Writing-Comments-and-Annotations_Annotations">writing annotations</a>.)</p>
</div>
<div class="paragraph">
<p><strong>Constants defined inside components:</strong>
As noted in the section on
<a href="#Defining-Components_Constants-Types-Enums-and-State-Machines">defining components</a>,
when you define a constant <code>c</code> inside a component <code>C</code>,
the name of the corresponding constant in the generated C&#43;&#43;
code is <code>C_c</code>.
As an example, run the following code through <code>fpp-to-cpp</code>
and examine the results:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">passive component C {
constant c = 0
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Generated header paths:</strong>
When one FPP definition <code>A</code> refers to another definition <code>B</code>,
the generated C&#43;&#43; file for <code>A</code> contains a directive to
include the generated header file for <code>B</code>.
The tool constructs the import path from the
<a href="#Specifying-Models-as-Files_Locating-Definitions">location</a> of the
definition of <code>B</code>.</p>
</div>
<div class="paragraph">
<p>For example, suppose the file <code>[path prefix]/A/A.fpp</code> contains the following
definition, where <code>[path prefix]</code> represents the path prefix of directory
<code>A</code> starting from the root of the file system:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">array A = [3] B</code></pre>
</div>
</div>
<div class="paragraph">
<p>And suppose the file <code>[path prefix]/B/B.fpp</code> contains the following definition:</p>
</div>
<div class="listingblock fpp">
<div class="content">
<pre class="prettyprint highlight"><code>array B = [3] U32</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you run this command in directory <code>[path prefix]/A</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-to-cpp -i ../B/B.fpp A.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>then in that directory the tool will generate a file <code>AArrayAc.hpp</code> containing
the following line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">#include "[path prefix]/B/BArrayAc.hpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Removing path prefixes:</strong>
Usually when generating C&#43;&#43; we don&#8217;t want to include the system-specific path
prefix.
Instead, we want the path to be specified relative to some known place, for
example
the root of the F Prime repository or a project repository.</p>
</div>
<div class="paragraph">
<p>To remove the prefix <em>prefix</em> from generated paths, use the option
<code>-p</code> <em>prefix</em> .
To continue the previous example, running</p>
</div>
<div class="listingblock">
<div class="content">
<pre>fpp-to-cpp -i ../B/B.fpp -p [path prefix] A.fpp</pre>
</div>
</div>
<div class="paragraph">
<p>generates a file <code>AArrayAc.hpp</code> containing the line</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">#include "B/BArrayAc.hpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that the path prefix <code>[path prefix]/</code> has been removed.</p>
</div>
<div class="paragraph">
<p>To specify multiple prefixes, separate them with commas:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>fpp-to-cpp -p prefix1,prefix2, ...</pre>
</div>
</div>
<div class="paragraph">
<p>For each generated path, the tool will delete the longest prefix
that matches a prefix in the list.</p>
</div>
<div class="paragraph">
<p>As discussed in the section on
<a href="#Specifying-Models-as-Files_Path-Name-Aliases_Relative-Paths-and-Symbolic-Links">relative paths and symbolic links</a>,
when a file name is relative to a path <em>S</em> that includes symbolic links,
the associated location is relative to the directory <em>D</em> pointed to by <em>S</em>.
In this case, providing <em>S</em> as an argument to <code>-p</code> will not work as expected.
To work around this issue, you can do one of the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Provide both <em>D</em> and <em>S</em> as arguments to <code>-p</code>.</p>
</li>
<li>
<p>Use absolute paths when presenting files to FPP code generation tools
with the <code>-p</code> option.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>The include guard prefix:</strong> By default, the include guard
for <code>FppConstantsAc.hpp</code> is <em>guard-prefix</em> <code>_FppConstantsAc_HPP</code>,
where <em>guard-prefix</em> is the absolute path of the current
directory, after replacing non-identifier characters with underscores.
For example, if the current directory is <code>/home/user</code>, then
the guard prefix is <code>_home_user</code>, and the include guard is
<code>_home_user_FppConstantsAc_HPP</code>.</p>
</div>
<div class="paragraph">
<p>The <code>-p</code> option, if present, is applied to the guard
prefix.
For example, if you run <code>fpp-to-cpp -p $PWD &#8230;&#8203;</code> then
the guard prefix will be empty.
In this case, the guard is <code>FppConstantsAc_HPP</code>.</p>
</div>
<div class="paragraph">
<p>If you wish to use a different prefix entirely, use the option
<code>-g</code> <em>guard-prefix</em>.
For example, if you run <code>fpp-to-cpp -g Commands &#8230;&#8203;</code>,
then the include guard will be <code>Commands_FppConstantsAc_HPP</code>.</p>
</div>
<div class="paragraph">
<p><strong>More options:</strong> The following additional options are available
when running <code>fpp-to-cpp</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>-d</code> <em>dir</em> : Use <em>dir</em> instead of the current directory as
the output directory for writing files.
For example,</p>
<div class="listingblock">
<div class="content">
<pre>fpp-to-cpp -d cpp ...</pre>
</div>
</div>
<div class="paragraph">
<p>writes output files
to the directory <code>cpp</code> (which must already exist).</p>
</div>
</li>
<li>
<p><code>-n</code> <em>file</em> : Write the names of the generated C&#43;&#43; files
to <em>file</em>.
This is useful for collecting autocoder build dependencies.</p>
</li>
<li>
<p><code>-s</code> <em>size</em> : Specify a default string size.
For example,</p>
<div class="listingblock">
<div class="content">
<pre>fpp-to-cpp -s 40 ...</pre>
</div>
</div>
<div class="paragraph">
<p>FPP allows string types with no specified size.
When generating code we need to provide a default size
to use when FPP doesn&#8217;t specify the size.
If you don&#8217;t specify the <code>-s</code> option, then the tool uses
an automatic default of 80.</p>
</div>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Types-Ports-State-Machines-and-Components">16.2.2. Types, Ports, State Machines, and Components</h4>
<div class="paragraph">
<p><strong>Generating code:</strong>
To generate code for type, port, state machine, and component definitions, you
run <code>fpp-to-cpp</code> in the same way as for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions">constant definitions</a>, with one exception:
the translator ignores the <code>-g</code> option, because the include guard comes from
the qualified name of the definition.
For example, a component whose qualified name in FPP is <code>A.B.C</code>
uses the name <code>A_B_CComponentAc_HPP</code> in its include guard.</p>
</div>
<div class="paragraph">
<p><strong>Alias types:</strong>
The generated code for an <a href="#Defining-Types_Alias-Type-Definitions">alias type
definition</a> is either a C-style <code>typedef</code> (in a <code>.h</code> file) or a C&#43;&#43;11-style
<code>using</code> alias (in a <code>.hpp</code> file). The generated code for an alias to an FPP
<code>string</code> type is always an alias to the F Prime type <code>Fw::String</code>; the size in
the <code>string</code> type is ignored when generating the alias.
For example, the following alias type definitions
all generate aliases to <code>Fw::String</code>, either directly or indirectly:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">type T1 = string size 40 # Generates an alias to Fw::String
type T2 = string size 80 # Generates an alias to Fw::String
type T3 = T2 # Generates an alias to T2, which is an alias to Fw::String</code></pre>
</div>
</div>
<div class="paragraph">
<p>When reporting generated files for alias types via the <code>-n</code> option,
<code>fpp-to-cpp</code> reports only <code>.hpp</code> files, not <code>.h</code> files.
This is to keep the analysis simple, so that it can be run when
<a href="#Analyzing-and-Translating-Models_Identifying-Generated-Files_Using-fpp-depend">computing dependencies</a>.
In a future version of FPP, we may revise the analysis strategy
and report the generation of <code>.h</code> files as well.</p>
</div>
<div class="paragraph">
<p><strong>Using the generated code:</strong>
Once you generate C&#43;&#43; code for these definitions, you can use it to
write a flight software implementation.
The <a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F
User Manual</a> explains how to do this.</p>
</div>
<div class="paragraph">
<p>For more information about the generated code for data products,
for state machines, and for state machine instances, see the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F
Prime design documentation</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Component-Implementation-and-Unit-Test-Code">16.2.3. Component Implementation and Unit Test Code</h4>
<div class="paragraph">
<p><code>fpp-to-cpp</code> has options <code>-t</code> and <code>-u</code> for generating component &#8220;templates&#8221;
or
partial implementations and for generating unit test code.
Here we cover the mechanics of using these options.
For more information on implementing and testing components in F Prime, see
the <a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/">F Prime User Manual</a>.</p>
</div>
<div class="paragraph">
<p><strong>Generating implementation templates:</strong>
When you run <code>fpp-to-cpp</code> with option <code>-t</code> and without option <code>-u</code>,
it generates a partial implementation for
each component definition <em>C</em> in the input.
The generated files are called <em>C</em> <code>.template.hpp</code> and <em>C</em> <code>.template.cpp</code>.
You can fill in the blanks in these files to provide the concrete
implementation of <em>C</em>.</p>
</div>
<div class="paragraph">
<p><strong>Generating unit test harness code:</strong>
When you run <code>fpp-to-cpp</code> with option <code>-u</code> and without option <code>-t</code>,
it generates support code for testing each component definition <em>C</em>
in the input.
The unit test support code resides in the following files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>C</em> <code>TesterBase.hpp</code> and <em>C</em> <code>TesterBase.cpp</code>.
These files define a class <em>C</em> <code>TesterBase</code>.
This class contains helper code for unit testing <em>C</em>,
for example an input port and history corresponding to each output port of <em>C</em>.</p>
</li>
<li>
<p><em>C</em> <code>GTestBase.hpp</code> and <em>C</em> <code>GTestBase.cpp</code>.
These files define a class <em>C</em> <code>GTestBase</code> derived
from <em>C</em>.
This class uses the Google Test framework to provide additional helper
code.
It is factored into a separate class so that you can use <em>C</em> <code>TesterBase</code>
without <em>C</em> <code>GTestBase</code> if you wish.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>Generating unit test templates:</strong>
When you run <code>fpp-to-cpp</code> with both the <code>-u</code> and the <code>-t</code> options,
it generates a template or partial implementation of the unit tests
for each component <em>C</em> in the input.
The generated code consists of the following files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>C</em> <code>Tester.hpp</code> and <em>C</em> <code>Tester.cpp</code>.
These files partially define a class <em>C</em> <code>Tester</code> that is derived from <em>C</em> <code>GTestBase</code>.
You can fill in the partial definition to provide unit tests for <em>C</em>.
If you are not using Google Test, then you can modify
<em>C</em> <code>Tester</code> so that it is derived from <em>C</em> <code>TesterBase</code>.</p>
</li>
<li>
<p><em>C</em> <code>TesterHelpers.cpp</code>. This file provides helper functions called by
the functions defined in <code>Tester.cpp</code>.
These functions are factored into a separate file so that you
can redefine them if you wish.
To redefine them, omit <em>C</em> <code>TesterHelpers.cpp</code> from your F Prime
unit test build.</p>
</li>
<li>
<p><em>C</em> <code>TestMain.cpp</code>. This file provides a minimal main function for unit
testing, including a sample test.
You can add your top-level test code to this file.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>Unit test auto helpers:</strong>
When running <code>fpp-to-cpp</code> with the <code>-u</code> option, you can also specify the <code>-a</code>
or <strong>unit test auto helpers</strong> option.
This option moves the generation of the file <em>C</em> <code>TesterHelpers.cpp</code>
from the unit test template code to the unit test harness code.
Specifically:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>When you run <code>fpp-to-cpp -a -u</code>, the file <em>C</em> <code>TesterHelpers.cpp</code>
is generated.</p>
</li>
<li>
<p>When you run <code>fpp-to-cpp -a -t -u</code>, the file <em>C</em> <code>TesterHelpers.cpp</code>
is not generated.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>-a</code> option supports a feature of the F Prime CMake build system called
<code>UT_AUTO_HELPERS</code>. With this feature enabled, you don&#8217;t have to manage the
file <em>C</em> <code>TesterHelpers.cpp</code> as part of your unit test source files; the
build system does it for you.</p>
</div>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Topology-Definitions">16.2.4. Topology Definitions</h4>
<div class="paragraph">
<p><code>fpp-to-cpp</code> also extracts <a href="#Defining-Topologies">topology definitions</a>
from the source files.
For each topology <em>T</em> defined in the source files, <code>fpp-to-cpp</code>
writes files <em>T</em> <code>TopologyAc.hpp</code> and <em>T</em> <code>TopologyAc.cpp</code>.
These files define two public functions:
<code>setup</code> for setting up the topology, and
<code>teardown</code>, for tearing down the topology.
The function definitions come from the definition of <em>T</em> and
from the
<a href="#Defining-Component-Instances_Init-Specifiers">init specifiers</a>
for the component instances used in <em>T</em>.
You can call these functions from a handwritten <code>main</code>
function.
We will explain how to write this <code>main</code> function in the
section on
<a href="#Writing-C-Plus-Plus-Implementations_Implementing-Deployments">implementing deployments</a>.</p>
</div>
<div class="paragraph">
<p>As an example, you can do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>On the command line, run <code>fpp-to-cpp -p $PWD</code>.</p>
</li>
<li>
<p>Copy the text of the <a href="#Defining-Topologies_A-Simple-Example">simple topology example</a> and paste it into the terminal.</p>
</li>
<li>
<p>Press return, control-D, and return.</p>
</li>
<li>
<p>Examine the generated files <code>SimpleTopologyAc.hpp</code>
and <code>SimpleTopologyAc.cpp</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You can examine the files <code>RefTopologyAc.hpp</code> and <code>RefTopologyAc.cpp</code>
in the F Prime repository.
Currently these files are checked in at <code>Ref/Top</code>.
Once we have integrated FPP with CMake, these files will be auto-generated
by CMake and will be located at <code>Ref/build-fprime-automatic-native/F-Prime/Ref/Top</code>.</p>
</div>
<div class="paragraph">
<p><strong>Options:</strong>
When translating topologies,
the <code>-d</code>, <code>-n</code>, and <code>-p</code> options work in the same way as for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions">translating constant definitions</a>.
The <code>-g</code> option is ignored, because
the include guard prefix comes from the name of the topology.</p>
</div>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Compiling-the-Generated-Code">16.2.5. Compiling the Generated Code</h4>
<div class="paragraph">
<p>The generated C&#43;&#43; is intended to compile with the following gcc
and clang compiler flags:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>--std=c++11
-Wall
-Wconversion
-Wdouble-promotion
-Werror
-Wextra
-Wno-unused-parameter
-Wold-style-cast
-Wshadow
-pedantic</pre>
</div>
</div>
<div class="paragraph">
<p>When using clang, the following flags must also be set:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>-Wno-vla-extension</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Formatting-FPP-Source">16.3. Formatting FPP Source</h3>
<div class="paragraph">
<p>The tool <code>fpp-format</code> accepts FPP source files as input
and rewrites them as formatted output.
You can use this tool to put your source files into
a standard form.</p>
</div>
<div class="paragraph">
<p>For example, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-format
array A = [3] U32 default [ 1, 2, 3 ]
^D
array A = [3] U32 default [
1
2
3
]</pre>
</div>
</div>
<div class="paragraph">
<p><code>fpp-format</code> has reformatted the default value so that each array
element is on its own line.</p>
</div>
<div class="paragraph">
<p>By default, <code>fpp-format</code> does not resolve include specifiers.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo 'constant a = 0' &gt; a.fppi
% fpp-format
include "a.fppi"
^D
include "a.fppi"</pre>
</div>
</div>
<div class="paragraph">
<p>The <code>-i</code> option causes <code>fpp-format</code> to resolve include specifiers.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% echo 'constant a = 0' &gt; a.fpp
% fpp-format -i
include "a.fppi"
^D
constant a = 0</pre>
</div>
</div>
<div class="paragraph">
<p><code>fpp-format</code> has one big limitation: it goes through
the FPP parser, so it deletes all
<a href="#Writing-Comments-and-Annotations_Comments">comments</a>
from the program
(<a href="#Writing-Comments-and-Annotations_Annotations">annotations</a>
are preserved).
To preserve comments on their own lines that precede
annotatable elements, you can run this script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="bash">#!/bin/sh
sed 's/^\( *\)#/\1@ #/' | fpp-format $@ | sed 's/^\( *\)@ #/\1#/'</code></pre>
</div>
</div>
<div class="paragraph">
<p>It converts comments to annotations, runs <code>fpp-format</code>, and converts the
annotations back to comments.</p>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Visualizing-Topologies">16.4. Visualizing Topologies</h3>
<div class="paragraph">
<p>FPP provides a tool called <code>fpp-to-layout</code> for generating files
that you can use to visualize topologies.
Given a topology <em>T</em>, this tool generates a directory containing
the <strong>layout input files</strong> for <em>T</em>.
There is one file for each <a href="#Defining-Topologies_Connection-Graphs">connection
graph</a> in <em>T</em>.
The files are designed to work with a tool called <code>fprime-layout</code>, which
we describe below.</p>
</div>
<div class="paragraph">
<p><strong>Procedure:</strong>
The usual procedure for running <code>fpp-to-layout</code> is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Identify one or more files <em>F</em> containing topology definitions
for which you wish to generate layout input files.</p>
</li>
<li>
<p><a href="#Specifying-Models-as-Files_Computing-Dependencies">Compute the dependencies</a> <em>D</em> of <em>F</em>.</p>
</li>
<li>
<p>If <em>D</em> is empty, then run <code>fpp-to-layout</code> <em>F</em>.</p>
</li>
<li>
<p>Otherwise run <code>fpp-to-layout -i</code> <em>D<sub>1</sub></em> <code>,</code> &#8230;&#8203; <code>,</code> <em>D<sub>n</sub></em> <em>F</em>, where <em>D<sub>i</sub></em> are the
names of the dependencies.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Except for the tool name, this procedure is identical to the one given for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus">generating C&#43;&#43;</a>.</p>
</div>
<div class="paragraph">
<p><strong>Input:</strong> You can provide input to <code>fpp-to-layout</code>
either through named files or through standard input.</p>
</div>
<div class="paragraph">
<p><strong>Tool behavior:</strong>
For each topology <em>T</em> defined in the input files <em>F</em>, <code>fpp-to-layout</code> does
the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If a directory named <em>T</em> <code>Layout</code> exists in the current directory, then
remove it.</p>
</li>
<li>
<p>Create a directory named <em>T</em> <code>Layout</code> in the current directory.</p>
</li>
<li>
<p>In the directory created in step 2, write one layout input file
for each of the connection graphs in <em>T</em>.
The
<a href="https://github.com/fprime-community/fprime-layout/wiki/Topology-Input"><code>fprime-layout</code> wiki</a>
describes the file format.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Options:</strong>
<code>fpp-to-layout</code> provides an option <code>-d</code> for selecting the current directory
to use when writing layout input files.
This option works in the same way as for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions"><code>fpp-to-cpp</code></a>.
See the <a href="https://github.com/nasa/fpp/wiki/fpp-to-layout">FPP wiki</a> for details.</p>
</div>
<div class="paragraph">
<p><strong>Producing visualizations:</strong>
Once you have generated layout input files, you can use a
companion tool called <code>fprime-layout</code> to read the files and produce a
<strong>topology visualization</strong>, i.e., a graphical rendering of the topology in which
the component instances are shapes, the ports are smaller shapes, and the
connections are arrows between the ports.
Topology visualization is an important part of the FPP work flow:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It provides a graphical representation of the instances and
connections in each connection graph.
This graphical representation is a useful complement to the
textual representation provided by the FPP source.</p>
</li>
<li>
<p>It makes explicit information that is only implicit in the
FPP source, e.g., the auto-generated port numbers of the connections and
the auto-generated connections of the pattern graph specifiers.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Using <code>fprime-layout</code>, you can do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Render the connection graphs as EPS (Encapsulated PostScript),
generating one EPS file for each connection graph.</p>
</li>
<li>
<p>Generate a set of layouts, one for each layout input file,
and view the layouts in a browser.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>See the <a href="https://github.com/fprime-community/fprime-layout"><code>fprime-layout</code>
repository</a> for more details.</p>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Generating-Ground-Dictionaries">16.5. Generating Ground Dictionaries</h3>
<div class="paragraph">
<p>A <strong>ground dictionary</strong> specifies all the commands,
events, telemetry, parameters, and data products in a FSW
application.
Typically a ground data system (GDS), such as the F Prime GDS,
uses the ground dictionary to provide the operational
interface to the application.
The interface typically includes real-time commanding;
real-time display of events and telemetry; logging of
commands, events, and telemetry; uplink and downlink of files, including data
products; and decoding of data products.
This section explains how to generate ground dictionaries from
FPP models.</p>
</div>
<div class="paragraph">
<p><strong>Tool name:</strong> The tool for generating ground dictionaries is called
<code>fpp-to-dict</code>.</p>
</div>
<div class="paragraph">
<p><strong>Procedure:</strong>
The usual procedure for running <code>fpp-to-dict</code> is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Identify one or more files <em>F</em> that you want to translate.</p>
</li>
<li>
<p><a href="#Specifying-Models-as-Files_Computing-Dependencies">Compute the dependencies</a> <em>D</em> of <em>F</em>.</p>
</li>
<li>
<p>If <em>D</em> is empty, then run <code>fpp-to-dict</code> <em>F</em>.</p>
</li>
<li>
<p>Otherwise run <code>fpp-to-dict -i</code> <em>D<sub>1</sub></em> <code>,</code> &#8230;&#8203; <code>,</code> <em>D<sub>n</sub></em> <em>F</em>, where <em>D<sub>i</sub></em> are the
names of the dependencies.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Except for the tool name, this procedure is identical to the one given for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus">generating C&#43;&#43;</a>.</p>
</div>
<div class="paragraph">
<p><strong>Input:</strong> As with the tools described above, you can provide input to
<code>fpp-to-dict</code>
either through named files or through standard input.</p>
</div>
<div class="paragraph">
<p><strong>Tool behavior:</strong>
For each topology <em>T</em> defined in the input files <em>F</em>, <code>fpp-to-dict</code> writes a
file
<em>T</em> <code>TopologyDictionary.json</code>.
The dictionary is specified in JavaScript Object Notation (JSON) format.
The JSON format is specified in the
<a href="https://fprime.jpl.nasa.gov/devel/docs/reference/fpp-json-dict/">F Prime design
documentation</a>.</p>
</div>
<div class="paragraph">
<p>Here is a common use case:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The input files <em>F</em> define a single topology <em>T</em>.
<em>T</em> describes all the component instances and connections in a FSW
application, and the generated dictionary <em>T</em> <code>TopologyDictionary.json</code>
is the dictionary for the application.</p>
</li>
<li>
<p>If <em>T</em> imports subtopologies, then those subtopologies are defined
in the dependency files <em>D</em>.
That way the subtopologies are part of the model, but no dictionaries
are generated for them.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>F Prime configuration:</strong>
When you run <code>fpp-to-dict</code> on an FPP model, the model must define the following
types:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>FwChanIdType</code></p>
</li>
<li>
<p><code>FwEventIdType</code></p>
</li>
<li>
<p><code>FwOpcodeType</code></p>
</li>
<li>
<p><code>FwPacketDescriptorType</code></p>
</li>
<li>
<p><code>FwTlmPacketizeIdType</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These types are required by the F Prime GDS, so they are included in the
dictionary.
Each of these types must be an alias of an integer type.
Typically you specify these types as part of F Prime configuration,
in the file <code>config/FpConfig.fpp</code>.
See the
<a href="https://fprime.jpl.nasa.gov/devel/docs/user-manual/framework/configuring-fprime/">F
Prime documentation</a> for details.</p>
</div>
<div class="paragraph">
<p><strong>Options:</strong>
<code>fpp-to-dict</code> provides the following options:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <code>-d</code> and <code>-s</code> options work in the same way as for
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Constant-Definitions"><code>fpp-to-cpp</code></a>.</p>
</li>
<li>
<p>You can use the <code>-f</code> and <code>-p</code> options to specify a framework version
and project version for the dictionary.
That way the dictionary is stamped with information that connects
it to the FSW version for which it is intended to be used.</p>
</li>
<li>
<p>You can use the <code>-l</code> option to specify library versions used
in the project.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>See the <a href="https://github.com/nasa/fpp/wiki/fpp-to-dict">FPP wiki</a> for details.</p>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Identifying-Generated-Files">16.6. Identifying Generated Files</h3>
<div class="paragraph">
<p>As discussed in the
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus">section on generating
C&#43;&#43;</a>,
the <code>-n</code> option
of <code>fpp-to-cpp</code> lets you collect the names of
files generated from an FPP model as those files are generated.
However, sometimes you need to know the names of the generated
files up front.
For example, the CMake build tool writes out a Makefile rule
for every generated file, and it does this as an initial step
before generating any files.
There are two ways to collect the names of generated files:
using <code>fpp-filenames</code> and using <code>fpp-depend</code>.</p>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Identifying-Generated-Files_Using-fpp-filenames">16.6.1. Using fpp-filenames</h4>
<div class="paragraph">
<p>Like <code>fpp-check</code>, <code>fpp-filenames</code> reads the files
provided as command-line arguments if there are any;
otherwise it reads from standard input.
The FPP source presented to <code>fpp-filenames</code> need not be a complete
model (i.e., it may contain undefined symbols).
When run with no options, tool parses the FPP source that you give it.
It identifies all definitions in the source that would cause
C&#43;&#43; files to be generated when running
<code>fpp-to-cpp</code> or <code>fpp-to-dict</code>.
Then it writes the names of those files to standard output.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames
array A = [3] U32
^D
AArrayAc.cpp
AArrayAc.hpp</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames
constant a = 0
^D
FppConstantsAc.cpp
FppConstantsAc.hpp</pre>
</div>
</div>
<div class="paragraph">
<p>You can run <code>fpp-filenames</code> with the <code>-u</code> option, with the <code>-t</code> option,
or with both options.
In these cases <code>fpp-filenames</code> writes out the names of
the files that would be generated by running <code>fpp-to-cpp</code> with the
corresponding options.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames -t
array A = [3] U32
passive component C {}
^D
C.template.cpp
C.template.hpp</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames -u
array A = [3] U32
passive component C {}
^D
array A = [3] U32
passive component C {}
AArrayAc.cpp
AArrayAc.hpp
CComponentAc.cpp
CComponentAc.hpp
CGTestBase.cpp
CGTestBase.hpp
CTesterBase.cpp
CTesterBase.hpp</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames -u -t
array A = [3] U32
passive component C {}
^D
CTestMain.cpp
CTester.cpp
CTester.hpp
CTesterHelpers.cpp</pre>
</div>
</div>
<div class="paragraph">
<p>You can also also run <code>fpp-filenames</code> with the <code>-a</code> option.
Again the results correspond to running <code>fpp-to-cpp</code> with this option.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-filenames -a -u -t
array A = [3] U32
passive component C {}
^D
CTestMain.cpp
CTester.cpp
CTester.hpp</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="Analyzing-and-Translating-Models_Identifying-Generated-Files_Using-fpp-depend">16.6.2. Using fpp-depend</h4>
<div class="paragraph">
<p>Alternatively, you can use
<a href="#Specifying-Models-as-Files_Computing-Dependencies"><code>fpp-depend</code></a>
to write out the names of generated files during dependency analysis.
The output is the same as for <code>fpp-filenames</code>, but this way you can
run one tool (<code>fpp-depend</code>) instead of two (<code>fpp-depend</code> and
<code>fpp-filenames</code>).
Running one tool may help your build go faster.</p>
</div>
<div class="paragraph">
<p>To write out the names of generated files, you can use the following
options provided by <code>fpp-depend</code>:</p>
</div>
<div class="paragraph">
<p><code>-a</code>: Report the generation of files with
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Component-Implementation-and-Unit-Test-Code">unit
test auto helpers enabled</a>.</p>
</div>
<div class="paragraph">
<p><code>-g</code> <em>file</em>: Write the names of the generated autocode files
to the file <em>file</em>.</p>
</div>
<div class="paragraph">
<p><code>-u</code> <em>file</em>: Write the names of the unit test support code
files to <em>file</em>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-depend -g generated.txt -u ut-generated.txt
array A = [3] U32
passive component C {}
^D
% cat generated.txt
AArrayAc.cpp
AArrayAc.hpp
CComponentAc.cpp
CComponentAc.hpp
% cat ut-generated.txt
CGTestBase.cpp
CGTestBase.hpp
CTesterBase.cpp
CTesterBase.hpp</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-depend -a -g generated.txt -u ut-generated.txt
array A = [3] U32
passive component C {}
^D
% cat generated.txt
AArrayAc.cpp
AArrayAc.hpp
CComponentAc.cpp
CComponentAc.hpp
% cat ut-generated.txt
CGTestBase.cpp
CGTestBase.hpp
CTesterBase.cpp
CTesterBase.hpp
CTesterHelpers.cpp</pre>
</div>
</div>
<div class="paragraph">
<p><code>fpp-depend</code> does not have an option for writing out the names of
implementation template files, since those file names are not
needed during dependency analysis.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Generating-JSON-Models">16.7. Generating JSON Models</h3>
<div class="paragraph">
<p>FPP provides a tool called <code>fpp-to-json</code> for converting FPP models to
JavaScript Object Notation (JSON) format.
Using this tool, you can import FPP models into programs written
in any language that has a library for reading JSON, e.g., JavaScript,
TypeScript, or Python.
Generating and importing JSON may be convenient if you need to develop
a simple analysis or translation tool for FPP models, and you don&#8217;t
want to develop the tool in Scala.
For more complex tools, we recommend that you develop in Scala
against the FPP compiler data structures.</p>
</div>
<div class="paragraph">
<p><strong>Procedure:</strong>
The usual procedure for running <code>fpp-to-json</code> is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Identify one or more files <em>F</em> that you want to analyze.</p>
</li>
<li>
<p><a href="#Specifying-Models-as-Files_Computing-Dependencies">Compute the dependencies</a> <em>D</em> of <em>F</em>.</p>
</li>
<li>
<p>Run <code>fpp-to-json</code> <em>D</em> <em>F</em>. Note that <em>D</em> may be empty.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>If you are using <code>fpp-to-json</code> with the <code>-s</code> option (see below),
then you can run <code>fpp-to-json</code> <em>F</em>, without computing dependencies.</p>
</div>
<div class="paragraph">
<p><strong>Tool behavior:</strong> When you run <code>fpp-to-json</code>, the tool checks the
syntax and semantics of the source model, reporting any errors that occur.
If everything checks out, it generates three files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>fpp-ast.json</code>: The abstract syntax tree (AST).
This is a tree data structure that represents the source syntax.
It contains AST nodes, each of which has a unique identifier.</p>
</li>
<li>
<p><code>fpp-loc-map.json</code>: The location map.
This object is a map from AST node IDs to the source
locations (file, line number, and column number)
of the corresponding AST nodes.</p>
</li>
<li>
<p><code>fpp-analysis.json</code>: The Analysis data structure.
This object contains semantic information
inferred from the source model, e.g., the types of all the
expressions and the constant values of all the numeric
expressions.
Only output data is included in the JSON; temporary
data structures used during the analysis algorithm are
omitted.
For more information on the Analysis data structure,
see the
<a href="https://github.com/nasa/fpp/wiki/Analysis-Data-Structure">FPP wiki</a>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>JSON format:</strong>
To understand this subsection, you need to know a little
bit about case classes in Scala.
For a primer, see
<a href="https://github.com/nasa/fpp/wiki/Pure-Functional-Programming-in-Scala#use-case-classes-for-pattern-matching">this wiki page</a>.</p>
</div>
<div class="paragraph">
<p>The JSON translation uses a Scala library called
<a href="https://circe.github.io/circe/">Circe</a>.
In general the translation follows a set of standard rules, so the
output format can be easily inferred from the types of the data structures
in the FPP source code:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A Scala case class <code>C</code> is translated as follows, unless
it extends a sealed trait (see below).
A value <code>v</code> of type <code>C</code> becomes
a JSON dictionary with the field names as keys and the field
values as their values.
For example a value <code>C(1,"hello")</code> of type <code>case class C(n: Int, s: String)</code>
becomes a JSON value <code>{ "n": 1, "s": "String" }</code>.</p>
</li>
<li>
<p>A Scala case class <code>C</code> that extends a sealed trait <code>T</code> represents a
named variant of type <code>T</code>.
In this case a value <code>v</code> of type <code>C</code> is wrapped in a dictionary with one
key (the variant name <code>C</code>) and one value (the value <code>v</code>).
For example, a value <code>C(1)</code> of type <code>case class C(n: Int) extends T</code>
becomes a JSON value <code>{ "C" : { "n" : 1 } }</code>, while a value
<code>D("hello")</code> of type <code>case class D(s: String) extends T</code>
becomes a JSON value <code>{ "D" : { "s" : "hello" } }</code>.
In this way each variant is labeled with the variant name.</p>
</li>
<li>
<p>A Scala list becomes a JSON array, and a Scala map becomes
a JSON dictionary.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>There are a few exceptions, either because the standard translation
does not work, or because we need special behavior for important
cases:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>We streamline the translation of the Scala Option type, translating
<code>Some(v)</code> as <code>{ "Some" : v }</code> and <code>None</code> as <code>"None"</code>.</p>
</li>
<li>
<p>In the AST, we translate
the type AstNode as if it were a variant type, i.e., we translate
<code>AstNode([data], [id])</code> to <code>"AstNode" : { "data" : [data], "id" : [id] } }</code>.
The <code>AstNode</code> keys identify the AstNode objects.</p>
</li>
<li>
<p>In the AST, to reduce clutter we skip over the <code>node</code>
field of module, component, and topology member lists.
This field is an artifact of the way the Scala code is written;
deleting it does not lose information.</p>
</li>
<li>
<p>In the Analysis data structure, to avoid repetition,
we translate AstNode values as <code>{ "astNodeId" : [node id] }</code>,
eliminating the data field of the node.
We also omit annotations from annotated AST nodes.
The data fields and the annotations can be looked up in the AST,
by searching for the node ID.</p>
</li>
<li>
<p>When translating an FPP symbol (i.e., a reference to a definition),
we provide the information in the
Symbol trait (the node ID and the unqualified name).
All symbols extend this trait.
We omit the AST node information stored in the concrete symbol.
This information can be looked up with the AST node ID.</p>
</li>
<li>
<p>When translating a component instance value, we replace
the component stored in the value with the corresponding
AST node ID.</p>
</li>
<li>
<p>When the keys of a Scala map cannot easily be
converted to strings, we convert the map to a list
of pairs, represented as an array of JSON arrays.
For example, this is how we translate the PortNumberMap
in the Analysis data structure, which maps Connection objects to integers.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><strong>Options:</strong> The following options are available
when running <code>fpp-to-json</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>-d</code> <em>dir</em> : Similar to the corresponding option of
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus"><code>fpp-to-cpp</code></a>.</p>
</li>
<li>
<p><code>-s</code>: Analyze syntax only:
With this option, <code>fpp-to-json</code> generates the AST and the
location map only; it doesn&#8217;t generate the Analysis data structure.
Because semantic analysis is not run, you don&#8217;t have to present
a complete or semantically correct FPP model to the tool.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="Analyzing-and-Translating-Models_Translating-Older-XML-to-FPP">16.8. Translating Older XML to FPP</h3>
<div class="paragraph">
<p>Previous versions of F Prime used XML to represent model
elements such as components and ports.
The FPP tool suite provides a capability to translate this
older format to FPP.
Its purpose is to address the following case:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>You have an older F Prime model that was developed in XML.</p>
</li>
<li>
<p>You wish to translate the model to FPP in order to use FPP as the source
language going forward.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The XML-to-FPP translation is designed to do most of the work in translating an
XML model into FPP.
As discussed below, some manual effort will still be required,
because the FPP and XML representations are not identical.
The good news is that this is a one-time effort: you can do it once
and use the FPP version thereafter.</p>
</div>
<div class="paragraph">
<p><strong>Tool name:</strong> The tool for translating XML to FPP is called
<code>fpp-from-xml</code>.</p>
</div>
<div class="paragraph">
<p><strong>Tool behavior:</strong>
Unlike the tools described above, <code>fpp-from-xml</code> does not read
from standard input.
To use it, you must name one or more XML files on the command line.
The reason is that the XML parsing library used by the tool requires
named files.
The tool reads the XML files you name, translates them, and
writes the result to standard output.</p>
</div>
<div class="paragraph">
<p>As an example, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; SSerializable.xml
&lt;serializable name="S"&gt;
&lt;members&gt;
&lt;member name="x" type="U32"&gt;
&lt;/member&gt;
&lt;member name="y" type="F32"&gt;
&lt;/member&gt;
&lt;/members&gt;
&lt;/serializable&gt;
^D
% fpp-from-xml SSerializableAi.xml
struct S {
x: U32
y: F32
}</pre>
</div>
</div>
<div class="paragraph">
<p>(The formula <code>cat &gt;</code> <em>file</em> lets us enter input to
the console and have it written to <em>file</em>.)</p>
</div>
<div class="paragraph">
<p><strong>Default values:</strong>
There are two issues to note in connection with translating default
values.</p>
</div>
<div class="paragraph">
<p>First, in FPP, every definition has a default value, but
the default value need not be given explicitly:
if you provide no explicit default value, then an implicit default is used.
By contrast, in F Prime XML, (1) you <em>must</em> supply default values for array
elements, and (2) you <em>may</em> supply default values for struct members
or enumerations.
To keep the translation simple, if default values are present in the XML
representation, then <code>fpp-from-xml</code> translates them to explicit values,
even if they could be made implicit.</p>
</div>
<div class="paragraph">
<p>Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; AArrayAi.xml
&lt;array name="A"&gt;
&lt;type&gt;U32&lt;/type&gt;
&lt;size&gt;3&lt;/size&gt;
&lt;format&gt;%u&lt;/format&gt;
&lt;default&gt;
&lt;value&gt;0&lt;/value&gt;
&lt;value&gt;0&lt;/value&gt;
&lt;value&gt;0&lt;/value&gt;
&lt;/default&gt;
&lt;/array&gt;
^D
% fpp-from-xml AArrayAi.xml
array A = [3] U32 default [
0
0
0
]</pre>
</div>
</div>
<div class="paragraph">
<p>Notice that the implicit default value <code>[ 0, 0, 0 ]</code> becomes
explicit when translating to XML and back to FPP.</p>
</div>
<div class="paragraph">
<p>Second, to keep the translation simple, only literal numeric values,
literal string values, literal Boolean values, and C&#43;&#43; qualified identifiers
(e.g., <code>a</code> or <code>A::B</code>) are translated.
Other values (e.g., values specified with C&#43;&#43; constructor calls), are not translated.
The reason is that the types of these values cannot be easily inferred from the
XML representation.
When a default value is not translated, the translator inserts an annotation
identifying what was not translated, so that you can do the translation
yourself.</p>
</div>
<div class="paragraph">
<p>For example, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; AArrayAi.xml
&lt;array name="A"&gt;
&lt;include_header&gt;T.hpp&lt;/include_header&gt;
&lt;type&gt;T&lt;/type&gt;
&lt;size&gt;3&lt;/size&gt;
&lt;format&gt;%s&lt;/format&gt;
&lt;default&gt;
&lt;value&gt;T()&lt;/value&gt;
&lt;value&gt;T()&lt;/value&gt;
&lt;value&gt;T()&lt;/value&gt;
&lt;/default&gt;
&lt;/array&gt;
^D
% fpp-from-xml AArrayAi.xml
@ FPP from XML: could not translate array value [ T(), T(), T() ]
array A = [3] T</pre>
</div>
</div>
<div class="paragraph">
<p>The tool cannot translate the value <code>T()</code>.
So it adds an annotation stating that.
In this case, <code>T()</code> is the default value associated with the
abstract type <code>T</code>, so using the implicit default is correct.
So in this case, just delete the annotation.</p>
</div>
<div class="paragraph">
<p>Here is another example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; BArrayAi.xml
&lt;array name="B"&gt;
&lt;import_array_type&gt;AArrayAi.xml&lt;/import_array_type&gt;
&lt;type&gt;A&lt;/type&gt;
&lt;size&gt;2&lt;/size&gt;
&lt;format&gt;%s&lt;/format&gt;
&lt;default&gt;
&lt;value&gt;A(1, 2)&lt;/value&gt;
&lt;value&gt;A(3, 4)&lt;/value&gt;
&lt;/default&gt;
&lt;/array&gt;
^D
% fpp-from-xml BArrayAi.xml
@ FPP from XML: could not translate array value [ A(1, 2), A(3, 4) ]
array B = [2] A</pre>
</div>
</div>
<div class="paragraph">
<p>Here the XML representation of the array values <code>[ 1, 2 ]</code> and <code>[ 3, 4 ]</code>
uses the C&#43;&#43; constructor calls <code>A(1, 2)</code> and <code>A(3, 4)</code>.
When translating <code>BArrayAi.xml</code>, <code>fpp-from-xml</code> doesn&#8217;t know how to translate
those values, because it doesn&#8217;t have any information about the type <code>A</code>.
So it omits the FPP default array value and reports the XML default element
values in the annotation.
That way, you can manually construct a default value in FPP.</p>
</div>
<div class="paragraph">
<p><strong>Inline enum definitions:</strong>
The following F Prime XML formats may include inline
enum definitions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>In the Serializable XML format,
enumerations may appear as member types.</p>
</li>
<li>
<p>In the Port XML format, enumerations may appear
as the types of arguments or as the return type.</p>
</li>
<li>
<p>In the XML formats for commands and for events,
enumerations may appear as the types of arguments.</p>
</li>
<li>
<p>In the XML formats for telemetry channels and for
parameters, enumerations may appear as the types of
data elements.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In each case, the enumerated constants are specified
as part of the definition of the member, argument, return type, etc.</p>
</div>
<div class="paragraph">
<p>FPP does not represent these inline enum definitions directly.
In FPP, enum definitions are always named, so they can be reused.
Therefore, when translating an F Prime XML file that contains inline enum
definitions, <code>fpp-from-xml</code> does the following: (1) translate
each inline definition to a named FPP enum; and (2) use the corresponding named
types in the translated FPP struct or port.</p>
</div>
<div class="paragraph">
<p>For example, here is an F Prime Serializable XML type
<code>N::S1</code> containing a member <code>m</code> whose type is an enum
<code>E</code> with three enumerated constants <code>A</code>, <code>B</code>, and <code>C</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>cat &gt; S1SerializableAi.xml
&lt;serializable namespace="N" name="S1"&gt;
&lt;members&gt;
&lt;member name="m" type="ENUM"&gt;
&lt;enum name="E"&gt;
&lt;item name="A"/&gt;
&lt;item name="B"/&gt;
&lt;item name="C"/&gt;
&lt;/enum&gt;
&lt;/member&gt;
&lt;/members&gt;
&lt;/serializable&gt;
^D</pre>
</div>
</div>
<div class="paragraph">
<p>Running <code>fpp-from-xml</code> on this file yields the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-from-xml S1SerializableAi.xml
module N {
enum E {
A = 0
B = 1
C = 2
}
struct S1 {
m: E
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>Notice the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The tool translates namespace <code>N</code> in XML to module <code>N</code> in FPP.</p>
</li>
<li>
<p>The tool translates Serializable type <code>S1</code> in namespace <code>N</code>
to struct type <code>S1</code> in module <code>N</code>.</p>
</li>
<li>
<p>The tool generates an enum type <code>N.E</code> to represent the
type of member <code>m</code> of struct <code>N.S1</code>.</p>
</li>
<li>
<p>The tool assigns member <code>m</code> of struct <code>N.S1</code> the type <code>N.E</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><strong>Format strings:</strong>
<code>fpp-from-xml</code> translates XML format strings to FPP
format strings, if it can.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; AArrayAi.xml
&lt;array name="A"&gt;
&lt;type&gt;F32&lt;/type&gt;
&lt;size&gt;3&lt;/size&gt;
&lt;format&gt;%f&lt;/format&gt;
&lt;default&gt;
&lt;value&gt;0.0f&lt;/value&gt;
&lt;value&gt;0.0f&lt;/value&gt;
&lt;value&gt;0.0f&lt;/value&gt;
&lt;/default&gt;
&lt;/array&gt;
^D</pre>
</div>
</div>
<div class="paragraph">
<p>Notice that this code contains the line</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;format&gt;%f&lt;/format&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>which is the XML representation of the format.</p>
</div>
<div class="paragraph">
<p>Now try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-from-xml AArrayAi.xml
array A = [3] F32 default [
0.0
0.0
0.0
] format "{f}"</pre>
</div>
</div>
<div class="paragraph">
<p>The XML format <code>%f</code> is translated back to the FPP format <code>{f}</code>.</p>
</div>
<div class="paragraph">
<p>If the tool cannot translate the format, it will insert an annotation
stating that. For example, <code>%q</code> is not a format recognized by
FPP, so a format containing this string won&#8217;t be translated:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat &gt; AArrayAi.xml
&lt;array name="A"&gt;
&lt;type&gt;F32&lt;/type&gt;
&lt;size&gt;1&lt;/size&gt;
&lt;format&gt;%q&lt;/format&gt;
&lt;default&gt;
&lt;value&gt;0.0&lt;/value&gt;
&lt;/default&gt;
&lt;/array&gt;
^D
% fpp-from-xml AArrayAi.xml
@ FPP from XML: could not translate format string "%q"
array A = [1] F32 default [
0.0
]</pre>
</div>
</div>
<div class="paragraph">
<p><strong>Import directives:</strong>
XML directives that import symbols (such as <code>import_port_type</code>)
are ignored in the translation.
These directives represent dependencies between XML files, which
become dependencies between FPP source files in the FPP translation.
Once the XML-to-FPP translation is done, you can handle these
dependencies in the ordinary way for FPP, as discussed in the
section on <a href="#Specifying-Models-as-Files">specifying models as files</a>.</p>
</div>
<div class="paragraph">
<p>XML directives that import XML dictionaries are translated
to
<a href="#Specifying-Models-as-Files_Include-Specifiers">include specifiers</a>.
For example, suppose that <code>CComponentAi.xml</code> defines component <code>C</code>
and contains the directive</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="xml">&lt;import_dictionary&gt;Commands.xml&lt;/import_dictionary&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Running <code>fpp-from-xml</code> on <code>CComponentAi.xml</code> produces an
FPP definition of a component <code>C</code>; the component definition
contains the include specifier</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">include "Commands.fppi"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Separately, you can use <code>fpp-from-xml</code> to translate <code>Commands.xml</code>
to <code>Commands.fppi</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="Writing-C-Plus-Plus-Implementations">17. Writing C Plus Plus Implementations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When constructing an F Prime deployment in C&#43;&#43;, there are generally
five kinds of implementations you have to write:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Implementations of
<a href="#Defining-Types_Abstract-Type-Definitions">abstract types</a>.
These are types that are named in the FPP model but are defined
directly in C&#43;&#43;.</p>
</li>
<li>
<p>Implementations of <a href="#Defining-State-Machines_Writing-a-State-Machine-Definition">external state machines</a>.</p>
</li>
<li>
<p>Implementations of
<a href="#Defining-Components">components</a>.</p>
</li>
<li>
<p>Implementations of any libraries used by the component implementations,
e.g., algorithm libraries or hardware device driver libraries.</p>
</li>
<li>
<p>A top-level implementation including a <code>main</code> function for running
the FSW application.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Implementing a component (item 3) involves filling out the API provided by
the C&#43;&#43; component base class.
This process is covered in detail in the F Prime user&#8217;s guide;
we won&#8217;t cover it further here.
Similarly, implementing libraries (item 4) is unrelated to FPP, so we
won&#8217;t cover it in this manual.
Here we focus on items 1, 2, and 5: implementing abstract types,
implementing external state machines, and implementing deployments.
We also discuss <strong>serialization</strong> of data values, i.e., representing
FPP data values as binary data for storage and transmission.</p>
</div>
<div class="sect2">
<h3 id="Writing-C-Plus-Plus-Implementations_Implementing-Abstract-Types">17.1. Implementing Abstract Types</h3>
<div class="paragraph">
<p>When translating to C&#43;&#43;, an
<a href="#Defining-Types_Abstract-Type-Definitions">abstract type definition</a>
represents a C&#43;&#43; class that you write directly in C&#43;&#43;.
When you use an abstract type <em>T</em> in an FPP definition <em>D</em> (for example, as the
member type of an array definition)
and you translate <em>D</em> to C&#43;&#43;, then the generated C&#43;&#43; for <em>D</em> contains an
<code>include</code> directive that includes a header file for <em>T</em>.</p>
</div>
<div class="paragraph">
<p>As an example, try this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% fpp-to-cpp -p $PWD
type T
array A = [3] T
^D</pre>
</div>
</div>
<div class="paragraph">
<p>Notice that we used the option <code>-p $PWD</code>.
This is to make the generated include path relative to the current directory.</p>
</div>
<div class="paragraph">
<p>Now run</p>
</div>
<div class="listingblock">
<div class="content">
<pre>% cat AArrayAc.hpp</pre>
</div>
</div>
<div class="paragraph">
<p>You should see the following line in the generated C&#43;&#43;:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">#include "T.hpp"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This line says that in order to compile <code>AArrayAc.cpp</code>,
a header file <code>T.hpp</code> must exist in the current directory.
It is up to you to provide that header file.</p>
</div>
<div class="paragraph">
<p><strong>General implementations:</strong>
In most cases, when implementing an abstract type <code>T</code> in C&#43;&#43;, you
will define
a class that extends <code>Fw::Serializable</code> from the F Prime framework.
Your class definition should include the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>An implementation of the virtual function</p>
<div class="listingblock">
<div class="content">
<pre>Fw::SerializeStatus T::serializeTo(
Fw::SerialBufferBase&amp;,
Fw::Endianness = Fw::Endianness::BIG
) const</pre>
</div>
</div>
<div class="paragraph">
<p>that specifies how to <strong>serialize</strong> a class instance to a buffer
(i.e., convert a class instance to a byte string stored in a buffer).</p>
</div>
</li>
<li>
<p>An implementation of the function</p>
<div class="listingblock">
<div class="content">
<pre>Fw::SerializeStatus T::deserializeFrom(
Fw::SerialBufferBase&amp;,
Fw::Endianness = Fw::Endianness::BIG
)</pre>
</div>
</div>
<div class="paragraph">
<p>that specifies how to <strong>deserialize</strong> a class instance from a
buffer (i.e., reconstruct a class instance from a byte string stored in a
buffer).</p>
</div>
</li>
<li>
<p>A constant <code>T::SERIALIZED_SIZE</code> that specifies the size in bytes
of a byte string serialized from the class.</p>
</li>
<li>
<p>A zero-argument constructor <code>T()</code>.</p>
</li>
<li>
<p>An overloaded equality operator</p>
<div class="listingblock">
<div class="content">
<pre>bool operator==(const T&amp; that) const;</pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>For more on serialization, see the section on
<a href="#Writing-C-Plus-Plus-Implementations_Serialization-of-FPP-Values">serialization of FPP values</a>.</p>
</div>
<div class="paragraph">
<p>Here is a minimal complete implementation of an abstract type <code>T</code>.
It has one member variable <code>x</code> of type <code>U32</code> and no methods other than
those required by F Prime.
We have made <code>T</code> a C&#43;&#43; struct (rather than a class) so that
all members are public by default.
To implement <code>serializeTo</code>, we use the <code>serializeFrom</code> function
provided by <code>Fw::SerialBufferBase</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>// A minimal implementation of abstract type T
#ifndef T_HPP
#define T_HPP
// Include Fw/Types/Serializable.hpp from the F Prime framework
#include "Fw/Types/Serializable.hpp"
struct T final : public Fw::Serializable { // Extend Fw::Serializable
// Define some shorthand for F Prime types
using SS = Fw::SerializeStatus SS;
using B = Fw::SerialBufferBase B;
using E = Fw::Endianness E;
// Define the constant SERIALIZED_SIZE
enum Constants { SERIALIZED_SIZE = sizeof(U32) };
// Provide a zero-argument constructor
T() : x(0) { }
// Define a comparison operator
bool operator==(const T&amp; that) const { return this-&gt;x == that.x; }
// Define the virtual serializeTo method
SS serializeTo(B&amp; b, E e) const final { return b.serializeFrom(x, e); }
// Define the virtual deserializeFrom method
SS deserializeFrom(B&amp; b, E e) final { return b.deserializeTo(x, e); }
// Provide some data
U32 x;
};
#endif</pre>
</div>
</div>
<div class="paragraph">
<p><strong>Serializable buffers used in ports:</strong>
In some cases, you may want to define an abstract type <code>T</code> that represents
a data buffer and that is used only in <a href="#Defining-Ports">port definitions</a>.
In this case you can implement
<code>T</code> as a class that extends <code>Fw::SerialBufferBase</code>.
Instead of implementing the <code>serializeTo</code> and <code>deserializeFrom</code> functions
directly, you override functions that get the address and the capacity
(allocated size) of the buffer; the base class <code>Fw::SerialBufferBase</code>
uses these functions to implement <code>serializeTo</code> and <code>deserializeFrom</code>.
For an example of how to do this, see the files <code>Fw/Cmd/CmdArgBuffer.hpp</code>
and <code>Fw/Cmd/CmdArgBuffer.cpp</code> in the F Prime repository.
Be careful, though: if you implement an abstract type <code>T</code> this way
and you try to use the type <code>T</code> outside of a port definition,
the generated C&#43;&#43; may not compile.</p>
</div>
</div>
<div class="sect2">
<h3 id="Writing-C-Plus-Plus-Implementations_Implementing-External-State-Machines">17.2. Implementing External State Machines</h3>
<div class="paragraph">
<p>An <a href="#Defining-State-Machines_Writing-a-State-Machine-Definition">external state machine</a> refers to a state machine implementation
supplied outside the FPP model.
To implement an external state machine, you can use
the <a href="https://github.com/JPLOpenSource/STARS/tree/main">State Autocoding for
Real-Time Systems (STARS)</a>
tool.
STARS provides several ways to specify state machines, and it
provides several C&#43;&#43; back ends.
The F Prime back end is designed to work with FPP code generation.</p>
</div>
<div class="paragraph">
<p>For an example of an external state machine implemented in STARS,
see <code>FppTest/state_machine</code> in the F Prime repository.</p>
</div>
</div>
<div class="sect2">
<h3 id="Writing-C-Plus-Plus-Implementations_Implementing-Deployments">17.3. Implementing Deployments</h3>
<div class="paragraph">
<p>At the highest level of an F Prime implementation, you write
two units of C&#43;&#43; code:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Application-specific definitions visible
both to the <code>main</code> function and to the auto-generated
topology code.</p>
</li>
<li>
<p>The <code>main</code> function.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>We describe each of these code units below.</p>
</div>
<div class="sect3">
<h4 id="Writing-C-Plus-Plus-Implementations_Implementing-Deployments_Application-Specific-Definitions">17.3.1. Application-Specific Definitions</h4>
<div class="paragraph">
<p>As discussed in the section on
<a href="#Analyzing-and-Translating-Models_Generating-C-Plus-Plus_Topology-Definitions">generating C&#43;&#43; topology definitions</a>, when you translate an FPP
topology <em>T</em> to C&#43;&#43;, the result goes into files
<em>T</em> <code>TopologyAc.hpp</code> and <em>T</em> <code>TopologyAc.cpp</code>.
The generated file <em>T</em> <code>TopologyAc.hpp</code> includes a file
<em>T</em> <code>TopologyDefs.hpp</code>.
The purpose of this file inclusion is as follows:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><em>T</em> <code>TopologyDefs.hpp</code> is not auto-generated.
You must write it by hand as part of your C&#43;&#43; implementation.</p>
</li>
<li>
<p>Because <em>T</em> <code>TopologyAc.cpp</code> includes <em>T</em> <code>TopologyAc.hpp</code>
and <em>T</em> <code>TopologyAc.hpp</code> includes <em>T</em> <code>TopologyDefs.hpp</code>,
the handwritten definitions in <em>T</em> <code>TopologyDefs.hpp</code> are visible
to the auto-generated code in <em>T</em> <code>TopologyAc.hpp</code> and
<code>TopologyAc.cpp</code>.</p>
</li>
<li>
<p>You can also include <em>T</em> <code>TopologyDefs.hpp</code> in your main
function (described in the next section) to make its
definitions visible there.
That way <code>main</code> and the auto-generated topology
code can share these custom definitions.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p><em>T</em> <code>TopologyDefs.hpp</code>
must be located in the same directory where the topology <em>T</em> is defined.
When writing the file <em>T</em> <code>TopologyDefs.hpp</code>, you should
follow the description given below.</p>
</div>
<div class="paragraph">
<p><strong>Topology state:</strong>
<em>T</em> <code>TopologyDefs.hpp</code> must define a type
<code>TopologyState</code> in the C&#43;&#43; namespace
corresponding to the FPP module where the topology <em>T</em> is defined.
For example, in <code>SystemReference/Top/topology.fpp</code> in the
<a href="https://github.com/fprime-community/fprime-system-reference/blob/main/SystemReference/Top/topology.fpp">F Prime system reference deployment</a>, the FPP topology <code>SystemReference</code> is defined in the FPP
module <code>SystemReference</code>, and so in
<a href="https://github.com/fprime-community/fprime-system-reference/blob/main/SystemReference/Top/SystemReferenceTopologyDefs.hpp"><code>SystemReference/Top/SystemReferenceTopologyDefs.hpp</code></a>, the type <code>TopologyState</code>
is defined in the namespace <code>SystemReference</code>.</p>
</div>
<div class="paragraph">
<p><code>TopologyState</code> may be any type.
Usually it is a struct or class.
The C&#43;&#43; code generated by FPP passes a value <code>state</code> of type <code>TopologyState</code> into
each of the functions for setting up and tearing down topologies.
You can read this value in the code associated with your
<a href="#Defining-Component-Instances_Init-Specifiers">init specifiers</a>.</p>
</div>
<div class="paragraph">
<p>In the F Prime system reference example, <code>TopologyState</code>
is a struct with two member variables: a C-style string
<code>hostName</code> that stores a host name and a <code>U32</code> value <code>portNumber</code>
that stores a port number.
The main function defined in <code>Main.cpp</code> parses the command-line
arguments to the application, uses the result to create an object
<code>state</code> of type <code>TopologyState</code>, and passes the <code>state</code> object
into the functions for setting up and tearing down the topology.
The <code>startTasks</code> phase for the <code>comDriver</code> instance uses the <code>state</code>
object in the following way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="fpp">phase Fpp.ToCpp.Phases.startTasks """
// Initialize socket server if and only if there is a valid specification
if (state.hostName != nullptr &amp;&amp; state.portNumber != 0) {
Os::TaskString name("ReceiveTask");
// Uplink is configured for receive so a socket task is started
comDriver.configure(state.hostName, state.portNumber);
comDriver.startSocketTask(
name,
true,
ConfigConstants::SystemReference_comDriver::PRIORITY,
ConfigConstants::SystemReference_comDriver::STACK_SIZE
);
}
"""</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this code snippet, the expressions <code>state.hostName</code> and <code>state.portNumber</code>
refer to the <code>hostName</code> and <code>portNumber</code> member variables of the
state object passed in from the main function.</p>
</div>
<div class="paragraph">
<p>The <code>state</code> object is passed in to the setup and teardown functions
via <code>const</code> reference.
Therefore, you may read, but not write, the <code>state</code> object in the
code associated with the init specifiers.</p>
</div>
<div class="paragraph">
<p><strong>Health ping entries:</strong>
If your topology uses an instance of the standard component <code>Svc::Health</code> for
monitoring
the health of components with threads, then <em>T</em> <code>TopologyDefs.hpp</code>
must define the <strong>health ping entries</strong> used by the health component instance.
The health ping entries specify the time in seconds to wait for the
receipt of a health ping before declaring a timeout.
For each component being monitored, there are two timeout intervals:
a warning interval and a fatal interval.
If the warning interval passes without a health ping, then a warning event occurs.
If the fatal interval passes without a health ping, then a fatal event occurs.</p>
</div>
<div class="paragraph">
<p>You must specify the health ping entries in the namespace corresponding
to the FPP module where <em>T</em> is defined.
To specify the health ping entries, you do the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Open a namespace <code>PingEntries</code>.</p>
</li>
<li>
<p>In that namespace, open a namespace corresponding to the name
of each component instance with health ping ports.</p>
</li>
<li>
<p>Inside namespace in item 2, define a C&#43;&#43; enumeration with
the following constants <code>WARN</code> and <code>FATAL</code>.
Set <code>WARN</code> equal to the warning interval for the enclosing
component instance.
Set <code>FATAL</code> equal to the fatal interval.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>For example, here are the health ping entries from
<code>SystemReference/Top/SystemReferenceTopologyDefs.hpp</code>
in the F Prime system reference repository:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">namespace SystemReference {
...
// Health ping entries
namespace PingEntries {
namespace SystemReference_blockDrv { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_chanTlm { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_cmdDisp { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_cmdSeq { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_eventLogger { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_fileDownlink { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_fileManager { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_fileUplink { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_imageProcessor { enum {WARN = 3, FATAL = 5}; }
namespace SystemReference_prmDb { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_processedImageBufferLogger { enum {WARN = 3, FATAL = 5}; }
namespace SystemReference_rateGroup1Comp { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_rateGroup2Comp { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_rateGroup3Comp { enum { WARN = 3, FATAL = 5 }; }
namespace SystemReference_saveImageBufferLogger { enum { WARN = 3, FATAL = 5 }; }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Other definitions:</strong>
You can put any compile-time definitions you wish into <em>T</em> <code>TopologyAc.hpp</code>
If you need link-time definitions (e.g., to declare variables with storage),
you can put them in <em>T</em> <code>TopologyAc.cpp</code>, but this is not required.</p>
</div>
<div class="paragraph">
<p>For example, <code>SystemReference/Top/SystemReferenceTopologyAc.hpp</code> declares
a variable <code>SystemReference::Allocation::mallocator</code> of type <code>Fw::MallocAllocator</code>.
It provides an allocator used in the setup and teardown
of several component instances.
The corresponding link-time symbol is defined in <code>SystemReferenceTopologyDefs.cpp</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="Writing-C-Plus-Plus-Implementations_Implementing-Deployments_The-Main-Function">17.3.2. The Main Function</h4>
<div class="paragraph">
<p>You must write a main function that performs application-specific
and system-specific tasks such as parsing command-line arguments,
handling signals, and returning a numeric code to the system on exit.
Your main code can use the following public interface provided
by <em>T</em> <code>TopologyAc.hpp</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">// ----------------------------------------------------------------------
// Public interface functions
// ----------------------------------------------------------------------
//! Set up the topology
void setup(
const TopologyState&amp; state //!&lt; The topology state
);
//! Tear down the topology
void teardown(
const TopologyState&amp; state //!&lt; The topology state
);</code></pre>
</div>
</div>
<div class="paragraph">
<p>These functions reside in the C&#43;&#43; namespace corresponding to
the FPP module where the topology <em>T</em> is defined.</p>
</div>
<div class="paragraph">
<p>On Linux, a typical main function might work this way:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Parse command-line arguments. Use the result to construct
a <code>TopologyState</code> object <code>state</code>.</p>
</li>
<li>
<p>Set up a signal handler to catch signals.</p>
</li>
<li>
<p>Call <em>T</em> <code>::setup</code>, passing in the <code>state</code> object, to
construct and initialize the topology.</p>
</li>
<li>
<p>Start the topology running, e.g., by looping in the main thread
until a signal is handled, or by calling a start function on a
timer component (see, e.g., <code>Svc::LinuxTimer</code>).
The loop or timer typically runs until a signal is caught, e.g.,
when the user presses control-C at the console.</p>
</li>
<li>
<p>On catching a signal</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>Set a flag that causes the main loop to exit or the timer
to stop.
This flag must be a volatile and atomic variable (e.g.,
<code>std::atomic_bool</code>) because it is accessed
concurrently by signal handlers and threads.</p>
</li>
<li>
<p>Call <em>T</em> <code>::teardown</code>, passing in the <code>state</code> object, to
tear down the topology.</p>
</li>
<li>
<p>Wait some time for all the threads to exit.</p>
</li>
<li>
<p>Exit the main thread.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>For an example like this, see <code>SystemReference/Top/Main.cpp</code> in the
F Prime system reference repository.</p>
</div>
</div>
<div class="sect3">
<h4 id="Writing-C-Plus-Plus-Implementations_Implementing-Deployments_Public-Symbols">17.3.3. Public Symbols</h4>
<div class="paragraph">
<p>The header file <em>T</em> <code>TopologyAc.hpp</code> declares several public
symbols that you can use when writing your main function.</p>
</div>
<div class="paragraph">
<p><strong>Instance variables:</strong>
Each component instance used in the topology is declared as
an <code>extern</code> variable, so you can refer to any component instance
in the main function.
For example, the main function in the <code>SystemReference</code> topology
calls the method <code>callIsr</code> of the <code>blockDrv</code> (block driver)
component instance, in order to simulate an interrupt service
routine (ISR) call triggered by a hardware interrupt.</p>
</div>
<div class="paragraph">
<p><strong>Helper functions:</strong>
The auto-generated <code>setup</code> function calls the following auto-generated
helper functions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">void initComponents(const TopologyState&amp; state);
void configComponents(const TopologyState&amp; state);
void setBaseIds();
void connectComponents();
void regCommands();
void readParameters();
void loadParameters();
void startTasks(const TopologyState&amp; state);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The auto-generated <code>teardown</code> function calls the following
auto-generated helper functions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code data-lang="cpp">void stopTasks(const TopologyState&amp; state);
void freeThreads(const TopologyState&amp; state);
void tearDownComponents(const TopologyState&amp; state);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The helper functions are declared as public symbols in <em>T</em>
<code>TopologyAc.hpp</code>, so if you wish, you may write your own versions
of <code>setup</code> and <code>teardown</code> that call these functions directly.
The FPP modeling is designed so that you don&#8217;t have to do this;
you can put any custom C&#43;&#43; code for setup or teardown into
<a href="#Defining-Component-Instances_Init-Specifiers">init specifiers</a>
and let the FPP translator generate complete <code>setup</code> and <code>teardown</code>
functions that you simply call, as described above.
Using init specifiers generally produces cleaner integration between
the model and the C&#43;&#43; code: you write the custom
C&#43;&#43; code once, any topology <em>T</em> that uses an instance <em>I</em> will pick
up the custom C&#43;&#43; code for <em>I</em>, and the FPP translator will automatically
put the code for <em>I</em> into the correct place in <em>T</em> <code>TopologyAc.cpp</code>.
However, if you wish to write the custom code directly into your main
function, you may.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="Writing-C-Plus-Plus-Implementations_Serialization-of-FPP-Values">17.4. Serialization of FPP Values</h3>
<div class="paragraph">
<p>Every value represented in FPP can be <strong>serialized</strong>, i.e., converted into a
machine-independent sequence of bytes.
Serialization provides a consistent way to store data (e.g.,
to onboard storage) and to transmit data (e.g., to or from the ground).
The F Prime framework also uses serialization to pass data through asynchronous
port invocations.
The data is serialized when it is put on a message queue
and then <strong>deserialized</strong> (i.e., converted from a byte sequence to
a C&#43;&#43; representation)
when it is taken off the queue for processing.</p>
</div>
<div class="paragraph">
<p>F Prime uses the following rules for serializing data:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Values of primitive integer type are serialized as follows:</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>A value of unsigned integer type (<code>U8</code>, <code>U16</code>, <code>U32</code>, or <code>U64</code>)
is serialized into big-endian order (most significant byte first) by default,
using the number of bytes implied by the bit width.
For example, the <code>U16</code> value 10 (decimal) is serialized as the
two bytes <code>00</code> <code>0A</code> (hex). If little-endian order is desired, the optional mode parameter can be specified as <code>Fw::Serialization::LITTLE</code>. This stores the data least significant byte order. The <code>U16</code> value 10 (decimal) is serialized in little-endian as the two bytes <code>0A</code> <code>00</code> (hex).</p>
</li>
<li>
<p>A value of signed integer type (<code>I8</code>, <code>I16</code>, <code>I32</code>, or <code>I64</code>)
is serialized by first converting the value to an unsigned value of the same bit
width and then serializing the unsigned value as stated in rule 1.a.
If the value is nonnegative, then the unsigned value is
the same as the signed value.
Otherwise the unsigned value is the two&#8217;s complement of the signed value.
For example:</p>
<div class="olist lowerroman">
<ol class="lowerroman" type="i">
<li>
<p>The <code>I16</code> value 10 (decimal) is serialized as two bytes, yielding the bytes <code>00</code> <code>0A</code> (hex) in big-endian and <code>0A</code> <code>00</code> (hex) in little-endian.</p>
</li>
<li>
<p>The <code>I16</code> value -10 (decimal) is serialized by
(1) computing the <code>U16</code> value 2<sup>16</sup> - 10 = 65526
and (2) serializing that value as two bytes in the selected byte order,
yielding the bytes <code>FF</code> <code>F6</code> (hex) big-endian and <code>F6</code> <code>FF</code> (hex) little-endian.</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
</li>
<li>
<p>A value of floating-point type (<code>F32</code> or <code>F64</code>)
is serialized in the selected byte order according to the IEEE
standard for representing these values.</p>
</li>
<li>
<p>A value of Boolean type is serialized as a single byte.
The byte values used to represent <code>true</code> and <code>false</code>
are <code>FW_SERIALIZE_TRUE_VALUE</code> and <code>FW_SERIALIZE_FALSE_VALUE</code>,
which are defined in the F Prime configuration header <code>FpConfig.h</code>.</p>
</li>
<li>
<p>A value of string type is serialized as a size followed
by the string characters in string order.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>The size is serialized according to rule 1 for primitive
integer types.
The F Prime type definition <code>FwSizeStoreType</code> specifies the type to use
for the size.
This type definition is user-configurable; it is found in the
F Prime configuration file <code>FpConfig.fpp</code>.</p>
</li>
<li>
<p>There is one byte for each character of the string, and there is
no null terminator.
Each string character is serialized as an <code>I8</code> value according to rule 1.b.</p>
</li>
</ol>
</div>
</li>
<li>
<p>A value of <a href="#Defining-Types_Array-Type-Definitions">array type</a>
is serialized as a sequence of serialized values, one for each array
element, in array order.
Each value is serialized using these rules.</p>
</li>
<li>
<p>A value of <a href="#Defining-Types_Struct-Type-Definitions">struct type</a>
is serialized member-by-member, in the order
that the members appear in the FPP struct definition,
with no padding.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>Except for
<a href="#Defining-Types_Struct-Type-Definitions_Member-Arrays">member arrays</a>,
each member is serialized using these rules.</p>
</li>
<li>
<p>Each member array is serialized as stated in rule 5.</p>
</li>
</ol>
</div>
</li>
<li>
<p>A value of <a href="#Defining-Enums">enum type</a> is converted to a primitive
integer value of the <a href="#Defining-Enums_The-Representation-Type">representation
type</a> specified in the enum definition.
This value is serialized as stated in rule 1.</p>
</li>
<li>
<p>A value of <a href="#Defining-Types_Abstract-Type-Definitions">abstract type</a> is
serialized according to its
<a href="#Writing-C-Plus-Plus-Implementations_Implementing-Abstract-Types">C&#43;&#43; implementation</a>.</p>
</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2025-11-06 16:00:29 -0800
</div>
</div>
<script src="code-prettify/run_prettify.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
messageStyle: "none",
tex2jax: {
inlineMath: [["\\(", "\\)"]],
displayMath: [["\\[", "\\]"]],
ignoreClass: "nostem|nolatexmath"
},
asciimath2jax: {
delimiters: [["\\$", "\\$"]],
ignoreClass: "nostem|noasciimath"
},
TeX: { equationNumbers: { autoNumber: "none" } }
})
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
data.math.root.display = "block"
}
return data
})
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>
</body>
</html>