diff --git a/.gitignore b/.gitignore
index 487583958f..ef9ffc5fb3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,3 +57,7 @@ core
./Gds/docs/doxy
*Dictionary.xml
+*TopologyAppID.csv
+*TopologyAppAi_IDTableLog.txt
+
+.vscode
diff --git a/.pydevproject b/.pydevproject
index d001f0aea3..40e9f40a0a 100644
--- a/.pydevproject
+++ b/.pydevproject
@@ -1,5 +1,5 @@
Default
-python interpreter
+python 2.7
diff --git a/Autocoders/MagicDrawCompPlugin/FpCompAuto.jar b/Autocoders/MagicDrawCompPlugin/FpCompAuto.jar
index c1f17c8b1f..fb39a8bd0a 100644
Binary files a/Autocoders/MagicDrawCompPlugin/FpCompAuto.jar and b/Autocoders/MagicDrawCompPlugin/FpCompAuto.jar differ
diff --git a/Autocoders/MagicDrawCompPlugin/Makefile b/Autocoders/MagicDrawCompPlugin/Makefile
index 2ff89bfd5e..a4c05e1453 100644
--- a/Autocoders/MagicDrawCompPlugin/Makefile
+++ b/Autocoders/MagicDrawCompPlugin/Makefile
@@ -31,6 +31,7 @@ install:
mkdir -p $(MD_INSTALL_LOC)/plugins/gov.nasa.jpl.magicdraw.componentAutocoder
cp FpCompAuto.jar $(MD_INSTALL_LOC)/plugins/gov.nasa.jpl.magicdraw.componentAutocoder
cp plugin.xml $(MD_INSTALL_LOC)/plugins/gov.nasa.jpl.magicdraw.componentAutocoder
+ cp -r lib $(MD_INSTALL_LOC)/plugins/gov.nasa.jpl.magicdraw.componentAutocoder
#install: FpCompAuto.jar
# cp FpCompAuto.jar /Users/bocchino/Downloads/MagicDraw/plugins/gov.nasa.jpl.magicdraw.componentAutocoder/FpCompAuto.jar
diff --git a/Autocoders/MagicDrawCompPlugin/README b/Autocoders/MagicDrawCompPlugin/README
index 191ec2c401..979bf50903 100644
--- a/Autocoders/MagicDrawCompPlugin/README
+++ b/Autocoders/MagicDrawCompPlugin/README
@@ -1,10 +1,14 @@
This contains the MagicDraw Plugin for the Component Autocoder:
To install this plugin:
- - copy the files 'FpCompAuto.jar' and 'plugin.xml' found in this directory into the MagicDraw installation plugin directory:
+ - copy the files 'FpCompAuto.jar' and 'plugin.xml' and directory 'lib' found in this directory into the MagicDraw installation plugin directory:
ie /Applications/MagicDraw_UML_17.2/plugins/gov.nasa.jpl.magicdraw.componentAutocoder.
- This can also be done by typing "make install MD_INSTALL_LOC="
+```
+cp -r plugin.xml FpCompAuto.jar lib /Applications/MagicDraw_UML_17.2/plugins/gov.nasa.jpl.magicdraw.componentAutocoder
+```
+
To rebuild the plugin from the command line:
- Run 'make' in this directory. This will generate or re-generate a file 'FpCompAuto.jar' that contains the plugin.
- Copy 'FpCompAuto.jar' to 'FpCompAuto.jar' as described above.
@@ -97,3 +101,7 @@ version 4.5
- Converted to Makefile based builds (Bocchino) and removed buggy sequence port autonumbering (Canham)
- Name of plug-in was changed to "FpCompAuto.jar" away from Eclipse project default name
- Added make target to install plug-in correctly
+
+version 4.6
+--------------
+- Added plugin dependencies to plugin.xml for MagicDraw 18.5+
diff --git a/Autocoders/MagicDrawCompPlugin/plugin.xml b/Autocoders/MagicDrawCompPlugin/plugin.xml
index e97e3cd691..8faa5bc59e 100644
--- a/Autocoders/MagicDrawCompPlugin/plugin.xml
+++ b/Autocoders/MagicDrawCompPlugin/plugin.xml
@@ -2,7 +2,7 @@
@@ -10,8 +10,10 @@
-
+
+
+
diff --git a/Autocoders/bin/codegen.py b/Autocoders/bin/codegen.py
index 32196f3215..efbaa772f0 100644
--- a/Autocoders/bin/codegen.py
+++ b/Autocoders/bin/codegen.py
@@ -340,7 +340,8 @@ def generate_topology(the_parsed_topology_xml, xml_filename, opt):
member_elem = etree.Element("member")
member_elem.attrib["name"] = member_name
member_elem.attrib["format_specifier"] = member_format_specifier
- member_elem.attrib["description"] = member_comment
+ if member_comment != None:
+ member_elem.attrib["description"] = member_comment
if type(member_type) == type(tuple()):
enum_value = 0
type_name = "%s::%s::%s"%(serializable_type,member_name,member_type[0][1])
diff --git a/Autocoders/schema/default/parameters_schema.rng b/Autocoders/schema/default/parameters_schema.rng
index 2f84e20934..ba7d1a13d1 100644
--- a/Autocoders/schema/default/parameters_schema.rng
+++ b/Autocoders/schema/default/parameters_schema.rng
@@ -68,9 +68,9 @@
-
-
-
+
+
+
@@ -276,4 +276,4 @@
-
\ No newline at end of file
+
diff --git a/Autocoders/src/generators/templates/channels/ChannelHeader.tmpl b/Autocoders/src/generators/templates/channels/ChannelHeader.tmpl
index c1db239182..ba89a4b537 100644
--- a/Autocoders/src/generators/templates/channels/ChannelHeader.tmpl
+++ b/Autocoders/src/generators/templates/channels/ChannelHeader.tmpl
@@ -8,25 +8,25 @@ XML Source: ${source}
'''
# Import the types this way so they do not need prefixing for execution.
-from models.serialize.type_exceptions import *
-from models.serialize.type_base import *
+from fprime.gse.models.serialize.type_exceptions import *
+from fprime.gse.models.serialize.type_base import *
-from models.serialize.bool_type import *
-from models.serialize.enum_type import *
-from models.serialize.f32_type import *
-from models.serialize.f64_type import *
+from fprime.gse.models.serialize.bool_type import *
+from fprime.gse.models.serialize.enum_type import *
+from fprime.gse.models.serialize.f32_type import *
+from fprime.gse.models.serialize.f64_type import *
-from models.serialize.u8_type import *
-from models.serialize.u16_type import *
-from models.serialize.u32_type import *
-from models.serialize.u64_type import *
+from fprime.gse.models.serialize.u8_type import *
+from fprime.gse.models.serialize.u16_type import *
+from fprime.gse.models.serialize.u32_type import *
+from fprime.gse.models.serialize.u64_type import *
-from models.serialize.i8_type import *
-from models.serialize.i16_type import *
-from models.serialize.i32_type import *
-from models.serialize.i64_type import *
+from fprime.gse.models.serialize.i8_type import *
+from fprime.gse.models.serialize.i16_type import *
+from fprime.gse.models.serialize.i32_type import *
+from fprime.gse.models.serialize.i64_type import *
-from models.serialize.string_type import *
-from models.serialize.serializable_type import *
+from fprime.gse.models.serialize.string_type import *
+from fprime.gse.models.serialize.serializable_type import *
-from models.common import channel_telemetry
+from fprime.gse.models.common import channel_telemetry
diff --git a/Autocoders/src/generators/templates/commands/CommandHeader.tmpl b/Autocoders/src/generators/templates/commands/CommandHeader.tmpl
index cb80d6c327..af8f82f7b7 100644
--- a/Autocoders/src/generators/templates/commands/CommandHeader.tmpl
+++ b/Autocoders/src/generators/templates/commands/CommandHeader.tmpl
@@ -8,25 +8,25 @@ XML Source: ${source}
'''
# Import the types this way so they do not need prefixing for execution.
-from models.serialize.type_exceptions import *
-from models.serialize.type_base import *
+from fprime.gse.models.serialize.type_exceptions import *
+from fprime.gse.models.serialize.type_base import *
-from models.serialize.bool_type import *
-from models.serialize.enum_type import *
-from models.serialize.f32_type import *
-from models.serialize.f64_type import *
+from fprime.gse.models.serialize.bool_type import *
+from fprime.gse.models.serialize.enum_type import *
+from fprime.gse.models.serialize.f32_type import *
+from fprime.gse.models.serialize.f64_type import *
-from models.serialize.u8_type import *
-from models.serialize.u16_type import *
-from models.serialize.u32_type import *
-from models.serialize.u64_type import *
+from fprime.gse.models.serialize.u8_type import *
+from fprime.gse.models.serialize.u16_type import *
+from fprime.gse.models.serialize.u32_type import *
+from fprime.gse.models.serialize.u64_type import *
-from models.serialize.i8_type import *
-from models.serialize.i16_type import *
-from models.serialize.i32_type import *
-from models.serialize.i64_type import *
+from fprime.gse.models.serialize.i8_type import *
+from fprime.gse.models.serialize.i16_type import *
+from fprime.gse.models.serialize.i32_type import *
+from fprime.gse.models.serialize.i64_type import *
-from models.serialize.string_type import *
-from models.serialize.serializable_type import *
+from fprime.gse.models.serialize.string_type import *
+from fprime.gse.models.serialize.serializable_type import *
-from models.common import command
+from fprime.gse.models.common import command
diff --git a/Autocoders/src/generators/templates/events/EventHeader.tmpl b/Autocoders/src/generators/templates/events/EventHeader.tmpl
index a0ed4203d9..421302b80d 100644
--- a/Autocoders/src/generators/templates/events/EventHeader.tmpl
+++ b/Autocoders/src/generators/templates/events/EventHeader.tmpl
@@ -8,25 +8,25 @@ XML Source: ${source}
'''
# Import the types this way so they do not need prefixing for execution.
-from models.serialize.type_exceptions import *
-from models.serialize.type_base import *
+from fprime.gse.models.serialize.type_exceptions import *
+from fprime.gse.models.serialize.type_base import *
-from models.serialize.bool_type import *
-from models.serialize.enum_type import *
-from models.serialize.f32_type import *
-from models.serialize.f64_type import *
+from fprime.gse.models.serialize.bool_type import *
+from fprime.gse.models.serialize.enum_type import *
+from fprime.gse.models.serialize.f32_type import *
+from fprime.gse.models.serialize.f64_type import *
-from models.serialize.u8_type import *
-from models.serialize.u16_type import *
-from models.serialize.u32_type import *
-from models.serialize.u64_type import *
+from fprime.gse.models.serialize.u8_type import *
+from fprime.gse.models.serialize.u16_type import *
+from fprime.gse.models.serialize.u32_type import *
+from fprime.gse.models.serialize.u64_type import *
-from models.serialize.i8_type import *
-from models.serialize.i16_type import *
-from models.serialize.i32_type import *
-from models.serialize.i64_type import *
+from fprime.gse.models.serialize.i8_type import *
+from fprime.gse.models.serialize.i16_type import *
+from fprime.gse.models.serialize.i32_type import *
+from fprime.gse.models.serialize.i64_type import *
-from models.serialize.string_type import *
-from models.serialize.serializable_type import *
+from fprime.gse.models.serialize.string_type import *
+from fprime.gse.models.serialize.serializable_type import *
-from models.common import event
+from fprime.gse.models.common import event
diff --git a/Autocoders/src/generators/templates/port/finishPortH.tmpl b/Autocoders/src/generators/templates/port/finishPortH.tmpl
index 753feb6e3b..92e82979db 100644
--- a/Autocoders/src/generators/templates/port/finishPortH.tmpl
+++ b/Autocoders/src/generators/templates/port/finishPortH.tmpl
@@ -16,5 +16,5 @@
} // end namespace $namespace
#end for
#end if
-\#endif /* ${name.upper()}_HPP_ */
+\#endif /* ${name_space.upper()}_${name.upper()}_PORT_HPP_ */
diff --git a/Autocoders/src/generators/templates/port/startPortH.tmpl b/Autocoders/src/generators/templates/port/startPortH.tmpl
index f559f75e11..9f14c82efe 100644
--- a/Autocoders/src/generators/templates/port/startPortH.tmpl
+++ b/Autocoders/src/generators/templates/port/startPortH.tmpl
@@ -5,6 +5,6 @@
* Author: ${user}
*
*/
-\#ifndef ${name.upper()}PORT_HPP_
-\#define ${name.upper()}PORT_HPP_
+\#ifndef ${name_space.upper()}_${name.upper()}_PORT_HPP_
+\#define ${name_space.upper()}_${name.upper()}_PORT_HPP_
diff --git a/Autocoders/src/generators/templates/serialize/SerialBody.tmpl b/Autocoders/src/generators/templates/serialize/SerialBody.tmpl
index 40c643523a..773e5954be 100644
--- a/Autocoders/src/generators/templates/serialize/SerialBody.tmpl
+++ b/Autocoders/src/generators/templates/serialize/SerialBody.tmpl
@@ -5,8 +5,10 @@ class ${name}(SerializableType):
def __init__(self):
m_list = [
-#for ($membername,$type,$format_string) in $mem_list:
+#for ($membername,$type,$format_string,$size) in $mem_list:
+#for $i in range($size)
("$membername",$type,"$format_string"),
+#end for
#end for
]
diff --git a/Autocoders/src/generators/templates/serialize/SerialImport.tmpl b/Autocoders/src/generators/templates/serialize/SerialImport.tmpl
index 0c9275e057..9663eada28 100644
--- a/Autocoders/src/generators/templates/serialize/SerialImport.tmpl
+++ b/Autocoders/src/generators/templates/serialize/SerialImport.tmpl
@@ -1,23 +1,23 @@
# Import the types this way so they do not need prefixing for execution.
-from models.serialize.type_exceptions import *
-from models.serialize.type_base import *
+from fprime.gse.models.serialize.type_exceptions import *
+from fprime.gse.models.serialize.type_base import *
-from models.serialize.bool_type import *
-from models.serialize.enum_type import *
-from models.serialize.f32_type import *
-from models.serialize.f64_type import *
+from fprime.gse.models.serialize.bool_type import *
+from fprime.gse.models.serialize.enum_type import *
+from fprime.gse.models.serialize.f32_type import *
+from fprime.gse.models.serialize.f64_type import *
-from models.serialize.u8_type import *
-from models.serialize.u16_type import *
-from models.serialize.u32_type import *
-from models.serialize.u64_type import *
+from fprime.gse.models.serialize.u8_type import *
+from fprime.gse.models.serialize.u16_type import *
+from fprime.gse.models.serialize.u32_type import *
+from fprime.gse.models.serialize.u64_type import *
-from models.serialize.i8_type import *
-from models.serialize.i16_type import *
-from models.serialize.i32_type import *
-from models.serialize.i64_type import *
+from fprime.gse.models.serialize.i8_type import *
+from fprime.gse.models.serialize.i16_type import *
+from fprime.gse.models.serialize.i32_type import *
+from fprime.gse.models.serialize.i64_type import *
-from models.serialize.string_type import *
-from models.serialize.serializable_type import *
+from fprime.gse.models.serialize.string_type import *
+from fprime.gse.models.serialize.serializable_type import *
diff --git a/Autocoders/src/generators/templates/test_impl/cpp.tmpl b/Autocoders/src/generators/templates/test_impl/cpp.tmpl
index bb3d77fc93..97ec31ecd4 100644
--- a/Autocoders/src/generators/templates/test_impl/cpp.tmpl
+++ b/Autocoders/src/generators/templates/test_impl/cpp.tmpl
@@ -147,6 +147,54 @@ $emit_port_params([ $param_portNum ] + $port_params[$instance])
#end if
#end for
+
+#if len($serial_output_ports) > 0:
+ // ----------------------------------------------------------------------
+ // Connect serial output ports
+ // ----------------------------------------------------------------------
+#for $instance, $sync, $priority, $max_num in $serial_output_ports:
+ #if $max_num == 1 or $max_num == "1":
+ this->component.set_${instance}_OutputPort(
+ 0,
+ this->get_from_${instance}(0)
+ );
+ #else
+ #set LT = "<"
+ for (NATIVE_INT_TYPE i = 0; i $LT $max_num; ++i) {
+ this->component.set_${instance}_OutputPort(
+ i,
+ this->get_from_${instance}(i)
+ );
+ }
+ #end if
+
+#end for
+#end if
+
+#if len($serial_input_ports) > 0:
+ // ----------------------------------------------------------------------
+ // Connect serial input ports
+ // ----------------------------------------------------------------------
+#for $instance, $sync, $priority, $full, $max_num in $serial_input_ports:
+ // $instance
+ #if $max_num == 1 or $max_num == "1":
+ this->connect_to_${instance}(
+ 0,
+ this->component.get_${instance}_InputPort(0)
+ );
+ #else
+ #set LT = "<"
+ for (NATIVE_INT_TYPE i = 0; i $LT $max_num; ++i) {
+ this->connect_to_${instance}(
+ i,
+ this->component.get_${instance}_InputPort(i)
+ );
+ }
+ #end if
+
+#end for
+#end if
+
}
void Tester ::
diff --git a/Autocoders/src/generators/visitors/ChannelVisitor.py b/Autocoders/src/generators/visitors/ChannelVisitor.py
index c13eacd2be..fb9035c15a 100644
--- a/Autocoders/src/generators/visitors/ChannelVisitor.py
+++ b/Autocoders/src/generators/visitors/ChannelVisitor.py
@@ -148,7 +148,7 @@ class ChannelVisitor(AbstractVisitor.AbstractVisitor):
c.ser_import = None
- (c.type,c.ser_import,type_name) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
+ (c.type,c.ser_import,type_name,dontcare) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
# special case for enums and Gse GUI. Needs to convert %d to %s
if type_name == "enum":
c.format_string = "%s"
diff --git a/Autocoders/src/generators/visitors/CommandVisitor.py b/Autocoders/src/generators/visitors/CommandVisitor.py
index 314beec01c..2cdb04a6ad 100644
--- a/Autocoders/src/generators/visitors/CommandVisitor.py
+++ b/Autocoders/src/generators/visitors/CommandVisitor.py
@@ -232,7 +232,7 @@ class CommandVisitor(AbstractVisitor.AbstractVisitor):
for arg_obj in obj.get_args():
# convert XML types to Python classes
- (type_string,ser_import,dontcare) = DictTypeConverter.DictTypeConverter().convert(arg_obj.get_type(),arg_obj.get_size())
+ (type_string,ser_import,dontcare,dontcare2) = DictTypeConverter.DictTypeConverter().convert(arg_obj.get_type(),arg_obj.get_size())
if ser_import != None:
c.ser_import_list.append(ser_import)
c.arglist.append((arg_obj.get_name(),arg_obj.get_comment(),type_string))
@@ -257,7 +257,7 @@ class CommandVisitor(AbstractVisitor.AbstractVisitor):
c.ser_import_list = list()
# convert XML types to Python classes
- (type_string,ser_import,dontcare) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
+ (type_string,ser_import,dontcare,dontcare2) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
if ser_import != None:
c.ser_import_list.append(ser_import)
c.arglist.append((obj.get_name(),obj.get_comment(),type_string))
diff --git a/Autocoders/src/generators/visitors/EventVisitor.py b/Autocoders/src/generators/visitors/EventVisitor.py
index 931875827c..b2a3b9b368 100644
--- a/Autocoders/src/generators/visitors/EventVisitor.py
+++ b/Autocoders/src/generators/visitors/EventVisitor.py
@@ -157,7 +157,7 @@ class EventVisitor(AbstractVisitor.AbstractVisitor):
s = arg_obj.get_size()
d = arg_obj.get_comment()
# convert XML types to Python classes
- (type_string,ser_import,type_name) = DictTypeConverter.DictTypeConverter().convert(t,s)
+ (type_string,ser_import,type_name,dontcare) = DictTypeConverter.DictTypeConverter().convert(t,s)
if ser_import != None:
c.ser_import_list.append(ser_import)
# convert format specifier if necessary
diff --git a/Autocoders/src/generators/visitors/InstanceChannelVisitor.py b/Autocoders/src/generators/visitors/InstanceChannelVisitor.py
index c5af89da64..f5e22288e2 100644
--- a/Autocoders/src/generators/visitors/InstanceChannelVisitor.py
+++ b/Autocoders/src/generators/visitors/InstanceChannelVisitor.py
@@ -169,7 +169,7 @@ class InstanceChannelVisitor(AbstractVisitor.AbstractVisitor):
c.ser_import = None
- (c.type,c.ser_import,type_name) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
+ (c.type,c.ser_import,type_name,dontcare) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
# special case for enums and Gse GUI. Needs to convert %d to %s
if type_name == "enum":
c.format_string = "%s"
diff --git a/Autocoders/src/generators/visitors/InstanceCommandVisitor.py b/Autocoders/src/generators/visitors/InstanceCommandVisitor.py
index 0bda83d908..544ce755e0 100644
--- a/Autocoders/src/generators/visitors/InstanceCommandVisitor.py
+++ b/Autocoders/src/generators/visitors/InstanceCommandVisitor.py
@@ -235,7 +235,7 @@ class InstanceCommandVisitor(AbstractVisitor.AbstractVisitor):
for arg_obj in obj.get_args():
# convert XML types to Python classes
- (type_string,ser_import,dontcare) = DictTypeConverter.DictTypeConverter().convert(arg_obj.get_type(),arg_obj.get_size())
+ (type_string,ser_import,dontcare,dontcare2) = DictTypeConverter.DictTypeConverter().convert(arg_obj.get_type(),arg_obj.get_size())
if ser_import != None:
c.ser_import_list.append(ser_import)
c.arglist.append((arg_obj.get_name(),arg_obj.get_comment(),type_string))
@@ -268,7 +268,7 @@ class InstanceCommandVisitor(AbstractVisitor.AbstractVisitor):
c.ser_import_list = list()
# convert XML types to Python classes
- (type_string,ser_import,dontcare) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
+ (type_string,ser_import,dontcare,dontcare2) = DictTypeConverter.DictTypeConverter().convert(obj.get_type(),obj.get_size())
if ser_import != None:
c.ser_import_list.append(ser_import)
c.arglist.append((obj.get_name(),obj.get_comment(),type_string))
diff --git a/Autocoders/src/generators/visitors/InstanceEventVisitor.py b/Autocoders/src/generators/visitors/InstanceEventVisitor.py
index 25885cf8be..2cf93d4611 100644
--- a/Autocoders/src/generators/visitors/InstanceEventVisitor.py
+++ b/Autocoders/src/generators/visitors/InstanceEventVisitor.py
@@ -177,7 +177,7 @@ class InstanceEventVisitor(AbstractVisitor.AbstractVisitor):
s = arg_obj.get_size()
d = arg_obj.get_comment()
# convert XML types to Python classes
- (type_string,ser_import,type_name) = DictTypeConverter.DictTypeConverter().convert(t,s)
+ (type_string,ser_import,type_name,dontcare) = DictTypeConverter.DictTypeConverter().convert(t,s)
if ser_import != None:
c.ser_import_list.append(ser_import)
# convert format specifier if necessary
diff --git a/Autocoders/src/generators/visitors/InstanceSerializableVisitor.py b/Autocoders/src/generators/visitors/InstanceSerializableVisitor.py
index 94702795a9..21f686a7f0 100644
--- a/Autocoders/src/generators/visitors/InstanceSerializableVisitor.py
+++ b/Autocoders/src/generators/visitors/InstanceSerializableVisitor.py
@@ -228,7 +228,7 @@ class InstanceSerializableVisitor(AbstractVisitor.AbstractVisitor):
c.mem_list = list()
for (n,t,s,f,comment) in obj.get_members():
# convert XML types to Python classes
- (type_string,dontcare,type_name) = DictTypeConverter.DictTypeConverter().convert(t,s)
+ (type_string,dontcare,type_name,use_size) = DictTypeConverter.DictTypeConverter().convert(t,s)
if type_name == "enum":
format_string = DictTypeConverter.DictTypeConverter().format_replace(f,0,'d','s')
# check for an error
@@ -237,7 +237,7 @@ class InstanceSerializableVisitor(AbstractVisitor.AbstractVisitor):
sys.exit(-1)
else:
f = format_string
- c.mem_list.append((n,type_string,f))
+ c.mem_list.append((n,type_string,f,int(s) if use_size else 1))
self._writeTmpl(c, "publicVisit")
diff --git a/Autocoders/src/generators/visitors/PortHVisitor.py b/Autocoders/src/generators/visitors/PortHVisitor.py
index 3d099bbba7..513f55e6b9 100644
--- a/Autocoders/src/generators/visitors/PortHVisitor.py
+++ b/Autocoders/src/generators/visitors/PortHVisitor.py
@@ -219,6 +219,7 @@ class PortHVisitor(AbstractVisitor.AbstractVisitor):
"""
c = startPortH.startPortH()
c.name = obj.get_type
+ c.name_space = obj.get_namespace()
d = datetime.datetime.now()
c.date = d.strftime("%A, %d %B %Y")
c.user = os.environ['USER']
@@ -370,6 +371,7 @@ class PortHVisitor(AbstractVisitor.AbstractVisitor):
else:
c.namespace_list = obj.get_namespace().split('::')
c.name = obj.get_type()
+ c.name_space = obj.get_namespace();
c.desc = obj.get_comment()
c.args_string = self._get_args_string(obj)
r = obj.get_return()
diff --git a/Autocoders/src/generators/visitors/SerializableVisitor.py b/Autocoders/src/generators/visitors/SerializableVisitor.py
index 21fe87e07f..5be16afa59 100644
--- a/Autocoders/src/generators/visitors/SerializableVisitor.py
+++ b/Autocoders/src/generators/visitors/SerializableVisitor.py
@@ -228,7 +228,7 @@ class SerializableVisitor(AbstractVisitor.AbstractVisitor):
c.mem_list = list()
for (n,t,s,f,comment) in obj.get_members():
# convert XML types to Python classes
- (type_string,dontcare,type_name) = DictTypeConverter.DictTypeConverter().convert(t,s)
+ (type_string,dontcare,type_name,use_size) = DictTypeConverter.DictTypeConverter().convert(t,s)
if type_name == "enum":
format_string = DictTypeConverter.DictTypeConverter().format_replace(f,0,'d','s')
# check for an error
@@ -237,7 +237,7 @@ class SerializableVisitor(AbstractVisitor.AbstractVisitor):
sys.exit(-1)
else:
f = format_string
- c.mem_list.append((n,type_string,f))
+ c.mem_list.append((n,type_string,f,int(s) if use_size else 1))
self._writeTmpl(c, "publicVisit")
diff --git a/Autocoders/src/parsers/XmlComponentParser.py b/Autocoders/src/parsers/XmlComponentParser.py
index ce0a469d5b..9cae04982c 100644
--- a/Autocoders/src/parsers/XmlComponentParser.py
+++ b/Autocoders/src/parsers/XmlComponentParser.py
@@ -981,7 +981,7 @@ class XmlComponentParser(object):
def get_imported_dictionary_files(self):
"""
- Return a list of all imported dictonary XML files.
+ Return a list of all imported dictionary XML files.
"""
return self.__import_dictionary_files
diff --git a/Autocoders/src/utils/DictTypeConverter.py b/Autocoders/src/utils/DictTypeConverter.py
index 8be9be746a..ebcc21c760 100644
--- a/Autocoders/src/utils/DictTypeConverter.py
+++ b/Autocoders/src/utils/DictTypeConverter.py
@@ -10,6 +10,7 @@ class DictTypeConverter(object):
type_string = ""
type_name = t
ser_import = None
+ use_size = False if size is None else True
# check for enums
if (type(t) == type(tuple())):
# extract enumeration arguments
@@ -34,6 +35,7 @@ class DictTypeConverter(object):
type_name = "enum"
# otherwise, lookup type translation in table
elif t == "string":
+ use_size = False
type_string += "StringType(max_string_len=%s)"%size
else:
type_lookup = {
@@ -56,7 +58,7 @@ class DictTypeConverter(object):
ser_type = t.split("::")
type_string += "%s.%s()" %(".".join(ser_type),ser_type[-1])
ser_import = ".".join(ser_type)
- return (type_string,ser_import,type_name)
+ return (type_string,ser_import,type_name,use_size)
def format_replace(self, format_string, spec_num, old, new):
"""
diff --git a/Autocoders/test/command1/test/ut/GTestBase.cpp b/Autocoders/test/command1/test/ut/GTestBase.cpp
index c28a2c8481..eec51d73ff 100644
--- a/Autocoders/test/command1/test/ut/GTestBase.cpp
+++ b/Autocoders/test/command1/test/ut/GTestBase.cpp
@@ -74,28 +74,28 @@ namespace Cmd {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -104,7 +104,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -113,7 +113,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
diff --git a/Autocoders/test/command1/test/ut/GTestBase.hpp b/Autocoders/test/command1/test/ut/GTestBase.hpp
index f058c57ed6..3804b8bdf0 100644
--- a/Autocoders/test/command1/test/ut/GTestBase.hpp
+++ b/Autocoders/test/command1/test/ut/GTestBase.hpp
@@ -82,7 +82,7 @@ namespace Cmd {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
diff --git a/Autocoders/test/command2/test/ut/GTestBase.cpp b/Autocoders/test/command2/test/ut/GTestBase.cpp
index b27753e562..fc12af7e80 100644
--- a/Autocoders/test/command2/test/ut/GTestBase.cpp
+++ b/Autocoders/test/command2/test/ut/GTestBase.cpp
@@ -74,28 +74,28 @@ namespace AcTest {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -104,7 +104,7 @@ namespace AcTest {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -113,7 +113,7 @@ namespace AcTest {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
diff --git a/Autocoders/test/command2/test/ut/GTestBase.hpp b/Autocoders/test/command2/test/ut/GTestBase.hpp
index 121ca7fb34..0aebd6cbd3 100644
--- a/Autocoders/test/command2/test/ut/GTestBase.hpp
+++ b/Autocoders/test/command2/test/ut/GTestBase.hpp
@@ -82,7 +82,7 @@ namespace AcTest {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
diff --git a/Autocoders/test/command_res/test/ut/GTestBase.cpp b/Autocoders/test/command_res/test/ut/GTestBase.cpp
index c28a2c8481..eec51d73ff 100644
--- a/Autocoders/test/command_res/test/ut/GTestBase.cpp
+++ b/Autocoders/test/command_res/test/ut/GTestBase.cpp
@@ -74,28 +74,28 @@ namespace Cmd {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -104,7 +104,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -113,7 +113,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
diff --git a/Autocoders/test/command_res/test/ut/GTestBase.hpp b/Autocoders/test/command_res/test/ut/GTestBase.hpp
index f058c57ed6..3804b8bdf0 100644
--- a/Autocoders/test/command_res/test/ut/GTestBase.hpp
+++ b/Autocoders/test/command_res/test/ut/GTestBase.hpp
@@ -82,7 +82,7 @@ namespace Cmd {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
diff --git a/Autocoders/test/command_string/test/ut/GTestBase.cpp b/Autocoders/test/command_string/test/ut/GTestBase.cpp
index b27753e562..fc12af7e80 100644
--- a/Autocoders/test/command_string/test/ut/GTestBase.cpp
+++ b/Autocoders/test/command_string/test/ut/GTestBase.cpp
@@ -74,28 +74,28 @@ namespace AcTest {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -104,7 +104,7 @@ namespace AcTest {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -113,7 +113,7 @@ namespace AcTest {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
diff --git a/Autocoders/test/command_string/test/ut/GTestBase.hpp b/Autocoders/test/command_string/test/ut/GTestBase.hpp
index 121ca7fb34..0aebd6cbd3 100644
--- a/Autocoders/test/command_string/test/ut/GTestBase.hpp
+++ b/Autocoders/test/command_string/test/ut/GTestBase.hpp
@@ -82,7 +82,7 @@ namespace AcTest {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
diff --git a/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.cpp b/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.cpp
index 5fef159ea0..0854f594ff 100644
--- a/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.cpp
+++ b/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.cpp
@@ -75,28 +75,28 @@ namespace Components {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -105,7 +105,7 @@ namespace Components {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -114,7 +114,7 @@ namespace Components {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
@@ -164,27 +164,27 @@ namespace Components {
assertTlm_somechan(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const Ref::Gnc::Quaternion& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_somechan->size())
+ ASSERT_LT(__index, this->tlmHistory_somechan->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel somechan\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_somechan->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_somechan& e =
- this->tlmHistory_somechan->at(index);
+ this->tlmHistory_somechan->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel somechan\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
@@ -234,28 +234,28 @@ namespace Components {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const Ref::Gnc::Quaternion arg1,
const F32 arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -264,7 +264,7 @@ namespace Components {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -273,7 +273,7 @@ namespace Components {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.hpp b/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.hpp
index 69daffe5c9..fc2ebb5f81 100644
--- a/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.hpp
+++ b/Autocoders/test/comp_diff_namespace/test/ut/GTestBase.hpp
@@ -110,7 +110,7 @@ namespace Components {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
@@ -147,7 +147,7 @@ namespace Components {
void assertTlm_somechan(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const Ref::Gnc::Quaternion& val /*!< The channel value*/
) const;
@@ -178,7 +178,7 @@ namespace Components {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const Ref::Gnc::Quaternion arg1, /*!< The quaternion command argument*/
const F32 arg2, /*!< The F32 command argument*/
const U8 arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/event1/test/ut/GTestBase.cpp b/Autocoders/test/event1/test/ut/GTestBase.cpp
index 23397d08a3..01e8148adf 100644
--- a/Autocoders/test/event1/test/ut/GTestBase.cpp
+++ b/Autocoders/test/event1/test/ut/GTestBase.cpp
@@ -94,28 +94,28 @@ namespace Somewhere {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
const F32 arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -124,7 +124,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -133,7 +133,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/event1/test/ut/GTestBase.hpp b/Autocoders/test/event1/test/ut/GTestBase.hpp
index 923a9cb40e..197acdd56b 100644
--- a/Autocoders/test/event1/test/ut/GTestBase.hpp
+++ b/Autocoders/test/event1/test/ut/GTestBase.hpp
@@ -93,7 +93,7 @@ namespace Somewhere {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
const F32 arg2, /*!< The F32 command argument*/
const U8 arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/event2/test/ut/GTestBase.cpp b/Autocoders/test/event2/test/ut/GTestBase.cpp
index 765fde56a6..0795cd62a2 100644
--- a/Autocoders/test/event2/test/ut/GTestBase.cpp
+++ b/Autocoders/test/event2/test/ut/GTestBase.cpp
@@ -94,28 +94,28 @@ namespace Cmd {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
const F32 arg2,
const Ref::Gnc::Quaternion arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -124,7 +124,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -133,7 +133,7 @@ namespace Cmd {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/event2/test/ut/GTestBase.hpp b/Autocoders/test/event2/test/ut/GTestBase.hpp
index 3d382e4294..e0b82f5282 100644
--- a/Autocoders/test/event2/test/ut/GTestBase.hpp
+++ b/Autocoders/test/event2/test/ut/GTestBase.hpp
@@ -93,7 +93,7 @@ namespace Cmd {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
const F32 arg2, /*!< The F32 command argument*/
const Ref::Gnc::Quaternion arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/event_enum/test/ut/GTestBase.cpp b/Autocoders/test/event_enum/test/ut/GTestBase.cpp
index cb92dfdc79..7f43045e71 100644
--- a/Autocoders/test/event_enum/test/ut/GTestBase.cpp
+++ b/Autocoders/test/event_enum/test/ut/GTestBase.cpp
@@ -94,28 +94,28 @@ namespace Somewhere {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
TestLogComponentBase::SomeEnum arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -124,7 +124,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -133,7 +133,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/event_enum/test/ut/GTestBase.hpp b/Autocoders/test/event_enum/test/ut/GTestBase.hpp
index ced51d2256..04f3314f67 100644
--- a/Autocoders/test/event_enum/test/ut/GTestBase.hpp
+++ b/Autocoders/test/event_enum/test/ut/GTestBase.hpp
@@ -93,7 +93,7 @@ namespace Somewhere {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
TestLogComponentBase::SomeEnum arg2, /*!< The enum command argument*/
const U8 arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/event_string/test/ut/GTestBase.cpp b/Autocoders/test/event_string/test/ut/GTestBase.cpp
index 74a8aae98f..5bea25dcd9 100644
--- a/Autocoders/test/event_string/test/ut/GTestBase.cpp
+++ b/Autocoders/test/event_string/test/ut/GTestBase.cpp
@@ -94,28 +94,28 @@ namespace Somewhere {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
const char *const arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -124,7 +124,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2.toChar() << "\n";
@@ -133,7 +133,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/event_string/test/ut/GTestBase.hpp b/Autocoders/test/event_string/test/ut/GTestBase.hpp
index 76f0b87324..90855f94db 100644
--- a/Autocoders/test/event_string/test/ut/GTestBase.hpp
+++ b/Autocoders/test/event_string/test/ut/GTestBase.hpp
@@ -93,7 +93,7 @@ namespace Somewhere {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
const char *const arg2, /*!< The F32 command argument*/
const U8 arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/event_throttle/test/ut/GTestBase.cpp b/Autocoders/test/event_throttle/test/ut/GTestBase.cpp
index 74509758a5..169d6d3349 100644
--- a/Autocoders/test/event_throttle/test/ut/GTestBase.cpp
+++ b/Autocoders/test/event_throttle/test/ut/GTestBase.cpp
@@ -94,28 +94,28 @@ namespace Somewhere {
assertEvents_SomeEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
const F32 arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeEvent& e =
- this->eventHistory_SomeEvent->at(index);
+ this->eventHistory_SomeEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -124,7 +124,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -133,7 +133,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
@@ -163,28 +163,28 @@ namespace Somewhere {
assertEvents_SomeOtherEvent(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const I32 arg1,
const F32 arg2,
const U8 arg3
) const
{
- ASSERT_GT(this->eventHistory_SomeOtherEvent->size(), index)
+ ASSERT_GT(this->eventHistory_SomeOtherEvent->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event SomeOtherEvent\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_SomeOtherEvent->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_SomeOtherEvent& e =
- this->eventHistory_SomeOtherEvent->at(index);
+ this->eventHistory_SomeOtherEvent->at(__index);
ASSERT_EQ(arg1, e.arg1)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg1 at index "
- << index
+ << __index
<< " in history of event SomeOtherEvent\n"
<< " Expected: " << arg1 << "\n"
<< " Actual: " << e.arg1 << "\n";
@@ -193,7 +193,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg2 at index "
- << index
+ << __index
<< " in history of event SomeOtherEvent\n"
<< " Expected: " << arg2 << "\n"
<< " Actual: " << e.arg2 << "\n";
@@ -202,7 +202,7 @@ namespace Somewhere {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument arg3 at index "
- << index
+ << __index
<< " in history of event SomeOtherEvent\n"
<< " Expected: " << arg3 << "\n"
<< " Actual: " << e.arg3 << "\n";
diff --git a/Autocoders/test/event_throttle/test/ut/GTestBase.hpp b/Autocoders/test/event_throttle/test/ut/GTestBase.hpp
index 52e708c00e..0398b6d27c 100644
--- a/Autocoders/test/event_throttle/test/ut/GTestBase.hpp
+++ b/Autocoders/test/event_throttle/test/ut/GTestBase.hpp
@@ -99,7 +99,7 @@ namespace Somewhere {
void assertEvents_SomeEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
const F32 arg2, /*!< The F32 command argument*/
const U8 arg3 /*!< The U8 command argument*/
@@ -120,7 +120,7 @@ namespace Somewhere {
void assertEvents_SomeOtherEvent(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const I32 arg1, /*!< The I32 command argument*/
const F32 arg2, /*!< The F32 command argument*/
const U8 arg3 /*!< The U8 command argument*/
diff --git a/Autocoders/test/tlm1/test/ut/GTestBase.cpp b/Autocoders/test/tlm1/test/ut/GTestBase.cpp
index 9c5b2703b8..e80b0dcb77 100644
--- a/Autocoders/test/tlm1/test/ut/GTestBase.cpp
+++ b/Autocoders/test/tlm1/test/ut/GTestBase.cpp
@@ -94,27 +94,27 @@ namespace Tlm {
assertTlm_somechan(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_somechan->size())
+ ASSERT_LT(__index, this->tlmHistory_somechan->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel somechan\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_somechan->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_somechan& e =
- this->tlmHistory_somechan->at(index);
+ this->tlmHistory_somechan->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel somechan\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
diff --git a/Autocoders/test/tlm1/test/ut/GTestBase.hpp b/Autocoders/test/tlm1/test/ut/GTestBase.hpp
index 87bafb8b4c..988c7c2a85 100644
--- a/Autocoders/test/tlm1/test/ut/GTestBase.hpp
+++ b/Autocoders/test/tlm1/test/ut/GTestBase.hpp
@@ -97,7 +97,7 @@ namespace Tlm {
void assertTlm_somechan(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32& val /*!< The channel value*/
) const;
diff --git a/Autocoders/test/tlm2/test/ut/GTestBase.cpp b/Autocoders/test/tlm2/test/ut/GTestBase.cpp
index b8911c7524..0f22a3e0fc 100644
--- a/Autocoders/test/tlm2/test/ut/GTestBase.cpp
+++ b/Autocoders/test/tlm2/test/ut/GTestBase.cpp
@@ -94,27 +94,27 @@ namespace Tlm {
assertTlm_AQuat(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const Ref::Gnc::Quaternion& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_AQuat->size())
+ ASSERT_LT(__index, this->tlmHistory_AQuat->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel AQuat\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_AQuat->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_AQuat& e =
- this->tlmHistory_AQuat->at(index);
+ this->tlmHistory_AQuat->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel AQuat\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
diff --git a/Autocoders/test/tlm2/test/ut/GTestBase.hpp b/Autocoders/test/tlm2/test/ut/GTestBase.hpp
index e6570b4db1..2dc8e682d9 100644
--- a/Autocoders/test/tlm2/test/ut/GTestBase.hpp
+++ b/Autocoders/test/tlm2/test/ut/GTestBase.hpp
@@ -97,7 +97,7 @@ namespace Tlm {
void assertTlm_AQuat(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const Ref::Gnc::Quaternion& val /*!< The channel value*/
) const;
diff --git a/Drv/BlockDriver/BlockDriverComponentAi.xml b/Drv/BlockDriver/BlockDriverComponentAi.xml
index b814389801..ec8f0e33a9 100644
--- a/Drv/BlockDriver/BlockDriverComponentAi.xml
+++ b/Drv/BlockDriver/BlockDriverComponentAi.xml
@@ -11,6 +11,7 @@
Svc/Cycle/CyclePortAi.xmlDrv/DataTypes/DataBufferPortAi.xmlSvc/Ping/PingPortAi.xml
+ Drv/BlockDriver/Tlm.xmlAn example block driver component with data buffers and interrupts
@@ -54,13 +55,6 @@
-
-
-
- Driver cycle count
-
-
-
diff --git a/Drv/LinuxGpioDriver/Events.xml b/Drv/LinuxGpioDriver/Events.xml
index aa5e8306a8..bb097e8726 100755
--- a/Drv/LinuxGpioDriver/Events.xml
+++ b/Drv/LinuxGpioDriver/Events.xml
@@ -1,6 +1,6 @@
-
+
Open error
@@ -11,6 +11,9 @@
The error code
+
+ The error string
+
diff --git a/Drv/LinuxGpioDriver/LinuxGpioDriverComponentImpl.cpp b/Drv/LinuxGpioDriver/LinuxGpioDriverComponentImpl.cpp
index 760064397b..156054b2c2 100755
--- a/Drv/LinuxGpioDriver/LinuxGpioDriverComponentImpl.cpp
+++ b/Drv/LinuxGpioDriver/LinuxGpioDriverComponentImpl.cpp
@@ -181,7 +181,7 @@ namespace Drv {
* gpio_set_edge
****************************************************************/
- int gpio_set_edge(unsigned int gpio, char *edge)
+ int gpio_set_edge(unsigned int gpio, const char *edge)
{
int fd, len;
char buf[MAX_BUF];
@@ -288,11 +288,15 @@ namespace Drv {
// Configure:
stat = gpio_export(gpio);
if (-1 == stat) {
- this->log_WARNING_HI_GP_OpenError(gpio,this->m_fd);
+ Fw::LogStringArg arg = strerror(errno);
+ this->log_WARNING_HI_GP_OpenError(gpio,stat,arg);
+ return false;
}
stat = gpio_set_dir(gpio, direction == GPIO_OUT ? 1 : 0);
if (-1 == stat) {
- this->log_WARNING_HI_GP_OpenError(gpio,this->m_fd);
+ Fw::LogStringArg arg = strerror(errno);
+ this->log_WARNING_HI_GP_OpenError(gpio,stat,arg);
+ return false;
}
// If needed, set edge to rising in intTaskEntry()
@@ -300,7 +304,8 @@ namespace Drv {
// Open:
this->m_fd = gpio_fd_open(gpio);
if (-1 == this->m_fd) {
- this->log_WARNING_HI_GP_OpenError(gpio,this->m_fd);
+ Fw::LogStringArg arg = strerror(errno);
+ this->log_WARNING_HI_GP_OpenError(gpio,errno,arg);
} else {
this->m_gpio = gpio;
}
diff --git a/Drv/LinuxGpioDriver/docs/LinuxGpioDriver.md b/Drv/LinuxGpioDriver/docs/LinuxGpioDriver.md
index f99f4bb5a4..2ee3618dc9 100644
--- a/Drv/LinuxGpioDriver/docs/LinuxGpioDriver.md
+++ b/Drv/LinuxGpioDriver/docs/LinuxGpioDriver.md
@@ -10,6 +10,7 @@
|GP_OpenError|0 (0x0)|Open error| | | | |
| | | |gpio|I32||The device|
| | | |error|I32||The error code|
+| | | |msg|Fw::LogStringArg&|40|The error string|
|GP_ConfigError|1 (0x1)|GPIO configure error| | | | |
| | | |gpio|I32||The device|
| | | |error|I32||The error code|
diff --git a/Drv/LinuxGpioDriver/mod.mk b/Drv/LinuxGpioDriver/mod.mk
index c787a3eda2..79b026ab72 100755
--- a/Drv/LinuxGpioDriver/mod.mk
+++ b/Drv/LinuxGpioDriver/mod.mk
@@ -21,9 +21,11 @@ SRC_CYGWIN = LinuxGpioDriverComponentImpl.cpp
SRC_DARWIN = LinuxGpioDriverComponentImplStub.cpp
+SRC_RASPIAN = LinuxGpioDriverComponentImpl.cpp
+
+SRC_LINUXRT = LinuxGpioDriverComponentImpl.cpp
+
HDR = LinuxGpioDriverComponentImpl.hpp
SUBDIRS = test
-
-SRC_LINUXRT = LinuxGpioDriverComponentImpl.cpp
diff --git a/Drv/LinuxSerialDriver/Events.xml b/Drv/LinuxSerialDriver/Events.xml
index f351b6cce0..fb3bc317a1 100644
--- a/Drv/LinuxSerialDriver/Events.xml
+++ b/Drv/LinuxSerialDriver/Events.xml
@@ -1,6 +1,6 @@
-
+
UART open error
@@ -11,6 +11,9 @@
The error code
+
+ error string
+
diff --git a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.cpp b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.cpp
index ad941fccfd..fb29ef4662 100644
--- a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.cpp
+++ b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.cpp
@@ -41,7 +41,7 @@ namespace Drv {
// Construction, initialization, and destruction
// ----------------------------------------------------------------------
- void LinuxSerialDriverComponentImpl::open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block) {
+ bool LinuxSerialDriverComponentImpl::open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block) {
/*
Their config:
@@ -78,8 +78,9 @@ namespace Drv {
if (fd == -1) {
DEBUG_PRINT("open UART device %s failed.\n", device);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,this->m_fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,this->m_fd,_err);
+ return false;
} else {
DEBUG_PRINT("Successfully opened UART device %s fd %d\n", device, fd);
}
@@ -94,8 +95,9 @@ namespace Drv {
DEBUG_PRINT("tcgetattr failed: (%d): %s\n",stat,strerror(errno));
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
} else {
DEBUG_PRINT("tcgetattr passed.\n");
}
@@ -119,8 +121,9 @@ namespace Drv {
DEBUG_PRINT("tcsetattr failed: (%d): %s\n",stat,strerror(errno));
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
} else {
DEBUG_PRINT("tcsetattr passed.\n");
}
@@ -135,8 +138,9 @@ namespace Drv {
DEBUG_PRINT("tcgetattr UART fd %d failed\n", fd);
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
}
// modify flow control flags
@@ -147,8 +151,9 @@ namespace Drv {
DEBUG_PRINT("tcsetattr UART fd %d failed\n", fd);
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
}
}
@@ -191,8 +196,9 @@ namespace Drv {
DEBUG_PRINT("tcgetattr UART fd %d failed\n", fd);
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
}
// CS8 = 8 data bits, CLOCAL = Local line, CREAD = Enable Reciever
@@ -251,14 +257,15 @@ namespace Drv {
DEBUG_PRINT("tcsetattr UART fd %d failed\n", fd);
close(fd);
Fw::LogStringArg _arg = device;
- this->log_WARNING_HI_DR_OpenError(_arg,fd);
- return;
+ Fw::LogStringArg _err = strerror(errno);
+ this->log_WARNING_HI_DR_OpenError(_arg,fd,_err);
+ return false;
}
// All done!
Fw::LogStringArg _arg = device;
this->log_ACTIVITY_HI_DR_PortOpened(_arg);
-
+ return true;
}
LinuxSerialDriverComponentImpl ::
diff --git a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.hpp b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.hpp
index 81daaced9a..289b776e10 100644
--- a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.hpp
+++ b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImpl.hpp
@@ -76,7 +76,7 @@ namespace Drv {
} UartParity;
// Open device with specified baud and flow control.
- void open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block);
+ bool open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block);
//! start the serial poll thread.
//! buffSize is the max receive buffer size
@@ -107,7 +107,7 @@ namespace Drv {
//!
void readBufferSend_handler(
const NATIVE_INT_TYPE portNum, /*!< The port number*/
- Fw::Buffer fwBuffer
+ Fw::Buffer& fwBuffer
);
NATIVE_INT_TYPE m_fd; //!< file descriptor returned for I/O device
diff --git a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplCommon.cpp b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplCommon.cpp
index 3ece35df26..837c3f9b29 100644
--- a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplCommon.cpp
+++ b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplCommon.cpp
@@ -44,7 +44,7 @@ namespace Drv {
void LinuxSerialDriverComponentImpl ::
readBufferSend_handler(
const NATIVE_INT_TYPE portNum,
- Fw::Buffer Buffer
+ Fw::Buffer& Buffer
)
{
this->m_readBuffMutex.lock();
diff --git a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplStub.cpp b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplStub.cpp
index 934dd5b2cc..b52383ba4f 100644
--- a/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplStub.cpp
+++ b/Drv/LinuxSerialDriver/LinuxSerialDriverComponentImplStub.cpp
@@ -45,7 +45,7 @@ namespace Drv {
startReadThread(NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize, NATIVE_INT_TYPE cpuAffinity) {
}
- void LinuxSerialDriverComponentImpl::open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block) {
+ bool LinuxSerialDriverComponentImpl::open(const char* const device, UartBaudRate baud, UartFlowControl fc, UartParity parity, bool block) {
}
diff --git a/Drv/LinuxSerialDriver/docs/LinuxSerialDriver.md b/Drv/LinuxSerialDriver/docs/LinuxSerialDriver.md
index 536a85216e..25e1bbef0d 100644
--- a/Drv/LinuxSerialDriver/docs/LinuxSerialDriver.md
+++ b/Drv/LinuxSerialDriver/docs/LinuxSerialDriver.md
@@ -16,6 +16,7 @@
|DR_OpenError|0 (0x0)|UART open error| | | | |
| | | |device|Fw::LogStringArg&|40|The device|
| | | |error|I32||The error code|
+| | | |name|Fw::LogStringArg&|40|error string|
|DR_ConfigError|1 (0x1)|UART config error| | | | |
| | | |device|Fw::LogStringArg&|40|The device|
| | | |error|I32||The error code|
diff --git a/Drv/LinuxSerialDriver/mod.mk b/Drv/LinuxSerialDriver/mod.mk
index 3fe4a6a195..9b8efc2f06 100755
--- a/Drv/LinuxSerialDriver/mod.mk
+++ b/Drv/LinuxSerialDriver/mod.mk
@@ -21,8 +21,11 @@ SRC_CYGWIN = LinuxSerialDriverComponentImpl.cpp
SRC_DARWIN = LinuxSerialDriverComponentImplStub.cpp
+SRC_RASPIAN = LinuxSerialDriverComponentImpl.cpp
+
+SRC_LINUXRT = LinuxSerialDriverComponentImpl.cpp
+
HDR = LinuxSerialDriverComponentImpl.hpp
SUBDIRS = test
-SRC_LINUXRT = LinuxSerialDriverComponentImpl.cpp
diff --git a/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp b/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp
index 54e7e5b198..05aa897ad7 100644
--- a/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp
+++ b/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.cpp
@@ -73,10 +73,11 @@ namespace Drv {
}
this->m_bytes += readBuffer.getsize();
this->tlmWrite_SPI_Bytes(this->m_bytes);
+ return;
}
- void LinuxSpiDriverComponentImpl::open(NATIVE_INT_TYPE device,
+ bool LinuxSpiDriverComponentImpl::open(NATIVE_INT_TYPE device,
NATIVE_INT_TYPE select,
SpiFrequency clock) {
@@ -96,7 +97,7 @@ namespace Drv {
if (fd == -1) {
DEBUG_PRINT("open SPI device %d.%d failed. %d\n",device,select,errno);
this->log_WARNING_HI_SPI_OpenError(device,select,fd);
- return;
+ return false;
} else {
DEBUG_PRINT("Successfully opened SPI device %s fd %d\n",devName,fd);
}
@@ -112,7 +113,7 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_MODE fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d WR mode successfully configured to %d\n",fd,mode);
}
@@ -121,7 +122,7 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_MODE fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d RD mode successfully configured to %d\n",fd,mode);
}
@@ -134,7 +135,7 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_BITS_PER_WORD fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d WR bits per word successfully configured to %d\n",fd,bits);
}
@@ -143,7 +144,7 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_BITS_PER_WORD fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d RD bits per word successfully configured to %d\n",fd,bits);
}
@@ -155,7 +156,7 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_WR_MAX_SPEED_HZ fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d WR freq successfully configured to %d\n",fd,clock);
}
@@ -164,11 +165,13 @@ namespace Drv {
if (ret == -1) {
DEBUG_PRINT("ioctl SPI_IOC_RD_MAX_SPEED_HZ fd %d failed. %d\n",fd,errno);
this->log_WARNING_HI_SPI_ConfigError(device,select,ret);
- return;
+ return false;
} else {
DEBUG_PRINT("SPI fd %d RD freq successfully configured to %d\n",fd,clock);
}
+ return true;
+
}
LinuxSpiDriverComponentImpl::~LinuxSpiDriverComponentImpl(void) {
diff --git a/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.hpp b/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.hpp
index a90dcb65fe..efdd8a27c5 100644
--- a/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.hpp
+++ b/Drv/LinuxSpiDriver/LinuxSpiDriverComponentImpl.hpp
@@ -68,7 +68,7 @@ namespace Drv {
~LinuxSpiDriverComponentImpl(void);
//! Open device
- void open(NATIVE_INT_TYPE device,
+ bool open(NATIVE_INT_TYPE device,
NATIVE_INT_TYPE select,
SpiFrequency clock);
diff --git a/Drv/LinuxSpiDriver/mod.mk b/Drv/LinuxSpiDriver/mod.mk
index 065d516190..f3cc8c55de 100755
--- a/Drv/LinuxSpiDriver/mod.mk
+++ b/Drv/LinuxSpiDriver/mod.mk
@@ -21,9 +21,12 @@ SRC_CYGWIN = LinuxSpiDriverComponentImpl.cpp
SRC_DARWIN = LinuxSpiDriverComponentImplStub.cpp
+SRC_RASPIAN = LinuxSpiDriverComponentImpl.cpp
+
+SRC_LINUXRT = LinuxSpiDriverComponentImpl.cpp
+
HDR = LinuxSpiDriverComponentImpl.hpp
SUBDIRS = test
-SRC_LINUXRT = LinuxSpiDriverComponentImpl.cpp
diff --git a/Fw/Cfg/AcConstants.ini b/Fw/Cfg/AcConstants.ini
index 9a82d394ee..338ff61bf8 100644
--- a/Fw/Cfg/AcConstants.ini
+++ b/Fw/Cfg/AcConstants.ini
@@ -2,10 +2,10 @@
[Component]
-# Define numbers of ports
+# Define numbers of ports
ActiveRateGroupOutputPorts = 10 ; Number of rate group member output ports for ActiveRateGroup
-CmdDispatcherComponentCommandPorts = 20 ; Used for command and registration ports
+CmdDispatcherComponentCommandPorts = 30 ; Used for command and registration ports
CmdDispatcherSequencePorts = 5 ; Used for uplink/sequencer buffer/response ports
RateGroupDriverRateGroupPorts = 3 ; Used to drive rate groups
HealthPingPorts = 25 ; Used to ping active components
diff --git a/Fw/Cfg/Config.hpp b/Fw/Cfg/Config.hpp
index c386c4e62e..cb16f9eb27 100644
--- a/Fw/Cfg/Config.hpp
+++ b/Fw/Cfg/Config.hpp
@@ -161,7 +161,7 @@
// Define max length of assert string
#ifndef FW_ASSERT_TEXT_SIZE
-#define FW_ASSERT_TEXT_SIZE 80 //!< Size of string used to store assert description
+#define FW_ASSERT_TEXT_SIZE 120 //!< Size of string used to store assert description
#endif
// Adjust various configuration parameters in the architecture. Some of the above enables may disable some of the values
@@ -169,7 +169,7 @@
// The size of the object name stored in the object base class. Larger names will be truncated.
#if FW_OBJECT_NAMES
#ifndef FW_OBJ_NAME_MAX_SIZE
- #define FW_OBJ_NAME_MAX_SIZE 80 //!< Size of object name (if object names enabled)
+ #define FW_OBJ_NAME_MAX_SIZE 120 //!< Size of object name (if object names enabled)
#endif
#endif
@@ -242,7 +242,7 @@
// Specifies the maximum size of a string in a log event
#ifndef FW_LOG_STRING_MAX_SIZE
-#define FW_LOG_STRING_MAX_SIZE 80 //!< Max size of log string parameter type
+#define FW_LOG_STRING_MAX_SIZE 100 //!< Max size of log string parameter type
#endif
// Specifies the size of the buffer that contains the serialized telemetry value.
diff --git a/Fw/Com/ComPacket.hpp b/Fw/Com/ComPacket.hpp
index 3e7c179b14..86630f626a 100644
--- a/Fw/Com/ComPacket.hpp
+++ b/Fw/Com/ComPacket.hpp
@@ -23,6 +23,8 @@ namespace Fw {
FW_PACKET_TELEM, // !< Telemetry packet type - outgoing
FW_PACKET_LOG, // !< Log type - outgoing
FW_PACKET_FILE, // !< File type - incoming and outgoing
+ FW_PACKET_PACKETIZED_TLM, // !< Packetized telemetry packet type
+ FW_PACKET_IDLE, // !< Idle packet
FW_PACKET_UNKNOWN = 0xFF // !< Unknown packet
} ComPacketType;
diff --git a/Fw/Comp/ActiveComponentBase.cpp b/Fw/Comp/ActiveComponentBase.cpp
index 9a4ad704ae..001b97193a 100644
--- a/Fw/Comp/ActiveComponentBase.cpp
+++ b/Fw/Comp/ActiveComponentBase.cpp
@@ -4,30 +4,32 @@
#include
#include
+//#define DEBUG_PRINT(x,...) printf(x,##__VA_ARGS__); fflush(stdout)
+#define DEBUG_PRINT(x,...)
namespace Fw {
-
+
class ActiveComponentExitSerializableBuffer : public Fw::SerializeBufferBase {
-
+
public:
NATIVE_UINT_TYPE getBuffCapacity(void) const {
return sizeof(m_buff);
}
-
+
U8* getBuffAddr(void) {
return m_buff;
}
-
+
const U8* getBuffAddr(void) const {
return m_buff;
}
private:
-
+
U8 m_buff[sizeof(ActiveComponentBase::ACTIVE_COMPONENT_EXIT)];
-
+
};
-
+
#if FW_OBJECT_NAMES == 1
ActiveComponentBase::ActiveComponentBase(const char* name) : QueuedComponentBase(name) {
@@ -38,9 +40,9 @@ namespace Fw {
}
#endif
ActiveComponentBase::~ActiveComponentBase() {
-
+ DEBUG_PRINT("ActiveComponent %s destructor.\n",this->getObjName());
}
-
+
void ActiveComponentBase::init(NATIVE_INT_TYPE instance) {
QueuedComponentBase::init(instance);
}
@@ -51,11 +53,11 @@ namespace Fw {
buffer[size-1] = 0;
}
#endif
-
- void ActiveComponentBase::start(NATIVE_INT_TYPE identifier, NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize) {
-
+
+ void ActiveComponentBase::start(NATIVE_INT_TYPE identifier, NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize, NATIVE_INT_TYPE cpuAffinity) {
+
Fw::EightyCharString taskName;
-
+
#if FW_OBJECT_NAMES == 1
taskName = this->getObjName();
#else
@@ -63,18 +65,22 @@ namespace Fw {
(void)snprintf(taskNameChar,sizeof(taskNameChar),"ActComp_%d",Os::Task::getNumTasks());
taskName = taskNameChar;
#endif
-
- Os::Task::TaskStatus status = this->m_task.start(taskName, identifier, priority, stackSize, this->s_baseTask,
- this);
+
+ Os::Task::TaskStatus status = this->m_task.start(taskName, identifier, priority, stackSize, this->s_baseTask,this, cpuAffinity);
FW_ASSERT(status == Os::Task::TASK_OK,(NATIVE_INT_TYPE)status);
}
-
+
void ActiveComponentBase::exit(void) {
ActiveComponentExitSerializableBuffer exitBuff;
SerializeStatus stat = exitBuff.serialize((I32)ACTIVE_COMPONENT_EXIT);
FW_ASSERT(FW_SERIALIZE_OK == stat,static_cast(stat));
- Os::Queue::QueueStatus qStat = this->m_queue.send(exitBuff,0,Os::Queue::QUEUE_NONBLOCKING);
- FW_ASSERT(Os::Queue::QUEUE_OK == qStat,static_cast(qStat));
+ (void)this->m_queue.send(exitBuff,0,Os::Queue::QUEUE_NONBLOCKING);
+ DEBUG_PRINT("exit %s\n", this->getObjName());
+ }
+
+ Os::Task::TaskStatus ActiveComponentBase::join(void **value_ptr) {
+ DEBUG_PRINT("join %s\n", this->getObjName());
+ return this->m_task.join(value_ptr);
}
void ActiveComponentBase::s_baseTask(void* ptr) {
@@ -107,9 +113,9 @@ namespace Fw {
FW_ASSERT(0,(NATIVE_INT_TYPE)loopStatus);
}
}
-
+
}
-
+
void ActiveComponentBase::preamble(void) {
}
diff --git a/Fw/Comp/ActiveComponentBase.hpp b/Fw/Comp/ActiveComponentBase.hpp
index 9a1f3e8069..ed97bc4d67 100644
--- a/Fw/Comp/ActiveComponentBase.hpp
+++ b/Fw/Comp/ActiveComponentBase.hpp
@@ -19,8 +19,9 @@
namespace Fw {
class ActiveComponentBase : public QueuedComponentBase {
public:
- void start(NATIVE_INT_TYPE identifier, NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize); //!< called by instantiator when task is to be started
+ void start(NATIVE_INT_TYPE identifier, NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize, NATIVE_INT_TYPE cpuAffinity = -1); //!< called by instantiator when task is to be started
void exit(void); //!< exit task in active component
+ Os::Task::TaskStatus join(void **value_ptr); //!< provide return value of thread if value_ptr is not NULL
enum {
ACTIVE_COMPONENT_EXIT //!< message to exit active component task
@@ -31,7 +32,7 @@ namespace Fw {
ActiveComponentBase(const char* name); //!< Constructor
#else
ActiveComponentBase(); //!< Constructor
-#endif
+#endif
virtual ~ActiveComponentBase(); //!< Destructor
void init(NATIVE_INT_TYPE instance); //!< initialization code
virtual void preamble(void); //!< A function that will be called before the event loop is entered
diff --git a/Fw/FilePacket/FilePacket.cpp b/Fw/FilePacket/FilePacket.cpp
index 604a9b4520..3ac4aad3ad 100644
--- a/Fw/FilePacket/FilePacket.cpp
+++ b/Fw/FilePacket/FilePacket.cpp
@@ -166,8 +166,8 @@ namespace Fw {
status = FW_DESERIALIZE_TYPE_MISMATCH;
break;
default:
- status = static_cast(0);
- FW_ASSERT(0);
+ FW_ASSERT(0,status);
+ break;
}
return status;
}
diff --git a/Fw/FilePacket/FilePacket.hpp b/Fw/FilePacket/FilePacket.hpp
index 502aeb2dc2..fa173f1b20 100644
--- a/Fw/FilePacket/FilePacket.hpp
+++ b/Fw/FilePacket/FilePacket.hpp
@@ -99,6 +99,9 @@ namespace Fw {
//! The sequence index
U32 sequenceIndex;
+ //! Header size
+ enum { HEADERSIZE = sizeof(U8) + sizeof(sequenceIndex) };
+
PRIVATE:
//! Initialize a file packet header
@@ -181,6 +184,12 @@ namespace Fw {
//! Pointer to the file data
const U8 *data;
+ //! header size
+ enum { HEADERSIZE = Header::HEADERSIZE +
+ sizeof(byteOffset) +
+ sizeof(dataSize) };
+
+
public:
//! Initialize a data packet
diff --git a/Fw/Log/TextLogString.cpp b/Fw/Log/TextLogString.cpp
index 29fbbd9d7d..2a15e13e22 100644
--- a/Fw/Log/TextLogString.cpp
+++ b/Fw/Log/TextLogString.cpp
@@ -41,7 +41,7 @@ namespace Fw {
if (buff != this->m_buf) {
(void)strncpy(this->m_buf,buff,size);
// NULL terminate
- this->terminate();
+ this->terminate(sizeof(this->m_buf));
}
}
@@ -56,7 +56,7 @@ namespace Fw {
// deserialize string
SerializeStatus stat = buffer.deserialize((U8*)this->m_buf,maxSize);
// make sure it is null-terminated
- this->terminate();
+ this->terminate(maxSize);
return stat;
}
@@ -65,9 +65,9 @@ namespace Fw {
return FW_LOG_TEXT_BUFFER_SIZE;
}
- void TextLogString::terminate(void) {
+ void TextLogString::terminate(NATIVE_UINT_TYPE size) {
// null terminate the string
- this->m_buf[sizeof(this->m_buf)-1] = 0;
+ this->m_buf[size < sizeof(this->m_buf)?size:sizeof(this->m_buf)-1] = 0;
}
const TextLogString& TextLogString::operator=(const TextLogString& other) {
diff --git a/Fw/Log/TextLogString.hpp b/Fw/Log/TextLogString.hpp
index 149ea77ce7..39286a5be5 100644
--- a/Fw/Log/TextLogString.hpp
+++ b/Fw/Log/TextLogString.hpp
@@ -32,7 +32,7 @@ namespace Fw {
private:
void copyBuff(const char* buff, NATIVE_UINT_TYPE size);
NATIVE_UINT_TYPE getCapacity(void) const ;
- void terminate(void); //!< terminate the string
+ void terminate(NATIVE_UINT_TYPE size); //!< terminate the string
char m_buf[FW_LOG_TEXT_BUFFER_SIZE];
};
diff --git a/Fw/Log/abc.mdzip b/Fw/Log/abc.mdzip
deleted file mode 100644
index eb6fd6c86a..0000000000
Binary files a/Fw/Log/abc.mdzip and /dev/null differ
diff --git a/Fw/Time/Time.cpp b/Fw/Time/Time.cpp
index b12e0a0300..3154ed0d10 100644
--- a/Fw/Time/Time.cpp
+++ b/Fw/Time/Time.cpp
@@ -40,6 +40,15 @@ namespace Fw {
this->m_seconds = seconds;
}
+ const Time& Time::operator=(const Time& other) {
+ this->m_timeBase = other.m_timeBase;
+ this->m_timeContext = other.m_timeContext;
+ this->m_useconds = other.m_useconds;
+ this->m_seconds = other.m_seconds;
+
+ return other;
+ }
+
bool Time::operator==(const Time& other) const {
return (Time::compare(*this,other) == EQ);
}
diff --git a/Fw/Time/Time.hpp b/Fw/Time/Time.hpp
index a3c7c945a7..14625e6079 100644
--- a/Fw/Time/Time.hpp
+++ b/Fw/Time/Time.hpp
@@ -39,6 +39,7 @@ namespace Fw {
bool operator<(const Time& other) const;
bool operator>=(const Time& other) const;
bool operator<=(const Time& other) const;
+ const Time& operator=(const Time& other);
// Static methods:
//! The type of a comparison result
diff --git a/Fw/Types/Assert.cpp b/Fw/Types/Assert.cpp
index 76a71f3add..9aa360563d 100644
--- a/Fw/Types/Assert.cpp
+++ b/Fw/Types/Assert.cpp
@@ -12,7 +12,7 @@
#else
#if FW_ASSERT_LEVEL == FW_FILEID_ASSERT
-#define fileIdFs "Assert file ID %d: Line: %d "
+#define fileIdFs "Assert file ID 0x%08X: Line: %d "
#else
#define fileIdFs "Assert file \"%s\": Line: %d "
#endif
diff --git a/Fw/Types/CAssert.hpp b/Fw/Types/CAssert.hpp
index 392e88c244..5dc42edc66 100644
--- a/Fw/Types/CAssert.hpp
+++ b/Fw/Types/CAssert.hpp
@@ -9,6 +9,7 @@
#define FWCASSERT_HPP_
#include
+#include
#if FW_ASSERT_LEVEL == FW_NO_ASSERT
@@ -28,9 +29,18 @@
(CAssert0((U8*)__FILE__, __LINE__))))
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
I32 CAssert0(FILE_NAME_ARG file, U32 lineNo); //!< C assert function
I32 CAssert1(FILE_NAME_ARG file, U32 lineNo, NATIVE_INT_TYPE arg1); //!< C assert function 1
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+
+
#endif // ASSERT is defined
#endif /* FWCASSERT_HPP_ */
diff --git a/Fw/Types/MmapAllocator.cpp b/Fw/Types/MmapAllocator.cpp
new file mode 100755
index 0000000000..9c11b52aff
--- /dev/null
+++ b/Fw/Types/MmapAllocator.cpp
@@ -0,0 +1,50 @@
+/**
+ * \file
+ * \author Gene Merewether
+ * \brief Implementation of mmap based allocator
+ *
+ * \copyright
+ * Copyright 2009-2016, by the California Institute of Technology.
+ * ALL RIGHTS RESERVED. United States Government Sponsorship
+ * acknowledged. Any commercial use must be negotiated with the Office
+ * of Technology Transfer at the California Institute of Technology.
+ *
+ * This software may be subject to U.S. export control laws and
+ * regulations. By accepting this document, the user agrees to comply
+ * with all U.S. export laws and regulations. User has the
+ * responsibility to obtain export licenses, or other export authority
+ * as may be required before exporting such information to foreign
+ * countries or providing access to foreign persons.
+ */
+
+#include
+#include
+#include
+#include
+
+namespace Fw {
+
+ MmapAllocator::MmapAllocator() : m_length(0) {
+ }
+
+ MmapAllocator::~MmapAllocator() {
+ }
+
+ void *MmapAllocator::allocate(NATIVE_UINT_TYPE identifier, NATIVE_UINT_TYPE size) {
+ void* addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (addr == MAP_FAILED) {
+ return NULL;
+ }
+ this->m_length = size;
+ return addr;
+ }
+
+ void MmapAllocator::deallocate(NATIVE_UINT_TYPE identifier, void* ptr) {
+ if (this->m_length) {
+ int stat = munmap(ptr, this->m_length);
+ FW_ASSERT(stat == 0, stat);
+ }
+ }
+
+} /* namespace Fw */
diff --git a/Fw/Types/MmapAllocator.hpp b/Fw/Types/MmapAllocator.hpp
new file mode 100755
index 0000000000..b9756c4be5
--- /dev/null
+++ b/Fw/Types/MmapAllocator.hpp
@@ -0,0 +1,40 @@
+/**
+ * \file
+ * \author Gene Merewether
+ * \brief A MemAllocator implementation class that uses mmap.
+ *
+ * \copyright
+ * Copyright 2009-2016, by the California Institute of Technology.
+ * ALL RIGHTS RESERVED. United States Government Sponsorship
+ * acknowledged. Any commercial use must be negotiated with the Office
+ * of Technology Transfer at the California Institute of Technology.
+ *
+ * This software may be subject to U.S. export control laws and
+ * regulations. By accepting this document, the user agrees to comply
+ * with all U.S. export laws and regulations. User has the
+ * responsibility to obtain export licenses, or other export authority
+ * as may be required before exporting such information to foreign
+ * countries or providing access to foreign persons.
+ */
+
+#ifndef TYPES_MMAPALLOCATOR_HPP_
+#define TYPES_MMAPALLOCATOR_HPP_
+
+#include
+
+namespace Fw {
+
+ class MmapAllocator: public MemAllocator {
+ public:
+ MmapAllocator();
+ virtual ~MmapAllocator();
+ void *allocate(NATIVE_UINT_TYPE identifier, NATIVE_UINT_TYPE size);
+ void deallocate(NATIVE_UINT_TYPE identifier, void* ptr);
+
+ private:
+ NATIVE_UINT_TYPE m_length;
+ };
+
+} /* namespace Fw */
+
+#endif /* TYPES_MMAPALLOCATOR_HPP_ */
diff --git a/Fw/Types/PolyType.cpp b/Fw/Types/PolyType.cpp
index 64e8289a40..0ab3957722 100644
--- a/Fw/Types/PolyType.cpp
+++ b/Fw/Types/PolyType.cpp
@@ -403,7 +403,7 @@ namespace Fw {
SerializeStatus PolyType::serialize(SerializeBufferBase& buffer) const {
// store type
- SerializeStatus stat = buffer.serialize(static_cast (this->m_dataType));
+ SerializeStatus stat = buffer.serialize(static_cast (this->m_dataType));
// switch on type
switch (this->m_dataType) {
@@ -459,7 +459,7 @@ namespace Fw {
SerializeStatus PolyType::deserialize(SerializeBufferBase& buffer) {
// get type
- I32 des;
+ FwEnumStoreType des;
SerializeStatus stat = buffer.deserialize(des);
if (stat != FW_SERIALIZE_OK) {
diff --git a/Fw/Types/PolyType.hpp b/Fw/Types/PolyType.hpp
index 5066ac588a..7a96e1d25e 100644
--- a/Fw/Types/PolyType.hpp
+++ b/Fw/Types/PolyType.hpp
@@ -150,7 +150,7 @@ namespace Fw {
enum {
SERIALIZED_TYPE_ID = FW_TYPEID_POLY, //!< typeid for PolyType
- SERIALIZED_SIZE = sizeof(Type) + sizeof(PolyVal) + sizeof(NATIVE_INT_TYPE) //!< stored serialized size
+ SERIALIZED_SIZE = sizeof(FwEnumStoreType) + sizeof(PolyVal) //!< stored serialized size
};
diff --git a/Fw/Types/Serializable.cpp b/Fw/Types/Serializable.cpp
index 9be0186ea3..1715e22264 100644
--- a/Fw/Types/Serializable.cpp
+++ b/Fw/Types/Serializable.cpp
@@ -89,7 +89,7 @@ namespace Fw {
return FW_SERIALIZE_OK;
}
-#if FW_HAS_16_BIT==1
+#if FW_HAS_16_BIT==1
SerializeStatus SerializeBufferBase::serialize(U16 val) {
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
return FW_SERIALIZE_NO_ROOM_LEFT;
@@ -116,7 +116,7 @@ namespace Fw {
return FW_SERIALIZE_OK;
}
#endif
-#if FW_HAS_32_BIT==1
+#if FW_HAS_32_BIT==1
SerializeStatus SerializeBufferBase::serialize(U32 val) {
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
return FW_SERIALIZE_NO_ROOM_LEFT;
@@ -156,7 +156,7 @@ namespace Fw {
}
#endif
-#if FW_HAS_64_BIT==1
+#if FW_HAS_64_BIT==1
SerializeStatus SerializeBufferBase::serialize(U64 val) {
if (this->m_serLoc + (NATIVE_UINT_TYPE) sizeof(val) - 1 >= this->getBuffCapacity()) {
return FW_SERIALIZE_NO_ROOM_LEFT;
@@ -212,7 +212,7 @@ namespace Fw {
this->m_deserLoc = 0;
return FW_SERIALIZE_OK;
}
-#endif
+#endif
#if FW_HAS_F64
@@ -343,7 +343,7 @@ namespace Fw {
return FW_SERIALIZE_OK;
}
-#if FW_HAS_16_BIT==1
+#if FW_HAS_16_BIT==1
SerializeStatus SerializeBufferBase::deserialize(U16 &val) {
// check for room
if (this->getBuffLength() == this->m_deserLoc) {
@@ -376,7 +376,7 @@ namespace Fw {
return FW_SERIALIZE_OK;
}
#endif
-#if FW_HAS_32_BIT==1
+#if FW_HAS_32_BIT==1
SerializeStatus SerializeBufferBase::deserialize(U32 &val) {
// check for room
if (this->getBuffLength() == this->m_deserLoc) {
@@ -412,9 +412,9 @@ namespace Fw {
this->m_deserLoc += sizeof(val);
return FW_SERIALIZE_OK;
}
-#endif
+#endif
-#if FW_HAS_64_BIT==1
+#if FW_HAS_64_BIT==1
SerializeStatus SerializeBufferBase::deserialize(U64 &val) {
// check for room
@@ -599,6 +599,19 @@ namespace Fw {
this->m_deserLoc = 0;
}
+ SerializeStatus SerializeBufferBase::deserializeSkip(NATIVE_UINT_TYPE numBytesToSkip)
+ {
+ // check for room
+ if (this->getBuffLength() == this->m_deserLoc) {
+ return FW_DESERIALIZE_BUFFER_EMPTY;
+ } else if (this->getBuffLength() - this->m_deserLoc < numBytesToSkip) {
+ return FW_DESERIALIZE_SIZE_MISMATCH;
+ }
+ // update location in buffer to skip the value
+ this->m_deserLoc += numBytesToSkip;
+ return FW_SERIALIZE_OK;
+ }
+
NATIVE_UINT_TYPE SerializeBufferBase::getBuffLength(void) const {
return this->m_serLoc;
}
@@ -644,6 +657,25 @@ namespace Fw {
}
+ SerializeStatus SerializeBufferBase::copyRawOffset(SerializeBufferBase& dest, NATIVE_UINT_TYPE size) {
+ // make sure there is sufficient size in destination
+ if (dest.getBuffCapacity() < size + dest.getBuffLength()) {
+ return FW_SERIALIZE_NO_ROOM_LEFT;
+ }
+ // make sure there is sufficient buffer in source
+ if (this->getBuffLeft() < size) {
+ return FW_DESERIALIZE_SIZE_MISMATCH;
+ }
+
+ // otherwise, serialize bytes to destination without writing length
+ SerializeStatus stat = dest.serialize(&this->getBuffAddr()[this->m_deserLoc], size, true);
+ if (stat == FW_SERIALIZE_OK) {
+ this->m_deserLoc += size;
+ }
+ return stat;
+
+ }
+
// return address of buffer not yet deserialized. This is used
// to copy the remainder of a buffer.
const U8* SerializeBufferBase::getBuffAddrLeft(void) const {
diff --git a/Fw/Types/Serializable.hpp b/Fw/Types/Serializable.hpp
index 52592eaf22..1a9ef988a8 100644
--- a/Fw/Types/Serializable.hpp
+++ b/Fw/Types/Serializable.hpp
@@ -52,15 +52,15 @@ namespace Fw {
SerializeStatus serialize(U8 val); //!< serialize 8-bit unsigned int
SerializeStatus serialize(I8 val); //!< serialize 8-bit signed int
-#if FW_HAS_16_BIT==1
+#if FW_HAS_16_BIT==1
SerializeStatus serialize(U16 val); //!< serialize 16-bit unsigned int
SerializeStatus serialize(I16 val); //!< serialize 16-bit signed int
#endif
-#if FW_HAS_32_BIT==1
+#if FW_HAS_32_BIT==1
SerializeStatus serialize(U32 val); //!< serialize 32-bit unsigned int
SerializeStatus serialize(I32 val); //!< serialize 32-bit signed int
#endif
-#if FW_HAS_64_BIT==1
+#if FW_HAS_64_BIT==1
SerializeStatus serialize(U64 val); //!< serialize 64-bit unsigned int
SerializeStatus serialize(I64 val); //!< serialize 64-bit signed int
#endif
@@ -83,16 +83,16 @@ namespace Fw {
SerializeStatus deserialize(U8 &val); //!< deserialize 8-bit unsigned int
SerializeStatus deserialize(I8 &val); //!< deserialize 8-bit signed int
-#if FW_HAS_16_BIT==1
+#if FW_HAS_16_BIT==1
SerializeStatus deserialize(U16 &val); //!< deserialize 16-bit unsigned int
SerializeStatus deserialize(I16 &val); //!< deserialize 16-bit signed int
#endif
-#if FW_HAS_32_BIT==1
+#if FW_HAS_32_BIT==1
SerializeStatus deserialize(U32 &val); //!< deserialize 32-bit unsigned int
SerializeStatus deserialize(I32 &val); //!< deserialize 32-bit signed int
#endif
-#if FW_HAS_64_BIT==1
+#if FW_HAS_64_BIT==1
SerializeStatus deserialize(U64 &val); //!< deserialize 64-bit unsigned int
SerializeStatus deserialize(I64 &val); //!< deserialize 64-bit signed int
#endif
@@ -117,6 +117,7 @@ namespace Fw {
void resetSer(void); //!< reset to beginning of buffer to reuse for serialization
void resetDeser(void); //!< reset deserialization to beginning
+ SerializeStatus deserializeSkip(NATIVE_UINT_TYPE numBytesToSkip); //!< Skips the number of specified bytes for deserialization
virtual NATIVE_UINT_TYPE getBuffCapacity(void) const = 0; //!< returns capacity, not current size, of buffer
NATIVE_UINT_TYPE getBuffLength() const; //!< returns current buffer size
NATIVE_UINT_TYPE getBuffLeft() const; //!< returns how much deserialization buffer is left
@@ -128,6 +129,9 @@ namespace Fw {
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length); //!< sets buffer length manually after filling with data
SerializeStatus copyRaw(SerializeBufferBase& dest, NATIVE_UINT_TYPE size); //!< directly copies buffer without looking for a size in the stream.
// Will increment deserialization pointer
+ SerializeStatus copyRawOffset(SerializeBufferBase& dest, NATIVE_UINT_TYPE size); //!< directly copies buffer without looking for a size in the stream.
+ // Will increment deserialization pointer
+
#ifdef BUILD_UT
bool operator==(const SerializeBufferBase& other) const;
diff --git a/Fw/Types/test/ut/TypesTest.cpp b/Fw/Types/test/ut/TypesTest.cpp
index c427d6c1d9..0346af2a3a 100644
--- a/Fw/Types/test/ut/TypesTest.cpp
+++ b/Fw/Types/test/ut/TypesTest.cpp
@@ -235,6 +235,41 @@ TEST(SerializationTest,Serialization1) {
printf("Val: in: %s out: %s stat1: %d stat2: %d\n",
boolt1 ? "TRUE" : "FALSE", boolt2 ? "TRUE" : "FALSE", stat1, stat2);
+ printf("Skip deserialization Tests\n");
+#endif
+
+// Test skipping:
+
+ buff.resetSer();
+ stat1 = buff.serialize(u32t1);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat1);
+ stat2 = buff.serialize(u32t2);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat2);
+
+ // should fail:
+ stat1 = buff.deserializeSkip(10);
+ ASSERT_EQ(Fw::FW_DESERIALIZE_SIZE_MISMATCH,stat1);
+
+ // skip everything:
+ stat1 = buff.deserializeSkip(4);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat1);
+ stat2 = buff.deserializeSkip(4);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat2);
+
+ // should fail:
+ stat1 = buff.deserializeSkip(4);
+ ASSERT_EQ(Fw::FW_DESERIALIZE_BUFFER_EMPTY,stat1);
+
+ // skip half/read half:
+ buff.resetDeser();
+ stat1 = buff.deserializeSkip(4);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat1);
+ U32 u32val;
+ stat2 = buff.deserialize(u32val);
+ ASSERT_EQ(Fw::FW_SERIALIZE_OK,stat2);
+ ASSERT_EQ(u32t2,u32val);
+
+#if DEBUG_VERBOSE
printf("\nDeserialization Tests\n");
#endif
diff --git a/Gse/bin/ClientSocket.py b/Gse/bin/ClientSocket.py
index 2a6e10ef83..cc97e652e4 100644
--- a/Gse/bin/ClientSocket.py
+++ b/Gse/bin/ClientSocket.py
@@ -15,28 +15,28 @@ import socket
import struct
import time
-from controllers import client_sock
+from fprime.gse.controllers import client_sock
# Import the types this way so they do not need prefixing for execution.
-from models.serialize.type_exceptions import *
-from models.serialize.type_base import *
+from fprime.gse.models.serialize.type_exceptions import *
+from fprime.gse.models.serialize.type_base import *
-from models.serialize.bool_type import *
-from models.serialize.enum_type import *
-from models.serialize.f32_type import *
-from models.serialize.f64_type import *
+from fprime.gse.models.serialize.bool_type import *
+from fprime.gse.models.serialize.enum_type import *
+from fprime.gse.models.serialize.f32_type import *
+from fprime.gse.models.serialize.f64_type import *
-from models.serialize.u8_type import *
-from models.serialize.u16_type import *
-from models.serialize.u32_type import *
-from models.serialize.u64_type import *
+from fprime.gse.models.serialize.u8_type import *
+from fprime.gse.models.serialize.u16_type import *
+from fprime.gse.models.serialize.u32_type import *
+from fprime.gse.models.serialize.u64_type import *
-from models.serialize.i8_type import *
-from models.serialize.i16_type import *
-from models.serialize.i32_type import *
-from models.serialize.i64_type import *
+from fprime.gse.models.serialize.i8_type import *
+from fprime.gse.models.serialize.i16_type import *
+from fprime.gse.models.serialize.i32_type import *
+from fprime.gse.models.serialize.i64_type import *
-from models.serialize.string_type import *
-from models.serialize.serializable_type import *
+from fprime.gse.models.serialize.string_type import *
+from fprime.gse.models.serialize.serializable_type import *
diff --git a/Gse/bin/ThreadedTCPServer.py b/Gse/bin/ThreadedTCPServer.py
index 600d66d4a7..bde1e514a3 100644
--- a/Gse/bin/ThreadedTCPServer.py
+++ b/Gse/bin/ThreadedTCPServer.py
@@ -16,8 +16,8 @@ import errno
import time
import logging
-from utils import Logger
-from models.serialize.type_base import *
+from fprime.gse.utils import Logger
+from fprime.gse.models.serialize.type_base import *
from optparse import OptionParser
__version__ = 0.1
@@ -45,7 +45,7 @@ def signal_handler(signal, frame):
def now():
return time.ctime(time.time())
-class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
+class ThreadedTCPRequestHandler(SocketServer.StreamRequestHandler):
"""
Derived from original Stable demo during R&TD and adapted
for use in new FSW gse.py applicaiton.
@@ -61,7 +61,8 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
Any client that sends a "List" comment makes the server display all
registered clients.
"""
- SocketServer.BaseRequestHandler.allow_reuse_address = True
+ SocketServer.StreamRequestHandler.allow_reuse_address = True
+ SocketServer.StreamRequestHandler.timeout = 1
def handle(self): # on each client connect
"""
@@ -75,7 +76,7 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
self.registered = False
self.name = ''
self.id = 0
-
+
#print self.client_address, now() # show this client's address
# Read the data from the socket
data = self.recv(13)
@@ -187,9 +188,12 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
elif header == "Quit":
LOCK.acquire()
print "Quit received!"
+ SERVER.dest_obj[self.name].put(struct.pack(">I", 0xA5A5A5A5))
+ shutdown_event.set()
+ time.sleep(1)
+ print "Quit processed!"
SERVER.shutdown()
SERVER.server_close()
- shutdown_event.set()
LOCK.release()
break
@@ -215,6 +219,11 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
return ''
msg = msg + chunk
n = len(msg)
+ except socket.timeout:
+ if shutdown_event.is_set():
+ print "socket timed out and shutdown is requested"
+ return "Quit\n"
+ continue
except socket.error, err:
if err.errno == errno.ECONNRESET:
print "Socket error " + str(err.errno) + " (Connection reset by peer) occurred on recv()."
@@ -269,7 +278,7 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
data = tlm_packet_size + self.recv(size)
else:
- raise RuntimeError("unrecognized client")
+ raise RuntimeError("unrecognized client %s"%dst)
return data
@@ -305,10 +314,11 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
elif 'FSW' in dst:
dest_list = FSW_clients
for dest_elem in dest_list:
+ #print "Locking TCP"
LOCK.acquire()
if dest_elem in SERVER.dest_obj.keys():
# Send the message here....
- #print "Sending msg to ", dest_elem
+ #print "Sending TCP msg to ", dest_elem
SERVER.dest_obj[dest_elem].put(data)
LOCK.release()
@@ -414,7 +424,7 @@ class ThreadedUDPRequestHandler(SocketServer.BaseRequestHandler):
LOCK.acquire()
if dest_elem in SERVER.dest_obj.keys():
# Send the message here....
- #print "Sending msg to ", dest_elem
+ #print "Sending UDP msg to ", dest_elem
SERVER.dest_obj[dest_elem].put(data)
LOCK.release()
@@ -514,9 +524,11 @@ def main(argv=None):
#print "Process ID: %s" % p
while not shutdown_event.is_set():
- server_thread.join(timeout = 1.0)
- udp_server_thread.join(timeout = 1.0)
+ server_thread.join(timeout = 5.0)
+ udp_server_thread.join(timeout = 5.0)
+ print "shutdown from main thread"
+
SERVER.shutdown()
SERVER.server_close()
udp_server.shutdown()
diff --git a/Gse/bin/TlmPacketEditor.py b/Gse/bin/TlmPacketEditor.py
index 77ced6ea5a..67de93c135 100644
--- a/Gse/bin/TlmPacketEditor.py
+++ b/Gse/bin/TlmPacketEditor.py
@@ -9,11 +9,11 @@ import tkFileDialog
from optparse import OptionParser
-from utils import ConfigManager
-from controllers import channel_loader
-from models.tpe_models import SessionModel
-from controllers.tpe_controllers import SessionController
-from controllers.exceptions import GseControllerUndefinedDirectoryException
+from fprime.gse.utils import ConfigManager
+from fprime.gse.controllers import channel_loader
+from fprime.gse.models.tpe_models import SessionModel
+from fprime.gse.controllers.tpe_controllers import SessionController
+from fprime.gse.controllers.exceptions import GseControllerUndefinedDirectoryException
# Setup logging
Logger = logging.getLogger(__name__)
diff --git a/Gse/bin/cmd_telm_monitor.py b/Gse/bin/cmd_telm_monitor.py
index 1f84b9fa0b..f41bdfaec6 100644
--- a/Gse/bin/cmd_telm_monitor.py
+++ b/Gse/bin/cmd_telm_monitor.py
@@ -17,7 +17,7 @@ import Pmw
import struct
import math
import time
-from controllers import client_sock
+from fprime.gse.controllers import client_sock
#import ModeMgrSm
diff --git a/Gse/bin/gse.py b/Gse/bin/gse.py
old mode 100644
new mode 100755
index 077a879174..ff044a43bd
--- a/Gse/bin/gse.py
+++ b/Gse/bin/gse.py
@@ -22,15 +22,15 @@ import Pmw
import time
import glob
import random
-from utils import Logger
-from utils import PortFinder
-from utils import ConfigManager
+from fprime.gse.utils import Logger
+from fprime.gse.utils import PortFinder
+from fprime.gse.utils import ConfigManager
-import controllers.exceptions
+import fprime.gse.controllers.exceptions
import traceback
-from views import main_panel_factory
-from views import main_panel
+from fprime.gse.views import main_panel_factory
+from fprime.gse.views import main_panel
from optparse import OptionParser
__all__ = []
@@ -176,6 +176,10 @@ def main(argv=None):
#default=50007)
#default=PortFinder.old_getport(50000,[]))
)
+ parser.add_option("-s", "--stream_port", dest="stream_port", action="store", type="int", help="Set streaming socket server port [default: %default]", \
+ #default=50007)
+ #default=PortFinder.old_getport(50000,[]))
+ )
parser.add_option("-e", "--execute", dest="exec_app", action="store", type="string", help="Execute the specified fsw application after socket server and UI are up [default: %default]", \
default=fsw_app)
parser.add_option("-L", "--log-file-path", dest="log_file_path", action="store", type="string", help="Path to log files [default: %default]", \
@@ -188,6 +192,9 @@ def main(argv=None):
default="local")
parser.add_option("-n", "--no-about", dest="no_about", action="store_true", help="Do not show about text screen on start", \
default=True)
+ parser.add_option("-t", "--title", dest="title", action="store",type="string", help="Set GUI title", default="Fprime")
+
+ parser.add_option("-x", "--packetspec", dest="packetspec", action="store",type="string", help="Path to packet specification file", default=None)
#parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]")
@@ -263,7 +270,7 @@ def main(argv=None):
root.after(1000, execute, opts)
root.mainloop()
- except controllers.exceptions.GseControllerException, e:
+ except fprime.gse.controllers.exceptions.GseControllerException, e:
sys.stderr.write("Exception: %s\n"%e.getMsg())
traceback.print_exc()
return 2
diff --git a/Gse/bin/gse_api_cmds.py b/Gse/bin/gse_api_cmds.py
index a8888890d0..923d6a7ef8 100644
--- a/Gse/bin/gse_api_cmds.py
+++ b/Gse/bin/gse_api_cmds.py
@@ -3,7 +3,7 @@
import os
import sys
import time
-from utils.gse_api import GseApi
+from fprime.gse.utils.gse_api import GseApi
from optparse import OptionParser
__version__ = 0.1
diff --git a/Gse/bin/gse_api_monitor.py b/Gse/bin/gse_api_monitor.py
index 99a0c80e18..401db1d6f4 100644
--- a/Gse/bin/gse_api_monitor.py
+++ b/Gse/bin/gse_api_monitor.py
@@ -3,7 +3,7 @@
import os
import sys
#from gse_api import GseApi
-from utils.gse_api import GseApi
+from fprime.gse.utils.gse_api import GseApi
from optparse import OptionParser
__version__ = 0.1
diff --git a/Gse/bin/pexpect_runner.py b/Gse/bin/pexpect_runner.py
index 7b3a26fa26..dccb2822d1 100644
--- a/Gse/bin/pexpect_runner.py
+++ b/Gse/bin/pexpect_runner.py
@@ -32,8 +32,11 @@ def process_poller():
try:
child.expect('\r\n',timeout=1)
if exitThread:
- child.kill(signal.SIGINT)
- child.wait()
+ try:
+ child.kill(signal.SIGINT)
+ child.wait()
+ except:
+ print("KILL")
break
if len(child.before):
text_queue.put(child.before)
@@ -44,8 +47,11 @@ def process_poller():
break
except pexpect.TIMEOUT:
if exitThread:
- child.kill(signal.SIGINT)
- child.wait()
+ try:
+ child.kill(signal.SIGINT)
+ child.wait()
+ except:
+ print("KILL")
break
if len(child.before):
text_queue.put(child.before)
diff --git a/Gse/bin/required.txt b/Gse/bin/required.txt
index 98d177d00c..25de208be5 100644
--- a/Gse/bin/required.txt
+++ b/Gse/bin/required.txt
@@ -6,3 +6,6 @@ multiprocess
pexpect
Pmw
tkintertable
+pyzmq
+numpy
+pillow
diff --git a/Gse/bin/run_cmds.py b/Gse/bin/run_cmds.py
old mode 100644
new mode 100755
index 4ec0fab430..b045bed334
--- a/Gse/bin/run_cmds.py
+++ b/Gse/bin/run_cmds.py
@@ -3,7 +3,7 @@
import os
import sys
import time
-from utils.gse_api import GseApi
+from fprime.gse.utils.gse_api import GseApi
from optparse import OptionParser
__version__ = 0.1
@@ -47,7 +47,7 @@ def main(argv=None):
sys.stderr.write(indent + " for help use --help\n")
return 2
- api = GseApi(generated_path=opts.generated_path, port=opts.port, server_addr=opts.addr)
+ api = GseApi(generated_path=opts.generated_path, port=opts.port, server_addr=opts.addr, verbose=True)
# process each of the files
for script in args:
diff --git a/Gse/bin/tinyseqgen.py b/Gse/bin/tinyseqgen.py
old mode 100644
new mode 100755
index d210783689..fc853229c4
--- a/Gse/bin/tinyseqgen.py
+++ b/Gse/bin/tinyseqgen.py
@@ -19,6 +19,8 @@ import os
import copy
from datetime import datetime, timedelta
+from fprime.gse.models.serialize.type_exceptions import *
+
__author__ = "Kevin Dinkel"
__copyright__ = "Copyright 2015, California Institute of Technology."
__version__ = "1.0"
@@ -33,10 +35,10 @@ def __error(string):
sys.exit(1)
# try:
-from models.common.command import Descriptor
-from views.seq_panel import SeqBinaryWriter
-from controllers import command_loader
-from controllers import exceptions as gseExceptions
+from fprime.gse.models.common.command import Descriptor
+from fprime.gse.views.seq_panel import SeqBinaryWriter
+from fprime.gse.controllers import command_loader
+from fprime.gse.controllers import exceptions as gseExceptions
# except:
# __error("The Gse source code was not found in your $PYTHONPATH variable. Please set PYTHONPATH to something like: $BUILD_ROOT/Gse/src:$BUILD_ROOT/Gse/generated/$DEPLOYMENT_NAME")
@@ -122,10 +124,14 @@ def __parse(seqfile):
# If the string contains a "." assume that it is a float:
elif "." in arg:
return float(arg)
+ elif arg == 'True' or arg == 'true' or arg == 'TRUE':
+ return True
+ elif arg == 'False' or arg == 'false' or arg == 'FALSE':
+ return False
else:
try:
# See if it translates to an integer:
- return int(arg)
+ return int(arg,0)
except ValueError:
try:
# See if it translates to a float:
@@ -230,7 +236,7 @@ def __parse(seqfile):
__errorLine(i, "Encountered sytax error parsing arguments")
yield i, descriptor, seconds, useconds, mnemonic, args
-def generateSequence(inputFile, outputFile=None):
+def generateSequence(inputFile, outputFile=None, timebase=0xffff):
'''
Write a binary sequence file from a text sequence file
@param inputFile: A text input sequence file name (usually a .seq extension)
@@ -242,15 +248,15 @@ def generateSequence(inputFile, outputFile=None):
generated_command_path = generated_path + "/commands"
except:
__error("Environment variable 'GSE_GENERATED_PATH' not set. It should be set to something like '$BUILD_ROOT/Gse/generated/$DEPLOYMENT' and also added to $PYTHONPATH.")
- command_loader = command_loader.CommandLoader.getInstance()
+ cmds = command_loader.CommandLoader.getInstance()
try:
- command_loader.create(generated_command_path)
+ cmds.create(generated_command_path)
except gseExceptions.GseControllerUndefinedDirectoryException:
__error("Environment variable 'GSE_GENERATED_PATH' is set to '" + generated_path + "'. This is not a valid directory. Make sure this variable is set correctly, and the GSE python deployment autocode as been installed in this location.")
# Parse the input file:
command_list = []
- command_obj_dict = command_loader.getCommandDict()
+ command_obj_dict = cmds.getCommandDict()
for i, descriptor, seconds, useconds, mnemonic, args in __parse(inputFile):
# Make sure that command is in the command dictionary:
if mnemonic in command_obj_dict:
@@ -272,7 +278,7 @@ def generateSequence(inputFile, outputFile=None):
__errorLine(i, "'" + mnemonic + "' does not match any command in the command dictionary.")
# Write to the output file:
- writer = SeqBinaryWriter()
+ writer = SeqBinaryWriter(timebase=timebase)
if not outputFile:
outputFile = os.path.splitext(inputFile)[0] + ".bin"
try:
@@ -287,8 +293,21 @@ if __name__ == "__main__":
The main program if run from the commandline. Note that this file can also be used
as a module by calling the generateSequence() function
'''
- if len(sys.argv) == 2 or len(sys.argv) == 3:
- generateSequence(*sys.argv[1:])
+ timebase = 0xffff
+ good = False
+ args = copy.copy(sys.argv[1:])
+ try:
+ if "-t" in args:
+ index = args.index("-t")
+ timebase = int(args[index + 1], 0)
+ args = args[:index] + args[index + 2:]
+ good = True
+ except ValueError:
+ print "Could not parse time base: {0}".format(args[index + 1])
+ except IndexError:
+ print "No time base argument supplied to '-t' argument"
+ if (len(args) == 1 or len(args) == 2) and good:
+ generateSequence(*args, timebase=timebase)
else:
print "Usage: tinyseqgen sequence_file_in.seq [binary_sequence_file_out.bin]"
print
@@ -297,6 +316,8 @@ if __name__ == "__main__":
print "Description: tinyseqgen takes a simple input sequence format (.seq),"
print "and outputs a binary command sequence loadable by the Svc/SequenceFileLoader."
print
+ print " -t
-
+
A test parameter
diff --git a/Ref/Top/Components.hpp b/Ref/Top/Components.hpp
index 4d54102b60..cf7d253034 100644
--- a/Ref/Top/Components.hpp
+++ b/Ref/Top/Components.hpp
@@ -24,7 +24,6 @@ void exitTasks(void);
#include
#include
#include
-#include
#include
#include
#include
diff --git a/Ref/Top/CygwinTargetInit.cpp b/Ref/Top/CygwinTargetInit.cpp
deleted file mode 100644
index c74cd51368..0000000000
--- a/Ref/Top/CygwinTargetInit.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include
-
-void localTargetInit(void) {
-}
-
diff --git a/Ref/Top/RefTopologyAppAi_IDTableLog.txt b/Ref/Top/RefTopologyAppAi_IDTableLog.txt
index 4694ec70ad..0b505f120c 100644
--- a/Ref/Top/RefTopologyAppAi_IDTableLog.txt
+++ b/Ref/Top/RefTopologyAppAi_IDTableLog.txt
@@ -14,12 +14,12 @@
rateGroup3Comp | 241 (0xf1) | 20 | 20 | 2 | 2
fileUplink | 261 (0x105) | 20 | 20 | 8 | 8
SG5 | 281 (0x119) | 20 | 20 | 3 | 3
-fileUplinkBufferManager | 301 (0x12d) | 20 | 20 | 4 | 4
+fileUplinkBufferManager | 301 (0x12d) | 20 | 20 | 3 | 3
SG4 | 321 (0x141) | 20 | 20 | 3 | 3
fatalAdapter | 341 (0x155) | 20 | 20 | 8 | 8
health | 361 (0x169) | 20 | 20 | 8 | 8
sockGndIf | 381 (0x17d) | 20 | 20 | 4 | 4
-fileDownlinkBufferManag | 401 (0x191) | 20 | 20 | 4 | 4
+fileDownlinkBufferManag | 401 (0x191) | 20 | 20 | 3 | 3
er | | | | |
eventLogger | 421 (0x1a5) | 20 | 20 | 7 | 7
linuxTime | 441 (0x1b9) | 20 | 20 | None | 0
diff --git a/Ref/Top/RefTopologyAppDictionary.xml b/Ref/Top/RefTopologyAppDictionary.xml
new file mode 100644
index 0000000000..e4d71045d7
--- /dev/null
+++ b/Ref/Top/RefTopologyAppDictionary.xml
@@ -0,0 +1,1023 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ref/Top/RefTopologyAppID.csv b/Ref/Top/RefTopologyAppID.csv
deleted file mode 100644
index 431c23fb87..0000000000
--- a/Ref/Top/RefTopologyAppID.csv
+++ /dev/null
@@ -1,29 +0,0 @@
-component,instance,base_id,base_window_range
-FatalHandler,fatalHandler,1,20
-ActiveRateGroup,rateGroup1Comp,21,20
-PingReceiver,pingRcvr,41,20
-TlmChan,chanTlm,61,20
-SendBuff,sendBuffComp,81,20
-RecvBuff,recvBuffComp,101,20
-CommandDispatcher,cmdDisp,121,20
-PrmDb,prmDb,141,20
-ActiveRateGroup,rateGroup2Comp,161,20
-SignalGen,SG1,181,20
-SignalGen,SG3,201,20
-SignalGen,SG2,221,20
-ActiveRateGroup,rateGroup3Comp,241,20
-FileUplink,fileUplink,261,20
-SignalGen,SG5,281,20
-BufferManager,fileUplinkBufferManager,301,20
-SignalGen,SG4,321,20
-AssertFatalAdapter,fatalAdapter,341,20
-Health,health,361,20
-GndIf,sockGndIf,381,20
-BufferManager,fileDownlinkBufferManager,401,20
-ActiveLogger,eventLogger,421,20
-Time,linuxTime,441,20
-RateGroupDriver,rateGroupDriverComp,461,20
-BlockDriver,blockDrv,481,20
-FileDownlink,fileDownlink,501,20
-PassiveTextLogger,textLogger,521,20
-CmdSequencer,cmdSeq,541,23
diff --git a/Ref/Top/StubTargetInit.cpp b/Ref/Top/StubTargetInit.cpp
deleted file mode 100644
index c74cd51368..0000000000
--- a/Ref/Top/StubTargetInit.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include
-
-void localTargetInit(void) {
-}
-
diff --git a/Ref/Top/TargetInit.hpp b/Ref/Top/TargetInit.hpp
deleted file mode 100644
index b5ef3a6c48..0000000000
--- a/Ref/Top/TargetInit.hpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef TOP_TARGET_INIT_HPP
-#define TOP_TARGET_INIT_HPP
-
-extern "C" {
- void localTargetInit(void);
-}
-
-#endif
diff --git a/Ref/Top/Topology.cpp b/Ref/Top/Topology.cpp
index cf5dcc3a3c..f0a4b1dfaa 100644
--- a/Ref/Top/Topology.cpp
+++ b/Ref/Top/Topology.cpp
@@ -1,8 +1,5 @@
#include
-
-
#include
-#include
#include
#include
#include
@@ -22,25 +19,6 @@ enum {
UPLINK_BUFFER_QUEUE_SIZE = 30
};
-enum {
- ACTIVE_COMP_1HZ_RG,
- ACTIVE_COMP_P5HZ_RG,
- ACTIVE_COMP_P25HZ_RG,
- ACTIVE_COMP_CMD_DISP,
- ACTIVE_COMP_CMD_SEQ,
- ACTIVE_COMP_LOGGER,
- ACTIVE_COMP_TLM,
- ACTIVE_COMP_PRMDB,
- ACTIVE_COMP_FILE_DOWNLINK,
- ACTIVE_COMP_FILE_UPLINK,
-
- ACTIVE_COMP_BLKDRV,
- ACTIVE_COMP_PING_RECEIVER,
-
- CYCLER_TASK,
- NUM_ACTIVE_COMPS
-};
-
// Registry
#if FW_OBJECT_REGISTRATION == 1
static Fw::SimpleObjRegistry simpleReg;
@@ -222,8 +200,6 @@ void dumpobj(const char* objName) {
void constructApp(int port_number, char* hostname) {
- localTargetInit();
-
#if FW_PORT_TRACING
Fw::PortBase::setTrace(false);
#endif
@@ -322,24 +298,24 @@ void constructApp(int port_number, char* hostname) {
// Active component startup
// start rate groups
- rateGroup1Comp.start(ACTIVE_COMP_1HZ_RG, 120,10 * 1024);
- rateGroup2Comp.start(ACTIVE_COMP_P5HZ_RG, 119,10 * 1024);
- rateGroup3Comp.start(ACTIVE_COMP_P25HZ_RG, 118,10 * 1024);
+ rateGroup1Comp.start(0, 120,10 * 1024);
+ rateGroup2Comp.start(0, 119,10 * 1024);
+ rateGroup3Comp.start(0, 118,10 * 1024);
// start driver
- blockDrv.start(ACTIVE_COMP_BLKDRV,140,10*1024);
+ blockDrv.start(0,140,10*1024);
// start dispatcher
- cmdDisp.start(ACTIVE_COMP_CMD_DISP,101,10*1024);
+ cmdDisp.start(0,101,10*1024);
// start sequencer
- cmdSeq.start(ACTIVE_COMP_CMD_SEQ,100,10*1024);
+ cmdSeq.start(0,100,10*1024);
// start telemetry
- eventLogger.start(ACTIVE_COMP_LOGGER,98,10*1024);
- chanTlm.start(ACTIVE_COMP_TLM,97,10*1024);
- prmDb.start(ACTIVE_COMP_PRMDB,96,10*1024);
+ eventLogger.start(0,98,10*1024);
+ chanTlm.start(0,97,10*1024);
+ prmDb.start(0,96,10*1024);
- fileDownlink.start(ACTIVE_COMP_FILE_DOWNLINK, 100, 10*1024);
- fileUplink.start(ACTIVE_COMP_FILE_UPLINK, 100, 10*1024);
+ fileDownlink.start(0, 100, 10*1024);
+ fileUplink.start(0, 100, 10*1024);
- pingRcvr.start(ACTIVE_COMP_PING_RECEIVER, 100, 10*1024);
+ pingRcvr.start(0, 100, 10*1024);
// Initialize socket server
sockGndIf.startSocketTask(100, 10*1024, port_number, hostname, Svc::SocketGndIfImpl::SEND_UDP);
diff --git a/Ref/Top/VxHwTargetInit.cpp b/Ref/Top/VxHwTargetInit.cpp
deleted file mode 100644
index 1af4c09bad..0000000000
--- a/Ref/Top/VxHwTargetInit.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include
-
-#include
-
-void localTargetInit(void) {
-
- //Drv::PciIf::init();
-
-}
-
diff --git a/Ref/Top/VxWstsTargetInit.cpp b/Ref/Top/VxWstsTargetInit.cpp
deleted file mode 100644
index 29eea3550a..0000000000
--- a/Ref/Top/VxWstsTargetInit.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include
-
-
-void localTargetInit(void) {
- //Drv::PciIf::init();
-}
-
diff --git a/Ref/Top/mod.mk b/Ref/Top/mod.mk
index 3b40d62e4c..f92f31b4ed 100644
--- a/Ref/Top/mod.mk
+++ b/Ref/Top/mod.mk
@@ -1,24 +1,2 @@
SRC = Topology.cpp \
RefTopologyAppAi.xml
-
-SRC_CWSCP124 = VxHwTargetInit.cpp
-
-SRC_MXSCS750 = VxHwTargetInit.cpp
-
-SRC_SMP400K = VxHwTargetInit.cpp
-
-SRC_BAERAD750 = VxHwTargetInit.cpp
-
-SRC_SPHINX = VxHwTargetInit.cpp
-
-SRC_WSTS = VxWstsTargetInit.cpp
-
-SRC_LINUX = VxWstsTargetInit.cpp
-
-SRC_ARM_VEB = StubTargetInit.cpp
-
-SRC_CYGWIN = CygwinTargetInit.cpp
-
-SRC_UT699 = StubTargetInit.cpp
-
-SRC_DARWIN = StubTargetInit.cpp
diff --git a/Ref/scripts/compile_ref_sequence.sh b/Ref/scripts/compile_ref_sequence.sh
new file mode 100644
index 0000000000..5c9373dbb2
--- /dev/null
+++ b/Ref/scripts/compile_ref_sequence.sh
@@ -0,0 +1,35 @@
+#!/bin/csh
+# *******************************************************************************
+# * Copyright 2013, by the California Institute of Technology.
+# * ALL RIGHTS RESERVED. United States Government Sponsorship
+# * acknowledged. Any commercial use must be negotiated with the Office
+# * of Technology Transfer at the California Institute of Technology.
+# *
+# * This software may be subject to U.S. export control laws and
+# * regulations. By accepting this document, the user agrees to comply
+# * with all applicable U.S. export laws and regulations. User has the
+# * responsibility to obtain export licenses,
+# * or other export authority as may be required before exporting such
+# * information to foreign countries or providing access to foreign
+# * persons.
+# *
+
+if !($?BUILD_ROOT) then
+ set curdir = "${PWD}"
+ setenv BUILD_ROOT `dirname $0`/../..
+ cd $BUILD_ROOT
+ setenv BUILD_ROOT ${PWD}
+ cd ${curdir}
+endif
+
+echo "BUILD_ROOT is: ${BUILD_ROOT}"
+
+# Borrow some variables from build
+
+setenv PYTHON_BASE `make -s -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk print_python_base`
+echo "PYTHON_BASE: ${PYTHON_BASE}"
+
+setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib
+setenv PYTHONPATH ${BUILD_ROOT}/Gse/src
+setenv GSE_GENERATED_PATH ${BUILD_ROOT}/Gse/generated/Ref
+${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Gse/bin/tinyseqgen.py $*
diff --git a/Ref/scripts/run_ref.py b/Ref/scripts/run_ref.py
index f9be548b59..f298959ef7 100644
--- a/Ref/scripts/run_ref.py
+++ b/Ref/scripts/run_ref.py
@@ -1,6 +1,5 @@
#!/usr/bin/python
-import utils.PortFinder
import sys
import subprocess
import os
@@ -10,34 +9,13 @@ from optparse import OptionParser
def main(argv=None):
- start_port = 50000
- end_port = 50100
- used_port = None
- addr = "127.0.0.1"
- nobin = False
-
- #if len(sys.argv) > 1:
- # if sys.argv[1] == "-nobin":
- # print("Not starting binary.")
- # nobin = True
+ build_root = os.environ["BUILD_ROOT"]
python_bin = os.environ["PYTHON_BASE"] + "/bin/python"
- for port in range(start_port,end_port):
- if not utils.PortFinder.IsPortUsed(port):
- used_port = port
- print("Using port %d"%used_port)
- break;
-
- if (used_port == None):
- print("Could not find port in range %d to %d",start_port,end_port)
- return -1
-
- build_root = os.environ["BUILD_ROOT"]
-
parser = OptionParser()
- parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set the threaded TCP socket server port [default: %default]", default=used_port)
- parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default=addr)
+ parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set the threaded TCP socket server port [default: %default]", default=50000)
+ parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default="localhost")
parser.add_option("-n", "--nobin", dest="nobin", action="store_true", help="Disables the binary app from starting [default: %default]", default=False)
parser.add_option("-t", "--twin", dest="twin", action="store_true", help="Runs Threaed TCP Server in window, otherwise backgrounds [default: %default]", default=False)
diff --git a/Ref/scripts/run_ref.sh b/Ref/scripts/run_ref.sh
index d4b9862e9a..9a071654d6 100755
--- a/Ref/scripts/run_ref.sh
+++ b/Ref/scripts/run_ref.sh
@@ -38,5 +38,4 @@ echo "OUTPUT_DIR: ${OUTPUT_DIR}"
setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib
setenv PYTHONPATH ${BUILD_ROOT}/Gse/src
-${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Ref/scripts/run_ref.py $*
-
+${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Ref/scripts/run_ref.py $* &
diff --git a/Ref/scripts/run_ref_cmds.sh b/Ref/scripts/run_ref_cmds.sh
index 53f3ea0a46..ad6cb6a205 100755
--- a/Ref/scripts/run_ref_cmds.sh
+++ b/Ref/scripts/run_ref_cmds.sh
@@ -8,4 +8,4 @@ if !($?BUILD_ROOT) then
cd ${curdir}
endif
-${BUILD_ROOT}/Gse/bin/run_cmds.sh --addr 127.0.0.1 --port 50000 --dictionary ${BUILD_ROOT}/Gse/generated/Ref $*
+${BUILD_ROOT}/Gse/bin/run_cmds.sh --addr localhost --port 50000 --dictionary ${BUILD_ROOT}/Gse/generated/Ref $*
diff --git a/Ref/scripts/run_ref_gse.py b/Ref/scripts/run_ref_gse.py
index 6ffe85d07f..ffff3f0c2c 100644
--- a/Ref/scripts/run_ref_gse.py
+++ b/Ref/scripts/run_ref_gse.py
@@ -1,6 +1,5 @@
#!/usr/bin/python
-import fprime.gds.utils.PortFinder
import sys
import subprocess
import os
@@ -10,18 +9,6 @@ from optparse import OptionParser
def main(argv=None):
- start_port = 50000
- end_port = 50100
- used_port = None
- nobin = True
-
- hostname = os.uname()[1]
- if (hostname == "dieb-sse.jpl.nasa.gov") :
- addr = "192.168.0.1"
- else :
- addr = "192.168.0.33"
- print ("Using address %s"%addr)
-
python_bin = os.environ["PYTHON_BASE"] + "/bin/python"
for port in range(start_port,end_port):
@@ -37,8 +24,8 @@ def main(argv=None):
build_root = os.environ["BUILD_ROOT"]
parser = OptionParser()
- parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set the threaded TCP socket server port [default: %default]", default=used_port)
- parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default=addr)
+ parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set the threaded TCP socket server port [default: %default]", default=50000)
+ parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default="localhost")
parser.add_option("-n", "--nobin", dest="nobin", action="store_true", help="Disables the binary app from starting [default: %default]", default=False)
parser.add_option("-t", "--twin", dest="twin", action="store_true", help="Runs Threaed TCP Server in window, otherwise backgrounds [default: %default]", default=False)
@@ -68,29 +55,8 @@ def main(argv=None):
#print ("GUI: %s"%" ".join(GUI_args))
GUI = subprocess.Popen(GUI_args)
- # run Ref app
-
- op_sys = os.uname()[0]
-
- ref_bin = "%s/Ref/%s/Ref"%(build_root,os.environ["OUTPUT_DIR"])
-
- if not nobin:
- REF_args = [python_bin,"%s/Gse/bin/pexpect_runner.py"%build_root,"Ref.log","Ref Application",ref_bin,"-p","%d"%used_port,"-a",addr]
- REF = subprocess.Popen(REF_args)
-
GUI.wait()
- if not nobin:
- try:
- REF.send_signal(signal.SIGTERM)
- except:
- pass
-
- try:
- REF.wait()
- except:
- pass
-
try:
TTS.send_signal(signal.SIGINT)
except:
diff --git a/Ref/scripts/run_ref_gse.sh b/Ref/scripts/run_ref_gse.sh
index 0100882fef..3f6a7b0eeb 100755
--- a/Ref/scripts/run_ref_gse.sh
+++ b/Ref/scripts/run_ref_gse.sh
@@ -38,4 +38,4 @@ echo "OUTPUT_DIR: ${OUTPUT_DIR}"
setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib
setenv PYTHONPATH ${BUILD_ROOT}/Gse/src
-${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Ref/scripts/run_ref_gse.py $*
+${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Ref/scripts/run_ref_gse.py $* &
diff --git a/Svc/ActiveLogger/ActiveLoggerComponentAi.xml b/Svc/ActiveLogger/ActiveLoggerComponentAi.xml
index fd562fc30e..a3b1fb30f2 100644
--- a/Svc/ActiveLogger/ActiveLoggerComponentAi.xml
+++ b/Svc/ActiveLogger/ActiveLoggerComponentAi.xml
@@ -5,9 +5,12 @@
Fw/Log/LogPortAi.xmlFw/Com/ComPortAi.xml
- Fw/Log/LogPortAi.xmlSvc/Fatal/FatalEventPortAi.xmlSvc/Ping/PingPortAi.xml
+ Svc/ActiveLogger/ActiveLoggerCmdDict.xml
+ Svc/ActiveLogger/ActiveLoggerEvrDict.xml
+ Svc/ActiveLogger/ActiveLoggerIntIFDict.xml
+
A component for storing telemetry
@@ -36,222 +39,5 @@
-
-
-
- Set filter for reporting events. Events are not stored in component.
-
-
-
-
-
-
-
-
-
-
-
- Filter level
-
-
-
-
-
-
- Filter state
-
-
-
-
-
- Set filter for sending events. Event will not be sent as a buffer.
-
-
-
-
-
-
-
-
-
-
-
- Filter level
-
-
-
-
-
-
- Severity filter state
-
-
-
-
-
- Dump circular buffers of events to a file
-
-
-
-
-
-
-
-
- Filter a particular ID
-
-
-
-
-
-
-
-
-
- ID filter state
-
-
-
-
-
- Dump the filter states via events
-
-
-
-
-
-
-
- Failed to write circular buffer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The write stage
-
-
- The error code
-
-
-
-
-
- Evemt log file write complete
-
-
-
- number of records written
-
-
-
-
-
- Dump severity filter state
-
-
-
-
-
-
-
-
-
-
-
- The severity level
-
-
-
-
-
-
-
-
-
- Indicate ID is filtered
-
-
-
- The ID filtered
-
-
-
-
-
- Attempted to add ID to full ID filter ID
-
-
-
- The ID filtered
-
-
-
-
-
- Removed an ID from the filter
-
-
-
- The ID removed
-
-
-
-
-
- ID not in filter
-
-
-
- The ID removed
-
-
-
-
-
-
-
- internal interface to send log messages to component thread
-
-
-
- Log ID
-
-
- Time Tag
-
-
-
-
-
-
-
-
-
-
-
- The severity argument
-
-
- Buffer containing serialized log entry
-
-
-
-
diff --git a/Svc/ActiveLogger/ActiveLoggerEvrDict.xml b/Svc/ActiveLogger/ActiveLoggerEvrDict.xml
index 849f7d4b18..6efa6e8be0 100644
--- a/Svc/ActiveLogger/ActiveLoggerEvrDict.xml
+++ b/Svc/ActiveLogger/ActiveLoggerEvrDict.xml
@@ -1,5 +1,4 @@
-
Failed to write circular buffer
diff --git a/Svc/AssertFatalAdapter/AssertFatalAdapterComponentImpl.cpp b/Svc/AssertFatalAdapter/AssertFatalAdapterComponentImpl.cpp
index d69bb2f3e0..afa94910c1 100644
--- a/Svc/AssertFatalAdapter/AssertFatalAdapterComponentImpl.cpp
+++ b/Svc/AssertFatalAdapter/AssertFatalAdapterComponentImpl.cpp
@@ -24,6 +24,24 @@
#include
#include
+namespace Fw {
+ void defaultReportAssert
+ (
+ FILE_NAME_ARG file,
+ NATIVE_UINT_TYPE lineNo,
+ NATIVE_UINT_TYPE numArgs,
+ AssertArg arg1,
+ AssertArg arg2,
+ AssertArg arg3,
+ AssertArg arg4,
+ AssertArg arg5,
+ AssertArg arg6,
+ I8* destBuffer,
+ NATIVE_INT_TYPE buffSize
+ );
+
+}
+
namespace Svc {
// ----------------------------------------------------------------------
@@ -112,11 +130,15 @@ namespace Svc {
#if FW_ASSERT_LEVEL == FW_FILEID_ASSERT
Fw::LogStringArg fileArg;
- fileArg.format("%d",file);
+ fileArg.format("0x%08X",file);
#else
Fw::LogStringArg fileArg((const char*)file);
#endif
+ I8 msg[FW_ASSERT_TEXT_SIZE];
+ Fw::defaultReportAssert(file,lineNo,numArgs,arg1,arg2,arg3,arg4,arg5,arg6,msg,sizeof(msg));
+ fprintf(stderr, "%s\n",(const char*)msg);
+
switch (numArgs) {
case 0:
this->log_FATAL_AF_ASSERT_0(fileArg,lineNo);
diff --git a/Svc/BufferLogger/test/ut/Errors.cpp b/Svc/BufferLogger/test/ut/Errors.cpp
index 66e8453ada..c0f40ea224 100644
--- a/Svc/BufferLogger/test/ut/Errors.cpp
+++ b/Svc/BufferLogger/test/ut/Errors.cpp
@@ -120,7 +120,7 @@ namespace Svc {
ASSERT_EVENTS_BL_LogFileWriteError(
0,
Os::File::NOT_OPENED, // errornum
- sizeof(SIZE_TYPE), // bytesWritten
+ 0, // bytesWritten
sizeof(SIZE_TYPE), // bytesAttempted
fileName.toChar() // file
);
@@ -160,7 +160,7 @@ namespace Svc {
ASSERT_EVENTS_BL_LogFileWriteError(
i,
Os::File::NOT_OPENED,
- sizeof(SIZE_TYPE),
+ 0,
sizeof(SIZE_TYPE),
fileName.toChar()
);
diff --git a/Svc/BufferLogger/test/ut/GTestBase.cpp b/Svc/BufferLogger/test/ut/GTestBase.cpp
index 7cef7533e8..fc60f67a7c 100644
--- a/Svc/BufferLogger/test/ut/GTestBase.cpp
+++ b/Svc/BufferLogger/test/ut/GTestBase.cpp
@@ -74,28 +74,28 @@ namespace Svc {
assertCmdResponse(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const FwOpcodeType opCode,
const U32 cmdSeq,
const Fw::CommandResponse response
)
const
{
- ASSERT_LT(index, this->cmdResponseHistory->size())
+ ASSERT_LT(__index, this->cmdResponseHistory->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into command response history\n"
<< " Expected: Less than size of command response history ("
<< this->cmdResponseHistory->size() << ")\n"
- << " Actual: " << index << "\n";
- const CmdResponse& e = this->cmdResponseHistory->at(index);
+ << " Actual: " << __index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(__index);
ASSERT_EQ(opCode, e.opCode)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Opcode at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << opCode << "\n"
<< " Actual: " << e.opCode << "\n";
@@ -104,7 +104,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command sequence number at index "
- << index
+ << __index
<< " in command response history\n"
<< " Expected: " << cmdSeq << "\n"
<< " Actual: " << e.cmdSeq << "\n";
@@ -113,7 +113,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Command response at index "
- << index
+ << __index
<< " in command resopnse history\n"
<< " Expected: " << response << "\n"
<< " Actual: " << e.response << "\n";
@@ -163,27 +163,27 @@ namespace Svc {
assertTlm_BufferLogger_NumLoggedBuffers(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_BufferLogger_NumLoggedBuffers->size())
+ ASSERT_LT(__index, this->tlmHistory_BufferLogger_NumLoggedBuffers->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel BufferLogger_NumLoggedBuffers\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_BufferLogger_NumLoggedBuffers->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_BufferLogger_NumLoggedBuffers& e =
- this->tlmHistory_BufferLogger_NumLoggedBuffers->at(index);
+ this->tlmHistory_BufferLogger_NumLoggedBuffers->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel BufferLogger_NumLoggedBuffers\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
@@ -233,26 +233,26 @@ namespace Svc {
assertEvents_BL_LogFileClosed(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const char *const file
) const
{
- ASSERT_GT(this->eventHistory_BL_LogFileClosed->size(), index)
+ ASSERT_GT(this->eventHistory_BL_LogFileClosed->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event BL_LogFileClosed\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_BL_LogFileClosed->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_BL_LogFileClosed& e =
- this->eventHistory_BL_LogFileClosed->at(index);
+ this->eventHistory_BL_LogFileClosed->at(__index);
ASSERT_STREQ(file, e.file.toChar())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument file at index "
- << index
+ << __index
<< " in history of event BL_LogFileClosed\n"
<< " Expected: " << file << "\n"
<< " Actual: " << e.file.toChar() << "\n";
@@ -282,27 +282,27 @@ namespace Svc {
assertEvents_BL_LogFileOpenError(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32 errornum,
const char *const file
) const
{
- ASSERT_GT(this->eventHistory_BL_LogFileOpenError->size(), index)
+ ASSERT_GT(this->eventHistory_BL_LogFileOpenError->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event BL_LogFileOpenError\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_BL_LogFileOpenError->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_BL_LogFileOpenError& e =
- this->eventHistory_BL_LogFileOpenError->at(index);
+ this->eventHistory_BL_LogFileOpenError->at(__index);
ASSERT_EQ(errornum, e.errornum)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument errornum at index "
- << index
+ << __index
<< " in history of event BL_LogFileOpenError\n"
<< " Expected: " << errornum << "\n"
<< " Actual: " << e.errornum << "\n";
@@ -311,7 +311,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument file at index "
- << index
+ << __index
<< " in history of event BL_LogFileOpenError\n"
<< " Expected: " << file << "\n"
<< " Actual: " << e.file.toChar() << "\n";
@@ -341,27 +341,27 @@ namespace Svc {
assertEvents_BL_LogFileValidationError(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const char *const validationFile,
const U32 status
) const
{
- ASSERT_GT(this->eventHistory_BL_LogFileValidationError->size(), index)
+ ASSERT_GT(this->eventHistory_BL_LogFileValidationError->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event BL_LogFileValidationError\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_BL_LogFileValidationError->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_BL_LogFileValidationError& e =
- this->eventHistory_BL_LogFileValidationError->at(index);
+ this->eventHistory_BL_LogFileValidationError->at(__index);
ASSERT_STREQ(validationFile, e.validationFile.toChar())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument validationFile at index "
- << index
+ << __index
<< " in history of event BL_LogFileValidationError\n"
<< " Expected: " << validationFile << "\n"
<< " Actual: " << e.validationFile.toChar() << "\n";
@@ -370,7 +370,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument status at index "
- << index
+ << __index
<< " in history of event BL_LogFileValidationError\n"
<< " Expected: " << status << "\n"
<< " Actual: " << e.status << "\n";
@@ -400,29 +400,29 @@ namespace Svc {
assertEvents_BL_LogFileWriteError(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32 errornum,
const U32 bytesWritten,
const U32 bytesToWrite,
const char *const file
) const
{
- ASSERT_GT(this->eventHistory_BL_LogFileWriteError->size(), index)
+ ASSERT_GT(this->eventHistory_BL_LogFileWriteError->size(), __index)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of event BL_LogFileWriteError\n"
<< " Expected: Less than size of history ("
<< this->eventHistory_BL_LogFileWriteError->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const EventEntry_BL_LogFileWriteError& e =
- this->eventHistory_BL_LogFileWriteError->at(index);
+ this->eventHistory_BL_LogFileWriteError->at(__index);
ASSERT_EQ(errornum, e.errornum)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument errornum at index "
- << index
+ << __index
<< " in history of event BL_LogFileWriteError\n"
<< " Expected: " << errornum << "\n"
<< " Actual: " << e.errornum << "\n";
@@ -431,7 +431,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument bytesWritten at index "
- << index
+ << __index
<< " in history of event BL_LogFileWriteError\n"
<< " Expected: " << bytesWritten << "\n"
<< " Actual: " << e.bytesWritten << "\n";
@@ -440,7 +440,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument bytesToWrite at index "
- << index
+ << __index
<< " in history of event BL_LogFileWriteError\n"
<< " Expected: " << bytesToWrite << "\n"
<< " Actual: " << e.bytesToWrite << "\n";
@@ -449,7 +449,7 @@ namespace Svc {
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value of argument file at index "
- << index
+ << __index
<< " in history of event BL_LogFileWriteError\n"
<< " Expected: " << file << "\n"
<< " Actual: " << e.file.toChar() << "\n";
diff --git a/Svc/BufferLogger/test/ut/GTestBase.hpp b/Svc/BufferLogger/test/ut/GTestBase.hpp
index 6ba648088b..24f35461d9 100644
--- a/Svc/BufferLogger/test/ut/GTestBase.hpp
+++ b/Svc/BufferLogger/test/ut/GTestBase.hpp
@@ -194,7 +194,7 @@ namespace Svc {
void assertCmdResponse(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const FwOpcodeType opCode, /*!< The opcode*/
const U32 cmdSeq, /*!< The command sequence number*/
const Fw::CommandResponse response /*!< The command response*/
@@ -231,7 +231,7 @@ namespace Svc {
void assertTlm_BufferLogger_NumLoggedBuffers(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32& val /*!< The channel value*/
) const;
@@ -262,7 +262,7 @@ namespace Svc {
void assertEvents_BL_LogFileClosed(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const char *const file /*!< The file*/
) const;
@@ -281,7 +281,7 @@ namespace Svc {
void assertEvents_BL_LogFileOpenError(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32 errornum, /*!< The error number returned from the open operation*/
const char *const file /*!< The file*/
) const;
@@ -301,7 +301,7 @@ namespace Svc {
void assertEvents_BL_LogFileValidationError(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const char *const validationFile, /*!< The validation file*/
const U32 status /*!< The Os::Validate::Status return*/
) const;
@@ -321,7 +321,7 @@ namespace Svc {
void assertEvents_BL_LogFileWriteError(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32 errornum, /*!< The error number returned from the write operation*/
const U32 bytesWritten, /*!< The number of bytes successfully written*/
const U32 bytesToWrite, /*!< The number of bytes attempted*/
diff --git a/Svc/BufferManager/BufferManager.cpp b/Svc/BufferManager/BufferManager.cpp
index c4f4cff04d..6c0a9a8f5c 100644
--- a/Svc/BufferManager/BufferManager.cpp
+++ b/Svc/BufferManager/BufferManager.cpp
@@ -1,10 +1,10 @@
// ======================================================================
// \title BufferManager.hpp
// \author bocchino
-// \brief hpp file for BufferManager component implementation class
+// \brief BufferManager component interface
//
// \copyright
-// Copyright 2009-2015, by the California Institute of Technology.
+// Copyright (C) 2015-2017, by the California Institute of Technology.
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged. Any commercial use must be negotiated with the Office
// of Technology Transfer at the California Institute of Technology.
@@ -17,46 +17,62 @@
// countries or providing access to foreign persons.
// ======================================================================
-
-#include "Svc/BufferManager/BufferManager.hpp"
#include "Fw/Types/Assert.hpp"
#include "Fw/Types/BasicTypes.hpp"
-#include
-#include
-
-using namespace std;
+#include "Svc/BufferManager/BufferManager.hpp"
namespace Svc {
// ----------------------------------------------------------------------
- // Construction, initialization, and destruction
+ // Warnings::State
// ----------------------------------------------------------------------
- BufferManager ::
- BufferManager(
- const char *const compName,
- const U32 storeSize,
- const U32 allocationQueueSize
- ) :
- BufferManagerComponentBase(compName),
- store(storeSize),
- allocationQueue(allocationQueueSize)
+ BufferManager::Warnings::State ::
+ State(void) :
+ storeSizeExceeded(false),
+ tooManyBuffers(false)
{
}
- void BufferManager ::
- init(
- const NATIVE_INT_TYPE instance
- )
+ // ----------------------------------------------------------------------
+ // Warnings
+ // ----------------------------------------------------------------------
+
+ BufferManager::Warnings ::
+ Warnings(BufferManager& bufferManager) :
+ bufferManager(bufferManager)
{
- BufferManagerComponentBase::init(instance);
+
}
- BufferManager ::
- ~BufferManager(void)
+ void BufferManager::Warnings ::
+ update(const Status::t status)
{
-
+ switch (status) {
+ case Status::SUCCESS:
+ if (this->state.storeSizeExceeded || this->state.tooManyBuffers) {
+ this->bufferManager.log_ACTIVITY_HI_ClearedErrorState();
+ }
+ this->state.storeSizeExceeded = false;
+ this->state.tooManyBuffers = false;
+ break;
+ case Status::STORE_SIZE_EXCEEDED:
+ if (!this->state.storeSizeExceeded) {
+ this->bufferManager.log_WARNING_HI_StoreSizeExceeded();
+ this->state.storeSizeExceeded = true;
+ }
+ break;
+ case Status::TOO_MANY_BUFFERS:
+ if (!this->state.tooManyBuffers) {
+ this->bufferManager.log_WARNING_HI_TooManyBuffers();
+ this->state.tooManyBuffers = true;
+ }
+ break;
+ default:
+ FW_ASSERT(0);
+ break;
+ }
}
// ----------------------------------------------------------------------
@@ -64,12 +80,12 @@ namespace Svc {
// ----------------------------------------------------------------------
BufferManager::Store ::
- Store(
- const U32 size
- ) :
+ Store(const U32 size) :
totalSize(size),
memoryBase(new U8[size]),
- freeIndex(0)
+ freeIndex(0),
+ padSize(0),
+ allocatedSize(0)
{
}
@@ -88,29 +104,54 @@ namespace Svc {
BufferManager::Store::Status BufferManager::Store ::
allocate(
- const U32 n,
+ const U32 s,
U8* &result
)
{
- FW_ASSERT(this->freeIndex + n >= this->freeIndex);
- if (this->freeIndex + n > this->totalSize) {
- result = 0;
- return STAT_FAIL;
+ Status status = SUCCESS;
+ U32 newPadSize = 0;
+ FW_ASSERT(this->allocatedSize <= this->totalSize);
+ FW_ASSERT(this->freeIndex <= this->totalSize);
+ if (this->freeIndex + s > this->totalSize) {
+ // Pad size for wraparound allocation
+ newPadSize = this->totalSize - this->freeIndex;
}
- result = &this->memoryBase[this->freeIndex];
- this->freeIndex += n;
- return STAT_OK;
+ if (this->allocatedSize + s + newPadSize > this->totalSize) {
+ // Allocation too large
+ status = FAILURE;
+ result = 0;
+ }
+ else {
+ if (this->freeIndex + s > this->totalSize) {
+ // Wraparound allocation
+ FW_ASSERT(this->padSize == 0, this->padSize);
+ this->padSize = newPadSize;
+ this->allocatedSize += newPadSize;
+ this->freeIndex = 0;
+ }
+ result = &this->memoryBase[this->freeIndex];
+ this->allocatedSize += s;
+ this->freeIndex += s;
+ FW_ASSERT(this->allocatedSize <= this->totalSize);
+ FW_ASSERT(this->freeIndex <= this->totalSize);
+ }
+ return status;
}
- BufferManager::Store::Status BufferManager::Store ::
- free(const U32 n)
+ void BufferManager::Store ::
+ free(
+ const U32 size,
+ U8 *const address
+ )
{
- if (n > freeIndex) {
- this->freeIndex = 0;
- return STAT_FAIL;
+ FW_ASSERT(this->allocatedSize >= size, this->allocatedSize, size);
+ this->allocatedSize -= size;
+ if (address == this->memoryBase) {
+ // Wraparound allocation
+ FW_ASSERT(this->allocatedSize >= padSize, this->allocatedSize, padSize);
+ this->allocatedSize -= this->padSize;
+ this->padSize = 0;
}
- this->freeIndex -= n;
- return STAT_OK;
}
// ----------------------------------------------------------------------
@@ -118,9 +159,7 @@ namespace Svc {
// ----------------------------------------------------------------------
BufferManager::AllocationQueue ::
- AllocationQueue(
- const U32 size
- ) :
+ AllocationQueue(const U32 size) :
totalSize(size),
data(new Entry[size]),
nextId(0),
@@ -179,7 +218,7 @@ namespace Svc {
e.size = size;
this->allocateIndex = this->getNextIndex(this->allocateIndex);
++this->allocationSize;
- return Allocate::STAT_OK;
+ return Allocate::SUCCESS;
}
BufferManager::AllocationQueue::Free::Status
@@ -205,20 +244,37 @@ namespace Svc {
}
this->freeIndex = this->getNextIndex(this->freeIndex);
--this->allocationSize;
- return Free::STAT_OK;
+ return Free::SUCCESS;
+ }
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ BufferManager ::
+ BufferManager(
+ const char *const compName,
+ const U32 storeSize,
+ const U32 maxNumBuffers
+ ) :
+ BufferManagerComponentBase(compName),
+ warnings(*this),
+ store(storeSize),
+ allocationQueue(maxNumBuffers)
+ {
+
}
void BufferManager ::
- sendTelemetry(void)
+ init(const NATIVE_INT_TYPE instance)
{
- const U32 allocatedSize = this->store.getAllocatedSize();
- this->tlmWrite_BufferManager_AllocatedSize(
- const_cast(allocatedSize)
- );
- const U32 numAllocatedBuffers = this->allocationQueue.getAllocationSize();
- this->tlmWrite_BufferManager_NumAllocatedBuffers(
- const_cast(numAllocatedBuffers)
- );
+ BufferManagerComponentBase::init(instance);
+ }
+
+ BufferManager ::
+ ~BufferManager(void)
+ {
+
}
// ----------------------------------------------------------------------
@@ -236,60 +292,62 @@ namespace Svc {
Fw::Buffer buffer;
buffer.set(this->getInstance(), 0, 0, size);
+ Warnings::Status::t warningStatus = Warnings::Status::SUCCESS;
+
{
const Store::Status status =
this->store.allocate(size, address);
- if (status == BufferManager::Store::STAT_FAIL) {
- this->log_WARNING_HI_BufferManager_StoreSizeExceeded();
- return buffer;
+ if (status == BufferManager::Store::FAILURE) {
+ warningStatus = Warnings::Status::STORE_SIZE_EXCEEDED;
}
}
- {
+ if (warningStatus == Warnings::Status::SUCCESS) {
const AllocationQueue::Allocate::Status status =
this->allocationQueue.allocate(size, id);
if (status == AllocationQueue::Allocate::FULL) {
- this->store.free(size);
- this->log_WARNING_HI_BufferManager_AllocationQueueFull();
- return buffer;
+ this->store.free(size, address);
+ warningStatus = Warnings::Status::TOO_MANY_BUFFERS;
}
}
- this->sendTelemetry();
-
- buffer.setbufferID(id);
- buffer.setdata(reinterpret_cast(address));
+ if (warningStatus == Warnings::Status::SUCCESS) {
+ buffer.setbufferID(id);
+ buffer.setdata(reinterpret_cast(address));
+ }
+ this->warnings.update(warningStatus);
return buffer;
}
void BufferManager ::
bufferSendIn_handler(
const NATIVE_INT_TYPE portNum,
- Fw::Buffer& buffer
+ Fw::Buffer &buffer
)
{
+
const U32 instance = static_cast(this->getInstance());
FW_ASSERT(buffer.getmanagerID() == instance);
const U32 expectedId = buffer.getbufferID();
+ U8 *const address = reinterpret_cast(buffer.getdata());
U32 sawId = 0;
U32 size = 0;
- const AllocationQueue::Free::Status status =
- this->allocationQueue.free(expectedId, sawId, size);
+ {
+ const AllocationQueue::Free::Status status =
+ this->allocationQueue.free(expectedId, sawId, size);
+ FW_ASSERT(
+ status == AllocationQueue::Free::SUCCESS,
+ status, expectedId, sawId, size
+ );
+ }
- if (status == AllocationQueue::Free::EMPTY) {
- this->log_WARNING_HI_BufferManager_AllocationQueueEmpty();
- }
- else if (status == AllocationQueue::Free::ID_MISMATCH) {
- this->log_WARNING_HI_BufferManager_IDMismatch(expectedId, sawId);
- }
- else {
- const Store::Status status = this->store.free(size);
- FW_ASSERT(status == Store::STAT_OK);
- this->sendTelemetry();
+ {
+ this->store.free(size, address);
}
+
}
}
diff --git a/Svc/BufferManager/BufferManager.hpp b/Svc/BufferManager/BufferManager.hpp
index d0e52d7612..1574aafdf5 100644
--- a/Svc/BufferManager/BufferManager.hpp
+++ b/Svc/BufferManager/BufferManager.hpp
@@ -4,7 +4,7 @@
// \brief hpp file for BufferManager component implementation class
//
// \copyright
-// Copyright 2009-2015, by the California Institute of Technology.
+// Copyright 2015-2017, by the California Institute of Technology.
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged. Any commercial use must be negotiated with the Office
// of Technology Transfer at the California Institute of Technology.
@@ -28,29 +28,69 @@ namespace Svc {
public BufferManagerComponentBase
{
- public:
+ PRIVATE:
- // ----------------------------------------------------------------------
- // Construction, initialization, and destruction
- // ----------------------------------------------------------------------
+ // ----------------------------------------------------------------------
+ // Warnings
+ // ----------------------------------------------------------------------
- //! Construct object BufferManager
- //!
- BufferManager(
- const char *const compName, //!< The component name
- const U32 storeSize,
- const U32 allocationQueueSize
- );
+ class Warnings {
- //! Initialize object BufferManager
- //!
- void init(
- const NATIVE_INT_TYPE instance //!< The instance number
- );
+ public:
- //! Destroy object BufferManager
- //!
- ~BufferManager(void);
+ //! Status
+ struct Status {
+
+ typedef enum {
+ //! Success
+ SUCCESS,
+ //! Store size exceeded
+ STORE_SIZE_EXCEEDED,
+ //! Too many buffers
+ TOO_MANY_BUFFERS,
+ } t;
+
+ };
+
+ PRIVATE:
+
+ //! Whether we have emitted a warning
+ struct State {
+
+ //! Construct a State object
+ State(void);
+
+ //! StoreSizeExceeded
+ bool storeSizeExceeded;
+
+ //! TooManyBuffers
+ bool tooManyBuffers;
+
+ };
+
+ public:
+
+ //! Construct a Warnings object
+ Warnings(
+ BufferManager& bufferManager //!< The enclosing BufferManager
+ );
+
+ public:
+
+ //! Update the warning state
+ void update(
+ const Status::t status //!< The status
+ );
+
+ PRIVATE:
+
+ //! The enclosing BufferManager
+ BufferManager& bufferManager;
+
+ //! The warning state
+ State state;
+
+ };
PRIVATE:
@@ -80,7 +120,7 @@ namespace Svc {
// Types
// ----------------------------------------------------------------------
- typedef enum { STAT_OK, STAT_FAIL } Status;
+ typedef enum { SUCCESS, FAILURE } Status;
public:
@@ -97,8 +137,11 @@ namespace Svc {
U8* &result
);
- // Free n bytes from the store
- Status free(const U32 n);
+ // Free bytes from the store
+ void free(
+ const U32 size, //!< The allocation size
+ U8 *const address //!< The allocation address
+ );
PRIVATE:
@@ -116,9 +159,15 @@ namespace Svc {
// Variables
// ----------------------------------------------------------------------
- // Pointer to the first free byte of store memory
+ //! Pointer to the first free byte of store memory
U32 freeIndex;
+ //! The amount of padding at the end of the store, added to allocations that otherwise would wrap around
+ U32 padSize;
+
+ //! The total allocated size on the store
+ U32 allocatedSize;
+
};
PRIVATE:
@@ -151,7 +200,7 @@ namespace Svc {
struct Allocate {
typedef enum {
- STAT_OK, // Allocation OK
+ SUCCESS, // Allocation OK
FULL // No more room
} Status;
@@ -161,7 +210,7 @@ namespace Svc {
struct Free {
typedef enum {
- STAT_OK, // Free OK
+ SUCCESS, // Free OK
EMPTY, // Nothing to free
ID_MISMATCH // ID supplied was not at head of queue
} Status;
@@ -208,7 +257,6 @@ namespace Svc {
// Update a circular index
U32 getNextIndex(const U32 index);
-
PRIVATE:
// ----------------------------------------------------------------------
@@ -241,6 +289,30 @@ namespace Svc {
};
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object BufferManager
+ //!
+ BufferManager(
+ const char *const compName, //!< The component name
+ const U32 storeSize,
+ const U32 maxNumBuffers
+ );
+
+ //! Initialize object BufferManager
+ //!
+ void init(
+ const NATIVE_INT_TYPE instance //!< The instance number
+ );
+
+ //! Destroy object BufferManager
+ //!
+ ~BufferManager(void);
+
PRIVATE:
// ----------------------------------------------------------------------
@@ -258,28 +330,22 @@ namespace Svc {
//!
void bufferSendIn_handler(
const NATIVE_INT_TYPE portNum, //!< The port number
- Fw::Buffer& buffer
+ Fw::Buffer &buffer
);
- PRIVATE:
-
- // ----------------------------------------------------------------------
- // Helper methods
- // ----------------------------------------------------------------------
-
- // Send telemetry
- void sendTelemetry(void);
-
PRIVATE:
// ----------------------------------------------------------------------
// Variables
// ----------------------------------------------------------------------
- // The store
+ //! Warnings
+ Warnings warnings;
+
+ //! The store
Store store;
- // The allocation queue
+ //! The allocation queue
AllocationQueue allocationQueue;
};
diff --git a/Svc/BufferManager/BufferManagerComponentAi.xml b/Svc/BufferManager/BufferManagerComponentAi.xml
index d119e09e59..e876aaf137 100644
--- a/Svc/BufferManager/BufferManagerComponentAi.xml
+++ b/Svc/BufferManager/BufferManagerComponentAi.xml
@@ -3,36 +3,34 @@
- Fw/Buffer/BufferGetPortAi.xml
- Fw/Buffer/BufferSendPortAi.xmlFw/Time/TimePortAi.xml
- Fw/Tlm/TlmPortAi.xmlFw/Log/LogPortAi.xml
+ Fw/Log/LogTextPortAi.xml
+ Fw/Buffer/BufferSendPortAi.xml
+ Fw/Buffer/BufferGetPortAi.xml
+ Fw/Tlm/TlmPortAi.xmlSvc/BufferManager/Telemetry.xml
- Svc//BufferManager/Events.xml
-
+ Svc/BufferManager/Events.xml
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
+
-
+
\ No newline at end of file
diff --git a/Svc/BufferManager/BufferManagerModule.mdxml b/Svc/BufferManager/BufferManagerModule.mdxml
index 3565c3b4b1..2ccd1c4a1e 100644
--- a/Svc/BufferManager/BufferManagerModule.mdxml
+++ b/Svc/BufferManager/BufferManagerModule.mdxml
@@ -1,69 +1,75 @@
-
-
+
+ MagicDraw UML
- 17.0.5
+ 18.0
-
+
-
-
+
+
+
-
+
+ MagicDraw UML
- 17.0.5
+ 18.0
-
-
+
+
+
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
-
+
+
+
-
+
+
+ _17_0_5_1_e880346_1460698829316_162400_22335
- _17_0_5_1_e880346_1460698829300_245304_22314
- _17_0_5_1_e880346_1460698829317_774321_22336
- _17_0_5_1_e880346_1460698829318_225776_22339_17_0_5_1_e880346_1460698829146_655571_22301
- _17_0_5_1_e880346_1460698829317_512004_22338_17_0_5_1_e880346_1460698829317_277993_22337
+ _17_0_5_1_e880346_1460698829318_225776_22339
+ _17_0_5_1_e880346_1460698829300_245304_22314
+ _17_0_5_1_e880346_1460698829317_512004_22338
+ _17_0_5_1_e880346_1460698829317_774321_22336
+ _18_0_5_b8902dd_1526925014185_297868_14927
@@ -74,64 +80,71 @@
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
- _17_0_5_1_e880346_1460698829465_126110_22386
+
+ _17_0_5_1_e880346_1460698829465_438183_22387_17_0_5_1_e880346_1460698829453_583754_22361
- _17_0_5_1_e880346_1460698829465_75437_22388
- _17_0_5_1_e880346_1460698829465_549646_22389
+ _17_0_5_1_e880346_1460698829465_126110_22386_17_0_5_1_e880346_1460698829465_279948_22385_17_0_5_1_e880346_1460698829466_412865_22390
+ _17_0_5_1_e880346_1460698829465_75437_22388
+ _17_0_5_1_e880346_1460698829465_549646_22389
@@ -182,15 +195,23 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
@@ -199,78 +220,81 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -283,102 +307,278 @@
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
- _17_0_2_136f03d9_1344498413266_378771_11852
- _11_5EAPbeta_be00301_1147434586638_637562_1900
-
-
- magicdraw_uml_standard_profile_v_0001
-
-
- _17_0_5_1_e880346_1460698829145_787843_22300
-
-
- _17_0_2_2_9120299_1421800597812_375267_27997
-
-
- _17_0_2_2_9120299_1421171074686_28955_26514
-
-
- _17_0_2_2_9120299_1421111294349_905518_27938
-
-
- _17_0_2_2_9120299_1366841320552_114823_26850
-
-
- _16_8beta_2104050f_1262918510515_114803_6875
- _12_0EAPbeta_be00301_1156851270584_552173_1
-
-
- _17_0_5_1_89a0278_1457736977987_773486_11645
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- 301, 75, 161, 22381, 97, 0, 366376, 231, 10, 207191, 231; 376, 231; 240, 215, 86, 13Request buffer567, 231; 386, 231; 441, 215, 70, 13Send buffer504, 75, 136, 22572, 97, 0, 366567, 231, 10, 187191, 347; 567, 347; 344, 331, 70, 13Send buffer105, 75, 163, 22186, 97, 0, 366181, 231, 10, 1875, 5, 753, 499
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
@@ -410,36 +610,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
@@ -488,7 +684,7 @@
-
+
@@ -503,12 +699,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -535,91 +854,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ H4sIAAAAAAAAAC2LPQvCMBQA90L/Q6CrL7y8NjEpOCguDhURFydJ81GFpoGKiP9eUZeDg7uqLKouT6yzL0aCCWylaaVkh+2JEQpdFi4nPuVkh5vjX/rZPvkjjZeUfRj5/Wrn4H+y2uz26+MZlOjJkG6A0NTQ9FGBJSsh9ChQeUUSafFva3SGTKxBC6eh8csInzlCDJLQkzICfVm8AaPEP7CoAAAA
+
+
@@ -633,7 +881,7 @@
-
+
@@ -644,7 +892,7 @@
-
+
@@ -652,17 +900,11 @@
-
-
-
-
-
-
-
+
@@ -673,13 +915,8 @@
-
+
-
-
-
-
-
@@ -691,7 +928,7 @@
-
+
@@ -715,411 +952,298 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ H4sIAAAAAAAAAFPm5VL2zc9T8E2sVDAyVDA0sDK1tDI1VQhwCVEwMjC04OUCAHb0TLwiAAAA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 182, 84, 364, 224
+
+
+
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 538, 199, 15, 15
+
+
+
+
+ 556, 191, 72, 12
+
+ eventOut : Log
+
+
+ 556, 176, 58, 12
+
+ «LogEvent»
+
+
+
+
+
+
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 175, 128, 15, 15
+
+
+
+
+ 94, 120, 78, 12
+
+ timeCaller : Time
+
+
+ 120, 105, 52, 12
+
+ «TimeGet»
+
+
+
+
+
+
+
+
+
+ FILL_COLOR
+ FILL_COLOR_DESCRIPTION
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 175, 185, 15, 15
+
+
+
+
+ 43, 177, 129, 12
+
+ bufferSendIn : BufferSend
+
+
+ 90, 162, 82, 12
+
+ «guarded_input»
+
+
+
+
+
+
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 538, 144, 15, 15
+
+
+
+
+ 556, 136, 56, 12
+
+ tlmOut : Tlm
+
+
+ 556, 121, 60, 12
+
+ «Telemetry»
+
+
+
+
+
+
+
+
+
+ FILL_COLOR
+ FILL_COLOR_DESCRIPTION
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 175, 240, 15, 15
+
+
+
+
+ 38, 232, 134, 12
+
+ bufferGetCallee : BufferGet
+
+
+ 90, 217, 82, 12
+
+ «guarded_input»
+
+
+
+
+
+
+
+
+
+ STEREOTYPES_DISPLAY_MODE
+ STEREOTYPES_DISPLAY_MODE_DESCRIPTION
+ STEREOTYPE_DISPLAY_MODE_TEXT
+
+
+
+
+ SHOW_INHERITED_SIGN
+ SHOW_INHERITED_SIGN_DESCRIPTION
+
+
+ 538, 245, 15, 15
+
+
+
+
+ 556, 237, 111, 12
+
+ textEventOut : LogText
+
+
+ 556, 222, 79, 12
+
+ «LogTextEvent»
+
+
+
+
+
+
+
+
+
+ 5, 5, 705, 323
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -1167,7 +1291,7 @@
-
+
@@ -1185,169 +1309,79 @@
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- H4sIAAAAAAAAAAMAAAAAAAAAAAA=
-
-
+
@@ -1360,18 +1394,18 @@
-
+
-
+
-
+
-
+
@@ -1382,172 +1416,65 @@
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
-
+
-
+
-
+
+
-
-
-
-
-
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
@@ -1588,7 +1515,7 @@
-
+
@@ -1603,11 +1530,6 @@
-
-
-
-
-
@@ -1616,9 +1538,168 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1734,6 +1815,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1748,602 +1841,307 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ _11_5EAPbeta_be00301_1147434586638_637562_1900
+
+
+ magicdraw_uml_standard_profile_v_0001
+
+
+ _17_0_5_1_e880346_1460698829145_787843_22300
+
+
+ _17_0_2_2_9120299_1421800597812_375267_27997
+
+
+ _17_0_2_2_9120299_1421171074686_28955_26514
+
+
+ _17_0_2_2_9120299_1421111294349_905518_27938
+
+
+ _17_0_2_2_9120299_1366841320552_114823_26850
+
+
+ _12_0EAPbeta_be00301_1156851270584_552173_1
+
+
+ _17_0_5_1_89a0278_1457736977987_773486_11645
+
+
-
- #
-#Fri Apr 15 11:19:20 PDT 2016
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -2384,7 +2182,7 @@
-
+
@@ -2395,187 +2193,165 @@
-
- #
-#Fri Apr 15 11:19:20 PDT 2016
-com.nomagic.magicdraw.uml_model.shared_model=BINARY-30c929f3-81c8-4d7f-b29f-fe520d26910d,BINARY-c0f7dbd2-23e2-4ba7-a982-6db66ea5ca32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
- 182, 84, 364, 224
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 538, 199, 15, 15
-
-
-
-
- 556, 190, 73, 13
-
- eventOut : Log
-
-
- 556, 174, 59, 13
-
- «LogEvent»
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 175, 159, 15, 15
-
-
-
-
- 90, 150, 82, 13
-
- timeCaller : Time
-
-
- 117, 134, 55, 13
-
- «TimeGet»
-
-
-
-
-
-
-
-
-
- FILL_COLOR
- FILL_COLOR_DESCRIPTION
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 175, 240, 15, 15
-
-
-
-
- 46, 231, 126, 13
-
- bufferSendIn : BufferSend
-
-
- 90, 215, 82, 13
-
- «guarded_input»
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 538, 144, 15, 15
-
-
-
-
- 556, 135, 60, 13
-
- tlmOut : Tlm
-
-
- 556, 119, 62, 13
-
- «Telemetry»
-
-
-
-
-
-
-
-
-
- FILL_COLOR
- FILL_COLOR_DESCRIPTION
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 538, 254, 15, 15
-
-
-
-
- 556, 245, 133, 13
-
- bufferGetCallee : BufferGet
-
-
- 556, 229, 82, 13
-
- «guarded_input»
-
-
-
-
-
-
-
-
-
- 5, 5, 704, 323
-
-
-
-
+
+ 301, 75, 161, 22381, 97, 0, 366376, 231, 10, 207191, 231; 376, 231; 240, 215, 86, 13Request buffer567, 231; 386, 231; 441, 215, 70, 13Send buffer504, 75, 136, 22572, 97, 0, 366567, 231, 10, 187191, 347; 567, 347; 344, 331, 70, 13Send buffer105, 75, 163, 22186, 97, 0, 366181, 231, 10, 1875, 5, 753, 499
-
- H4sIAAAAAAAAAM1YW2+bMBR+51dEKq8g3zC4Uh7abpO2h62q+rKnyPaxF6YEENBt+fc7pKR32iaDaHkgvhz7Oz53++SiXFe6zU2+ytvNzBVtvQlOPtX57KyqZzSZUXpK1Skjs8sP1zNGqAyquvyziVel1avF4vLq25ePF9fhUnljvVQGW9pAuBQ+s9hOvermhE80o1RqsahdU97U1i1suQ6hKNf6R25D2P5BrX+HcLNeLW7WJbhVCM1S1w7uu4WummXZzv8HJgYkkekUuMgQkkrAr0idD5cGLMERoUBIK7SRZlJJHJeJAUl4RVTmGMJLEBqZUCCRCa2ycEkk1VlCLLHgh5iwOTLiWt2jIchPZ9s3zz41bHCeF7rOXRPjVOXqFpvzF8YGpGIkSXxmKCoCjOhU4xM0T8XRYFOCzGeJSzzlk9rHcZkYkIRAA2WaG3RZbolGGzXMY5cSxcmgekY5/zGgg/PPX8+uvkeW+BQMsIhxxyJhdBqhLbJIgpHS6cRqzuZ70E4UgQ/0tqlhJ4oto1jRcZkIMK40ZaFXEe4S95vEd3vEtqxd3MsvLqs2LwsMR/2afrwfno+31ZBvZ0RnqeLh0rLUYZ93wSajGsWkmSBE2cwpM7GXH5WJYA9ZIum6LJ4o5R/XT6SJA+PC1LBBjxTtSp2oq3SirtCJujoneljmzPchHtBjZwFbZuJe/9vOgNJeJn60s83jW8ntThSDa2ydV21ZP2g+Nov3LhrKEUYAM1QK6iQjXHEBKnGpAUz2jmRjp4Zp0J5K8Y525yVPJfaM4E0Nv0+1tzods8A41NcmAXtmrRj/86Z1hXW3HPSmWNX5L906cJUrAGc3K6R6ZrX7LB6QKWARpMAyTLdc8i7dGrzUZEC7L9EGayPjEpAjS3dq2IlOO0oGPS4Tb/nlAn/bpVWZF22zVyB+be3QTT5NkwSTFGPCUyogIeA09VxpailVI5vZRGjjZoJxnmmOgb27fXFiFVOeRxm1WSQgxYyP/ci7hBFgUlEC8z1oJ7rVH2g0U8OO6xnjPG0dA/v+rvXSY89rk8FfPnklcVMVAAA=
+
+ H4sIAAAAAAAAAAMAAAAAAAAAAAA=
+
+
+ H4sIAAAAAAAAAM1YTW/bMAy9B8h/CFBfbUiyJEsFcti6HTagW1H0slMgifLiIbEN292Wfz+6dbu2qdsms43l4OiD0qMeSVHSyVmxLU2T2WyTNbuFz5tqN5+dnBf54tzsFowuKDkV+lSIxcWHqwUjVM1nZVX83kWbwpnNanVx+fXzx7OrYK1T61KpLZaMhWDNU+WwnKS67eOpMIxSafiq8nVxXTm/csU2gLzYmu+ZC+DmDyrzK4Dr7WZ1vS3AbwKo16by8Leam7JeF83yf1CijwplEoi5QkwqAb888WmwtuAItnANXDpurLSjUjGtEn1UpJpo5RniS+AGtdAgUQujVbAmkholiCMO0j4tXIaa+MZ0cAjyw7vm1cWPDdu3XCuJSJWlSDFY3pKeCvQ8HaMvJgS1UsKLlMajWn5aJeaz91luqszXEapT+qrB4vKZtj7OODopM7HFuI0dMeinlqVYpUTHpNdCgzA1BfRY++WRkTE27FgbwSD2nlYJpMJXdZGbTYjTRN0s0f0kkSsqH3UMRkXZZEWOAdON6dq75uVwU/XGoSJGJToO1o4lHutxu4UoapAowzgh2imv7cgROakS89kBbKLotsifmOUfx49liyM3h7Fh57MOKrw7nYTt4SRszyZhezQJH55MlocI95my9YIbdaLOB24qPXZ7Xvjx1C6Lbsm7W1QEvnZVVjZF9aD42DXeOqg3WVgOzFLJqZeMxDrmoIVPLGAi90QNnSPGQdvj8V74LlaecrYn8LqV32bezq5DngqODblRwPZdFlNBVjc+d/5Whc4fyyr7aRoPvvQ5YO9ug1J7rnvI4D5WAazU4Bjm3ljGbe61eB9RQNsvMdbEzHoBcmB+x4Yda7mDZNNplXg1OFf4uxlbFlne1AftyC+N7b2HJ4kQmLAY4ymlHAQBb2gaa0MdpXpgTxsJDe9Xn768u/wWxsRpptM4VNSpkEOCWRDrYeoFI8CkpgSWB8gOnGuGeb+ZAvueUUmRFKZ4yHCzDTnuwaFhRoTeEkokSCYIWx4gO9arwJEOOTbswGE3zKvXFNgPLnbPvX281Dmf/QF5TJjvcxUAAA==
\ No newline at end of file
diff --git a/Svc/BufferManager/Events.xml b/Svc/BufferManager/Events.xml
index 450cb2934c..56e0f6eab4 100644
--- a/Svc/BufferManager/Events.xml
+++ b/Svc/BufferManager/Events.xml
@@ -12,51 +12,29 @@
- The Buffer Manager received a request to deallocate a buffer when the allocation queue was empty
+ The Buffer Manager has cleared its error state
- The Buffer Manager received an allocation request that, if granted, would cause the allocation queue to overflow
+ The Buffer Manager received an allocation request that, if granted, would cause the storage buffer to overflow
- The Buffer Manager received a deallocation request whose ID did not match the ID at the end of the allocation queue
-
-
- The expected ID value
-
-
- The ID value seen
-
-
+ The Buffer Manager received an allocation request that, if granted, would result in too many buffers
-
-
- The Buffer Manager received an allocation request that, if granted, would exceed the store size
-
-
diff --git a/Svc/BufferManager/Telemetry.xml b/Svc/BufferManager/Telemetry.xml
index d64cdb713b..5563453cec 100644
--- a/Svc/BufferManager/Telemetry.xml
+++ b/Svc/BufferManager/Telemetry.xml
@@ -12,19 +12,19 @@
The number of buffers currently allocatedThe total size of all allocated buffers
diff --git a/Svc/BufferManager/docs/BufferManager.md b/Svc/BufferManager/docs/BufferManager.md
index f23846b97c..c615761c94 100644
--- a/Svc/BufferManager/docs/BufferManager.md
+++ b/Svc/BufferManager/docs/BufferManager.md
@@ -13,9 +13,6 @@
|Event Name|ID|Description|Arg Name|Arg Type|Arg Size|Description
|---|---|---|---|---|---|---|
-|BufferManager_AllocationQueueEmpty|0 (0x0)|The Buffer Manager received a request to deallocate a buffer when the allocation queue was empty| | | | |
-|BufferManager_AllocationQueueFull|1 (0x1)|The Buffer Manager received an allocation request that, if granted, would cause the allocation queue to overflow| | | | |
-|BufferManager_IDMismatch|2 (0x2)|The Buffer Manager received a deallocation request whose ID did not match the ID at the end of the allocation queue| | | | |
-| | | |expected|U32||The expected ID value|
-| | | |saw|U32||The ID value seen|
-|BufferManager_StoreSizeExceeded|3 (0x3)|The Buffer Manager received an allocation request that, if granted, would exceed the store size| | | | |
+|ClearedErrorState|0 (0x0)|The Buffer Manager has cleared its error state| | | | |
+|StoreSizeExceeded|1 (0x1)|The Buffer Manager received an allocation request that, if granted, would cause the storage buffer to overflow| | | | |
+|TooManyBuffers|2 (0x2)|The Buffer Manager received an allocation request that, if granted, would result in too many buffers| | | | |
diff --git a/Svc/BufferManager/docs/img/BufferManagerBDD.jpg b/Svc/BufferManager/docs/img/BufferManagerBDD.jpg
index a187bd42b3..e3f5b120b7 100644
Binary files a/Svc/BufferManager/docs/img/BufferManagerBDD.jpg and b/Svc/BufferManager/docs/img/BufferManagerBDD.jpg differ
diff --git a/Svc/BufferManager/docs/sdd.md b/Svc/BufferManager/docs/sdd.md
index 43311029a3..63ab23a460 100644
--- a/Svc/BufferManager/docs/sdd.md
+++ b/Svc/BufferManager/docs/sdd.md
@@ -12,8 +12,8 @@ from a fixed-size store.
Requirement | Description | Rationale | Verification Method
---- | ---- | ---- | ----
-BM-001 | `BufferManager` shall maintain a fixed-size store and shall provide a callee port on which another component may request and receive variable-size buffers allocated from the store. | This requirement provides variable-sized buffers that may be passed between components by reference. Such buffers are useful for transferring large data items of varying length, such as file packets and images. For such data items, a fixed-size buffer such as `Fw::ComBuffer` is not practical. | Test
-BM-002 | `BufferManager` shall provide an input port on which a component that has been given a buffer may return the buffer for deallocation. | Deallocation prevents the fixed-size store from becoming exhausted. Note that the component returning the buffer is generally the receiver, while the component requesting the buffer is generally the sender. See the [sequence diagram](#SequenceDiagram) below. | Test
+ISF-BM-001 | `BufferManager` shall maintain a fixed-size store and shall provide a callee port on which another component may request and receive variable-size buffers allocated from the store. | This requirement provides variable-sized buffers that may be passed between components by reference. Such buffers are useful for transferring large data items of varying length, such as file packets and images. For such data items, a fixed-size buffer such as `Fw::ComBuffer` is not practical. | Test
+ISF-BM-002 | `BufferManager` shall provide an input port on which a component that has been given a buffer may return the buffer for deallocation. | Deallocation prevents the fixed-size store from becoming exhausted. Note that the component returning the buffer is generally the receiver, while the component requesting the buffer is generally the sender. See the [sequence diagram](#SequenceDiagram) below. | Test
## 3 Design
diff --git a/Svc/BufferManager/test/ut/GTestBase.cpp b/Svc/BufferManager/test/ut/GTestBase.cpp
index 928d5695e2..01250f205d 100644
--- a/Svc/BufferManager/test/ut/GTestBase.cpp
+++ b/Svc/BufferManager/test/ut/GTestBase.cpp
@@ -94,27 +94,27 @@ namespace Svc {
assertTlm_BufferManager_NumAllocatedBuffers(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_BufferManager_NumAllocatedBuffers->size())
+ ASSERT_LT(__index, this->tlmHistory_BufferManager_NumAllocatedBuffers->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel BufferManager_NumAllocatedBuffers\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_BufferManager_NumAllocatedBuffers->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_BufferManager_NumAllocatedBuffers& e =
- this->tlmHistory_BufferManager_NumAllocatedBuffers->at(index);
+ this->tlmHistory_BufferManager_NumAllocatedBuffers->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel BufferManager_NumAllocatedBuffers\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
@@ -144,27 +144,27 @@ namespace Svc {
assertTlm_BufferManager_AllocatedSize(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
- const U32 index,
+ const U32 __index,
const U32& val
)
const
{
- ASSERT_LT(index, this->tlmHistory_BufferManager_AllocatedSize->size())
+ ASSERT_LT(__index, this->tlmHistory_BufferManager_AllocatedSize->size())
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Index into history of telemetry channel BufferManager_AllocatedSize\n"
<< " Expected: Less than size of history ("
<< this->tlmHistory_BufferManager_AllocatedSize->size() << ")\n"
- << " Actual: " << index << "\n";
+ << " Actual: " << __index << "\n";
const TlmEntry_BufferManager_AllocatedSize& e =
- this->tlmHistory_BufferManager_AllocatedSize->at(index);
+ this->tlmHistory_BufferManager_AllocatedSize->at(__index);
ASSERT_EQ(val, e.arg)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
<< " Value: Value at index "
- << index
+ << __index
<< " on telmetry channel BufferManager_AllocatedSize\n"
<< " Expected: " << val << "\n"
<< " Actual: " << e.arg << "\n";
@@ -191,122 +191,63 @@ namespace Svc {
}
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueEmpty
+ // Event: ClearedErrorState
// ----------------------------------------------------------------------
void BufferManagerGTestBase ::
- assertEvents_BufferManager_AllocationQueueEmpty_size(
+ assertEvents_ClearedErrorState_size(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
const U32 size
) const
{
- ASSERT_EQ(size, this->eventsSize_BufferManager_AllocationQueueEmpty)
+ ASSERT_EQ(size, this->eventsSize_ClearedErrorState)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
- << " Value: Size of history for event BufferManager_AllocationQueueEmpty\n"
+ << " Value: Size of history for event ClearedErrorState\n"
<< " Expected: " << size << "\n"
- << " Actual: " << this->eventsSize_BufferManager_AllocationQueueEmpty << "\n";
+ << " Actual: " << this->eventsSize_ClearedErrorState << "\n";
}
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueFull
+ // Event: StoreSizeExceeded
// ----------------------------------------------------------------------
void BufferManagerGTestBase ::
- assertEvents_BufferManager_AllocationQueueFull_size(
+ assertEvents_StoreSizeExceeded_size(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
const U32 size
) const
{
- ASSERT_EQ(size, this->eventsSize_BufferManager_AllocationQueueFull)
+ ASSERT_EQ(size, this->eventsSize_StoreSizeExceeded)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
- << " Value: Size of history for event BufferManager_AllocationQueueFull\n"
+ << " Value: Size of history for event StoreSizeExceeded\n"
<< " Expected: " << size << "\n"
- << " Actual: " << this->eventsSize_BufferManager_AllocationQueueFull << "\n";
+ << " Actual: " << this->eventsSize_StoreSizeExceeded << "\n";
}
// ----------------------------------------------------------------------
- // Event: BufferManager_IDMismatch
+ // Event: TooManyBuffers
// ----------------------------------------------------------------------
void BufferManagerGTestBase ::
- assertEvents_BufferManager_IDMismatch_size(
+ assertEvents_TooManyBuffers_size(
const char *const __callSiteFileName,
const U32 __callSiteLineNumber,
const U32 size
) const
{
- ASSERT_EQ(size, this->eventHistory_BufferManager_IDMismatch->size())
+ ASSERT_EQ(size, this->eventsSize_TooManyBuffers)
<< "\n"
<< " File: " << __callSiteFileName << "\n"
<< " Line: " << __callSiteLineNumber << "\n"
- << " Value: Size of history for event BufferManager_IDMismatch\n"
+ << " Value: Size of history for event TooManyBuffers\n"
<< " Expected: " << size << "\n"
- << " Actual: " << this->eventHistory_BufferManager_IDMismatch->size() << "\n";
- }
-
- void BufferManagerGTestBase ::
- assertEvents_BufferManager_IDMismatch(
- const char *const __callSiteFileName,
- const U32 __callSiteLineNumber,
- const U32 index,
- const U32 expected,
- const U32 saw
- ) const
- {
- ASSERT_GT(this->eventHistory_BufferManager_IDMismatch->size(), index)
- << "\n"
- << " File: " << __callSiteFileName << "\n"
- << " Line: " << __callSiteLineNumber << "\n"
- << " Value: Index into history of event BufferManager_IDMismatch\n"
- << " Expected: Less than size of history ("
- << this->eventHistory_BufferManager_IDMismatch->size() << ")\n"
- << " Actual: " << index << "\n";
- const EventEntry_BufferManager_IDMismatch& e =
- this->eventHistory_BufferManager_IDMismatch->at(index);
- ASSERT_EQ(expected, e.expected)
- << "\n"
- << " File: " << __callSiteFileName << "\n"
- << " Line: " << __callSiteLineNumber << "\n"
- << " Value: Value of argument expected at index "
- << index
- << " in history of event BufferManager_IDMismatch\n"
- << " Expected: " << expected << "\n"
- << " Actual: " << e.expected << "\n";
- ASSERT_EQ(saw, e.saw)
- << "\n"
- << " File: " << __callSiteFileName << "\n"
- << " Line: " << __callSiteLineNumber << "\n"
- << " Value: Value of argument saw at index "
- << index
- << " in history of event BufferManager_IDMismatch\n"
- << " Expected: " << saw << "\n"
- << " Actual: " << e.saw << "\n";
- }
-
- // ----------------------------------------------------------------------
- // Event: BufferManager_StoreSizeExceeded
- // ----------------------------------------------------------------------
-
- void BufferManagerGTestBase ::
- assertEvents_BufferManager_StoreSizeExceeded_size(
- const char *const __callSiteFileName,
- const U32 __callSiteLineNumber,
- const U32 size
- ) const
- {
- ASSERT_EQ(size, this->eventsSize_BufferManager_StoreSizeExceeded)
- << "\n"
- << " File: " << __callSiteFileName << "\n"
- << " Line: " << __callSiteLineNumber << "\n"
- << " Value: Size of history for event BufferManager_StoreSizeExceeded\n"
- << " Expected: " << size << "\n"
- << " Actual: " << this->eventsSize_BufferManager_StoreSizeExceeded << "\n";
+ << " Actual: " << this->eventsSize_TooManyBuffers << "\n";
}
} // end namespace Svc
diff --git a/Svc/BufferManager/test/ut/GTestBase.hpp b/Svc/BufferManager/test/ut/GTestBase.hpp
index f77b7d050b..2f027f9eab 100644
--- a/Svc/BufferManager/test/ut/GTestBase.hpp
+++ b/Svc/BufferManager/test/ut/GTestBase.hpp
@@ -49,20 +49,14 @@
#define ASSERT_EVENTS_SIZE(size) \
this->assertEvents_size(__FILE__, __LINE__, size)
-#define ASSERT_EVENTS_BufferManager_AllocationQueueEmpty_SIZE(size) \
- this->assertEvents_BufferManager_AllocationQueueEmpty_size(__FILE__, __LINE__, size)
+#define ASSERT_EVENTS_ClearedErrorState_SIZE(size) \
+ this->assertEvents_ClearedErrorState_size(__FILE__, __LINE__, size)
-#define ASSERT_EVENTS_BufferManager_AllocationQueueFull_SIZE(size) \
- this->assertEvents_BufferManager_AllocationQueueFull_size(__FILE__, __LINE__, size)
+#define ASSERT_EVENTS_StoreSizeExceeded_SIZE(size) \
+ this->assertEvents_StoreSizeExceeded_size(__FILE__, __LINE__, size)
-#define ASSERT_EVENTS_BufferManager_IDMismatch_SIZE(size) \
- this->assertEvents_BufferManager_IDMismatch_size(__FILE__, __LINE__, size)
-
-#define ASSERT_EVENTS_BufferManager_IDMismatch(index, _expected, _saw) \
- this->assertEvents_BufferManager_IDMismatch(__FILE__, __LINE__, index, _expected, _saw)
-
-#define ASSERT_EVENTS_BufferManager_StoreSizeExceeded_SIZE(size) \
- this->assertEvents_BufferManager_StoreSizeExceeded_size(__FILE__, __LINE__, size)
+#define ASSERT_EVENTS_TooManyBuffers_SIZE(size) \
+ this->assertEvents_TooManyBuffers_size(__FILE__, __LINE__, size)
namespace Svc {
@@ -125,7 +119,7 @@ namespace Svc {
void assertTlm_BufferManager_NumAllocatedBuffers(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32& val /*!< The channel value*/
) const;
@@ -146,7 +140,7 @@ namespace Svc {
void assertTlm_BufferManager_AllocatedSize(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
+ const U32 __index, /*!< The index*/
const U32& val /*!< The channel value*/
) const;
@@ -165,10 +159,10 @@ namespace Svc {
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueEmpty
+ // Event: ClearedErrorState
// ----------------------------------------------------------------------
- void assertEvents_BufferManager_AllocationQueueEmpty_size(
+ void assertEvents_ClearedErrorState_size(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
const U32 size /*!< The asserted size*/
@@ -177,10 +171,10 @@ namespace Svc {
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueFull
+ // Event: StoreSizeExceeded
// ----------------------------------------------------------------------
- void assertEvents_BufferManager_AllocationQueueFull_size(
+ void assertEvents_StoreSizeExceeded_size(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
const U32 size /*!< The asserted size*/
@@ -189,30 +183,10 @@ namespace Svc {
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_IDMismatch
+ // Event: TooManyBuffers
// ----------------------------------------------------------------------
- void assertEvents_BufferManager_IDMismatch_size(
- const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
- const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 size /*!< The asserted size*/
- ) const;
-
- void assertEvents_BufferManager_IDMismatch(
- const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
- const U32 __callSiteLineNumber, /*!< The line number of the call site*/
- const U32 index, /*!< The index*/
- const U32 expected, /*!< The expected ID value*/
- const U32 saw /*!< The ID value seen*/
- ) const;
-
- protected:
-
- // ----------------------------------------------------------------------
- // Event: BufferManager_StoreSizeExceeded
- // ----------------------------------------------------------------------
-
- void assertEvents_BufferManager_StoreSizeExceeded_size(
+ void assertEvents_TooManyBuffers_size(
const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
const U32 __callSiteLineNumber, /*!< The line number of the call site*/
const U32 size /*!< The asserted size*/
diff --git a/Svc/BufferManager/test/ut/Main.cpp b/Svc/BufferManager/test/ut/Main.cpp
index 7f7380f8f8..48d4ba93b0 100644
--- a/Svc/BufferManager/test/ut/Main.cpp
+++ b/Svc/BufferManager/test/ut/Main.cpp
@@ -4,29 +4,9 @@
#include "Tester.hpp"
-TEST(Test, allocateAndFreeOne) {
+TEST(Test, ThreeBufferProblem) {
Svc::Tester tester;
- tester.allocateAndFreeOne();
-}
-
-TEST(Test, allocationQueueEmpty) {
- Svc::Tester tester;
- tester.allocationQueueEmpty();
-}
-
-TEST(Test, allocationQueueFull) {
- Svc::Tester tester;
- tester.allocationQueueFull();
-}
-
-TEST(Test, idMismatch) {
- Svc::Tester tester;
- tester.idMismatch();
-}
-
-TEST(Test, storeSizeExceeded) {
- Svc::Tester tester;
- tester.storeSizeExceeded();
+ tester.three_buffer_problem();
}
int main(int argc, char **argv) {
diff --git a/Svc/BufferManager/test/ut/Tester.cpp b/Svc/BufferManager/test/ut/Tester.cpp
index 83a87b91d6..eddfee5acc 100644
--- a/Svc/BufferManager/test/ut/Tester.cpp
+++ b/Svc/BufferManager/test/ut/Tester.cpp
@@ -1,6 +1,6 @@
// ======================================================================
-// \title BufferManager/test/ut/Tester.hpp
-// \author bocchino
+// \title BufferManager.hpp
+// \author mstarch
// \brief cpp file for BufferManager test harness implementation class
//
// \copyright
@@ -17,27 +17,29 @@
// countries or providing access to foreign persons.
// ======================================================================
-
-#include
-#include
-
#include "Tester.hpp"
-#include "Fw/Cmd/CmdPacket.hpp"
-#define MAX_HISTORY_SIZE 10
-#define STORE_SIZE 1024
-#define ALLOCATION_QUEUE_SIZE 10
#define INSTANCE 0
+#define MAX_HISTORY_SIZE 10
namespace Svc {
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
Tester ::
Tester(void) :
+#if FW_OBJECT_NAMES == 1
BufferManagerGTestBase("Tester", MAX_HISTORY_SIZE),
- bufferManager("BufferManager", STORE_SIZE, ALLOCATION_QUEUE_SIZE)
+ component("BufferManager", 12, 3)
+#else
+ BufferManagerGTestBase(MAX_HISTORY_SIZE),
+ component()
+#endif
{
- this->connectPorts();
this->initComponents();
+ this->connectPorts();
}
Tester ::
@@ -46,6 +48,28 @@ namespace Svc {
}
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ three_buffer_problem(void)
+ {
+ //Alocate 2 buffers
+ Fw::Buffer buffer1 = this->invoke_to_bufferGetCallee(0, 4);
+ Fw::Buffer buffer2 = this->invoke_to_bufferGetCallee(0, 4);
+ //Fill the 2nd buffer
+ *((U32*)buffer2.getdata()) = 0xDEADBEEF;
+ //Return the 1st buffer
+ this->invoke_to_bufferSendIn(0, buffer1);
+ //Allocate and fill 3rd buffer
+ Fw::Buffer buffer3 = this->invoke_to_bufferGetCallee(0, 4);
+ *((U32*)buffer3.getdata()) = 0x0;
+ //Check that no warnings have happened
+ //Check that buffer 2's data is intact. It Fails here.
+ ASSERT_EQ(0xDEADBEEF,*((U32*)buffer2.getdata()));
+ }
+
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
@@ -54,34 +78,40 @@ namespace Svc {
connectPorts(void)
{
- // timeCaller
- this->bufferManager.set_timeCaller_OutputPort(
- 0,
- this->get_from_timeCaller(0)
- );
-
// bufferSendIn
this->connect_to_bufferSendIn(
0,
- this->bufferManager.get_bufferSendIn_InputPort(0)
- );
-
- // tlmOut
- this->bufferManager.set_tlmOut_OutputPort(
- 0,
- this->get_from_tlmOut(0)
- );
-
- // eventOut
- this->bufferManager.set_eventOut_OutputPort(
- 0,
- this->get_from_eventOut(0)
+ this->component.get_bufferSendIn_InputPort(0)
);
// bufferGetCallee
this->connect_to_bufferGetCallee(
0,
- this->bufferManager.get_bufferGetCallee_InputPort(0)
+ this->component.get_bufferGetCallee_InputPort(0)
+ );
+
+ // timeCaller
+ this->component.set_timeCaller_OutputPort(
+ 0,
+ this->get_from_timeCaller(0)
+ );
+
+ // eventOut
+ this->component.set_eventOut_OutputPort(
+ 0,
+ this->get_from_eventOut(0)
+ );
+
+ // textEventOut
+ this->component.set_textEventOut_OutputPort(
+ 0,
+ this->get_from_textEventOut(0)
+ );
+
+ // tlmOut
+ this->component.set_tlmOut_OutputPort(
+ 0,
+ this->get_from_tlmOut(0)
);
}
@@ -90,131 +120,9 @@ namespace Svc {
initComponents(void)
{
this->init();
- this->bufferManager.init(INSTANCE);
- }
-
- // ----------------------------------------------------------------------
- // Tests
- // ----------------------------------------------------------------------
-
- void Tester ::
- allocateAndFreeOne(void)
- {
-
- Fw::Buffer b = this->invoke_to_bufferGetCallee(0, 10);
-
- ASSERT_EVENTS_SIZE(0);
-
- ASSERT_TLM_SIZE(2);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers_SIZE(1);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers(0, 1);
- ASSERT_TLM_BufferManager_AllocatedSize_SIZE(1);
- ASSERT_TLM_BufferManager_AllocatedSize(0, 10);
-
- ASSERT_EQ(
- static_cast(this->bufferManager.getInstance()),
- b.getmanagerID()
+ this->component.init(
+ INSTANCE
);
- ASSERT_EQ(
- static_cast(0),
- b.getbufferID()
- );
- // Make sure the allocated memory is good for writing
- U8 *const data = reinterpret_cast(b.getdata());
- bzero(data, 10);
- ASSERT_EQ(
- static_cast(10),
- b.getsize()
- );
-
- this->clearTlm();
- this->invoke_to_bufferSendIn(0, b);
-
- ASSERT_EVENTS_SIZE(0);
-
- ASSERT_TLM_SIZE(2);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers_SIZE(1);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers(0, 0);
- ASSERT_TLM_BufferManager_AllocatedSize_SIZE(1);
- ASSERT_TLM_BufferManager_AllocatedSize(0, 0);
-
}
- void Tester ::
- allocationQueueEmpty(void)
- {
-
- Fw::Buffer b;
- b.setmanagerID(this->getInstance());
- this->invoke_to_bufferSendIn(0, b);
-
- ASSERT_EVENTS_SIZE(1);
- ASSERT_EVENTS_BufferManager_AllocationQueueEmpty_SIZE(1);
-
- ASSERT_TLM_SIZE(0);
-
- }
-
- void Tester ::
- allocationQueueFull(void)
- {
-
- for (U32 i = 0; i < ALLOCATION_QUEUE_SIZE; ++i) {
- (void) this->invoke_to_bufferGetCallee(0, 10);
- ASSERT_EVENTS_SIZE(0);
- ASSERT_TLM_SIZE(2 * (i+1));
- ASSERT_TLM_BufferManager_NumAllocatedBuffers_SIZE(i+1);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers(i, i+1);
- ASSERT_TLM_BufferManager_AllocatedSize_SIZE(i+1);
- ASSERT_TLM_BufferManager_AllocatedSize(i, 10 * (i+1));
- }
-
- Fw::Buffer b = this->invoke_to_bufferGetCallee(0, 10);
- // Assert that buffer is invalid
- ASSERT_EQ(static_cast(0), b.getdata());
- ASSERT_EVENTS_SIZE(1);
- ASSERT_EVENTS_BufferManager_AllocationQueueFull_SIZE(1);
- ASSERT_TLM_SIZE(2 * ALLOCATION_QUEUE_SIZE);
-
- }
-
- void Tester ::
- idMismatch(void)
- {
-
- Fw::Buffer b = this->invoke_to_bufferGetCallee(0, 10);
-
- ASSERT_EVENTS_SIZE(0);
-
- ASSERT_TLM_SIZE(2);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers_SIZE(1);
- ASSERT_TLM_BufferManager_NumAllocatedBuffers(0, 1);
- ASSERT_TLM_BufferManager_AllocatedSize_SIZE(1);
- ASSERT_TLM_BufferManager_AllocatedSize(0, 10);
-
- b.setbufferID(b.getbufferID() + 1);
-
- this->clearTlm();
- this->invoke_to_bufferSendIn(0, b);
-
- ASSERT_EVENTS_SIZE(1);
- ASSERT_EVENTS_BufferManager_IDMismatch_SIZE(1);
-
- ASSERT_TLM_SIZE(0);
-
- }
-
- void Tester ::
- storeSizeExceeded(void)
- {
-
- Fw::Buffer b = this->invoke_to_bufferGetCallee(0, STORE_SIZE + 1);
- // Assert that buffer is invalid
- ASSERT_EQ(static_cast(0), b.getdata());
- ASSERT_EVENTS_SIZE(1);
- ASSERT_EVENTS_BufferManager_StoreSizeExceeded_SIZE(1);
- ASSERT_TLM_SIZE(0);
-
- }
-
-};
+} // end namespace Svc
diff --git a/Svc/BufferManager/test/ut/Tester.hpp b/Svc/BufferManager/test/ut/Tester.hpp
index 3f00053ceb..8f28cfa045 100644
--- a/Svc/BufferManager/test/ut/Tester.hpp
+++ b/Svc/BufferManager/test/ut/Tester.hpp
@@ -1,6 +1,6 @@
// ======================================================================
// \title BufferManager/test/ut/Tester.hpp
-// \author bocchino
+// \author mstarch
// \brief hpp file for BufferManager test harness implementation class
//
// \copyright
@@ -29,10 +29,18 @@ namespace Svc {
public BufferManagerGTestBase
{
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
public:
+ //! Construct object Tester
+ //!
Tester(void);
+ //! Destroy object Tester
+ //!
~Tester(void);
public:
@@ -41,41 +49,33 @@ namespace Svc {
// Tests
// ----------------------------------------------------------------------
- // Allocate and free one buffer
- void allocateAndFreeOne(void);
-
- // Error: Free request with empty allocation queue
- void allocationQueueEmpty(void);
-
- // Error: Allocation request with full allocation queue
- void allocationQueueFull(void);
-
- // Error: Mismatched buffer ID
- void idMismatch(void);
-
- // Error: Store size exceeded
- void storeSizeExceeded(void);
-
+ void three_buffer_problem(void);
private:
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
+ //! Connect ports
+ //!
void connectPorts(void);
+ //! Initialize components
+ //!
void initComponents(void);
private:
// ----------------------------------------------------------------------
- // The component under test
+ // Variables
// ----------------------------------------------------------------------
- BufferManager bufferManager;
+ //! The component under test
+ //!
+ BufferManager component;
};
-};
+} // end namespace Svc
#endif
diff --git a/Svc/BufferManager/test/ut/TesterBase.cpp b/Svc/BufferManager/test/ut/TesterBase.cpp
index d8d821a20f..47c9c63b38 100644
--- a/Svc/BufferManager/test/ut/TesterBase.cpp
+++ b/Svc/BufferManager/test/ut/TesterBase.cpp
@@ -51,8 +51,6 @@ namespace Svc {
#if FW_ENABLE_TEXT_LOGGING
this->textLogHistory = new History(maxHistorySize);
#endif
- this->eventHistory_BufferManager_IDMismatch =
- new History(maxHistorySize);
// Clear history
this->clearHistory();
}
@@ -67,7 +65,6 @@ namespace Svc {
#if FW_ENABLE_TEXT_LOGGING
delete this->textLogHistory;
#endif
- delete this->eventHistory_BufferManager_IDMismatch;
}
void BufferManagerTesterBase ::
@@ -109,35 +106,6 @@ namespace Svc {
}
- // Attach input port tlmOut
-
- for (
- NATIVE_INT_TYPE _port = 0;
- _port < this->getNum_from_tlmOut();
- ++_port
- ) {
-
- this->m_from_tlmOut[_port].init();
- this->m_from_tlmOut[_port].addCallComp(
- this,
- from_tlmOut_static
- );
- this->m_from_tlmOut[_port].setPortNum(_port);
-
-#if FW_OBJECT_NAMES == 1
- char _portName[80];
- (void) snprintf(
- _portName,
- sizeof(_portName),
- "%s_from_tlmOut[%d]",
- this->m_objName,
- _port
- );
- this->m_from_tlmOut[_port].setObjName(_portName);
-#endif
-
- }
-
// Attach input port eventOut
for (
@@ -167,56 +135,62 @@ namespace Svc {
}
- // Attach input port LogText
+ // Attach input port textEventOut
#if FW_ENABLE_TEXT_LOGGING == 1
for (
NATIVE_INT_TYPE _port = 0;
- _port < this->getNum_from_LogText();
+ _port < this->getNum_from_textEventOut();
++_port
) {
- this->m_from_LogText[_port].init();
- this->m_from_LogText[_port].addCallComp(
+ this->m_from_textEventOut[_port].init();
+ this->m_from_textEventOut[_port].addCallComp(
this,
- from_LogText_static
+ from_textEventOut_static
);
- this->m_from_LogText[_port].setPortNum(_port);
+ this->m_from_textEventOut[_port].setPortNum(_port);
#if FW_OBJECT_NAMES == 1
char _portName[80];
(void) snprintf(
_portName,
sizeof(_portName),
- "%s_from_LogText[%d]",
+ "%s_from_textEventOut[%d]",
this->m_objName,
_port
);
- this->m_from_LogText[_port].setObjName(_portName);
+ this->m_from_textEventOut[_port].setObjName(_portName);
#endif
}
#endif
- // Initialize output port bufferGetCallee
+ // Attach input port tlmOut
for (
NATIVE_INT_TYPE _port = 0;
- _port < this->getNum_to_bufferGetCallee();
+ _port < this->getNum_from_tlmOut();
++_port
) {
- this->m_to_bufferGetCallee[_port].init();
+
+ this->m_from_tlmOut[_port].init();
+ this->m_from_tlmOut[_port].addCallComp(
+ this,
+ from_tlmOut_static
+ );
+ this->m_from_tlmOut[_port].setPortNum(_port);
#if FW_OBJECT_NAMES == 1
char _portName[80];
- snprintf(
+ (void) snprintf(
_portName,
sizeof(_portName),
- "%s_to_bufferGetCallee[%d]",
+ "%s_from_tlmOut[%d]",
this->m_objName,
_port
);
- this->m_to_bufferGetCallee[_port].setObjName(_portName);
+ this->m_from_tlmOut[_port].setObjName(_portName);
#endif
}
@@ -244,36 +218,41 @@ namespace Svc {
}
+ // Initialize output port bufferGetCallee
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_to_bufferGetCallee();
+ ++_port
+ ) {
+ this->m_to_bufferGetCallee[_port].init();
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_to_bufferGetCallee[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_to_bufferGetCallee[_port].setObjName(_portName);
+#endif
+
+ }
+
}
// ----------------------------------------------------------------------
// Getters for port counts
// ----------------------------------------------------------------------
- NATIVE_INT_TYPE BufferManagerTesterBase ::
- getNum_to_bufferGetCallee(void) const
- {
- return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_bufferGetCallee);
- }
-
- NATIVE_INT_TYPE BufferManagerTesterBase ::
- getNum_to_bufferSendIn(void) const
- {
- return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_bufferSendIn);
- }
-
NATIVE_INT_TYPE BufferManagerTesterBase ::
getNum_from_timeCaller(void) const
{
return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_timeCaller);
}
- NATIVE_INT_TYPE BufferManagerTesterBase ::
- getNum_from_tlmOut(void) const
- {
- return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_tlmOut);
- }
-
NATIVE_INT_TYPE BufferManagerTesterBase ::
getNum_from_eventOut(void) const
{
@@ -282,26 +261,34 @@ namespace Svc {
#if FW_ENABLE_TEXT_LOGGING == 1
NATIVE_INT_TYPE BufferManagerTesterBase ::
- getNum_from_LogText(void) const
+ getNum_from_textEventOut(void) const
{
- return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_LogText);
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_textEventOut);
}
#endif
+ NATIVE_INT_TYPE BufferManagerTesterBase ::
+ getNum_to_bufferSendIn(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_bufferSendIn);
+ }
+
+ NATIVE_INT_TYPE BufferManagerTesterBase ::
+ getNum_to_bufferGetCallee(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_bufferGetCallee);
+ }
+
+ NATIVE_INT_TYPE BufferManagerTesterBase ::
+ getNum_from_tlmOut(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_tlmOut);
+ }
+
// ----------------------------------------------------------------------
// Connectors for to ports
// ----------------------------------------------------------------------
- void BufferManagerTesterBase ::
- connect_to_bufferGetCallee(
- const NATIVE_INT_TYPE portNum,
- Fw::InputBufferGetPort *const bufferGetCallee
- )
- {
- FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
- this->m_to_bufferGetCallee[portNum].addCallPort(bufferGetCallee);
- }
-
void BufferManagerTesterBase ::
connect_to_bufferSendIn(
const NATIVE_INT_TYPE portNum,
@@ -312,24 +299,21 @@ namespace Svc {
this->m_to_bufferSendIn[portNum].addCallPort(bufferSendIn);
}
+ void BufferManagerTesterBase ::
+ connect_to_bufferGetCallee(
+ const NATIVE_INT_TYPE portNum,
+ Fw::InputBufferGetPort *const bufferGetCallee
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
+ this->m_to_bufferGetCallee[portNum].addCallPort(bufferGetCallee);
+ }
+
// ----------------------------------------------------------------------
// Invocation functions for to ports
// ----------------------------------------------------------------------
- Fw::Buffer BufferManagerTesterBase ::
- invoke_to_bufferGetCallee(
- const NATIVE_INT_TYPE portNum,
- U32 size
- )
- {
- FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
- FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
- return this->m_to_bufferGetCallee[portNum].invoke(
- size
- );
- }
-
void BufferManagerTesterBase ::
invoke_to_bufferSendIn(
const NATIVE_INT_TYPE portNum,
@@ -343,17 +327,23 @@ namespace Svc {
);
}
+ Fw::Buffer BufferManagerTesterBase ::
+ invoke_to_bufferGetCallee(
+ const NATIVE_INT_TYPE portNum,
+ U32 size
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
+ FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(),static_cast(portNum));
+ return this->m_to_bufferGetCallee[portNum].invoke(
+ size
+ );
+ }
+
// ----------------------------------------------------------------------
// Connection status for to ports
// ----------------------------------------------------------------------
- bool BufferManagerTesterBase ::
- isConnected_to_bufferGetCallee(const NATIVE_INT_TYPE portNum)
- {
- FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(), static_cast(portNum));
- return this->m_to_bufferGetCallee[portNum].isConnected();
- }
-
bool BufferManagerTesterBase ::
isConnected_to_bufferSendIn(const NATIVE_INT_TYPE portNum)
{
@@ -361,6 +351,13 @@ namespace Svc {
return this->m_to_bufferSendIn[portNum].isConnected();
}
+ bool BufferManagerTesterBase ::
+ isConnected_to_bufferGetCallee(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_bufferGetCallee(), static_cast(portNum));
+ return this->m_to_bufferGetCallee[portNum].isConnected();
+ }
+
// ----------------------------------------------------------------------
// Getters for from ports
// ----------------------------------------------------------------------
@@ -372,13 +369,6 @@ namespace Svc {
return &this->m_from_timeCaller[portNum];
}
- Fw::InputTlmPort *BufferManagerTesterBase ::
- get_from_tlmOut(const NATIVE_INT_TYPE portNum)
- {
- FW_ASSERT(portNum < this->getNum_from_tlmOut(),static_cast(portNum));
- return &this->m_from_tlmOut[portNum];
- }
-
Fw::InputLogPort *BufferManagerTesterBase ::
get_from_eventOut(const NATIVE_INT_TYPE portNum)
{
@@ -388,13 +378,20 @@ namespace Svc {
#if FW_ENABLE_TEXT_LOGGING == 1
Fw::InputLogTextPort *BufferManagerTesterBase ::
- get_from_LogText(const NATIVE_INT_TYPE portNum)
+ get_from_textEventOut(const NATIVE_INT_TYPE portNum)
{
- FW_ASSERT(portNum < this->getNum_from_LogText(),static_cast(portNum));
- return &this->m_from_LogText[portNum];
+ FW_ASSERT(portNum < this->getNum_from_textEventOut(),static_cast(portNum));
+ return &this->m_from_textEventOut[portNum];
}
#endif
+ Fw::InputTlmPort *BufferManagerTesterBase ::
+ get_from_tlmOut(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_tlmOut(),static_cast(portNum));
+ return &this->m_from_tlmOut[portNum];
+ }
+
// ----------------------------------------------------------------------
// Static functions for from ports
// ----------------------------------------------------------------------
@@ -430,7 +427,7 @@ namespace Svc {
#if FW_ENABLE_TEXT_LOGGING == 1
void BufferManagerTesterBase ::
- from_LogText_static(
+ from_textEventOut_static(
Fw::PassiveComponentBase *const component,
const NATIVE_INT_TYPE portNum,
FwEventIdType id,
@@ -588,7 +585,7 @@ namespace Svc {
FW_ASSERT(id >= idBase, id, idBase);
switch (id - idBase) {
- case BufferManagerComponentBase::EVENTID_BUFFERMANAGER_ALLOCATIONQUEUEEMPTY:
+ case BufferManagerComponentBase::EVENTID_CLEAREDERRORSTATE:
{
#if FW_AMPCS_COMPATIBLE
@@ -601,13 +598,13 @@ namespace Svc {
static_cast(_zero_status)
);
#endif
- this->logIn_WARNING_HI_BufferManager_AllocationQueueEmpty();
+ this->logIn_ACTIVITY_HI_ClearedErrorState();
break;
}
- case BufferManagerComponentBase::EVENTID_BUFFERMANAGER_ALLOCATIONQUEUEFULL:
+ case BufferManagerComponentBase::EVENTID_STORESIZEEXCEEDED:
{
#if FW_AMPCS_COMPATIBLE
@@ -620,73 +617,13 @@ namespace Svc {
static_cast(_zero_status)
);
#endif
- this->logIn_WARNING_HI_BufferManager_AllocationQueueFull();
+ this->logIn_WARNING_HI_StoreSizeExceeded();
break;
}
- case BufferManagerComponentBase::EVENTID_BUFFERMANAGER_IDMISMATCH:
- {
-
- Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
-#if FW_AMPCS_COMPATIBLE
- // Deserialize the number of arguments.
- U8 _numArgs;
- _status = args.deserialize(_numArgs);
- FW_ASSERT(
- _status == Fw::FW_SERIALIZE_OK,
- static_cast(_status)
- );
- // verify they match expected.
- FW_ASSERT(_numArgs == 2,_numArgs,2);
-
-#endif
- U32 expected;
-#if FW_AMPCS_COMPATIBLE
- {
- // Deserialize the argument size
- U8 _argSize;
- _status = args.deserialize(_argSize);
- FW_ASSERT(
- _status == Fw::FW_SERIALIZE_OK,
- static_cast(_status)
- );
- FW_ASSERT(_argSize == sizeof(U32),_argSize,sizeof(U32));
- }
-#endif
- _status = args.deserialize(expected);
- FW_ASSERT(
- _status == Fw::FW_SERIALIZE_OK,
- static_cast(_status)
- );
-
- U32 saw;
-#if FW_AMPCS_COMPATIBLE
- {
- // Deserialize the argument size
- U8 _argSize;
- _status = args.deserialize(_argSize);
- FW_ASSERT(
- _status == Fw::FW_SERIALIZE_OK,
- static_cast(_status)
- );
- FW_ASSERT(_argSize == sizeof(U32),_argSize,sizeof(U32));
- }
-#endif
- _status = args.deserialize(saw);
- FW_ASSERT(
- _status == Fw::FW_SERIALIZE_OK,
- static_cast(_status)
- );
-
- this->logIn_WARNING_HI_BufferManager_IDMismatch(expected, saw);
-
- break;
-
- }
-
- case BufferManagerComponentBase::EVENTID_BUFFERMANAGER_STORESIZEEXCEEDED:
+ case BufferManagerComponentBase::EVENTID_TOOMANYBUFFERS:
{
#if FW_AMPCS_COMPATIBLE
@@ -699,7 +636,7 @@ namespace Svc {
static_cast(_zero_status)
);
#endif
- this->logIn_WARNING_HI_BufferManager_StoreSizeExceeded();
+ this->logIn_WARNING_HI_TooManyBuffers();
break;
@@ -718,10 +655,9 @@ namespace Svc {
clearEvents(void)
{
this->eventsSize = 0;
- this->eventsSize_BufferManager_AllocationQueueEmpty = 0;
- this->eventsSize_BufferManager_AllocationQueueFull = 0;
- this->eventHistory_BufferManager_IDMismatch->clear();
- this->eventsSize_BufferManager_StoreSizeExceeded = 0;
+ this->eventsSize_ClearedErrorState = 0;
+ this->eventsSize_StoreSizeExceeded = 0;
+ this->eventsSize_TooManyBuffers = 0;
}
#if FW_ENABLE_TEXT_LOGGING
@@ -803,58 +739,41 @@ namespace Svc {
#endif
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueEmpty
+ // Event: ClearedErrorState
// ----------------------------------------------------------------------
void BufferManagerTesterBase ::
- logIn_WARNING_HI_BufferManager_AllocationQueueEmpty(
+ logIn_ACTIVITY_HI_ClearedErrorState(
void
)
{
- ++this->eventsSize_BufferManager_AllocationQueueEmpty;
+ ++this->eventsSize_ClearedErrorState;
++this->eventsSize;
}
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueFull
+ // Event: StoreSizeExceeded
// ----------------------------------------------------------------------
void BufferManagerTesterBase ::
- logIn_WARNING_HI_BufferManager_AllocationQueueFull(
+ logIn_WARNING_HI_StoreSizeExceeded(
void
)
{
- ++this->eventsSize_BufferManager_AllocationQueueFull;
+ ++this->eventsSize_StoreSizeExceeded;
++this->eventsSize;
}
// ----------------------------------------------------------------------
- // Event: BufferManager_IDMismatch
+ // Event: TooManyBuffers
// ----------------------------------------------------------------------
void BufferManagerTesterBase ::
- logIn_WARNING_HI_BufferManager_IDMismatch(
- U32 expected,
- U32 saw
- )
- {
- EventEntry_BufferManager_IDMismatch e = {
- expected, saw
- };
- eventHistory_BufferManager_IDMismatch->push_back(e);
- ++this->eventsSize;
- }
-
- // ----------------------------------------------------------------------
- // Event: BufferManager_StoreSizeExceeded
- // ----------------------------------------------------------------------
-
- void BufferManagerTesterBase ::
- logIn_WARNING_HI_BufferManager_StoreSizeExceeded(
+ logIn_WARNING_HI_TooManyBuffers(
void
)
{
- ++this->eventsSize_BufferManager_StoreSizeExceeded;
+ ++this->eventsSize_TooManyBuffers;
++this->eventsSize;
}
diff --git a/Svc/BufferManager/test/ut/TesterBase.hpp b/Svc/BufferManager/test/ut/TesterBase.hpp
index 15fafa3493..eb9e5e61e4 100644
--- a/Svc/BufferManager/test/ut/TesterBase.hpp
+++ b/Svc/BufferManager/test/ut/TesterBase.hpp
@@ -54,13 +54,6 @@ namespace Svc {
// Connect these output ports to the input ports under test
// ----------------------------------------------------------------------
- //! Connect bufferGetCallee to to_bufferGetCallee[portNum]
- //!
- void connect_to_bufferGetCallee(
- const NATIVE_INT_TYPE portNum, /*!< The port number*/
- Fw::InputBufferGetPort *const bufferGetCallee /*!< The port*/
- );
-
//! Connect bufferSendIn to to_bufferSendIn[portNum]
//!
void connect_to_bufferSendIn(
@@ -68,6 +61,13 @@ namespace Svc {
Fw::InputBufferSendPort *const bufferSendIn /*!< The port*/
);
+ //! Connect bufferGetCallee to to_bufferGetCallee[portNum]
+ //!
+ void connect_to_bufferGetCallee(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Fw::InputBufferGetPort *const bufferGetCallee /*!< The port*/
+ );
+
public:
// ----------------------------------------------------------------------
@@ -83,14 +83,6 @@ namespace Svc {
const NATIVE_INT_TYPE portNum /*!< The port number*/
);
- //! Get the port that receives input from tlmOut
- //!
- //! \return from_tlmOut[portNum]
- //!
- Fw::InputTlmPort* get_from_tlmOut(
- const NATIVE_INT_TYPE portNum /*!< The port number*/
- );
-
//! Get the port that receives input from eventOut
//!
//! \return from_eventOut[portNum]
@@ -100,15 +92,23 @@ namespace Svc {
);
#if FW_ENABLE_TEXT_LOGGING == 1
- //! Get the port that receives input from LogText
+ //! Get the port that receives input from textEventOut
//!
- //! \return from_LogText[portNum]
+ //! \return from_textEventOut[portNum]
//!
- Fw::InputLogTextPort* get_from_LogText(
+ Fw::InputLogTextPort* get_from_textEventOut(
const NATIVE_INT_TYPE portNum /*!< The port number*/
);
#endif
+ //! Get the port that receives input from tlmOut
+ //!
+ //! \return from_tlmOut[portNum]
+ //!
+ Fw::InputTlmPort* get_from_tlmOut(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
protected:
// ----------------------------------------------------------------------
@@ -216,13 +216,6 @@ namespace Svc {
// Invocation functions for to ports
// ----------------------------------------------------------------------
- //! Invoke the to port connected to bufferGetCallee
- //!
- Fw::Buffer invoke_to_bufferGetCallee(
- const NATIVE_INT_TYPE portNum, /*!< The port number*/
- U32 size
- );
-
//! Invoke the to port connected to bufferSendIn
//!
void invoke_to_bufferSendIn(
@@ -230,36 +223,25 @@ namespace Svc {
Fw::Buffer &fwBuffer
);
+ //! Invoke the to port connected to bufferGetCallee
+ //!
+ Fw::Buffer invoke_to_bufferGetCallee(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ U32 size
+ );
+
public:
// ----------------------------------------------------------------------
// Getters for port counts
// ----------------------------------------------------------------------
- //! Get the number of to_bufferGetCallee ports
- //!
- //! \return The number of to_bufferGetCallee ports
- //!
- NATIVE_INT_TYPE getNum_to_bufferGetCallee(void) const;
-
- //! Get the number of to_bufferSendIn ports
- //!
- //! \return The number of to_bufferSendIn ports
- //!
- NATIVE_INT_TYPE getNum_to_bufferSendIn(void) const;
-
//! Get the number of from_timeCaller ports
//!
//! \return The number of from_timeCaller ports
//!
NATIVE_INT_TYPE getNum_from_timeCaller(void) const;
- //! Get the number of from_tlmOut ports
- //!
- //! \return The number of from_tlmOut ports
- //!
- NATIVE_INT_TYPE getNum_from_tlmOut(void) const;
-
//! Get the number of from_eventOut ports
//!
//! \return The number of from_eventOut ports
@@ -267,13 +249,31 @@ namespace Svc {
NATIVE_INT_TYPE getNum_from_eventOut(void) const;
#if FW_ENABLE_TEXT_LOGGING == 1
- //! Get the number of from_LogText ports
+ //! Get the number of from_textEventOut ports
//!
- //! \return The number of from_LogText ports
+ //! \return The number of from_textEventOut ports
//!
- NATIVE_INT_TYPE getNum_from_LogText(void) const;
+ NATIVE_INT_TYPE getNum_from_textEventOut(void) const;
#endif
+ //! Get the number of to_bufferSendIn ports
+ //!
+ //! \return The number of to_bufferSendIn ports
+ //!
+ NATIVE_INT_TYPE getNum_to_bufferSendIn(void) const;
+
+ //! Get the number of to_bufferGetCallee ports
+ //!
+ //! \return The number of to_bufferGetCallee ports
+ //!
+ NATIVE_INT_TYPE getNum_to_bufferGetCallee(void) const;
+
+ //! Get the number of from_tlmOut ports
+ //!
+ //! \return The number of from_tlmOut ports
+ //!
+ NATIVE_INT_TYPE getNum_from_tlmOut(void) const;
+
protected:
// ----------------------------------------------------------------------
@@ -282,17 +282,17 @@ namespace Svc {
//! Check whether port is connected
//!
- //! Whether to_bufferGetCallee[portNum] is connected
+ //! Whether to_bufferSendIn[portNum] is connected
//!
- bool isConnected_to_bufferGetCallee(
+ bool isConnected_to_bufferSendIn(
const NATIVE_INT_TYPE portNum /*!< The port number*/
);
//! Check whether port is connected
//!
- //! Whether to_bufferSendIn[portNum] is connected
+ //! Whether to_bufferGetCallee[portNum] is connected
//!
- bool isConnected_to_bufferSendIn(
+ bool isConnected_to_bufferGetCallee(
const NATIVE_INT_TYPE portNum /*!< The port number*/
);
@@ -365,75 +365,50 @@ namespace Svc {
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueEmpty
+ // Event: ClearedErrorState
// ----------------------------------------------------------------------
- //! Handle event BufferManager_AllocationQueueEmpty
+ //! Handle event ClearedErrorState
//!
- virtual void logIn_WARNING_HI_BufferManager_AllocationQueueEmpty(
+ virtual void logIn_ACTIVITY_HI_ClearedErrorState(
void
);
- //! Size of history for event BufferManager_AllocationQueueEmpty
+ //! Size of history for event ClearedErrorState
//!
- U32 eventsSize_BufferManager_AllocationQueueEmpty;
+ U32 eventsSize_ClearedErrorState;
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_AllocationQueueFull
+ // Event: StoreSizeExceeded
// ----------------------------------------------------------------------
- //! Handle event BufferManager_AllocationQueueFull
+ //! Handle event StoreSizeExceeded
//!
- virtual void logIn_WARNING_HI_BufferManager_AllocationQueueFull(
+ virtual void logIn_WARNING_HI_StoreSizeExceeded(
void
);
- //! Size of history for event BufferManager_AllocationQueueFull
+ //! Size of history for event StoreSizeExceeded
//!
- U32 eventsSize_BufferManager_AllocationQueueFull;
+ U32 eventsSize_StoreSizeExceeded;
protected:
// ----------------------------------------------------------------------
- // Event: BufferManager_IDMismatch
+ // Event: TooManyBuffers
// ----------------------------------------------------------------------
- //! Handle event BufferManager_IDMismatch
+ //! Handle event TooManyBuffers
//!
- virtual void logIn_WARNING_HI_BufferManager_IDMismatch(
- U32 expected, /*!< The expected ID value*/
- U32 saw /*!< The ID value seen*/
- );
-
- //! A history entry for event BufferManager_IDMismatch
- //!
- typedef struct {
- U32 expected;
- U32 saw;
- } EventEntry_BufferManager_IDMismatch;
-
- //! The history of BufferManager_IDMismatch events
- //!
- History
- *eventHistory_BufferManager_IDMismatch;
-
- protected:
-
- // ----------------------------------------------------------------------
- // Event: BufferManager_StoreSizeExceeded
- // ----------------------------------------------------------------------
-
- //! Handle event BufferManager_StoreSizeExceeded
- //!
- virtual void logIn_WARNING_HI_BufferManager_StoreSizeExceeded(
+ virtual void logIn_WARNING_HI_TooManyBuffers(
void
);
- //! Size of history for event BufferManager_StoreSizeExceeded
+ //! Size of history for event TooManyBuffers
//!
- U32 eventsSize_BufferManager_StoreSizeExceeded;
+ U32 eventsSize_TooManyBuffers;
protected:
@@ -525,14 +500,14 @@ namespace Svc {
// To ports
// ----------------------------------------------------------------------
- //! To port connected to bufferGetCallee
- //!
- Fw::OutputBufferGetPort m_to_bufferGetCallee[1];
-
//! To port connected to bufferSendIn
//!
Fw::OutputBufferSendPort m_to_bufferSendIn[1];
+ //! To port connected to bufferGetCallee
+ //!
+ Fw::OutputBufferGetPort m_to_bufferGetCallee[1];
+
private:
// ----------------------------------------------------------------------
@@ -543,20 +518,20 @@ namespace Svc {
//!
Fw::InputTimePort m_from_timeCaller[1];
- //! From port connected to tlmOut
- //!
- Fw::InputTlmPort m_from_tlmOut[1];
-
//! From port connected to eventOut
//!
Fw::InputLogPort m_from_eventOut[1];
#if FW_ENABLE_TEXT_LOGGING == 1
- //! From port connected to LogText
+ //! From port connected to textEventOut
//!
- Fw::InputLogTextPort m_from_LogText[1];
+ Fw::InputLogTextPort m_from_textEventOut[1];
#endif
+ //! From port connected to tlmOut
+ //!
+ Fw::InputTlmPort m_from_tlmOut[1];
+
private:
// ----------------------------------------------------------------------
@@ -571,16 +546,6 @@ namespace Svc {
Fw::Time &time /*!< The U32 cmd argument*/
);
- //! Static function for port from_tlmOut
- //!
- static void from_tlmOut_static(
- Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
- const NATIVE_INT_TYPE portNum, /*!< The port number*/
- FwChanIdType id, /*!< Telemetry Channel ID*/
- Fw::Time &timeTag, /*!< Time Tag*/
- Fw::TlmBuffer &val /*!< Buffer containing serialized telemetry value*/
- );
-
//! Static function for port from_eventOut
//!
static void from_eventOut_static(
@@ -593,9 +558,9 @@ namespace Svc {
);
#if FW_ENABLE_TEXT_LOGGING == 1
- //! Static function for port from_LogText
+ //! Static function for port from_textEventOut
//!
- static void from_LogText_static(
+ static void from_textEventOut_static(
Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
const NATIVE_INT_TYPE portNum, /*!< The port number*/
FwEventIdType id, /*!< Log ID*/
@@ -605,6 +570,16 @@ namespace Svc {
);
#endif
+ //! Static function for port from_tlmOut
+ //!
+ static void from_tlmOut_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwChanIdType id, /*!< Telemetry Channel ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::TlmBuffer &val /*!< Buffer containing serialized telemetry value*/
+ );
+
private:
// ----------------------------------------------------------------------
diff --git a/Svc/CmdDispatcher/CommandDispatcherComponentAi.xml b/Svc/CmdDispatcher/CommandDispatcherComponentAi.xml
index 10d00d2362..4538613627 100644
--- a/Svc/CmdDispatcher/CommandDispatcherComponentAi.xml
+++ b/Svc/CmdDispatcher/CommandDispatcherComponentAi.xml
@@ -186,22 +186,22 @@
-
+
- The command dispatcher has successfully recieved a NO-OP command from GUI
+ The command dispatcher has successfully recieved a NO-OP command
-
+
- The command dispatcher has successfully recieved a NO-OP command from GUI, now generating a NO-OP string
+ The command dispatcher has successfully recieved a NO-OP command from GUI with a string
-
+ The NO-OP string that is generated
-
+
This log event message returns the TEST_CMD_1 arguments.
diff --git a/Svc/CmdDispatcher/CommandDispatcherImpl.cpp b/Svc/CmdDispatcher/CommandDispatcherImpl.cpp
index 9bec4efd64..26d4ed4911 100644
--- a/Svc/CmdDispatcher/CommandDispatcherImpl.cpp
+++ b/Svc/CmdDispatcher/CommandDispatcherImpl.cpp
@@ -204,19 +204,19 @@ namespace Svc {
void CommandDispatcherImpl::CMD_NO_OP_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
Fw::LogStringArg no_op_string("Hello, World!");
// Log event for NO_OP here.
- this->log_COMMAND_NoOpReceived();
+ this->log_ACTIVITY_HI_NoOpReceived();
this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
}
void CommandDispatcherImpl::CMD_NO_OP_STRING_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg& arg1) {
Fw::LogStringArg msg(arg1.toChar());
// Echo the NO_OP_STRING args here.
- this->log_COMMAND_NoOpStringReceived(msg);
+ this->log_ACTIVITY_HI_NoOpStringReceived(msg);
this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
}
void CommandDispatcherImpl::CMD_TEST_CMD_1_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, I32 arg1, F32 arg2, U8 arg3) {
- this->log_COMMAND_TestCmd1Args(arg1,arg2,arg3);
+ this->log_ACTIVITY_HI_TestCmd1Args(arg1,arg2,arg3);
this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
}
diff --git a/Svc/CmdDispatcher/docs/CommandDispatcher.md b/Svc/CmdDispatcher/docs/CommandDispatcher.md
index b6cc6d4a3f..12eddc8e96 100644
--- a/Svc/CmdDispatcher/docs/CommandDispatcher.md
+++ b/Svc/CmdDispatcher/docs/CommandDispatcher.md
@@ -44,9 +44,9 @@
| | | |Opcode|U32||Invalid opcode|
|TooManyCommands|6 (0x6)|Exceeded the number of commands that can be simultaneously executed| | | | |
| | | |Opcode|U32||The opcode that overflowed the list|
-|NoOpReceived|7 (0x7)|The command dispatcher has successfully recieved a NO-OP command from GUI| | | | |
-|NoOpStringReceived|8 (0x8)|The command dispatcher has successfully recieved a NO-OP command from GUI, now generating a NO-OP string| | | | |
-| | | |No_op_string|Fw::LogStringArg&|40|The NO-OP string that is generated|
+|NoOpReceived|7 (0x7)|The command dispatcher has successfully recieved a NO-OP command| | | | |
+|NoOpStringReceived|8 (0x8)|The command dispatcher has successfully recieved a NO-OP command from GUI with a string| | | | |
+| | | |message|Fw::LogStringArg&|40|The NO-OP string that is generated|
|TestCmd1Args|9 (0x9)|This log event message returns the TEST_CMD_1 arguments.| | | | |
| | | |arg1|I32||Arg1|
| | | |arg2|F32||Arg2|
diff --git a/Svc/ComLogger/test/ut/Tester.cpp b/Svc/ComLogger/test/ut/Tester.cpp
index 5848f65445..f034bc6e16 100644
--- a/Svc/ComLogger/test/ut/Tester.cpp
+++ b/Svc/ComLogger/test/ut/Tester.cpp
@@ -429,7 +429,7 @@ namespace Svc {
ASSERT_EVENTS_FileWriteError(
0,
Os::File::NOT_OPENED,
- 2,
+ 0,
2,
(char*) fileName
);
@@ -468,7 +468,7 @@ namespace Svc {
ASSERT_EVENTS_FileWriteError(
1,
Os::File::NOT_OPENED,
- 2,
+ 0,
2,
(char*) fileName
);
diff --git a/Svc/FatalHandler/mod.mk b/Svc/FatalHandler/mod.mk
index 6515b41d57..8ab2bd3361 100644
--- a/Svc/FatalHandler/mod.mk
+++ b/Svc/FatalHandler/mod.mk
@@ -14,14 +14,14 @@
SRC = FatalHandlerComponentAi.xml FatalHandlerComponentCommonImpl.cpp
-SRC_BAERAD750 = FatalHandlerComponentVxWorksImpl.cpp
-
SRC_LINUX = FatalHandlerComponentLinuxImpl.cpp
SRC_CYGWIN = FatalHandlerComponentLinuxImpl.cpp
SRC_DARWIN = FatalHandlerComponentLinuxImpl.cpp
+SRC_RASPIAN = FatalHandlerComponentLinuxImpl.cpp
+
HDR = FatalHandlerComponentImpl.hpp
SUBDIRS =
\ No newline at end of file
diff --git a/Svc/FileUplink/test/ut/Tester.cpp b/Svc/FileUplink/test/ut/Tester.cpp
index 2f6cfc511b..f9cc19711e 100644
--- a/Svc/FileUplink/test/ut/Tester.cpp
+++ b/Svc/FileUplink/test/ut/Tester.cpp
@@ -598,7 +598,7 @@ namespace Svc {
{
const Fw::FilePacket::DataPacket dataPacket = {
{ Fw::FilePacket::T_DATA, this->sequenceIndex++ },
- byteOffset,
+ static_cast(byteOffset),
PACKET_SIZE,
packetData
};
diff --git a/Svc/FileUplink/test/ut/mod.mk b/Svc/FileUplink/test/ut/mod.mk
index 6c05551abc..2c305713a8 100644
--- a/Svc/FileUplink/test/ut/mod.mk
+++ b/Svc/FileUplink/test/ut/mod.mk
@@ -19,6 +19,7 @@ TEST_MODS= \
Fw/Time \
Fw/Tlm \
Fw/Types \
+ Utils/Hash \
Os \
Svc/FileUplink \
gtest
diff --git a/Svc/GndIf/Commands.xml b/Svc/GndIf/Commands.xml
new file mode 100644
index 0000000000..b37ab3f628
--- /dev/null
+++ b/Svc/GndIf/Commands.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ Enable the interface for ground communications
+
+
+
diff --git a/Svc/GndIf/GndIfComponentAi.xml b/Svc/GndIf/GndIfComponentAi.xml
index 1ff3d72be2..2600bebca2 100644
--- a/Svc/GndIf/GndIfComponentAi.xml
+++ b/Svc/GndIf/GndIfComponentAi.xml
@@ -10,7 +10,10 @@
Svc/GndIf/GetConnectedPortAi.xmlFw/Time/TimePortAi.xmlFw/Buffer/BufferGetPortAi.xml
+
Svc/GndIf/Events.xml
+ Svc/GndIf/Commands.xml
+
diff --git a/Svc/GndIf/GndIfComponentReport.txt b/Svc/GndIf/GndIfComponentReport.txt
new file mode 100644
index 0000000000..1983b6d43e
--- /dev/null
+++ b/Svc/GndIf/GndIfComponentReport.txt
@@ -0,0 +1,6 @@
+Input Ports: 3
+Output Ports: 7
+Commands: 1
+ OpCodes: 0x00
+Events: 4
+ EventIds: 0,1,2,3
diff --git a/Svc/GndIf/GndIfModule.mdxml b/Svc/GndIf/GndIfModule.mdxml
index 87a052ed6d..b16ccc0589 100644
--- a/Svc/GndIf/GndIfModule.mdxml
+++ b/Svc/GndIf/GndIfModule.mdxml
@@ -1,6 +1,6 @@
-
+
@@ -14,8 +14,8 @@
-
+
@@ -27,13 +27,13 @@
-
+
-
+
@@ -45,26 +45,26 @@
-
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+ _17_0_2_2_9120299_1420854889598_85433_26470_18_0_5_9120299_1466625418636_261605_14851_17_0_2_2_9120299_1420856684364_960917_27802
@@ -147,6 +147,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -212,44 +243,36 @@
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -257,7 +280,39 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -271,35 +326,35 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -311,8 +366,8 @@
-
-
+
+
@@ -334,7 +389,7 @@
-
+
@@ -345,7 +400,7 @@
-
+
@@ -356,7 +411,7 @@
-
+
@@ -367,7 +422,7 @@
-
+
@@ -379,7 +434,7 @@
-
+
@@ -441,6 +496,7 @@
+
@@ -465,40 +521,15 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
@@ -506,6 +537,7 @@
+
@@ -566,61 +598,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -715,38 +724,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -807,6 +840,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -824,7 +883,7 @@
-
+
@@ -835,7 +894,7 @@
-
+
@@ -847,7 +906,7 @@
-
+
@@ -858,7 +917,7 @@
-
+
@@ -892,7 +951,7 @@
- H4sIAAAAAAAAAFPmUg5PTVHwKs1TMDJSMDS2MrawMjZTCHAJUTAyMDTjSs7P1cvLz01Mz0zWA5MpRYnleqW5OfG5+SmpOXrFGYlFqSkQjq2Tp59jUKSuZaKBmbmhibGuQaqxoa5JoqGFroVJqpFuSqJZcqpBYrKZiUUSFwBV6z8ceQAAAA==
+ H4sIAAAAAAAAAFPmUg4pTVXwTy5RMDJWMDS1MjK2MjJXCHAJUTAyMLTgSs7P1cvLz01Mz0zWA5MpRYnleqW5OfG5+SmpOXrFGYlFqSkQjq2Tp59jUKRuqqllqqlJSqpuarJJmq6JoWmirmWiabKuUVJSWqp5cmpScpoBFwA9d3pOeQAAAA==
@@ -908,7 +967,7 @@
-
+
@@ -919,7 +978,7 @@
-
+
@@ -931,7 +990,7 @@
-
+
@@ -942,7 +1001,7 @@
-
+
@@ -955,7 +1014,7 @@
-
+
@@ -980,7 +1039,81 @@
- H4sIAAAAAAAAAFPmUg5PTVHwKs1TMDJSMDS2MrawMjZTCHAJUTAyMDTjAgAvbj+AIAAAAA==
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ H4sIAAAAAAAAAFPmUg4pTVXwTy5RMDJWMDS1MjK2MjJXCHAJUTAyMLTgAgCj/OHdIAAAAA==
@@ -991,7 +1124,7 @@
-
+
@@ -1008,7 +1141,7 @@
-
+
@@ -1041,7 +1174,7 @@
-
+
@@ -1057,18 +1190,18 @@
-
+
-
+
-
+
-
+
@@ -1079,51 +1212,52 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
-
-
+
+
+
-
+
-
+
@@ -1131,35 +1265,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1254,11 +1359,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -1276,12 +1411,8 @@
-
-
-
-
-
+
@@ -1337,95 +1468,17 @@
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1517,6 +1570,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1556,6 +1629,7 @@
+
@@ -1631,6 +1705,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1664,6 +1827,9 @@
_17_0_5_1_89a0278_1457736977987_773486_11645
+
+ _17_0_2_2_9120299_1421802142133_763918_28061
+
@@ -1681,7 +1847,7 @@
-
+
@@ -1692,7 +1858,7 @@
-
+
@@ -1704,7 +1870,7 @@
-
+
@@ -1742,53 +1908,53 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1799,7 +1965,7 @@
-
+
@@ -1810,7 +1976,7 @@
-
+
@@ -1821,7 +1987,7 @@
-
+
@@ -1832,15 +1998,26 @@
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
@@ -1975,285 +2152,106 @@
-
-
-
-
-
- 5, 5, 711, 351
-
-
-
-
-
-
-
- FILL_COLOR
- FILL_COLOR_DESCRIPTION
-
-
-
- TAGGED_VALUES_DISPLAY_MODE
- TAGGED_VALUES_DISPLAY_MODE_DESCRIPTION
- ON_SHAPE
-
-
-
-
- 133, 77, 392, 189
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT
-
-
-
-
- 126, 99, 15, 15
-
-
-
-
- 28, 90, 95, 13
-
- downlinkPort : Com
-
-
- 57, 74, 66, 13
-
- «sync_input»
-
-
-
- 0, 0, 66, 13
-
- <html><body>
-<p>{direction = in}</p>
-</body></html>
-
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT
-
-
-
-
- 517, 172, 15, 15
-
-
-
-
- 535, 163, 81, 13
-
- uplinkPort : Com
-
-
- 535, 147, 43, 13
-
- «output»
-
-
-
- 147, 0, 73, 13
-
- <html><body>
-<p>{direction = out}</p>
-</body></html>
-
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 126, 143, 15, 15
-
-
-
-
- 77, 134, 46, 13
-
- Log : Log
-
-
- 64, 118, 59, 13
-
- «LogEvent»
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT
-
-
-
-
- 126, 232, 15, 15
-
-
-
-
- 65, 223, 58, 13
-
- Time : Time
-
-
- 68, 207, 55, 13
-
- «TimeGet»
-
-
-
-
-
-
-
-
-
- STEREOTYPES_DISPLAY_MODE
- STEREOTYPES_DISPLAY_MODE_DESCRIPTION
- STEREOTYPE_DISPLAY_MODE_TEXT_AND_ICON
-
-
-
-
- 126, 185, 15, 15
-
-
-
-
- 33, 176, 90, 13
-
- LogText : LogText
-
-
- 42, 160, 81, 13
-
- «LogTextEvent»
-
-
-
-
-
-
-
- 160, 258, 15, 15
-
-
-
-
- 170, 276, 184, 13
-
- fileDownlinkBufferSendIn : BufferSend
-
-
-
-
-
-
- 436, 258, 15, 15
-
-
-
-
- 446, 276, 193, 13
-
- fileDownlinkBufferSendOut : BufferSend
-
-
-
-
-
-
- 169, 70, 15, 15
-
-
-
-
- 114, 49, 147, 13
-
- fileUplinkBufferGet : BufferGet
-
-
-
-
-
-
- 417, 70, 15, 15
-
-
-
-
- 400, 49, 179, 13
-
- fileUplinkBufferSendOut : BufferSend
-
-
-
-
-
-
-
+ 5, 5, 711, 351FILL_COLORFILL_COLOR_DESCRIPTIONTAGGED_VALUES_DISPLAY_MODETAGGED_VALUES_DISPLAY_MODE_DESCRIPTIONON_SHAPE133, 77, 392, 189STEREOTYPES_DISPLAY_MODESTEREOTYPES_DISPLAY_MODE_DESCRIPTIONSTEREOTYPE_DISPLAY_MODE_TEXTSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION126, 99, 15, 1528, 90, 95, 13downlinkPort : Com57, 74, 66, 13«sync_input»0, 0, 66, 13<html><body><p>{direction = in}</p></body></html>STEREOTYPES_DISPLAY_MODESTEREOTYPES_DISPLAY_MODE_DESCRIPTIONSTEREOTYPE_DISPLAY_MODE_TEXTSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION517, 172, 15, 15535, 163, 81, 13uplinkPort : Com535, 147, 43, 13«output»147, 0, 73, 13<html><body><p>{direction = out}</p></body></html>STEREOTYPES_DISPLAY_MODESTEREOTYPES_DISPLAY_MODE_DESCRIPTIONSTEREOTYPE_DISPLAY_MODE_TEXT_AND_ICONSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION126, 143, 15, 1577, 134, 46, 13Log : Log64, 118, 59, 13«LogEvent»STEREOTYPES_DISPLAY_MODESTEREOTYPES_DISPLAY_MODE_DESCRIPTIONSTEREOTYPE_DISPLAY_MODE_TEXTSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION126, 232, 15, 1565, 223, 58, 13Time : Time68, 207, 55, 13«TimeGet»STEREOTYPES_DISPLAY_MODESTEREOTYPES_DISPLAY_MODE_DESCRIPTIONSTEREOTYPE_DISPLAY_MODE_TEXT_AND_ICONSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION126, 185, 15, 1533, 176, 90, 13LogText : LogText42, 160, 81, 13«LogTextEvent»SHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION160, 258, 15, 15170, 276, 184, 13fileDownlinkBufferSendIn : BufferSendSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION436, 258, 15, 15446, 276, 193, 13fileDownlinkBufferSendOut : BufferSendSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION169, 70, 15, 15114, 49, 147, 13fileUplinkBufferGet : BufferGetSHOW_INHERITED_SIGNSHOW_INHERITED_SIGN_DESCRIPTION417, 70, 15, 15400, 49, 179, 13fileUplinkBufferSendOut : BufferSend
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -2282,6 +2280,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2378,10 +2405,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- H4sIAAAAAAAAAM1Yy26bQBTd+ysshS1oXgwzkbxo0i6aRRtFkaqurHlcApUNCHDb/H2vHZqnSWIXUL2wB+YO58y5Z+6MOTkv15Vpc5uv8vZ2DkVb385OvoGfX2yKOWNzyk+5OuVyfvnxes4IlbOqLn/fRqvSmdVyeXn19eLT+XWQ6dS6VGqLLWN9kIlUOWwnqd72iTQ2jFJpxLKGptzUDpauXAe+KNfmJneB3/342vwK/Ga9Wm7WpYdV4JvM1OAfLgtTNVnZLv4HEj1KpJpoBQwhpRcGSWgvg8warYKMSGpUTBxxPu0j4XIkAq3p0BDkB7j2zbmPDTs7ywtT59BE2FVB3WJzsedejypCKM0Mt5ge7ogRCViW4iUlmpNeUoO4YgrokVbFkV4YG3Yk5w+S7WlJzDrcMPVGyxR8yG2ShMI5Epok5SEispgKyTnzi0OCZ7iemrIwqxD5RR296J5d5Moaoi4zUVm1eVngMuzGdPe724vhHtW3uhUxKtE8yBxLAK+5pUGmqMEEGCYI0U6BtiOv80lJzHq0BJRzvS4Lh+FQ3OQFQJ0XN4vDwvuevi9Tdw94lvJ/HD9Sno+sZ2PD9qi9dcFuSNR5YHfRI+3+4L5K2RWAINtWAJwQlgCcCtYALFuPisC4lXJSEk80dnl0x+lvb+ShcXVetWX9qPnUxu8d1LcXW+GZpVJQkIxwzYXXMSTWQ5wCUUNvweOgPVfxPvbvqn6u2IuAN73+PpO/5u7jDlzH1oZRwF64FXfDvGmhwIK9Y9BZsarzn6YFDxUUHntvVxj1wrWHDO7R1HsrtXcMlyaXfHussSmWQE+338RYw5mF2MuB1R0bdqTZDlIfpyXRo4RzTMcKBB5eweJBViQMtsfZZHugT1WiYnS/iPXAeR8b9q0qtMTPTqiqzIu2OWgDfm3sSCoP4rdpSfQooZIkRhKaMZFSKnxMPBiacm2oo3Rom42ENjv7/OXD1fdQGyITKnhIgNNQGKpCJYCF3kgHxDgplF0cEDvsyWKYV15TYA/rlUHmPQn2w3/wfS+/Xuuc/QF+XjXyWRUAAA==
+ H4sIAAAAAAAAAM1Yy47bNhTd+ysMRFsJfIpkAC+atIt20QTBbLoy+LgcKbAlQda0nb/vlaO8ZkYzsSsKmYWHFC91Ds998EKv3rbHzg61qw/1cL+FZujvN69u7mD7zg9bxrdUvmb8NdPb97/ebBmhetP17b/3xaH19rDfv//w7o/f3t5klYnOx9I4HFkXskpE7XGsohnXRJSWUVpase/h1N71Hva+PWahaY/2tvZZOP8Lvf0nC3fHw/7u2AY4ZOFU2R7C12lju1PVDrufgcSMEtEQo4EhZBmERRImlFnlrNFZRUpqtSSe+BDnSPgaicBgJzQE+Qh+ePHsqWE3b+rG9jWcClzqoB9wuHvi2YwqQmjDLHfoHu6JFQocizilxHAyS2qRqFgDOlFWXBkLqWETRf4i3l6XxGbCzWOwpowQcu6UyoX3JLcq8hwRmaSi5JyF3SXGG8ynU9vYQ478iole8YVd4dseiskzRdsNddtgGk57pufT491yr5rLbk2sVoZnlWcKcM4dzSpNLTrAMkGI8RqMS5znq5LYzGgJKOfx2DYezaG5rRuAvm5ud5eZz739KU99esEDl//P/Yn8fGU9Sw07o/YYBectxRQD58mMtE8bz1XKqQBk1VgB8EBYAvAoWAOwbH1TBNJWylVJfKexr4tPnD6vFgFOvq+7oe2/GX4fxj+6ae4udiIwR0tBoWSEGy6CkaBcABmB6KWv4DRoD1X8Yvs5qx8q9sjgxVj/sSB/Lrqva7iurQ1JwB5FK96G9WmABgv2mcEUil1f/20HCNBBE3D1/oBWj6L2ks0zmobgShM8w9TkJR/bGhexBAY6/hLrLGcOZCgXVjc1bKLTLlIf1yUxo4T3zEgNAptXcNjICsVgbGfV2NBHrbTE6BfSLOz31LAvVaE9/p2F6tq6GU4XXcDP7Z1R2QYVvS6xqQhEjg2G03h0rUbnRx4U0dbSUvGk8bYuiUTxtogS65KYUUIrJZGEYUxESkWQJIClkRtLPaVLJ1witM2b3//85cNfOUgDUgTIwYuYCyptbqz0OXMugvLgfCS7C2wT5dGV4qWGXbajXOZT5xrYy2bGIudeBfvrt5enPno+t7j5Dyu4X2hRFwAA
\ No newline at end of file
diff --git a/Svc/GndIf/README b/Svc/GndIf/README
old mode 100644
new mode 100755
diff --git a/Svc/GndIf/docs/.gitignore b/Svc/GndIf/docs/.gitignore
old mode 100644
new mode 100755
diff --git a/Svc/GndIf/docs/GndIf.md b/Svc/GndIf/docs/GndIf.md
index 6f92413366..7e983a4b7d 100644
--- a/Svc/GndIf/docs/GndIf.md
+++ b/Svc/GndIf/docs/GndIf.md
@@ -2,6 +2,12 @@
# GndIf Component Dictionary
+## Command List
+
+|Mnemonic|ID|Description|Arg Name|Arg Type|Comment
+|---|---|---|---|---|---|
+|GNDIF_ENABLE_INTERFACE|0 (0x0)|Enable the interface for ground communications| | |
+
## Event List
diff --git a/Svc/Health/HealthComponentImpl.cpp b/Svc/Health/HealthComponentImpl.cpp
index 91fb76bdb9..5241961586 100644
--- a/Svc/Health/HealthComponentImpl.cpp
+++ b/Svc/Health/HealthComponentImpl.cpp
@@ -1,4 +1,4 @@
-// ======================================================================
+// ======================================================================
// \title Health.hpp
// \author Tim
// \brief hpp file for Health component implementation class
@@ -8,14 +8,14 @@
// ALL RIGHTS RESERVED. United States Government Sponsorship
// acknowledged. Any commercial use must be negotiated with the Office
// of Technology Transfer at the California Institute of Technology.
-//
+//
// This software may be subject to U.S. export control laws and
// regulations. By accepting this document, the user agrees to comply
// with all U.S. export laws and regulations. User has the
// responsibility to obtain export licenses, or other export authority
// as may be required before exporting such information to foreign
// countries or providing access to foreign persons.
-// ======================================================================
+// ======================================================================
#include
#include "Fw/Types/BasicTypes.hpp"
@@ -123,8 +123,8 @@ namespace Svc {
// increment cycles for the entry
this->m_pingTrackerEntries[entry].cycleCount++;
} else {
- // check to see if it is at warning threshold and decrement cycle count
- if (this->m_pingTrackerEntries[entry].cycleCount++ ==
+ // check to see if it is at warning threshold
+ if (this->m_pingTrackerEntries[entry].cycleCount ==
this->m_pingTrackerEntries[entry].entry.warnCycles) {
Fw::LogStringArg _arg = this->m_pingTrackerEntries[entry].entry.entryName;
this->log_WARNING_HI_HLTH_PING_WARN(_arg);
@@ -137,6 +137,8 @@ namespace Svc {
this->log_FATAL_HLTH_PING_LATE(_arg);
}
} // if at warning or fatal threshold
+
+ this->m_pingTrackerEntries[entry].cycleCount++;
} // if clear entry
} // if entry has ping enabled
} // for each entry
diff --git a/Svc/Health/mod.mk b/Svc/Health/mod.mk
index d4914ea647..c0f0007e60 100644
--- a/Svc/Health/mod.mk
+++ b/Svc/Health/mod.mk
@@ -23,6 +23,4 @@ SRC_CYGWIN = Stub/HealthComponentStubChecks.cpp
SRC_DARWIN = Stub/HealthComponentStubChecks.cpp
-SRC_BAERAD750 = VxWorks/HealthComponentVxWorksChecks.cpp
-
-SRC_SPHINX = VxWorks/HealthComponentVxWorksChecks.cpp
+SRC_RASPIAN = Stub/HealthComponentStubChecks.cpp
diff --git a/Svc/LinuxTime/mod.mk b/Svc/LinuxTime/mod.mk
index bbc798c1ac..ffc67b19fe 100644
--- a/Svc/LinuxTime/mod.mk
+++ b/Svc/LinuxTime/mod.mk
@@ -24,9 +24,7 @@ SRC_CYGWIN = LinuxTimeImpl.cpp
SRC_DARWIN = DarwinTimeImpl.cpp
-SRC_BAERAD750 = VxWorksTimeImpl.cpp
-
-SRC_SPHINX = VxWorksTimeImpl.cpp
+SRC_RASPIAN = LinuxTimeImpl.cpp
HDR = LinuxTimeImpl.hpp
diff --git a/Svc/LinuxTimer/LinuxTimer.mdxml b/Svc/LinuxTimer/LinuxTimer.mdxml
new file mode 100644
index 0000000000..5d83d44d57
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimer.mdxml
@@ -0,0 +1,915 @@
+
+
+
+
+
+
+
+ MagicDraw UML
+ 18.0
+
+
+
+
+
+
+
+
+
+
+
+
+ MagicDraw UML
+ 18.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ _18_0_5_29e014b_1496079525168_681354_13286
+
+
+ _17_0_2_2_9120299_1366841320552_114823_26850
+
+
+ magicdraw_uml_standard_profile_v_0001
+
+
+ _17_0_5_1_9120299_1439830514493_64160_12351
+
+
+ _11_5EAPbeta_be00301_1147434586638_637562_1900
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ H4sIAAAAAAAAAFPm5VL2zc9T8E2sVDCyVDA0sDI1sTI2UwhwCVEwMjA05+UCABzFl7kiAAAA
+
+
+ H4sIAAAAAAAAAFPm5VL2zc9T8E2sVDCyVDA0sDI1sTI2UwhwCVEwMjA05+UCABzFl7kiAAAA
+
+
+ H4sIAAAAAAAAAAMAAAAAAAAAAAA=
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ H4sIAAAAAAAAAMVXXW+bMBR9R+I/IJVXEDYk4Ep5abeXSdWqqe/oYl+GK8DIONvy7+ekpEub0DRtyHjBNvfL5xz7Jle3qunAyELW0qw8bI1euc7VnWq9O1h5lHkkup4l1/Hcu//y4NGIpK5zI1vQEvuw06pDbexwcWDNdez4zyqsFYc6z+9/fP/29fbBr5IkYxTiopyzmEeQpFjQ0k5JxOKozDX2aqk55lw1vmhVAz8l98XmJTT89sWyqfNlowTWvugr0Cj+TVvo+kqZxf9LPbbtoqSQCIJ+NU8zamtJGfcrIMncr0pCMSYE4nlJJgXgskVYKFD3qoU6sGHCIUr4HCTkSuNaMY/ITag6I1VrFTT4DOvD8uJ8oUaFmUWQpSz2K05TC1ESF8SvMgJgIaJJFDGeISsmluhFi3CdE9C0po1qX9HySf+puODSQoEGhv0OSSdH/1jaMbzXVG18woGozWQE3MPGL0NzGT7tcJs5FNhzLTuj9M7wJX/vdRojDaLZLANusUozVlj0SmHvmCKlmcWQkUIAgYISmPQAXbaIPdSf2d/K/zXCewbHNfE+MQwqOGfn++gpmiTZvsDt7S57gy3HpxIG9XZa/gKDAjtshf26qq3VntBPcT5KUW6fjUI6JVvTn3SK3/J1nQHUYNu5g3XjDtZ9O1i37WC3ay9OMR5TSpam9gAhozQpCUnELBIIpIwZEE4IO7NUJso21Q31wV1OnfbMXJ7lHr5I7p1fmIf+lbz10XX+AnOkRzL9DAAA
+
+
\ No newline at end of file
diff --git a/Svc/LinuxTimer/LinuxTimerComponentAi.xml b/Svc/LinuxTimer/LinuxTimerComponentAi.xml
new file mode 100644
index 0000000000..3b1118d19a
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimerComponentAi.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Svc/Cycle/CyclePortAi.xml
+ A Linux interval timer
+
+
+
+
+ Cycle output
+
+
+
+
+
diff --git a/Svc/LinuxTimer/LinuxTimerComponentImpl.hpp b/Svc/LinuxTimer/LinuxTimerComponentImpl.hpp
new file mode 100644
index 0000000000..afc15a5064
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimerComponentImpl.hpp
@@ -0,0 +1,72 @@
+// ======================================================================
+// \title LinuxTimerImpl.hpp
+// \author tim
+// \brief hpp file for LinuxTimer component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef LinuxTimer_HPP
+#define LinuxTimer_HPP
+
+#include "Svc/LinuxTimer/LinuxTimerComponentAc.hpp"
+
+namespace Svc {
+
+ class LinuxTimerComponentImpl :
+ public LinuxTimerComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object LinuxTimer
+ //!
+ LinuxTimerComponentImpl(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName /*!< The component name*/
+#else
+ void
+#endif
+ );
+
+ //! Initialize object LinuxTimer
+ //!
+ void init(
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ //! Destroy object LinuxTimer
+ //!
+ ~LinuxTimerComponentImpl(void);
+
+ //! Start timer
+ void startTimer(NATIVE_INT_TYPE interval); //!< interval in milliseconds
+
+ //! Quit timer
+ void quit(void);
+
+ bool m_quit; //!< flag to quit
+
+ Svc::TimerVal m_timer;
+
+
+ };
+
+} // end namespace Svc
+
+#endif
diff --git a/Svc/LinuxTimer/LinuxTimerComponentImplCommon.cpp b/Svc/LinuxTimer/LinuxTimerComponentImplCommon.cpp
new file mode 100644
index 0000000000..22fd78a6d2
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimerComponentImplCommon.cpp
@@ -0,0 +1,62 @@
+// ======================================================================
+// \title LinuxTimerImpl.cpp
+// \author tim
+// \brief cpp file for LinuxTimer component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+
+#include
+#include "Fw/Types/BasicTypes.hpp"
+
+namespace Svc {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ LinuxTimerComponentImpl ::
+#if FW_OBJECT_NAMES == 1
+ LinuxTimerComponentImpl(
+ const char *const compName
+ ) :
+ LinuxTimerComponentBase(compName)
+#else
+ LinuxTimerImpl(void)
+#endif
+ ,m_quit(false)
+ {
+
+ }
+
+ void LinuxTimerComponentImpl ::
+ init(
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ LinuxTimerComponentBase::init(instance);
+ }
+
+ LinuxTimerComponentImpl ::
+ ~LinuxTimerComponentImpl(void)
+ {
+
+ }
+
+ void LinuxTimerComponentImpl::quit(void) {
+ this->m_quit = true;
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/LinuxTimerComponentImplTaskDelay.cpp b/Svc/LinuxTimer/LinuxTimerComponentImplTaskDelay.cpp
new file mode 100644
index 0000000000..f24621a9fb
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimerComponentImplTaskDelay.cpp
@@ -0,0 +1,38 @@
+// ======================================================================
+// \title LinuxTimerImpl.cpp
+// \author tim
+// \brief cpp file for LinuxTimer component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+
+#include
+#include "Fw/Types/BasicTypes.hpp"
+#include
+
+namespace Svc {
+
+ void LinuxTimerComponentImpl::startTimer(NATIVE_INT_TYPE interval) {
+ while (1) {
+ Os::Task::delay(interval);
+ if (this->m_quit) {
+ return;
+ }
+ this->m_timer.take();
+ this->CycleOut_out(0,this->m_timer);
+ }
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/LinuxTimerComponentImplTimerFd.cpp b/Svc/LinuxTimer/LinuxTimerComponentImplTimerFd.cpp
new file mode 100644
index 0000000000..28ad25c774
--- /dev/null
+++ b/Svc/LinuxTimer/LinuxTimerComponentImplTimerFd.cpp
@@ -0,0 +1,64 @@
+// ======================================================================
+// \title LinuxTimerImpl.cpp
+// \author tim
+// \brief cpp file for LinuxTimer component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+
+#include
+#include "Fw/Types/BasicTypes.hpp"
+#include
+#include
+#include
+#include
+
+namespace Svc {
+
+ void LinuxTimerComponentImpl::startTimer(NATIVE_INT_TYPE interval) {
+ int fd;
+ struct itimerspec itval;
+
+ /* Create the timer */
+ fd = timerfd_create (CLOCK_MONOTONIC, 0);
+
+ itval.it_interval.tv_sec = interval/1000;
+ itval.it_interval.tv_nsec = interval*1000000;
+ itval.it_value.tv_sec = interval/1000;
+ itval.it_value.tv_nsec = interval*1000000;
+
+ timerfd_settime (fd, 0, &itval, NULL);
+
+ while (1) {
+ unsigned long long missed;
+ int ret = read (fd, &missed, sizeof (missed));
+ if (-1 == ret) {
+ printf("timer read error: %s\n",strerror(errno));
+ }
+ if (this->m_quit) {
+ itval.it_interval.tv_sec = 0;
+ itval.it_interval.tv_nsec = 0;
+ itval.it_value.tv_sec = 0;
+ itval.it_value.tv_nsec = 0;
+
+ timerfd_settime (fd, 0, &itval, NULL);
+ return;
+ }
+ this->m_timer.take();
+ this->CycleOut_out(0,this->m_timer);
+ }
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/Makefile b/Svc/LinuxTimer/Makefile
new file mode 100644
index 0000000000..484f2ab17c
--- /dev/null
+++ b/Svc/LinuxTimer/Makefile
@@ -0,0 +1,15 @@
+# This Makefile goes in each module, and allows building of an individual module library.
+# It is expected that each developer will add targets of their own for building and running
+# tests, for example.
+
+# derive module name from directory
+
+MODULE_DIR = Svc/LinuxTimer
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
+# Add module specific targets here
\ No newline at end of file
diff --git a/Svc/LinuxTimer/SDFLIGHT_ac_sloc.txt b/Svc/LinuxTimer/SDFLIGHT_ac_sloc.txt
new file mode 100644
index 0000000000..53f046fb70
--- /dev/null
+++ b/Svc/LinuxTimer/SDFLIGHT_ac_sloc.txt
@@ -0,0 +1,4 @@
+ sloc ncsl comments ;, file
+ 159 90 39 27 /home/tcanham/source/leonardo-fsw/Svc/LinuxTimer/LinuxTimerComponentAc.cpp
+ 170 57 84 17 /home/tcanham/source/leonardo-fsw/Svc/LinuxTimer/LinuxTimerComponentAc.hpp
+ 329 147 123 44 total [ncsl:sloc 44%]
diff --git a/Svc/LinuxTimer/SDFLIGHT_written_sloc.txt b/Svc/LinuxTimer/SDFLIGHT_written_sloc.txt
new file mode 100644
index 0000000000..fcb6129de9
--- /dev/null
+++ b/Svc/LinuxTimer/SDFLIGHT_written_sloc.txt
@@ -0,0 +1,4 @@
+ sloc ncsl comments ;, file
+ 62 30 22 3 /home/tcanham/source/leonardo-fsw/Svc/LinuxTimer/LinuxTimerComponentImplCommon.cpp
+ 72 26 34 8 /home/tcanham/source/leonardo-fsw/Svc/LinuxTimer/LinuxTimerComponentImpl.hpp
+ 134 56 56 11 total [ncsl:sloc 41%]
diff --git a/Svc/LinuxTimer/SDFLIGHT_xml_sloc.txt b/Svc/LinuxTimer/SDFLIGHT_xml_sloc.txt
new file mode 100644
index 0000000000..fca5c83a27
--- /dev/null
+++ b/Svc/LinuxTimer/SDFLIGHT_xml_sloc.txt
@@ -0,0 +1,3 @@
+ sloc ncsl comments ;, file
+ 21 19 0 4 /home/tcanham/source/leonardo-fsw/Svc/LinuxTimer/LinuxTimerComponentAi.xml
+ 21 19 0 4 total [ncsl:sloc 86%]
diff --git a/Svc/LinuxTimer/docs/LinuxTimer.md b/Svc/LinuxTimer/docs/LinuxTimer.md
new file mode 100644
index 0000000000..e91e3f97f1
--- /dev/null
+++ b/Svc/LinuxTimer/docs/LinuxTimer.md
@@ -0,0 +1,5 @@
+LinuxTimer Component Dictionary
+# LinuxTimer Component Dictionary
+
+
+
diff --git a/Svc/LinuxTimer/mod.mk b/Svc/LinuxTimer/mod.mk
new file mode 100644
index 0000000000..b8ffb9e064
--- /dev/null
+++ b/Svc/LinuxTimer/mod.mk
@@ -0,0 +1,37 @@
+#
+# Copyright 2004-2008, by the California Institute of Technology.
+# ALL RIGHTS RESERVED. United States Government Sponsorship
+# acknowledged. Any commercial use must be negotiated with the Office
+# of Technology Transfer at the California Institute of Technology.
+#
+# Information included herein is controlled under the International
+# Traffic in Arms Regulations ("ITAR") by the U.S. Department of State.
+# Export or transfer of this information to a Foreign Person or foreign
+# entity requires an export license issued by the U.S. State Department
+# or an ITAR exemption prior to the export or transfer.
+#
+
+# This is a template for the mod.mk file that goes in each module
+# and each module's subdirectories.
+# With a fresh checkout, "make gen_make" should be invoked. It should also be
+# run if any of the variables are updated. Any unused variables can
+# be deleted from the file.
+
+# There are some standard files that are included for reference
+SRC = LinuxTimerComponentImplCommon.cpp LinuxTimerComponentAi.xml
+
+SRC_LINUX = LinuxTimerComponentImplTimerFd.cpp
+
+SRC_CYGWIN = LinuxTimerComponentImplTaskDelay.cpp
+
+SRC_DARWIN = LinuxTimerComponentImplTaskDelay.cpp
+
+SRC_RASPIAN = LinuxTimerComponentImplTimerFd.cpp
+
+HDR = LinuxTimerComponentImpl.hpp
+
+SUBDIRS = test
+
+
+
+SRC_LINUXRT = LinuxTimerComponentImplTimerFd.cpp
diff --git a/Svc/LinuxTimer/test/mod.mk b/Svc/LinuxTimer/test/mod.mk
new file mode 100644
index 0000000000..2b9ea41e51
--- /dev/null
+++ b/Svc/LinuxTimer/test/mod.mk
@@ -0,0 +1 @@
+SUBDIRS = ut
\ No newline at end of file
diff --git a/Svc/LinuxTimer/test/ut/GTestBase.cpp b/Svc/LinuxTimer/test/ut/GTestBase.cpp
new file mode 100644
index 0000000000..b196f8dc93
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/GTestBase.cpp
@@ -0,0 +1,93 @@
+// ======================================================================
+// \title LinuxTimer/test/ut/GTestBase.cpp
+// \author Auto-generated
+// \brief cpp file for LinuxTimer component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "GTestBase.hpp"
+
+namespace Svc {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ LinuxTimerGTestBase ::
+ LinuxTimerGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+ LinuxTimerTesterBase (
+#if FW_OBJECT_NAMES == 1
+ compName,
+#endif
+ maxHistorySize
+ )
+ {
+
+ }
+
+ LinuxTimerGTestBase ::
+ ~LinuxTimerGTestBase(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerGTestBase ::
+ assertFromPortHistory_size(
+ const char *const __ISF_callSiteFileName,
+ const U32 __ISF_callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistorySize)
+ << "\n"
+ << " File: " << __ISF_callSiteFileName << "\n"
+ << " Line: " << __ISF_callSiteLineNumber << "\n"
+ << " Value: Total size of all from port histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistorySize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: CycleOut
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerGTestBase ::
+ assert_from_CycleOut_size(
+ const char *const __ISF_callSiteFileName,
+ const U32 __ISF_callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistory_CycleOut->size())
+ << "\n"
+ << " File: " << __ISF_callSiteFileName << "\n"
+ << " Line: " << __ISF_callSiteLineNumber << "\n"
+ << " Value: Size of history for from_CycleOut\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistory_CycleOut->size() << "\n";
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/test/ut/GTestBase.hpp b/Svc/LinuxTimer/test/ut/GTestBase.hpp
new file mode 100644
index 0000000000..bd0b33f0fb
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/GTestBase.hpp
@@ -0,0 +1,117 @@
+// ======================================================================
+// \title LinuxTimer/test/ut/GTestBase.hpp
+// \author Auto-generated
+// \brief hpp file for LinuxTimer component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef LinuxTimer_GTEST_BASE_HPP
+#define LinuxTimer_GTEST_BASE_HPP
+
+#include "TesterBase.hpp"
+#include "gtest/gtest.h"
+
+// ----------------------------------------------------------------------
+// Macros for typed user from port history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_FROM_PORT_HISTORY_SIZE(size) \
+ this->assertFromPortHistory_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_CycleOut_SIZE(size) \
+ this->assert_from_CycleOut_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_CycleOut(index, _cycleStart) \
+ { \
+ ASSERT_GT(this->fromPortHistory_CycleOut->size(), static_cast(index)) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Index into history of from_CycleOut\n" \
+ << " Expected: Less than size of history (" \
+ << this->fromPortHistory_CycleOut->size() << ")\n" \
+ << " Actual: " << index << "\n"; \
+ const FromPortEntry_CycleOut& _e = \
+ this->fromPortHistory_CycleOut->at(index); \
+ ASSERT_EQ(_cycleStart, _e.cycleStart) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Value of argument cycleStart at index " \
+ << index \
+ << " in history of from_CycleOut\n" \
+ << " Expected: " << _cycleStart << "\n" \
+ << " Actual: " << _e.cycleStart << "\n"; \
+ }
+
+namespace Svc {
+
+ //! \class LinuxTimerGTestBase
+ //! \brief Auto-generated base class for LinuxTimer component Google Test harness
+ //!
+ class LinuxTimerGTestBase :
+ public LinuxTimerTesterBase
+ {
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object LinuxTimerGTestBase
+ //!
+ LinuxTimerGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object LinuxTimerGTestBase
+ //!
+ virtual ~LinuxTimerGTestBase(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void assertFromPortHistory_size(
+ const char *const __ISF_callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __ISF_callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From port: CycleOut
+ // ----------------------------------------------------------------------
+
+ void assert_from_CycleOut_size(
+ const char *const __ISF_callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __ISF_callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ };
+
+} // end namespace Svc
+
+#endif
diff --git a/Svc/LinuxTimer/test/ut/Tester.cpp b/Svc/LinuxTimer/test/ut/Tester.cpp
new file mode 100644
index 0000000000..c944c1590b
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/Tester.cpp
@@ -0,0 +1,108 @@
+// ======================================================================
+// \title LinuxTimer.hpp
+// \author tim
+// \brief cpp file for LinuxTimer test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "Tester.hpp"
+
+#define INSTANCE 0
+#define MAX_HISTORY_SIZE 10
+
+namespace Svc {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ Tester ::
+ Tester(void) :
+#if FW_OBJECT_NAMES == 1
+ LinuxTimerGTestBase("Tester", MAX_HISTORY_SIZE),
+ component("LinuxTimer")
+#else
+ LinuxTimerGTestBase(MAX_HISTORY_SIZE),
+ component()
+#endif
+ ,m_numCalls(0)
+ {
+ this->initComponents();
+ this->connectPorts();
+ }
+
+ Tester ::
+ ~Tester(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ runCycles(void)
+ {
+ this->m_numCalls = 5;
+ this->component.startTimer(1000);
+ }
+
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ from_CycleOut_handler(
+ const NATIVE_INT_TYPE portNum,
+ Svc::TimerVal &cycleStart
+ )
+ {
+ printf("TICK\n");
+
+ if (--this->m_numCalls == 0) {
+ this->component.quit();
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ connectPorts(void)
+ {
+
+ // CycleOut
+ this->component.set_CycleOut_OutputPort(
+ 0,
+ this->get_from_CycleOut(0)
+ );
+
+
+
+
+ }
+
+ void Tester ::
+ initComponents(void)
+ {
+ this->init();
+ this->component.init(
+ INSTANCE
+ );
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/test/ut/Tester.hpp b/Svc/LinuxTimer/test/ut/Tester.hpp
new file mode 100644
index 0000000000..581ba69730
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/Tester.hpp
@@ -0,0 +1,99 @@
+// ======================================================================
+// \title LinuxTimer/test/ut/Tester.hpp
+// \author tim
+// \brief hpp file for LinuxTimer test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef TESTER_HPP
+#define TESTER_HPP
+
+#include "GTestBase.hpp"
+#include "Svc/LinuxTimer/LinuxTimerComponentImpl.hpp"
+
+namespace Svc {
+
+ class Tester :
+ public LinuxTimerGTestBase
+ {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ public:
+
+ //! Construct object Tester
+ //!
+ Tester(void);
+
+ //! Destroy object Tester
+ //!
+ ~Tester(void);
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ //! To do
+ //!
+ void runCycles(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler for from_CycleOut
+ //!
+ void from_CycleOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Svc::TimerVal &cycleStart /*!< Cycle start timer value*/
+ );
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ //! Connect ports
+ //!
+ void connectPorts(void);
+
+ //! Initialize components
+ //!
+ void initComponents(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Variables
+ // ----------------------------------------------------------------------
+
+ //! The component under test
+ //!
+ LinuxTimerComponentImpl component;
+
+ NATIVE_INT_TYPE m_numCalls;
+
+ };
+
+} // end namespace Svc
+
+#endif
diff --git a/Svc/LinuxTimer/test/ut/TesterBase.cpp b/Svc/LinuxTimer/test/ut/TesterBase.cpp
new file mode 100644
index 0000000000..4566f60dde
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/TesterBase.cpp
@@ -0,0 +1,194 @@
+// ======================================================================
+// \title LinuxTimer/test/ut/TesterBase.cpp
+// \author Auto-generated
+// \brief cpp file for LinuxTimer component test harness base class
+//
+// \copyright
+// Copyright 2009-2016, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include
+#include
+#include "TesterBase.hpp"
+
+namespace Svc {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ LinuxTimerTesterBase ::
+ LinuxTimerTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+#if FW_OBJECT_NAMES == 1
+ Fw::PassiveComponentBase(compName)
+#else
+ Fw::PassiveComponentBase()
+#endif
+ {
+ // Initialize histories for typed user output ports
+ this->fromPortHistory_CycleOut =
+ new History(maxHistorySize);
+ // Clear history
+ this->clearHistory();
+ }
+
+ LinuxTimerTesterBase ::
+ ~LinuxTimerTesterBase(void)
+ {
+ }
+
+ void LinuxTimerTesterBase ::
+ init(
+ const NATIVE_INT_TYPE instance
+ )
+ {
+
+ // Initialize base class
+
+ Fw::PassiveComponentBase::init(instance);
+
+ // Attach input port CycleOut
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_CycleOut();
+ ++_port
+ ) {
+
+ this->m_from_CycleOut[_port].init();
+ this->m_from_CycleOut[_port].addCallComp(
+ this,
+ from_CycleOut_static
+ );
+ this->m_from_CycleOut[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_CycleOut[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_CycleOut[_port].setObjName(_portName);
+#endif
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ NATIVE_INT_TYPE LinuxTimerTesterBase ::
+ getNum_from_CycleOut(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_CycleOut);
+ }
+
+
+ // ----------------------------------------------------------------------
+ // Getters for from ports
+ // ----------------------------------------------------------------------
+
+ Svc::InputCyclePort *LinuxTimerTesterBase ::
+ get_from_CycleOut(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_CycleOut(),static_cast(portNum));
+ return &this->m_from_CycleOut[portNum];
+ }
+
+ // ----------------------------------------------------------------------
+ // Static functions for from ports
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerTesterBase ::
+ from_CycleOut_static(
+ Fw::PassiveComponentBase *const callComp,
+ const NATIVE_INT_TYPE portNum,
+ Svc::TimerVal &cycleStart
+ )
+ {
+ FW_ASSERT(callComp);
+ LinuxTimerTesterBase* _testerBase =
+ static_cast(callComp);
+ _testerBase->from_CycleOut_handlerBase(
+ portNum,
+ cycleStart
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerTesterBase ::
+ clearFromPortHistory(void)
+ {
+ this->fromPortHistorySize = 0;
+ this->fromPortHistory_CycleOut->clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: CycleOut
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerTesterBase ::
+ pushFromPortEntry_CycleOut(
+ Svc::TimerVal &cycleStart
+ )
+ {
+ FromPortEntry_CycleOut _e = {
+ cycleStart
+ };
+ this->fromPortHistory_CycleOut->push_back(_e);
+ ++this->fromPortHistorySize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler base functions for from ports
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerTesterBase ::
+ from_CycleOut_handlerBase(
+ const NATIVE_INT_TYPE portNum,
+ Svc::TimerVal &cycleStart
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_from_CycleOut(),static_cast(portNum));
+ this->from_CycleOut_handler(
+ portNum,
+ cycleStart
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // History
+ // ----------------------------------------------------------------------
+
+ void LinuxTimerTesterBase ::
+ clearHistory()
+ {
+ this->clearFromPortHistory();
+ }
+
+} // end namespace Svc
diff --git a/Svc/LinuxTimer/test/ut/TesterBase.hpp b/Svc/LinuxTimer/test/ut/TesterBase.hpp
new file mode 100644
index 0000000000..b4c68a4730
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/TesterBase.hpp
@@ -0,0 +1,256 @@
+// ======================================================================
+// \title LinuxTimer/test/ut/TesterBase.hpp
+// \author Auto-generated
+// \brief hpp file for LinuxTimer component test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef LinuxTimer_TESTER_BASE_HPP
+#define LinuxTimer_TESTER_BASE_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Svc {
+
+ //! \class LinuxTimerTesterBase
+ //! \brief Auto-generated base class for LinuxTimer component test harness
+ //!
+ class LinuxTimerTesterBase :
+ public Fw::PassiveComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Initialization
+ // ----------------------------------------------------------------------
+
+ //! Initialize object LinuxTimerTesterBase
+ //!
+ virtual void init(
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for 'from' ports
+ // Connect these input ports to the output ports under test
+ // ----------------------------------------------------------------------
+
+ //! Get the port that receives input from CycleOut
+ //!
+ //! \return from_CycleOut[portNum]
+ //!
+ Svc::InputCyclePort* get_from_CycleOut(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object LinuxTimerTesterBase
+ //!
+ LinuxTimerTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object LinuxTimerTesterBase
+ //!
+ virtual ~LinuxTimerTesterBase(void);
+
+ // ----------------------------------------------------------------------
+ // Test history
+ // ----------------------------------------------------------------------
+
+ protected:
+
+ //! \class History
+ //! \brief A history of port inputs
+ //!
+ template class History {
+
+ public:
+
+ //! Create a History
+ //!
+ History(
+ const U32 maxSize /*!< The maximum history size*/
+ ) :
+ numEntries(0),
+ maxSize(maxSize)
+ {
+ this->entries = new T[maxSize];
+ }
+
+ //! Destroy a History
+ //!
+ ~History() {
+ delete[] this->entries;
+ }
+
+ //! Clear the history
+ //!
+ void clear() { this->numEntries = 0; }
+
+ //! Push an item onto the history
+ //!
+ void push_back(
+ T entry /*!< The item*/
+ ) {
+ FW_ASSERT(this->numEntries < this->maxSize);
+ entries[this->numEntries++] = entry;
+ }
+
+ //! Get an item at an index
+ //!
+ //! \return The item at index i
+ //!
+ T at(
+ const U32 i /*!< The index*/
+ ) const {
+ FW_ASSERT(i < this->numEntries);
+ return entries[i];
+ }
+
+ //! Get the number of entries in the history
+ //!
+ //! \return The number of entries in the history
+ //!
+ U32 size(void) const { return this->numEntries; }
+
+ private:
+
+ //! The number of entries in the history
+ //!
+ U32 numEntries;
+
+ //! The maximum history size
+ //!
+ const U32 maxSize;
+
+ //! The entries
+ //!
+ T *entries;
+
+ };
+
+ //! Clear all history
+ //!
+ void clearHistory(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Handler prototypes for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler prototype for from_CycleOut
+ //!
+ virtual void from_CycleOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Svc::TimerVal &cycleStart /*!< Cycle start timer value*/
+ ) = 0;
+
+ //! Handler base function for from_CycleOut
+ //!
+ void from_CycleOut_handlerBase(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Svc::TimerVal &cycleStart /*!< Cycle start timer value*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Clear from port history
+ //!
+ void clearFromPortHistory(void);
+
+ //! The total number of from port entries
+ //!
+ U32 fromPortHistorySize;
+
+ //! Push an entry on the history for from_CycleOut
+ void pushFromPortEntry_CycleOut(
+ Svc::TimerVal &cycleStart /*!< Cycle start timer value*/
+ );
+
+ //! A history entry for from_CycleOut
+ //!
+ typedef struct {
+ Svc::TimerVal cycleStart;
+ } FromPortEntry_CycleOut;
+
+ //! The history for from_CycleOut
+ //!
+ History
+ *fromPortHistory_CycleOut;
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ //! Get the number of from_CycleOut ports
+ //!
+ //! \return The number of from_CycleOut ports
+ //!
+ NATIVE_INT_TYPE getNum_from_CycleOut(void) const;
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ //! From port connected to CycleOut
+ //!
+ Svc::InputCyclePort m_from_CycleOut[1];
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Static functions for output ports
+ // ----------------------------------------------------------------------
+
+ //! Static function for port from_CycleOut
+ //!
+ static void from_CycleOut_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Svc::TimerVal &cycleStart /*!< Cycle start timer value*/
+ );
+
+ };
+
+} // end namespace Svc
+
+#endif
diff --git a/Svc/LinuxTimer/test/ut/main.cpp b/Svc/LinuxTimer/test/ut/main.cpp
new file mode 100644
index 0000000000..753f438205
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/main.cpp
@@ -0,0 +1,17 @@
+// ----------------------------------------------------------------------
+// Main.cpp
+// ----------------------------------------------------------------------
+
+#include "Tester.hpp"
+#include
+
+TEST(Nominal, InitTest) {
+ TEST_CASE(103.1.1,"Cycle Test");
+ Svc::Tester tester;
+ tester.runCycles();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/Svc/LinuxTimer/test/ut/mod.mk b/Svc/LinuxTimer/test/ut/mod.mk
new file mode 100644
index 0000000000..adb0517320
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/mod.mk
@@ -0,0 +1,36 @@
+#
+# Copyright 2004-2008, by the California Institute of Technology.
+# ALL RIGHTS RESERVED. United States Government Sponsorship
+# acknowledged. Any commercial use must be negotiated with the Office
+# of Technology Transfer at the California Institute of Technology.
+#
+# Information included herein is controlled under the International
+# Traffic in Arms Regulations ("ITAR") by the U.S. Department of State.
+# Export or transfer of this information to a Foreign Person or foreign
+# entity requires an export license issued by the U.S. State Department
+# or an ITAR exemption prior to the export or transfer.
+#
+
+# This is a template for the mod.mk file that goes in each module
+# and each module's subdirectories.
+# With a fresh checkout, "make gen_make" should be invoked. It should also be
+# run if any of the variables are updated. Any unused variables can
+# be deleted from the file.
+
+# There are some standard files that are included for reference
+
+TEST_SRC = TesterBase.cpp \
+ GTestBase.cpp \
+ Tester.cpp \
+ main.cpp
+
+TEST_MODS = Svc/LinuxTimer \
+ Fw/Comp \
+ Fw/Obj \
+ Fw/Time \
+ Fw/Types \
+ Svc/Sched \
+ Svc/Cycle \
+ Fw/Port \
+ Os \
+ gtest
diff --git a/Svc/LinuxTimer/test/ut/runtest_CYGWIN b/Svc/LinuxTimer/test/ut/runtest_CYGWIN
new file mode 100644
index 0000000000..122b62e66e
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/runtest_CYGWIN
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+$(dirname "$0")/runtest_all $1
\ No newline at end of file
diff --git a/Svc/LinuxTimer/test/ut/runtest_DARWIN b/Svc/LinuxTimer/test/ut/runtest_DARWIN
new file mode 100644
index 0000000000..122b62e66e
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/runtest_DARWIN
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+$(dirname "$0")/runtest_all $1
\ No newline at end of file
diff --git a/Svc/LinuxTimer/test/ut/runtest_LINUX b/Svc/LinuxTimer/test/ut/runtest_LINUX
new file mode 100644
index 0000000000..122b62e66e
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/runtest_LINUX
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+$(dirname "$0")/runtest_all $1
\ No newline at end of file
diff --git a/Svc/LinuxTimer/test/ut/runtest_all b/Svc/LinuxTimer/test/ut/runtest_all
new file mode 100644
index 0000000000..e19590303c
--- /dev/null
+++ b/Svc/LinuxTimer/test/ut/runtest_all
@@ -0,0 +1,6 @@
+#!/bin/sh
+LOC=${BUILD_ROOT}/Svc/LinuxTimer/test/ut
+cd ${LOC}
+echo "Running ${LOC}/$1/test_ut"
+${LOC}/$1/test_ut
+
diff --git a/Svc/PassiveConsoleTextLogger/mod.mk b/Svc/PassiveConsoleTextLogger/mod.mk
index 774babe964..b813d3a0ee 100644
--- a/Svc/PassiveConsoleTextLogger/mod.mk
+++ b/Svc/PassiveConsoleTextLogger/mod.mk
@@ -18,12 +18,8 @@ SRC_CYGWIN = Stub/PrintfLoggerImplStub.cpp
SRC_LINUX = Stub/PrintfLoggerImplStub.cpp
-SRC_TIMSP430 = MSP/TextLoggerImplMsp.cpp
-
SRC_DARWIN = Stub/PrintfLoggerImplStub.cpp
-SRC_BAERAD750 = VxWorks/VxWorksLoggerImpl.cpp
-
-SRC_SPHINX = VxWorks/VxWorksLoggerImpl.cpp
+SRC_RASPIAN = Stub/PrintfLoggerImplStub.cpp
HDR = ConsoleTextLoggerImpl.hpp
diff --git a/Svc/SocketGndIf/README b/Svc/SocketGndIf/README
old mode 100644
new mode 100755
diff --git a/Svc/SocketGndIf/SvcSocketGndIfImpl.cpp b/Svc/SocketGndIf/SvcSocketGndIfImpl.cpp
index 60aa0a968c..456627fc9a 100644
--- a/Svc/SocketGndIf/SvcSocketGndIfImpl.cpp
+++ b/Svc/SocketGndIf/SvcSocketGndIfImpl.cpp
@@ -30,6 +30,9 @@
#error Unsupported OS!
#endif
+//#define DEBUG_PRINT(x,...) printf(x,##__VA_ARGS__); fflush(stdout)
+#define DEBUG_PRINT(x,...)
+
namespace Svc {
/////////////////////////////////////////////////////////////////////
@@ -81,10 +84,14 @@ namespace Svc {
,m_connectionFd(-1)
,m_udpFd(-1)
,m_udpConnectionFd(-1)
+ ,m_priority(1)
+ ,m_stackSize(1024)
,port_number(0)
,hostname(NULL)
+ ,m_cpuAffinity(-1)
,useDefaultHeader(true)
,m_prot(SEND_UDP)
+ ,m_portConfigured(false)
{
}
@@ -95,6 +102,41 @@ namespace Svc {
SocketGndIfImpl::~SocketGndIfImpl() {
}
+ void SocketGndIfImpl ::
+ GNDIF_ENABLE_INTERFACE_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq
+ )
+ {
+ if (m_portConfigured) {
+
+ this->startSocketTask(this->m_priority,
+ this->m_stackSize,
+ this->port_number,
+ this->hostname,
+ this->m_prot,
+ this->m_cpuAffinity);
+
+ this->cmdResponse_out(opCode, cmdSeq, Fw::COMMAND_OK);
+ } else {
+ this->cmdResponse_out(opCode, cmdSeq, Fw::COMMAND_EXECUTION_ERROR);
+ }
+ }
+
+ void SocketGndIfImpl ::
+ setSocketTaskProperties(I32 priority, NATIVE_INT_TYPE stackSize, U32 portNumber, char* hostname, DownlinkProt prot, NATIVE_INT_TYPE cpuAffinity)
+ {
+
+ this->m_priority = priority;
+ this->m_stackSize = stackSize;
+ this->port_number = portNumber;
+ this->hostname = hostname;
+ this->m_prot = prot;
+ this->m_cpuAffinity = cpuAffinity;
+
+ this->m_portConfigured = true;
+ }
+
void SocketGndIfImpl::startSocketTask(I32 priority, NATIVE_INT_TYPE stackSize, U32 port_number, char* hostname, DownlinkProt prot, NATIVE_INT_TYPE cpuAffinity) {
Fw::EightyCharString name("ScktRead");
this->port_number = port_number;
@@ -120,9 +162,13 @@ namespace Svc {
int sockAddrSize;
char ip[100];
char buf[256];
-
+ //Closes any previously existing socket connections
+ //this allows the openSocket call to be retry-safe
+ this->m_connectionFd = -1;
+ close(this->m_udpFd);
+ close(this->m_socketFd);
if ((this->m_socketFd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
- (void) printf("Socket error: %s\n",strerror(errno));
+ DEBUG_PRINT("Socket error: %s\n",strerror(errno));
return;
}
@@ -132,7 +178,9 @@ namespace Svc {
this->m_udpFd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == this->m_udpFd) {
- (void) printf("UDP Socket error: %s\n",strerror(errno));
+ //Was already open
+ close(this->m_socketFd);
+ DEBUG_PRINT("UDP Socket error: %s\n",strerror(errno));
return;
}
@@ -150,7 +198,7 @@ namespace Svc {
// set socket write to timeout after 1 sec
if (setsockopt (this->m_socketFd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
sizeof(timeout)) < 0) {
- (void)printf("setsockopt error: %s\n",strerror(errno));
+ DEBUG_PRINT("setsockopt error: %s\n",strerror(errno));
}
// Fill in data structure with server information
@@ -174,7 +222,10 @@ namespace Svc {
struct hostent *he;
struct in_addr **addr_list;
if ((he = gethostbyname(this->hostname)) == NULL) {
- (void)printf("Unable to get hostname\n");
+ DEBUG_PRINT("Unable to get hostname\n");
+ //Force connect to close
+ close(this->m_udpFd);
+ close(this->m_socketFd);
return;
}
@@ -187,6 +238,9 @@ namespace Svc {
servaddr.sin_addr.s_addr = inet_addr(ip);
if (connect(this->m_socketFd, (struct sockaddr *) &servaddr, sockAddrSize) < 0) {
+ //Force connect to close
+ close(this->m_udpFd);
+ close(this->m_socketFd);
this->m_socketFd = -1;
return;
}
@@ -197,11 +251,11 @@ namespace Svc {
#else
if (socketWrite(this->m_socketFd, (U8*)buf, strnlen(buf, 13)) < 0) {
#endif
- (void) printf("write error on port %d \n", port);
+ DEBUG_PRINT("write error on port %d \n", port);
return;
}
this->log_ACTIVITY_HI_ConnectedToServer(port);
- (void) printf("Sent register FSW string to ground\n");
+ DEBUG_PRINT("Sent register FSW string to ground\n");
//m_connectionFd is set so m_socketFd can register ISF before other tasks try to write data to ground
this->m_connectionFd = this->m_socketFd;
}
@@ -241,7 +295,7 @@ namespace Svc {
// first, read packet delimiter
bytesRead = socketRead(comp->m_socketFd,(U8*)&packetDelimiter,sizeof(packetDelimiter));
if( -1 == bytesRead ) {
- (void) printf("Delim read error: %s",strerror(errno));
+ DEBUG_PRINT("Delim read error: %s",strerror(errno));
break;
}
@@ -251,17 +305,17 @@ namespace Svc {
}
if (bytesRead != sizeof(packetDelimiter)) {
- (void) printf("Didn't get right pd size: %ld\n",(long int)bytesRead);
+ DEBUG_PRINT("Didn't get right pd size: %ld\n",(long int)bytesRead);
}
// correct for network order
packetDelimiter = ntohl(packetDelimiter);
// if magic number to quit, exit loop
if (packetDelimiter == 0xA5A5A5A5) {
- (void) printf("packetDelimiter = 0x%x\n", packetDelimiter);
- //break;
+ DEBUG_PRINT("packetDelimiter = 0x%x\n", packetDelimiter);
+ break;
} else if (packetDelimiter != SocketGndIfImpl::PKT_DELIM) {
- (void) printf("Unexpected delimiter 0x%08X\n",packetDelimiter);
+ DEBUG_PRINT("Unexpected delimiter 0x%08X\n",packetDelimiter);
// just keep reading until a delimiter is found
continue;
}
@@ -269,7 +323,7 @@ namespace Svc {
// now read packet size
bytesRead = socketRead(comp->m_connectionFd,(U8*)&packetSize,sizeof(packetSize));
if( -1 == bytesRead ) {
- (void) printf("Size read error: %s",strerror(errno));
+ DEBUG_PRINT("Size read error: %s",strerror(errno));
break;
}
@@ -279,7 +333,7 @@ namespace Svc {
}
if (bytesRead != sizeof(packetSize)) {
- (void) printf("Didn't get right ps size!\n");
+ DEBUG_PRINT("Didn't get right ps size!\n");
}
// correct for network order
@@ -297,7 +351,7 @@ namespace Svc {
// check size of command
if (packetSize > FW_COM_BUFFER_MAX_SIZE) {
comp->log_WARNING_HI_GNDIF_ReceiveError(GNDIF_PacketTooBig, comp->port_number);
- (void) printf("Packet to large! :%d\n",packetSize);
+ DEBUG_PRINT("Packet to large! :%d\n",packetSize);
// might as well wait for the next packet
break;
}
@@ -306,7 +360,7 @@ namespace Svc {
bytesRead = socketRead(comp->m_socketFd,(U8*)buf+sizeof(packetDesc),packetSize-sizeof(packetDesc));
if (-1 == bytesRead) {
comp->log_WARNING_HI_GNDIF_ReceiveError(GNDIF_PacketReadError, comp->port_number);
- (void) printf("Size read error: %s\n",strerror(errno));
+ DEBUG_PRINT("Size read error: %s\n",strerror(errno));
break;
}
@@ -326,7 +380,7 @@ namespace Svc {
// check read size
if (bytesRead != (ssize_t)packetSize) {
comp->log_WARNING_HI_GNDIF_ReceiveError(GNDIF_ReadSizeMismatch, comp->port_number);
- (void) printf("Read size mismatch: A: %ld E: %d\n",(long int)bytesRead,packetSize);
+ DEBUG_PRINT("Read size mismatch: A: %ld E: %d\n",(long int)bytesRead,packetSize);
}
@@ -348,12 +402,12 @@ namespace Svc {
bytesRead = socketRead(comp->m_socketFd, data_ptr, packetSize - sizeof(packetDesc));
if (-1 == bytesRead) {
comp->log_WARNING_HI_GNDIF_ReceiveError(GNDIF_PacketReadError, comp->port_number);
- (void) printf("Size read error: %s\n",strerror(errno));
+ DEBUG_PRINT("Size read error: %s\n",strerror(errno));
break;
}
// for(uint32_t i =0; i < bytesRead; i++){
- // (void) printf("IN_DATA:%02x\n", data_ptr[i]);
+ // DEBUG_PRINT("IN_DATA:%02x\n", data_ptr[i]);
// }
if (comp->isConnected_fileUplinkBufferSendOut_OutputPort(0)) {
@@ -377,7 +431,8 @@ namespace Svc {
comp->log_WARNING_LO_LostConnectionToServer(comp->port_number);
while (comp->m_connectionFd == -1){
Os::Task::delay(5000);
- comp->openSocket(comp->port_number);
+ DEBUG_PRINT("Reopen socket\n");
+ comp->openSocket(comp->port_number);
}
}
else {
@@ -421,10 +476,10 @@ namespace Svc {
(void)socketWrite(this->m_connectionFd,(U8*)buf, packet_size);
//Send msg
(void)socketWrite(this->m_connectionFd,(U8*)fwBuffer.getdata(), buffer_size);
- //printf("PACKET BYTES SENT: %d\n", bytes_sent);
+ //DEBUG_PRINT("PACKET BYTES SENT: %d\n", bytes_sent);
// for(uint32_t i = 0; i < bytes_sent; i++){
- // printf("%02x\n",((U8*)fwBuffer.getdata())[i]);
+ // DEBUG_PRINT("%02x\n",((U8*)fwBuffer.getdata())[i]);
// }
this->fileDownlinkBufferSendOut_out(0,fwBuffer);
@@ -444,7 +499,7 @@ namespace Svc {
data_net_size = htonl(data.getBuffLength());
// check to see if someone is connected
if (this->m_connectionFd != -1) {
- //(void) printf("Trying to send %ld bytes to ground.\n",data.getBuffLength() + header_size + sizeof(data_size));
+ //DEBUG_PRINT("Trying to send %ld bytes to ground.\n",data.getBuffLength() + header_size + sizeof(data_size));
if (this->useDefaultHeader) {
strncpy(buf, "A5A5 GUI ", sizeof(buf));
}
@@ -468,13 +523,13 @@ namespace Svc {
sizeof(m_servAddr));
}
if (bytes_sent < 0) {
- (void) printf("write error on port %d: %s\n", this->port_number, strerror(errno));
+ DEBUG_PRINT("write error on port %d: %s\n", this->port_number, strerror(errno));
return;
}
else if (bytes_sent != (I32)(header_size + data_size + sizeof(data_size))) {
- (void) printf("Not all data sent. E: %lu A: %d\n", (long unsigned int)(header_size + data_size + sizeof(data_size)), bytes_sent);
+ DEBUG_PRINT("Not all data sent. E: %lu A: %d\n", (long unsigned int)(header_size + data_size + sizeof(data_size)), bytes_sent);
} else {
-// (void) printf("Sent %d bytes to ground.\n",bytes_sent);
+// DEBUG_PRINT("Sent %d bytes to ground.\n",bytes_sent);
}
}
}
diff --git a/Svc/SocketGndIf/SvcSocketGndIfImpl.hpp b/Svc/SocketGndIf/SvcSocketGndIfImpl.hpp
index b73223464a..6841d71e8a 100644
--- a/Svc/SocketGndIf/SvcSocketGndIfImpl.hpp
+++ b/Svc/SocketGndIf/SvcSocketGndIfImpl.hpp
@@ -24,6 +24,8 @@ namespace Svc {
SEND_TCP
};
+ void setSocketTaskProperties(I32 priority, NATIVE_INT_TYPE stackSize, U32 portNumber, char* hostname, DownlinkProt prot = SEND_UDP, NATIVE_INT_TYPE cpuAffinity = -1);
+
void startSocketTask(NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize, U32 port_number, char* hostname, DownlinkProt prot = SEND_UDP, NATIVE_INT_TYPE cpuAffinity = -1);
void setUseDefaultHeader(bool useDefault);
private:
@@ -39,6 +41,13 @@ namespace Svc {
Fw::Buffer &fwBuffer
);
+ //! Implementation for GNDIF_ENABLE_INTERFACE command handler
+ //! Enable the interface for ground communications
+ void GNDIF_ENABLE_INTERFACE_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
static void socketReadTask(void* ptr);
void downlinkPort_handler(NATIVE_INT_TYPE portNum, Fw::ComBuffer &data, U32 context);
Svc::ConnectionStatus isConnected_handler(NATIVE_INT_TYPE portNum);
@@ -49,11 +58,16 @@ namespace Svc {
NATIVE_INT_TYPE m_udpConnectionFd; // !< connection file descriptor
struct sockaddr_in m_servAddr; // !< UDP server
+ I32 m_priority;
+ NATIVE_INT_TYPE m_stackSize;
U32 port_number;
char* hostname;
+ NATIVE_INT_TYPE m_cpuAffinity;
Os::Task socketTask;
bool useDefaultHeader; // Use the default header for downlink, ie "A5A5 GUI "
DownlinkProt m_prot; // is downlink TCP or UDP
+
+ bool m_portConfigured;
};
}
diff --git a/Svc/SocketGndIf/docs/sdd.md b/Svc/SocketGndIf/docs/sdd.md
old mode 100644
new mode 100755
diff --git a/Svc/SocketGndIf/mod.mk b/Svc/SocketGndIf/mod.mk
index b263be4121..8c65ad1162 100644
--- a/Svc/SocketGndIf/mod.mk
+++ b/Svc/SocketGndIf/mod.mk
@@ -23,20 +23,10 @@ SRC =
HDR = SvcSocketGndIfImpl.hpp
-SRC_CWSCP124 = SvcSocketGndIfImpl.cpp
-
-SRC_MXSCS750 = SvcSocketGndIfImpl.cpp
-
-SRC_SMP400K = SvcSocketGndIfImpl.cpp
-
-SRC_BAERAD750 = SvcSocketGndIfImpl.cpp
-
-SRC_SPHINX = SvcSocketGndIfImpl.cpp
-
SRC_LINUX = SvcSocketGndIfImpl.cpp
-SRC_WSTS = SvcSocketGndIfImpl.cpp
-
SRC_CYGWIN = SvcSocketGndIfImpl.cpp
SRC_DARWIN = SvcSocketGndIfImpl.cpp
+
+SRC_RASPIAN = SvcSocketGndIfImpl.cpp
diff --git a/docs/Tutorials/MathComponent/MathPorts/Makefile b/docs/Tutorials/MathComponent/MathPorts/Makefile
new file mode 100644
index 0000000000..40e6adc9a1
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathPorts/Makefile
@@ -0,0 +1,10 @@
+# derive module name from directory
+
+MODULE_DIR = Ref/MathPorts
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
diff --git a/docs/Tutorials/MathComponent/MathPorts/MathOpPortAi.xml b/docs/Tutorials/MathComponent/MathPorts/MathOpPortAi.xml
new file mode 100644
index 0000000000..0943fc8295
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathPorts/MathOpPortAi.xml
@@ -0,0 +1,21 @@
+
+
+ Port to perform an operation on two numbers
+
+
+
+
+
+
+
+
+
+
+
+
+
+ operation argument
+
+
+
+
diff --git a/docs/Tutorials/MathComponent/MathPorts/MathResultPortAi.xml b/docs/Tutorials/MathComponent/MathPorts/MathResultPortAi.xml
new file mode 100644
index 0000000000..cdf8af370b
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathPorts/MathResultPortAi.xml
@@ -0,0 +1,11 @@
+
+
+ Port to return the result of a math operation
+
+
+
+ the result of the operation
+
+
+
+
diff --git a/docs/Tutorials/MathComponent/MathPorts/mod.mk b/docs/Tutorials/MathComponent/MathPorts/mod.mk
new file mode 100644
index 0000000000..675654cac3
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathPorts/mod.mk
@@ -0,0 +1,4 @@
+SRC = MathOpPortAi.xml \
+ MathResultPortAi.xml
+
+
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/MathReceiver/Makefile b/docs/Tutorials/MathComponent/MathReceiver/Makefile
new file mode 100644
index 0000000000..b68ddeced5
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/Makefile
@@ -0,0 +1,10 @@
+# derive module name from directory
+
+MODULE_DIR = Ref/MathReceiver
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
diff --git a/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentAi.xml b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentAi.xml
new file mode 100644
index 0000000000..a76cd8836c
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentAi.xml
@@ -0,0 +1,107 @@
+
+ Ref/MathPorts/MathOpPortAi.xml
+ Ref/MathPorts/MathResultPortAi.xml
+ Svc/Sched/SchedPortAi.xml
+ Ref/MathTypes/MathOpSerializableAi.xml
+ Component sending a math operation
+
+
+
+ Port for receiving the math operation
+
+
+
+
+ Port for returning the math result
+
+
+
+
+ The rate group scheduler input
+
+
+
+
+
+
+ Set operation multiplication factor1
+
+
+
+ The first factor
+
+
+
+
+ Clear the event throttle
+
+
+
+
+
+
+ The operation
+
+
+
+
+ The number of MR_SET_FACTOR1 commands
+
+
+
+
+ Factor 1 value
+
+
+
+
+ Factor 2 value
+
+
+
+
+
+
+ Operation factor 1
+
+
+
+ The factor value
+
+
+
+
+
+ Updated factor 2
+
+
+
+ The factor value
+
+
+
+
+
+ Math operation performed
+
+
+
+ The operation
+
+
+
+
+
+ Event throttle cleared
+
+
+
+
+
+
+ A test parameter
+
+
+
+
+
diff --git a/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.cpp b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.cpp
new file mode 100644
index 0000000000..c1f9c8f887
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.cpp
@@ -0,0 +1,166 @@
+// ======================================================================
+// \title MathReceiverImpl.cpp
+// \author tcanham
+// \brief cpp file for MathReceiver component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+
+#include
+#include "Fw/Types/BasicTypes.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ MathReceiverComponentImpl ::
+#if FW_OBJECT_NAMES == 1
+ MathReceiverComponentImpl(
+ const char *const compName
+ ) :
+ MathReceiverComponentBase(compName)
+#else
+ MathReceiverImpl(void)
+#endif
+ ,m_factor1(0.0)
+ ,m_factor1s(0)
+ {
+
+ }
+
+ void MathReceiverComponentImpl ::
+ init(
+ const NATIVE_INT_TYPE queueDepth,
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ MathReceiverComponentBase::init(queueDepth, instance);
+ }
+
+ MathReceiverComponentImpl ::
+ ~MathReceiverComponentImpl(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ // declare result serializable
+ Ref::MathOp op;
+ F32 res = 0.0;
+ switch (operation) {
+ case MATH_ADD:
+ op.setop(ADD);
+ res = (val1 + val2)*this->m_factor1;
+ break;
+ case MATH_SUB:
+ op.setop(SUB);
+ res = (val1 - val2)*this->m_factor1;
+ break;
+ case MATH_MULTIPLY:
+ op.setop(MULT);
+ res = (val1 * val2)*this->m_factor1;
+ break;
+ case MATH_DIVIDE:
+ op.setop(DIVIDE);
+ res = (val1 / val2)*this->m_factor1;
+ break;
+ default:
+ FW_ASSERT(0,operation);
+ break;
+ }
+ Fw::ParamValid valid;
+ res = res/this->paramGet_factor2(valid);
+
+ op.setval1(val1);
+ op.setval2(val2);
+ op.setresult(res);
+ this->log_ACTIVITY_HI_MR_OPERATION_PERFORMED(op);
+ this->tlmWrite_MR_OPERATION(op);
+ this->mathOut_out(0,res);
+ }
+
+ void MathReceiverComponentImpl ::
+ SchedIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context
+ )
+ {
+ QueuedComponentBase::MsgDispatchStatus stat = QueuedComponentBase::MSG_DISPATCH_OK;
+ // empty message queue
+ while (stat != MSG_DISPATCH_EMPTY) {
+ stat = this->doDispatch();
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ void MathReceiverComponentImpl ::
+ MR_SET_FACTOR1_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ F32 val
+ )
+ {
+ this->m_factor1 = val;
+ this->log_ACTIVITY_HI_MR_SET_FACTOR1(val);
+ this->tlmWrite_MR_FACTOR1(val);
+ this->tlmWrite_MR_FACTOR1S(++this->m_factor1s);
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+
+ void MathReceiverComponentImpl ::
+ MR_CLEAR_EVENT_THROTTLE_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq
+ )
+ {
+ // clear throttle
+ this->log_ACTIVITY_HI_MR_SET_FACTOR1_ThrottleClear();
+ // send event that throttle is cleared
+ this->log_ACTIVITY_HI_MR_THROTTLE_CLEARED();
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+
+ void MathReceiverComponentImpl ::
+ parameterUpdated(
+ FwPrmIdType id /*!< The parameter ID*/
+ ) {
+ if (id == PARAMID_FACTOR2) {
+ Fw::ParamValid valid;
+ F32 val = this->paramGet_factor2(valid);
+ this->log_ACTIVITY_HI_MR_UPDATED_FACTOR2(val);
+ }
+ }
+
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.hpp b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.hpp
new file mode 100644
index 0000000000..fb18b4c95b
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/MathReceiverComponentImpl.hpp
@@ -0,0 +1,114 @@
+// ======================================================================
+// \title MathReceiverImpl.hpp
+// \author tcanham
+// \brief hpp file for MathReceiver component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathReceiver_HPP
+#define MathReceiver_HPP
+
+#include "Ref/MathReceiver/MathReceiverComponentAc.hpp"
+
+namespace Ref {
+
+ class MathReceiverComponentImpl :
+ public MathReceiverComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathReceiver
+ //!
+ MathReceiverComponentImpl(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName /*!< The component name*/
+#else
+ void
+#endif
+ );
+
+ //! Initialize object MathReceiver
+ //!
+ void init(
+ const NATIVE_INT_TYPE queueDepth, /*!< The queue depth*/
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ //! Destroy object MathReceiver
+ //!
+ ~MathReceiverComponentImpl(void);
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ //! Handler implementation for mathIn
+ //!
+ void mathIn_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ //! Handler implementation for SchedIn
+ //!
+ void SchedIn_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ NATIVE_UINT_TYPE context /*!< The call order*/
+ );
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ //! Implementation for MR_SET_FACTOR1 command handler
+ //! Set operation multiplication factor1
+ void MR_SET_FACTOR1_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ F32 val /*!< The first factor*/
+ );
+
+ //! Implementation for MR_CLEAR_EVENT_THROTTLE command handler
+ //! Clear the event throttle
+ void MR_CLEAR_EVENT_THROTTLE_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
+ // stored factor1
+ F32 m_factor1;
+ // number of times factor1 has been written
+ U32 m_factor1s;
+
+ void parameterUpdated(
+ FwPrmIdType id /*!< The parameter ID*/
+ );
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathReceiver/mod.mk b/docs/Tutorials/MathComponent/MathReceiver/mod.mk
new file mode 100644
index 0000000000..71f8e72599
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/mod.mk
@@ -0,0 +1,5 @@
+SRC = MathReceiverComponentAi.xml MathReceiverComponentImpl.cpp
+
+HDR = MathReceiverComponentImpl.hpp
+
+SUBDIRS = test
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/mod.mk b/docs/Tutorials/MathComponent/MathReceiver/test/mod.mk
new file mode 100644
index 0000000000..871e2ff159
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/mod.mk
@@ -0,0 +1 @@
+SUBDIRS = ut
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.cpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.cpp
new file mode 100644
index 0000000000..0a36ebb0c0
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.cpp
@@ -0,0 +1,569 @@
+// ======================================================================
+// \title MathReceiver/test/ut/GTestBase.cpp
+// \author Auto-generated
+// \brief cpp file for MathReceiver component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "GTestBase.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ MathReceiverGTestBase ::
+ MathReceiverGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+ MathReceiverTesterBase (
+#if FW_OBJECT_NAMES == 1
+ compName,
+#endif
+ maxHistorySize
+ )
+ {
+
+ }
+
+ MathReceiverGTestBase ::
+ ~MathReceiverGTestBase(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Commands
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertCmdResponse_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ((unsigned long) size, this->cmdResponseHistory->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of command response history\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->cmdResponseHistory->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertCmdResponse(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ const Fw::CommandResponse response
+ )
+ const
+ {
+ ASSERT_LT(index, this->cmdResponseHistory->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into command response history\n"
+ << " Expected: Less than size of command response history ("
+ << this->cmdResponseHistory->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(index);
+ ASSERT_EQ(opCode, e.opCode)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Opcode at index "
+ << index
+ << " in command response history\n"
+ << " Expected: " << opCode << "\n"
+ << " Actual: " << e.opCode << "\n";
+ ASSERT_EQ(cmdSeq, e.cmdSeq)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Command sequence number at index "
+ << index
+ << " in command response history\n"
+ << " Expected: " << cmdSeq << "\n"
+ << " Actual: " << e.cmdSeq << "\n";
+ ASSERT_EQ(response, e.response)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Command response at index "
+ << index
+ << " in command resopnse history\n"
+ << " Expected: " << response << "\n"
+ << " Actual: " << e.response << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Telemetry
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertTlm_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->tlmSize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all telemetry histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmSize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_OPERATION
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_OPERATION_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MR_OPERATION->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MR_OPERATION\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MR_OPERATION->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_OPERATION(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const Ref::MathOp& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MR_OPERATION->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MR_OPERATION\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MR_OPERATION->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MR_OPERATION& e =
+ this->tlmHistory_MR_OPERATION->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MR_OPERATION\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1S
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR1S_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MR_FACTOR1S->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MR_FACTOR1S\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MR_FACTOR1S->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR1S(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const U32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MR_FACTOR1S->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MR_FACTOR1S\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MR_FACTOR1S->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MR_FACTOR1S& e =
+ this->tlmHistory_MR_FACTOR1S->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MR_FACTOR1S\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR1_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MR_FACTOR1->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MR_FACTOR1\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MR_FACTOR1->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR1(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MR_FACTOR1->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MR_FACTOR1\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MR_FACTOR1->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MR_FACTOR1& e =
+ this->tlmHistory_MR_FACTOR1->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MR_FACTOR1\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR2
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR2_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MR_FACTOR2->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MR_FACTOR2\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MR_FACTOR2->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertTlm_MR_FACTOR2(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MR_FACTOR2->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MR_FACTOR2\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MR_FACTOR2->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MR_FACTOR2& e =
+ this->tlmHistory_MR_FACTOR2->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MR_FACTOR2\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Events
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertEvents_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventsSize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all event histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventsSize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_SET_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_SET_FACTOR1_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventHistory_MR_SET_FACTOR1->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MR_SET_FACTOR1\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventHistory_MR_SET_FACTOR1->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_SET_FACTOR1(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32 val
+ ) const
+ {
+ ASSERT_GT(this->eventHistory_MR_SET_FACTOR1->size(), index)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of event MR_SET_FACTOR1\n"
+ << " Expected: Less than size of history ("
+ << this->eventHistory_MR_SET_FACTOR1->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const EventEntry_MR_SET_FACTOR1& e =
+ this->eventHistory_MR_SET_FACTOR1->at(index);
+ ASSERT_EQ(val, e.val)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument val at index "
+ << index
+ << " in history of event MR_SET_FACTOR1\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.val << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_UPDATED_FACTOR2
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_UPDATED_FACTOR2_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventHistory_MR_UPDATED_FACTOR2->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MR_UPDATED_FACTOR2\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventHistory_MR_UPDATED_FACTOR2->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_UPDATED_FACTOR2(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32 val
+ ) const
+ {
+ ASSERT_GT(this->eventHistory_MR_UPDATED_FACTOR2->size(), index)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of event MR_UPDATED_FACTOR2\n"
+ << " Expected: Less than size of history ("
+ << this->eventHistory_MR_UPDATED_FACTOR2->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const EventEntry_MR_UPDATED_FACTOR2& e =
+ this->eventHistory_MR_UPDATED_FACTOR2->at(index);
+ ASSERT_EQ(val, e.val)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument val at index "
+ << index
+ << " in history of event MR_UPDATED_FACTOR2\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.val << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_OPERATION_PERFORMED
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_OPERATION_PERFORMED_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventHistory_MR_OPERATION_PERFORMED->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MR_OPERATION_PERFORMED\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventHistory_MR_OPERATION_PERFORMED->size() << "\n";
+ }
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_OPERATION_PERFORMED(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const Ref::MathOp val
+ ) const
+ {
+ ASSERT_GT(this->eventHistory_MR_OPERATION_PERFORMED->size(), index)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of event MR_OPERATION_PERFORMED\n"
+ << " Expected: Less than size of history ("
+ << this->eventHistory_MR_OPERATION_PERFORMED->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const EventEntry_MR_OPERATION_PERFORMED& e =
+ this->eventHistory_MR_OPERATION_PERFORMED->at(index);
+ ASSERT_EQ(val, e.val)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument val at index "
+ << index
+ << " in history of event MR_OPERATION_PERFORMED\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.val << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_THROTTLE_CLEARED
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertEvents_MR_THROTTLE_CLEARED_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventsSize_MR_THROTTLE_CLEARED)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MR_THROTTLE_CLEARED\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventsSize_MR_THROTTLE_CLEARED << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assertFromPortHistory_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistorySize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all from port histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistorySize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void MathReceiverGTestBase ::
+ assert_from_mathOut_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistory_mathOut->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for from_mathOut\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistory_mathOut->size() << "\n";
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.hpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.hpp
new file mode 100644
index 0000000000..fc7750cf36
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/GTestBase.hpp
@@ -0,0 +1,390 @@
+// ======================================================================
+// \title MathReceiver/test/ut/GTestBase.hpp
+// \author Auto-generated
+// \brief hpp file for MathReceiver component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathReceiver_GTEST_BASE_HPP
+#define MathReceiver_GTEST_BASE_HPP
+
+#include "TesterBase.hpp"
+#include "gtest/gtest.h"
+
+// ----------------------------------------------------------------------
+// Macros for command history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_CMD_RESPONSE_SIZE(size) \
+ this->assertCmdResponse_size(__FILE__, __LINE__, size)
+
+#define ASSERT_CMD_RESPONSE(index, opCode, cmdSeq, response) \
+ this->assertCmdResponse(__FILE__, __LINE__, index, opCode, cmdSeq, response)
+
+// ----------------------------------------------------------------------
+// Macros for telemetry history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_TLM_SIZE(size) \
+ this->assertTlm_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MR_OPERATION_SIZE(size) \
+ this->assertTlm_MR_OPERATION_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MR_OPERATION(index, value) \
+ this->assertTlm_MR_OPERATION(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MR_FACTOR1S_SIZE(size) \
+ this->assertTlm_MR_FACTOR1S_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MR_FACTOR1S(index, value) \
+ this->assertTlm_MR_FACTOR1S(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MR_FACTOR1_SIZE(size) \
+ this->assertTlm_MR_FACTOR1_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MR_FACTOR1(index, value) \
+ this->assertTlm_MR_FACTOR1(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MR_FACTOR2_SIZE(size) \
+ this->assertTlm_MR_FACTOR2_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MR_FACTOR2(index, value) \
+ this->assertTlm_MR_FACTOR2(__FILE__, __LINE__, index, value)
+
+// ----------------------------------------------------------------------
+// Macros for event history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_EVENTS_SIZE(size) \
+ this->assertEvents_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(size) \
+ this->assertEvents_MR_SET_FACTOR1_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MR_SET_FACTOR1(index, _val) \
+ this->assertEvents_MR_SET_FACTOR1(__FILE__, __LINE__, index, _val)
+
+#define ASSERT_EVENTS_MR_UPDATED_FACTOR2_SIZE(size) \
+ this->assertEvents_MR_UPDATED_FACTOR2_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MR_UPDATED_FACTOR2(index, _val) \
+ this->assertEvents_MR_UPDATED_FACTOR2(__FILE__, __LINE__, index, _val)
+
+#define ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(size) \
+ this->assertEvents_MR_OPERATION_PERFORMED_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MR_OPERATION_PERFORMED(index, _val) \
+ this->assertEvents_MR_OPERATION_PERFORMED(__FILE__, __LINE__, index, _val)
+
+#define ASSERT_EVENTS_MR_THROTTLE_CLEARED_SIZE(size) \
+ this->assertEvents_MR_THROTTLE_CLEARED_size(__FILE__, __LINE__, size)
+
+// ----------------------------------------------------------------------
+// Macros for typed user from port history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_FROM_PORT_HISTORY_SIZE(size) \
+ this->assertFromPortHistory_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_mathOut_SIZE(size) \
+ this->assert_from_mathOut_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_mathOut(index, _result) \
+ { \
+ ASSERT_GT(this->fromPortHistory_mathOut->size(), static_cast(index)) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Index into history of from_mathOut\n" \
+ << " Expected: Less than size of history (" \
+ << this->fromPortHistory_mathOut->size() << ")\n" \
+ << " Actual: " << index << "\n"; \
+ const FromPortEntry_mathOut& _e = \
+ this->fromPortHistory_mathOut->at(index); \
+ ASSERT_EQ(_result, _e.result) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Value of argument result at index " \
+ << index \
+ << " in history of from_mathOut\n" \
+ << " Expected: " << _result << "\n" \
+ << " Actual: " << _e.result << "\n"; \
+ }
+
+namespace Ref {
+
+ //! \class MathReceiverGTestBase
+ //! \brief Auto-generated base class for MathReceiver component Google Test harness
+ //!
+ class MathReceiverGTestBase :
+ public MathReceiverTesterBase
+ {
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathReceiverGTestBase
+ //!
+ MathReceiverGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object MathReceiverGTestBase
+ //!
+ virtual ~MathReceiverGTestBase(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Commands
+ // ----------------------------------------------------------------------
+
+ //! Assert size of command response history
+ //!
+ void assertCmdResponse_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ //! Assert command response in history at index
+ //!
+ void assertCmdResponse(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ const Fw::CommandResponse response /*!< The command response*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Telemetry
+ // ----------------------------------------------------------------------
+
+ //! Assert size of telemetry history
+ //!
+ void assertTlm_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_OPERATION
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MR_OPERATION_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MR_OPERATION(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const Ref::MathOp& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1S
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MR_FACTOR1S_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MR_FACTOR1S(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const U32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MR_FACTOR1_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MR_FACTOR1(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR2
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MR_FACTOR2_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MR_FACTOR2(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Events
+ // ----------------------------------------------------------------------
+
+ void assertEvents_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_SET_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MR_SET_FACTOR1_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertEvents_MR_SET_FACTOR1(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32 val /*!< The factor value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_UPDATED_FACTOR2
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MR_UPDATED_FACTOR2_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertEvents_MR_UPDATED_FACTOR2(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32 val /*!< The factor value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_OPERATION_PERFORMED
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MR_OPERATION_PERFORMED_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertEvents_MR_OPERATION_PERFORMED(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const Ref::MathOp val /*!< The operation*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_THROTTLE_CLEARED
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MR_THROTTLE_CLEARED_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void assertFromPortHistory_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void assert_from_mathOut_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.cpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.cpp
new file mode 100644
index 0000000000..f0d72216c0
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.cpp
@@ -0,0 +1,571 @@
+// ======================================================================
+// \title MathReceiver.hpp
+// \author tcanham
+// \brief cpp file for MathReceiver test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "Tester.hpp"
+
+#define INSTANCE 0
+#define MAX_HISTORY_SIZE 10
+#define QUEUE_DEPTH 10
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ Tester ::
+ Tester(void) :
+#if FW_OBJECT_NAMES == 1
+ MathReceiverGTestBase("Tester", MAX_HISTORY_SIZE),
+ component("MathReceiver")
+#else
+ MathReceiverGTestBase(MAX_HISTORY_SIZE),
+ component()
+#endif
+ {
+ this->initComponents();
+ this->connectPorts();
+ }
+
+ Tester ::
+ ~Tester(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ testAddCommand(void)
+ {
+ // load parameters
+ this->component.loadParameters();
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_ADD);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ // Since factor1 is the default value of 0, result will be zero
+ ASSERT_from_mathOut(0,0.0);
+ // verify telemetry and events
+
+ // the event and telemetry channel use the Ref::MathOp type for values
+ Ref::MathOp checkOp(2.0,3.0,Ref::ADD,0.0);
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+
+ // clear the history before sending the command
+ this->clearHistory();
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ ASSERT_TLM_MR_FACTOR1S_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1S(0,1);
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // Repeat the operation with the new factor
+
+ // clear the history before sending the port call
+ this->clearHistory();
+
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_ADD);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ // Now that factor1 is updated, the result should be:
+ F32 result = (2.0+3.0)*2.0;
+ ASSERT_from_mathOut(0,result);
+ // verify telemetry and events
+
+ // the event and telemetry channel use the Ref::MathOp type for values
+ checkOp.set(2.0,3.0,Ref::ADD,result);
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+
+ // clear the history
+ this->clearHistory();
+
+ // set the test value for the parameter
+ this->paramSet_factor2(3.0,Fw::PARAM_VALID);
+ // now send the factor2 parameter to the component
+ this->paramSend_factor2(0,0);
+ // verify the parameter update notification event was sent
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_UPDATED_FACTOR2_SIZE(1);
+ ASSERT_EVENTS_MR_UPDATED_FACTOR2(0,3.0);
+
+ // Do the computation again and verify that the parameter was used
+
+ // clear the history
+ this->clearHistory();
+
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_ADD);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ // Now that factor2 parameter is updated, the result should be:
+ result = (2.0+3.0)*2.0/3.0;
+ ASSERT_from_mathOut(0,result);
+ // verify telemetry and events
+
+ // the event and telemetry channel use the Ref::MathOp type for values
+ checkOp.set(2.0,3.0,Ref::ADD,result);
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+
+}
+
+ void Tester ::
+ testSubCommand(void)
+ {
+ // set the test value for the parameter before loading - it will be initialized to this value
+ this->paramSet_factor2(5.0,Fw::PARAM_VALID);
+
+ // load parameters
+ this->component.loadParameters();
+
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ ASSERT_TLM_MR_FACTOR1S_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1S(0,1);
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // clear the history
+ this->clearHistory();
+
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_SUB);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+ F32 result = (2.0-3.0)*2.0/5.0;
+ // the event and telemetry channel use the Ref::MathOp type for values
+ Ref::MathOp checkOp(2.0,3.0,Ref::SUB,result);
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ ASSERT_from_mathOut(0,result);
+ // verify telemetry and events
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+ }
+
+ void Tester ::
+ testMultCommand(void)
+ {
+ // set the test value for the parameter before loading - it will be initialized to this value
+ this->paramSet_factor2(-1.0,Fw::PARAM_VALID);
+
+ // load parameters
+ this->component.loadParameters();
+
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+ ASSERT_TLM_MR_FACTOR1S_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1S(0,1);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // clear the history
+ this->clearHistory();
+
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_MULTIPLY);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+ F32 result = (2.0*3.0)*2.0/-1.0;
+ // the event and telemetry channel use the Ref::MathOp type for values
+ Ref::MathOp checkOp(2.0,3.0,Ref::MULT,result);
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ ASSERT_from_mathOut(0,result);
+ // verify telemetry and events
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+ }
+
+ void Tester ::
+ testDivCommand(void)
+ {
+ // set the test value for the parameter before loading - it will be initialized to this value
+ this->paramSet_factor2(25.0,Fw::PARAM_VALID);
+
+ // load parameters
+ this->component.loadParameters();
+
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+ ASSERT_TLM_MR_FACTOR1S_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1S(0,1);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // clear the history
+ this->clearHistory();
+
+ // invoke operation port with add operation
+ this->invoke_to_mathIn(0,2.0,3.0,Ref::MATH_DIVIDE);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+
+ // verify the result of the operation was returned
+ F32 result = (2.0/3.0)*2.0/25;
+ // the event and telemetry channel use the Ref::MathOp type for values
+ Ref::MathOp checkOp(2.0,3.0,Ref::DIVIDE,result);
+
+ // check that there was one and only one port invocation
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // check that only the port we expected was invoked
+ ASSERT_from_mathOut_SIZE(1);
+ // check that the component did the operation correctly.
+ ASSERT_from_mathOut(0,result);
+ // verify telemetry and events
+
+ // check that there was only one event
+ ASSERT_EVENTS_SIZE(1);
+ // check that it was the op event
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED_SIZE(1);
+ // check that the event has the correct argument
+ ASSERT_EVENTS_MR_OPERATION_PERFORMED(0,checkOp);
+
+ // check that there was only one channel written
+ ASSERT_TLM_SIZE(1);
+ // check that it was the op channel
+ ASSERT_TLM_MR_OPERATION_SIZE(1);
+ // check for the correct value of the channel
+ ASSERT_TLM_MR_OPERATION(0,checkOp);
+ }
+
+ void Tester ::
+ testThrottle(void)
+ {
+
+ // send the number of commands required to throttle the event
+ // Use the autocoded value so the unit test passes if the
+ // throttle value is changed
+ for (NATIVE_UINT_TYPE cycle = 0; cycle < MathReceiverComponentBase::EVENTID_MR_SET_FACTOR1_THROTTLE; cycle++) {
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ ASSERT_TLM_MR_FACTOR1S_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1S(0,cycle+1);
+
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // clear the history
+ this->clearHistory();
+ }
+
+ // sending the command now will not result in an event since
+ // the throttle value has been reached
+
+ // send the command to set factor1 to 2.0
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value events
+ ASSERT_EVENTS_SIZE(0);
+ // verify the changed value channel
+ ASSERT_TLM_SIZE(2);
+ ASSERT_TLM_MR_FACTOR1_SIZE(1);
+ ASSERT_TLM_MR_FACTOR1(0,2.0);
+ // verify the command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ ASSERT_CMD_RESPONSE(0,MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1,10,Fw::COMMAND_OK);
+
+ // clear the history
+ this->clearHistory();
+
+ // send the command to clear the throttle
+ this->sendCmd_MR_CLEAR_EVENT_THROTTLE(0,10);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify clear event was sent
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_THROTTLE_CLEARED_SIZE(1);
+
+ // clear the history
+ this->clearHistory();
+ // sending the command will now produce the event again
+ this->sendCmd_MR_SET_FACTOR1(0,10,2.0);
+ // invoke scheduler port to dispatch message
+ this->invoke_to_SchedIn(0,0);
+ // verify the changed value event
+ ASSERT_EVENTS_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1_SIZE(1);
+ ASSERT_EVENTS_MR_SET_FACTOR1(0,2.0);
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ this->pushFromPortEntry_mathOut(result);
+ }
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ connectPorts(void)
+ {
+
+ // mathIn
+ this->connect_to_mathIn(
+ 0,
+ this->component.get_mathIn_InputPort(0)
+ );
+
+ // SchedIn
+ this->connect_to_SchedIn(
+ 0,
+ this->component.get_SchedIn_InputPort(0)
+ );
+
+ // CmdDisp
+ this->connect_to_CmdDisp(
+ 0,
+ this->component.get_CmdDisp_InputPort(0)
+ );
+
+ // mathOut
+ this->component.set_mathOut_OutputPort(
+ 0,
+ this->get_from_mathOut(0)
+ );
+
+ // CmdStatus
+ this->component.set_CmdStatus_OutputPort(
+ 0,
+ this->get_from_CmdStatus(0)
+ );
+
+ // CmdReg
+ this->component.set_CmdReg_OutputPort(
+ 0,
+ this->get_from_CmdReg(0)
+ );
+
+ // ParamGet
+ this->component.set_ParamGet_OutputPort(
+ 0,
+ this->get_from_ParamGet(0)
+ );
+
+ // ParamSet
+ this->component.set_ParamSet_OutputPort(
+ 0,
+ this->get_from_ParamSet(0)
+ );
+
+ // Tlm
+ this->component.set_Tlm_OutputPort(
+ 0,
+ this->get_from_Tlm(0)
+ );
+
+ // Time
+ this->component.set_Time_OutputPort(
+ 0,
+ this->get_from_Time(0)
+ );
+
+ // Log
+ this->component.set_Log_OutputPort(
+ 0,
+ this->get_from_Log(0)
+ );
+
+ // LogText
+ this->component.set_LogText_OutputPort(
+ 0,
+ this->get_from_LogText(0)
+ );
+
+ }
+
+ void Tester ::
+ initComponents(void)
+ {
+ this->init();
+ this->component.init(
+ QUEUE_DEPTH, INSTANCE
+ );
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.hpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.hpp
new file mode 100644
index 0000000000..68498d32a7
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/Tester.hpp
@@ -0,0 +1,101 @@
+// ======================================================================
+// \title MathReceiver/test/ut/Tester.hpp
+// \author tcanham
+// \brief hpp file for MathReceiver test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef TESTER_HPP
+#define TESTER_HPP
+
+#include "GTestBase.hpp"
+#include "Ref/MathReceiver/MathReceiverComponentImpl.hpp"
+
+namespace Ref {
+
+ class Tester :
+ public MathReceiverGTestBase
+ {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ public:
+
+ //! Construct object Tester
+ //!
+ Tester(void);
+
+ //! Destroy object Tester
+ //!
+ ~Tester(void);
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ //! To do
+ //!
+ void testAddCommand(void);
+ void testSubCommand(void);
+ void testMultCommand(void);
+ void testDivCommand(void);
+ void testThrottle(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler for from_mathOut
+ //!
+ void from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ );
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ //! Connect ports
+ //!
+ void connectPorts(void);
+
+ //! Initialize components
+ //!
+ void initComponents(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Variables
+ // ----------------------------------------------------------------------
+
+ //! The component under test
+ //!
+ MathReceiverComponentImpl component;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.cpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.cpp
new file mode 100644
index 0000000000..e6fbaaf6ac
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.cpp
@@ -0,0 +1,1545 @@
+// ======================================================================
+// \title MathReceiver/test/ut/TesterBase.cpp
+// \author Auto-generated
+// \brief cpp file for MathReceiver component test harness base class
+//
+// \copyright
+// Copyright 2009-2016, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include
+#include
+#include "TesterBase.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ MathReceiverTesterBase ::
+ MathReceiverTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+#if FW_OBJECT_NAMES == 1
+ Fw::PassiveComponentBase(compName)
+#else
+ Fw::PassiveComponentBase()
+#endif
+ {
+ // Initialize command history
+ this->cmdResponseHistory = new History(maxHistorySize);
+ // Initialize telemetry histories
+ this->tlmHistory_MR_OPERATION =
+ new History(maxHistorySize);
+ this->tlmHistory_MR_FACTOR1S =
+ new History(maxHistorySize);
+ this->tlmHistory_MR_FACTOR1 =
+ new History(maxHistorySize);
+ this->tlmHistory_MR_FACTOR2 =
+ new History(maxHistorySize);
+ // Initialize event histories
+#if FW_ENABLE_TEXT_LOGGING
+ this->textLogHistory = new History(maxHistorySize);
+#endif
+ this->eventHistory_MR_SET_FACTOR1 =
+ new History(maxHistorySize);
+ this->eventHistory_MR_UPDATED_FACTOR2 =
+ new History(maxHistorySize);
+ this->eventHistory_MR_OPERATION_PERFORMED =
+ new History(maxHistorySize);
+ // Initialize histories for typed user output ports
+ this->fromPortHistory_mathOut =
+ new History(maxHistorySize);
+ // Clear history
+ this->clearHistory();
+ }
+
+ MathReceiverTesterBase ::
+ ~MathReceiverTesterBase(void)
+ {
+ // Destroy command history
+ delete this->cmdResponseHistory;
+ // Destroy telemetry histories
+ delete this->tlmHistory_MR_OPERATION;
+ delete this->tlmHistory_MR_FACTOR1S;
+ delete this->tlmHistory_MR_FACTOR1;
+ delete this->tlmHistory_MR_FACTOR2;
+ // Destroy event histories
+#if FW_ENABLE_TEXT_LOGGING
+ delete this->textLogHistory;
+#endif
+ delete this->eventHistory_MR_SET_FACTOR1;
+ delete this->eventHistory_MR_UPDATED_FACTOR2;
+ delete this->eventHistory_MR_OPERATION_PERFORMED;
+ }
+
+ void MathReceiverTesterBase ::
+ init(
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ this->m_param_factor2_valid = Fw::PARAM_UNINIT;
+
+ // Initialize base class
+
+ Fw::PassiveComponentBase::init(instance);
+
+ // Attach input port mathOut
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_mathOut();
+ ++_port
+ ) {
+
+ this->m_from_mathOut[_port].init();
+ this->m_from_mathOut[_port].addCallComp(
+ this,
+ from_mathOut_static
+ );
+ this->m_from_mathOut[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_mathOut[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_mathOut[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port CmdStatus
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_CmdStatus();
+ ++_port
+ ) {
+
+ this->m_from_CmdStatus[_port].init();
+ this->m_from_CmdStatus[_port].addCallComp(
+ this,
+ from_CmdStatus_static
+ );
+ this->m_from_CmdStatus[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_CmdStatus[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_CmdStatus[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port CmdReg
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_CmdReg();
+ ++_port
+ ) {
+
+ this->m_from_CmdReg[_port].init();
+ this->m_from_CmdReg[_port].addCallComp(
+ this,
+ from_CmdReg_static
+ );
+ this->m_from_CmdReg[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_CmdReg[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_CmdReg[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port ParamGet
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_ParamGet();
+ ++_port
+ ) {
+
+ this->m_from_ParamGet[_port].init();
+ this->m_from_ParamGet[_port].addCallComp(
+ this,
+ from_ParamGet_static
+ );
+ this->m_from_ParamGet[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_ParamGet[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_ParamGet[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port ParamSet
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_ParamSet();
+ ++_port
+ ) {
+
+ this->m_from_ParamSet[_port].init();
+ this->m_from_ParamSet[_port].addCallComp(
+ this,
+ from_ParamSet_static
+ );
+ this->m_from_ParamSet[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_ParamSet[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_ParamSet[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Tlm
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Tlm();
+ ++_port
+ ) {
+
+ this->m_from_Tlm[_port].init();
+ this->m_from_Tlm[_port].addCallComp(
+ this,
+ from_Tlm_static
+ );
+ this->m_from_Tlm[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Tlm[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Tlm[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Time
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Time();
+ ++_port
+ ) {
+
+ this->m_from_Time[_port].init();
+ this->m_from_Time[_port].addCallComp(
+ this,
+ from_Time_static
+ );
+ this->m_from_Time[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Time[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Time[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Log
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Log();
+ ++_port
+ ) {
+
+ this->m_from_Log[_port].init();
+ this->m_from_Log[_port].addCallComp(
+ this,
+ from_Log_static
+ );
+ this->m_from_Log[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Log[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Log[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port LogText
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_LogText();
+ ++_port
+ ) {
+
+ this->m_from_LogText[_port].init();
+ this->m_from_LogText[_port].addCallComp(
+ this,
+ from_LogText_static
+ );
+ this->m_from_LogText[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_LogText[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_LogText[_port].setObjName(_portName);
+#endif
+
+ }
+#endif
+
+ // Initialize output port mathIn
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_to_mathIn();
+ ++_port
+ ) {
+ this->m_to_mathIn[_port].init();
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_to_mathIn[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_to_mathIn[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Initialize output port SchedIn
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_to_SchedIn();
+ ++_port
+ ) {
+ this->m_to_SchedIn[_port].init();
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_to_SchedIn[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_to_SchedIn[_port].setObjName(_portName);
+#endif
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_to_mathIn(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_mathIn);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_mathOut(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_mathOut);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_to_SchedIn(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_SchedIn);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_to_CmdDisp(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_CmdDisp);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_CmdStatus(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_CmdStatus);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_CmdReg(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_CmdReg);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_ParamGet(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_ParamGet);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_ParamSet(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_ParamSet);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_Tlm(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Tlm);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_Time(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Time);
+ }
+
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_Log(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Log);
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ NATIVE_INT_TYPE MathReceiverTesterBase ::
+ getNum_from_LogText(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_LogText);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Connectors for to ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ connect_to_mathIn(
+ const NATIVE_INT_TYPE portNum,
+ Ref::InputMathOpPort *const mathIn
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ this->m_to_mathIn[portNum].addCallPort(mathIn);
+ }
+
+ void MathReceiverTesterBase ::
+ connect_to_SchedIn(
+ const NATIVE_INT_TYPE portNum,
+ Svc::InputSchedPort *const SchedIn
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_SchedIn(),static_cast(portNum));
+ this->m_to_SchedIn[portNum].addCallPort(SchedIn);
+ }
+
+ void MathReceiverTesterBase ::
+ connect_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum,
+ Fw::InputCmdPort *const CmdDisp
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_CmdDisp(),static_cast(portNum));
+ this->m_to_CmdDisp[portNum].addCallPort(CmdDisp);
+ }
+
+
+ // ----------------------------------------------------------------------
+ // Invocation functions for to ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ invoke_to_mathIn(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ this->m_to_mathIn[portNum].invoke(
+ val1, val2, operation
+ );
+ }
+
+ void MathReceiverTesterBase ::
+ invoke_to_SchedIn(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_SchedIn(),static_cast(portNum));
+ FW_ASSERT(portNum < this->getNum_to_SchedIn(),static_cast(portNum));
+ this->m_to_SchedIn[portNum].invoke(
+ context
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // Connection status for to ports
+ // ----------------------------------------------------------------------
+
+ bool MathReceiverTesterBase ::
+ isConnected_to_mathIn(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(), static_cast(portNum));
+ return this->m_to_mathIn[portNum].isConnected();
+ }
+
+ bool MathReceiverTesterBase ::
+ isConnected_to_SchedIn(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_SchedIn(), static_cast(portNum));
+ return this->m_to_SchedIn[portNum].isConnected();
+ }
+
+ bool MathReceiverTesterBase ::
+ isConnected_to_CmdDisp(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_CmdDisp(), static_cast(portNum));
+ return this->m_to_CmdDisp[portNum].isConnected();
+ }
+
+ // ----------------------------------------------------------------------
+ // Getters for from ports
+ // ----------------------------------------------------------------------
+
+ Ref::InputMathResultPort *MathReceiverTesterBase ::
+ get_from_mathOut(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_mathOut(),static_cast(portNum));
+ return &this->m_from_mathOut[portNum];
+ }
+
+ Fw::InputCmdResponsePort *MathReceiverTesterBase ::
+ get_from_CmdStatus(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_CmdStatus(),static_cast(portNum));
+ return &this->m_from_CmdStatus[portNum];
+ }
+
+ Fw::InputCmdRegPort *MathReceiverTesterBase ::
+ get_from_CmdReg(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_CmdReg(),static_cast(portNum));
+ return &this->m_from_CmdReg[portNum];
+ }
+
+ Fw::InputPrmGetPort *MathReceiverTesterBase ::
+ get_from_ParamGet(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_ParamGet(),static_cast(portNum));
+ return &this->m_from_ParamGet[portNum];
+ }
+
+ Fw::InputPrmSetPort *MathReceiverTesterBase ::
+ get_from_ParamSet(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_ParamSet(),static_cast(portNum));
+ return &this->m_from_ParamSet[portNum];
+ }
+
+ Fw::InputTlmPort *MathReceiverTesterBase ::
+ get_from_Tlm(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Tlm(),static_cast(portNum));
+ return &this->m_from_Tlm[portNum];
+ }
+
+ Fw::InputTimePort *MathReceiverTesterBase ::
+ get_from_Time(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Time(),static_cast(portNum));
+ return &this->m_from_Time[portNum];
+ }
+
+ Fw::InputLogPort *MathReceiverTesterBase ::
+ get_from_Log(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Log(),static_cast(portNum));
+ return &this->m_from_Log[portNum];
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ Fw::InputLogTextPort *MathReceiverTesterBase ::
+ get_from_LogText(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_LogText(),static_cast(portNum));
+ return &this->m_from_LogText[portNum];
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Static functions for from ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ from_mathOut_static(
+ Fw::PassiveComponentBase *const callComp,
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ FW_ASSERT(callComp);
+ MathReceiverTesterBase* _testerBase =
+ static_cast(callComp);
+ _testerBase->from_mathOut_handlerBase(
+ portNum,
+ result
+ );
+ }
+
+ void MathReceiverTesterBase ::
+ from_CmdStatus_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ const Fw::CommandResponse response
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->cmdResponseIn(opCode, cmdSeq, response);
+ }
+
+ void MathReceiverTesterBase ::
+ from_CmdReg_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ const FwOpcodeType opCode
+ )
+ {
+
+ }
+
+ void MathReceiverTesterBase ::
+ from_Tlm_static(
+ Fw::PassiveComponentBase *const component,
+ NATIVE_INT_TYPE portNum,
+ FwChanIdType id,
+ Fw::Time &timeTag,
+ Fw::TlmBuffer &val
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->dispatchTlm(id, timeTag, val);
+ }
+
+ void MathReceiverTesterBase ::
+ from_Log_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ FwEventIdType id,
+ Fw::Time &timeTag,
+ Fw::LogSeverity severity,
+ Fw::LogBuffer &args
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->dispatchEvents(id, timeTag, severity, args);
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ void MathReceiverTesterBase ::
+ from_LogText_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ FwEventIdType id,
+ Fw::Time &timeTag,
+ Fw::TextLogSeverity severity,
+ Fw::TextLogString &text
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->textLogIn(id,timeTag,severity,text);
+ }
+#endif
+
+ void MathReceiverTesterBase ::
+ from_Time_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ Fw::Time& time
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+ time = _testerBase->m_testTime;
+ }
+
+
+ Fw::ParamValid MathReceiverTesterBase ::
+ from_ParamGet_static(
+ Fw::PassiveComponentBase* component,
+ NATIVE_INT_TYPE portNum,
+ FwPrmIdType id,
+ Fw::ParamBuffer &val
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+
+ Fw::SerializeStatus _status;
+ Fw::ParamValid _ret = Fw::PARAM_VALID;
+ val.resetSer();
+
+ const U32 idBase = _testerBase->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+
+ switch (id - idBase) {
+ case 0:
+ {
+ _status = val.serialize(_testerBase->m_param_factor2);
+ _ret = _testerBase->m_param_factor2_valid;
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ }
+ break;
+ default:
+ FW_ASSERT(id);
+ break;
+ }
+
+ return _ret;
+ }
+
+ void MathReceiverTesterBase ::
+ from_ParamSet_static(
+ Fw::PassiveComponentBase* component,
+ NATIVE_INT_TYPE portNum,
+ FwPrmIdType id,
+ Fw::ParamBuffer &val
+ )
+ {
+ MathReceiverTesterBase* _testerBase =
+ static_cast(component);
+
+ Fw::SerializeStatus _status;
+ val.resetDeser();
+
+ // This is exercised completely in autocode,
+ // so just verify that it works. If it doesn't
+ // it probably is an autocoder error.
+
+ const U32 idBase = _testerBase->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+
+ switch (id - idBase) {
+ case 0:
+ {
+ F32 factor2Val;
+ _status = val.deserialize(factor2Val);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(
+ factor2Val ==
+ _testerBase->m_param_factor2
+ );
+ break;
+ }
+
+ default: {
+ FW_ASSERT(id);
+ break;
+ }
+
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ clearFromPortHistory(void)
+ {
+ this->fromPortHistorySize = 0;
+ this->fromPortHistory_mathOut->clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ pushFromPortEntry_mathOut(
+ F32 result
+ )
+ {
+ FromPortEntry_mathOut _e = {
+ result
+ };
+ this->fromPortHistory_mathOut->push_back(_e);
+ ++this->fromPortHistorySize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler base functions for from ports
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ from_mathOut_handlerBase(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_from_mathOut(),static_cast(portNum));
+ this->from_mathOut_handler(
+ portNum,
+ result
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // Command response handling
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ cmdResponseIn(
+ const FwOpcodeType opCode,
+ const U32 seq,
+ const Fw::CommandResponse response
+ )
+ {
+ CmdResponse e = { opCode, seq, response };
+ this->cmdResponseHistory->push_back(e);
+ }
+
+ // ----------------------------------------------------------------------
+ // Command: MR_SET_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ sendCmd_MR_SET_FACTOR1(
+ const NATIVE_INT_TYPE instance,
+ const U32 cmdSeq,
+ F32 val
+ )
+ {
+
+ // Serialize arguments
+
+ Fw::CmdArgBuffer buff;
+ Fw::SerializeStatus _status;
+ _status = buff.serialize(val);
+ FW_ASSERT(_status == Fw::FW_SERIALIZE_OK,static_cast(_status));
+
+ // Call output command port
+
+ FwOpcodeType _opcode;
+ const U32 idBase = this->getIdBase();
+ _opcode = MathReceiverComponentBase::OPCODE_MR_SET_FACTOR1 + idBase;
+
+ if (this->m_to_CmdDisp[0].isConnected()) {
+ this->m_to_CmdDisp[0].invoke(
+ _opcode,
+ cmdSeq,
+ buff
+ );
+ }
+ else {
+ printf("Test Command Output port not connected!\n");
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Command: MR_CLEAR_EVENT_THROTTLE
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ sendCmd_MR_CLEAR_EVENT_THROTTLE(
+ const NATIVE_INT_TYPE instance,
+ const U32 cmdSeq
+ )
+ {
+
+ // Serialize arguments
+
+ Fw::CmdArgBuffer buff;
+
+ // Call output command port
+
+ FwOpcodeType _opcode;
+ const U32 idBase = this->getIdBase();
+ _opcode = MathReceiverComponentBase::OPCODE_MR_CLEAR_EVENT_THROTTLE + idBase;
+
+ if (this->m_to_CmdDisp[0].isConnected()) {
+ this->m_to_CmdDisp[0].invoke(
+ _opcode,
+ cmdSeq,
+ buff
+ );
+ }
+ else {
+ printf("Test Command Output port not connected!\n");
+ }
+
+ }
+
+
+ void MathReceiverTesterBase ::
+ sendRawCmd(FwOpcodeType opcode, U32 cmdSeq, Fw::CmdArgBuffer& args) {
+
+ const U32 idBase = this->getIdBase();
+ FwOpcodeType _opcode = opcode + idBase;
+ if (this->m_to_CmdDisp[0].isConnected()) {
+ this->m_to_CmdDisp[0].invoke(
+ _opcode,
+ cmdSeq,
+ args
+ );
+ }
+ else {
+ printf("Test Command Output port not connected!\n");
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // History
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ clearHistory()
+ {
+ this->cmdResponseHistory->clear();
+ this->clearTlm();
+ this->textLogHistory->clear();
+ this->clearEvents();
+ this->clearFromPortHistory();
+ }
+
+ // ----------------------------------------------------------------------
+ // Time
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ setTestTime(const Fw::Time& time)
+ {
+ this->m_testTime = time;
+ }
+
+ // ----------------------------------------------------------------------
+ // Telemetry dispatch
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ dispatchTlm(
+ const FwChanIdType id,
+ const Fw::Time &timeTag,
+ Fw::TlmBuffer &val
+ )
+ {
+
+ val.resetDeser();
+
+ const U32 idBase = this->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+
+ switch (id - idBase) {
+
+ case MathReceiverComponentBase::CHANNELID_MR_OPERATION:
+ {
+ Ref::MathOp arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MR_OPERATION: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MR_OPERATION(timeTag, arg);
+ break;
+ }
+
+ case MathReceiverComponentBase::CHANNELID_MR_FACTOR1S:
+ {
+ U32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MR_FACTOR1S: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MR_FACTOR1S(timeTag, arg);
+ break;
+ }
+
+ case MathReceiverComponentBase::CHANNELID_MR_FACTOR1:
+ {
+ F32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MR_FACTOR1: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MR_FACTOR1(timeTag, arg);
+ break;
+ }
+
+ case MathReceiverComponentBase::CHANNELID_MR_FACTOR2:
+ {
+ F32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MR_FACTOR2: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MR_FACTOR2(timeTag, arg);
+ break;
+ }
+
+ default: {
+ FW_ASSERT(0, id);
+ break;
+ }
+
+ }
+
+ }
+
+ void MathReceiverTesterBase ::
+ clearTlm(void)
+ {
+ this->tlmSize = 0;
+ this->tlmHistory_MR_OPERATION->clear();
+ this->tlmHistory_MR_FACTOR1S->clear();
+ this->tlmHistory_MR_FACTOR1->clear();
+ this->tlmHistory_MR_FACTOR2->clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_OPERATION
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ tlmInput_MR_OPERATION(
+ const Fw::Time& timeTag,
+ const Ref::MathOp& val
+ )
+ {
+ TlmEntry_MR_OPERATION e = { timeTag, val };
+ this->tlmHistory_MR_OPERATION->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1S
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ tlmInput_MR_FACTOR1S(
+ const Fw::Time& timeTag,
+ const U32& val
+ )
+ {
+ TlmEntry_MR_FACTOR1S e = { timeTag, val };
+ this->tlmHistory_MR_FACTOR1S->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ tlmInput_MR_FACTOR1(
+ const Fw::Time& timeTag,
+ const F32& val
+ )
+ {
+ TlmEntry_MR_FACTOR1 e = { timeTag, val };
+ this->tlmHistory_MR_FACTOR1->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR2
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ tlmInput_MR_FACTOR2(
+ const Fw::Time& timeTag,
+ const F32& val
+ )
+ {
+ TlmEntry_MR_FACTOR2 e = { timeTag, val };
+ this->tlmHistory_MR_FACTOR2->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event dispatch
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ dispatchEvents(
+ const FwEventIdType id,
+ Fw::Time &timeTag,
+ const Fw::LogSeverity severity,
+ Fw::LogBuffer &args
+ )
+ {
+
+ args.resetDeser();
+
+ const U32 idBase = this->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+ switch (id - idBase) {
+
+ case MathReceiverComponentBase::EVENTID_MR_SET_FACTOR1:
+ {
+
+ Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
+#if FW_AMPCS_COMPATIBLE
+ // Deserialize the number of arguments.
+ U8 _numArgs;
+ _status = args.deserialize(_numArgs);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ // verify they match expected.
+ FW_ASSERT(_numArgs == 1,_numArgs,1);
+
+#endif
+ F32 val;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(F32),_argSize,sizeof(F32));
+ }
+#endif
+ _status = args.deserialize(val);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ this->logIn_ACTIVITY_HI_MR_SET_FACTOR1(val);
+
+ break;
+
+ }
+
+ case MathReceiverComponentBase::EVENTID_MR_UPDATED_FACTOR2:
+ {
+
+ Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
+#if FW_AMPCS_COMPATIBLE
+ // Deserialize the number of arguments.
+ U8 _numArgs;
+ _status = args.deserialize(_numArgs);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ // verify they match expected.
+ FW_ASSERT(_numArgs == 1,_numArgs,1);
+
+#endif
+ F32 val;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(F32),_argSize,sizeof(F32));
+ }
+#endif
+ _status = args.deserialize(val);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ this->logIn_ACTIVITY_HI_MR_UPDATED_FACTOR2(val);
+
+ break;
+
+ }
+
+ case MathReceiverComponentBase::EVENTID_MR_OPERATION_PERFORMED:
+ {
+
+ Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
+#if FW_AMPCS_COMPATIBLE
+ // Deserialize the number of arguments.
+ U8 _numArgs;
+ _status = args.deserialize(_numArgs);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ // verify they match expected.
+ FW_ASSERT(_numArgs == 1,_numArgs,1);
+
+#endif
+ Ref::MathOp val;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(Ref::MathOp),_argSize,sizeof(Ref::MathOp));
+ }
+#endif
+ _status = args.deserialize(val);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ this->logIn_ACTIVITY_HI_MR_OPERATION_PERFORMED(val);
+
+ break;
+
+ }
+
+ case MathReceiverComponentBase::EVENTID_MR_THROTTLE_CLEARED:
+ {
+
+#if FW_AMPCS_COMPATIBLE
+ // For AMPCS, decode zero arguments
+ Fw::SerializeStatus _zero_status = Fw::FW_SERIALIZE_OK;
+ U8 _noArgs;
+ _zero_status = args.deserialize(_noArgs);
+ FW_ASSERT(
+ _zero_status == Fw::FW_SERIALIZE_OK,
+ static_cast(_zero_status)
+ );
+#endif
+ this->logIn_ACTIVITY_HI_MR_THROTTLE_CLEARED();
+
+ break;
+
+ }
+
+ default: {
+ FW_ASSERT(0, id);
+ break;
+ }
+
+ }
+
+ }
+
+ void MathReceiverTesterBase ::
+ clearEvents(void)
+ {
+ this->eventsSize = 0;
+ this->eventHistory_MR_SET_FACTOR1->clear();
+ this->eventHistory_MR_UPDATED_FACTOR2->clear();
+ this->eventHistory_MR_OPERATION_PERFORMED->clear();
+ this->eventsSize_MR_THROTTLE_CLEARED = 0;
+ }
+
+#if FW_ENABLE_TEXT_LOGGING
+
+ // ----------------------------------------------------------------------
+ // Text events
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ textLogIn(
+ const U32 id,
+ Fw::Time &timeTag,
+ const Fw::TextLogSeverity severity,
+ const Fw::TextLogString &text
+ )
+ {
+ TextLogEntry e = { id, timeTag, severity, text };
+ textLogHistory->push_back(e);
+ }
+
+ void MathReceiverTesterBase ::
+ printTextLogHistoryEntry(
+ const TextLogEntry& e,
+ FILE* file
+ )
+ {
+ const char *severityString = "UNKNOWN";
+ switch (e.severity) {
+ case Fw::LOG_FATAL:
+ severityString = "FATAL";
+ break;
+ case Fw::LOG_WARNING_HI:
+ severityString = "WARNING_HI";
+ break;
+ case Fw::LOG_WARNING_LO:
+ severityString = "WARNING_LO";
+ break;
+ case Fw::LOG_COMMAND:
+ severityString = "COMMAND";
+ break;
+ case Fw::LOG_ACTIVITY_HI:
+ severityString = "ACTIVITY_HI";
+ break;
+ case Fw::LOG_ACTIVITY_LO:
+ severityString = "ACTIVITY_LO";
+ break;
+ case Fw::LOG_DIAGNOSTIC:
+ severityString = "DIAGNOSTIC";
+ break;
+ default:
+ severityString = "SEVERITY ERROR";
+ break;
+ }
+
+ fprintf(
+ file,
+ "EVENT: (%d) (%d:%d,%d) %s: %s\n",
+ e.id,
+ const_cast(e).timeTag.getTimeBase(),
+ const_cast(e).timeTag.getSeconds(),
+ const_cast(e).timeTag.getUSeconds(),
+ severityString,
+ e.text.toChar()
+ );
+
+ }
+
+ void MathReceiverTesterBase ::
+ printTextLogHistory(FILE *file)
+ {
+ for (U32 i = 0; i < this->textLogHistory->size(); ++i) {
+ this->printTextLogHistoryEntry(
+ this->textLogHistory->at(i),
+ file
+ );
+ }
+ }
+
+#endif
+
+ // ----------------------------------------------------------------------
+ // Event: MR_SET_FACTOR1
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ logIn_ACTIVITY_HI_MR_SET_FACTOR1(
+ F32 val
+ )
+ {
+ EventEntry_MR_SET_FACTOR1 e = {
+ val
+ };
+ eventHistory_MR_SET_FACTOR1->push_back(e);
+ ++this->eventsSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_UPDATED_FACTOR2
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ logIn_ACTIVITY_HI_MR_UPDATED_FACTOR2(
+ F32 val
+ )
+ {
+ EventEntry_MR_UPDATED_FACTOR2 e = {
+ val
+ };
+ eventHistory_MR_UPDATED_FACTOR2->push_back(e);
+ ++this->eventsSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_OPERATION_PERFORMED
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ logIn_ACTIVITY_HI_MR_OPERATION_PERFORMED(
+ Ref::MathOp val
+ )
+ {
+ EventEntry_MR_OPERATION_PERFORMED e = {
+ val
+ };
+ eventHistory_MR_OPERATION_PERFORMED->push_back(e);
+ ++this->eventsSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MR_THROTTLE_CLEARED
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ logIn_ACTIVITY_HI_MR_THROTTLE_CLEARED(
+ void
+ )
+ {
+ ++this->eventsSize_MR_THROTTLE_CLEARED;
+ ++this->eventsSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Parameter factor2
+ // ----------------------------------------------------------------------
+
+ void MathReceiverTesterBase ::
+ paramSet_factor2(
+ const F32& val,
+ Fw::ParamValid valid
+ )
+ {
+ this->m_param_factor2 = val;
+ this->m_param_factor2_valid = valid;
+ }
+
+ void MathReceiverTesterBase ::
+ paramSend_factor2(
+ NATIVE_INT_TYPE instance,
+ U32 cmdSeq
+ )
+ {
+
+ // Build command for parameter set
+
+ Fw::CmdArgBuffer args;
+ FW_ASSERT(
+ args.serialize(
+ this->m_param_factor2
+ ) == Fw::FW_SERIALIZE_OK
+ );
+ const U32 idBase = this->getIdBase();
+ FwOpcodeType _prmOpcode;
+ _prmOpcode = MathReceiverComponentBase::OPCODE_FACTOR2_SET + idBase;
+ if (not this->m_to_CmdDisp[0].isConnected()) {
+ printf("Test Command Output port not connected!\n");
+ }
+ else {
+ this->m_to_CmdDisp[0].invoke(
+ _prmOpcode,
+ cmdSeq,
+ args
+ );
+ }
+
+ }
+
+ void MathReceiverTesterBase ::
+ paramSave_factor2 (
+ NATIVE_INT_TYPE instance,
+ U32 cmdSeq
+ )
+
+ {
+ Fw::CmdArgBuffer args;
+ FwOpcodeType _prmOpcode;
+ const U32 idBase = this->getIdBase();
+ _prmOpcode = MathReceiverComponentBase::OPCODE_FACTOR2_SAVE + idBase;
+ if (not this->m_to_CmdDisp[0].isConnected()) {
+ printf("Test Command Output port not connected!\n");
+ }
+ else {
+ this->m_to_CmdDisp[0].invoke(
+ _prmOpcode,
+ cmdSeq,
+ args
+ );
+ }
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.hpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.hpp
new file mode 100644
index 0000000000..5a2b304d6c
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/TesterBase.hpp
@@ -0,0 +1,986 @@
+// ======================================================================
+// \title MathReceiver/test/ut/TesterBase.hpp
+// \author Auto-generated
+// \brief hpp file for MathReceiver component test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathReceiver_TESTER_BASE_HPP
+#define MathReceiver_TESTER_BASE_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Ref {
+
+ //! \class MathReceiverTesterBase
+ //! \brief Auto-generated base class for MathReceiver component test harness
+ //!
+ class MathReceiverTesterBase :
+ public Fw::PassiveComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Initialization
+ // ----------------------------------------------------------------------
+
+ //! Initialize object MathReceiverTesterBase
+ //!
+ virtual void init(
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Connectors for 'to' ports
+ // Connect these output ports to the input ports under test
+ // ----------------------------------------------------------------------
+
+ //! Connect mathIn to to_mathIn[portNum]
+ //!
+ void connect_to_mathIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Ref::InputMathOpPort *const mathIn /*!< The port*/
+ );
+
+ //! Connect SchedIn to to_SchedIn[portNum]
+ //!
+ void connect_to_SchedIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Svc::InputSchedPort *const SchedIn /*!< The port*/
+ );
+
+ //! Connect CmdDisp to to_CmdDisp[portNum]
+ //!
+ void connect_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Fw::InputCmdPort *const CmdDisp /*!< The port*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for 'from' ports
+ // Connect these input ports to the output ports under test
+ // ----------------------------------------------------------------------
+
+ //! Get the port that receives input from mathOut
+ //!
+ //! \return from_mathOut[portNum]
+ //!
+ Ref::InputMathResultPort* get_from_mathOut(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from CmdStatus
+ //!
+ //! \return from_CmdStatus[portNum]
+ //!
+ Fw::InputCmdResponsePort* get_from_CmdStatus(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from CmdReg
+ //!
+ //! \return from_CmdReg[portNum]
+ //!
+ Fw::InputCmdRegPort* get_from_CmdReg(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from ParamGet
+ //!
+ //! \return from_ParamGet[portNum]
+ //!
+ Fw::InputPrmGetPort* get_from_ParamGet(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from ParamSet
+ //!
+ //! \return from_ParamSet[portNum]
+ //!
+ Fw::InputPrmSetPort* get_from_ParamSet(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Tlm
+ //!
+ //! \return from_Tlm[portNum]
+ //!
+ Fw::InputTlmPort* get_from_Tlm(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Time
+ //!
+ //! \return from_Time[portNum]
+ //!
+ Fw::InputTimePort* get_from_Time(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Log
+ //!
+ //! \return from_Log[portNum]
+ //!
+ Fw::InputLogPort* get_from_Log(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Get the port that receives input from LogText
+ //!
+ //! \return from_LogText[portNum]
+ //!
+ Fw::InputLogTextPort* get_from_LogText(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathReceiverTesterBase
+ //!
+ MathReceiverTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object MathReceiverTesterBase
+ //!
+ virtual ~MathReceiverTesterBase(void);
+
+ // ----------------------------------------------------------------------
+ // Test history
+ // ----------------------------------------------------------------------
+
+ protected:
+
+ //! \class History
+ //! \brief A history of port inputs
+ //!
+ template class History {
+
+ public:
+
+ //! Create a History
+ //!
+ History(
+ const U32 maxSize /*!< The maximum history size*/
+ ) :
+ numEntries(0),
+ maxSize(maxSize)
+ {
+ this->entries = new T[maxSize];
+ }
+
+ //! Destroy a History
+ //!
+ ~History() {
+ delete[] this->entries;
+ }
+
+ //! Clear the history
+ //!
+ void clear() { this->numEntries = 0; }
+
+ //! Push an item onto the history
+ //!
+ void push_back(
+ T entry /*!< The item*/
+ ) {
+ FW_ASSERT(this->numEntries < this->maxSize);
+ entries[this->numEntries++] = entry;
+ }
+
+ //! Get an item at an index
+ //!
+ //! \return The item at index i
+ //!
+ T at(
+ const U32 i /*!< The index*/
+ ) const {
+ FW_ASSERT(i < this->numEntries);
+ return entries[i];
+ }
+
+ //! Get the number of entries in the history
+ //!
+ //! \return The number of entries in the history
+ //!
+ U32 size(void) const { return this->numEntries; }
+
+ private:
+
+ //! The number of entries in the history
+ //!
+ U32 numEntries;
+
+ //! The maximum history size
+ //!
+ const U32 maxSize;
+
+ //! The entries
+ //!
+ T *entries;
+
+ };
+
+ //! Clear all history
+ //!
+ void clearHistory(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Handler prototypes for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler prototype for from_mathOut
+ //!
+ virtual void from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ ) = 0;
+
+ //! Handler base function for from_mathOut
+ //!
+ void from_mathOut_handlerBase(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Clear from port history
+ //!
+ void clearFromPortHistory(void);
+
+ //! The total number of from port entries
+ //!
+ U32 fromPortHistorySize;
+
+ //! Push an entry on the history for from_mathOut
+ void pushFromPortEntry_mathOut(
+ F32 result /*!< the result of the operation*/
+ );
+
+ //! A history entry for from_mathOut
+ //!
+ typedef struct {
+ F32 result;
+ } FromPortEntry_mathOut;
+
+ //! The history for from_mathOut
+ //!
+ History
+ *fromPortHistory_mathOut;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Invocation functions for to ports
+ // ----------------------------------------------------------------------
+
+ //! Invoke the to port connected to mathIn
+ //!
+ void invoke_to_mathIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ //! Invoke the to port connected to SchedIn
+ //!
+ void invoke_to_SchedIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ NATIVE_UINT_TYPE context /*!< The call order*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ //! Get the number of to_mathIn ports
+ //!
+ //! \return The number of to_mathIn ports
+ //!
+ NATIVE_INT_TYPE getNum_to_mathIn(void) const;
+
+ //! Get the number of from_mathOut ports
+ //!
+ //! \return The number of from_mathOut ports
+ //!
+ NATIVE_INT_TYPE getNum_from_mathOut(void) const;
+
+ //! Get the number of to_SchedIn ports
+ //!
+ //! \return The number of to_SchedIn ports
+ //!
+ NATIVE_INT_TYPE getNum_to_SchedIn(void) const;
+
+ //! Get the number of to_CmdDisp ports
+ //!
+ //! \return The number of to_CmdDisp ports
+ //!
+ NATIVE_INT_TYPE getNum_to_CmdDisp(void) const;
+
+ //! Get the number of from_CmdStatus ports
+ //!
+ //! \return The number of from_CmdStatus ports
+ //!
+ NATIVE_INT_TYPE getNum_from_CmdStatus(void) const;
+
+ //! Get the number of from_CmdReg ports
+ //!
+ //! \return The number of from_CmdReg ports
+ //!
+ NATIVE_INT_TYPE getNum_from_CmdReg(void) const;
+
+ //! Get the number of from_ParamGet ports
+ //!
+ //! \return The number of from_ParamGet ports
+ //!
+ NATIVE_INT_TYPE getNum_from_ParamGet(void) const;
+
+ //! Get the number of from_ParamSet ports
+ //!
+ //! \return The number of from_ParamSet ports
+ //!
+ NATIVE_INT_TYPE getNum_from_ParamSet(void) const;
+
+ //! Get the number of from_Tlm ports
+ //!
+ //! \return The number of from_Tlm ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Tlm(void) const;
+
+ //! Get the number of from_Time ports
+ //!
+ //! \return The number of from_Time ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Time(void) const;
+
+ //! Get the number of from_Log ports
+ //!
+ //! \return The number of from_Log ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Log(void) const;
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Get the number of from_LogText ports
+ //!
+ //! \return The number of from_LogText ports
+ //!
+ NATIVE_INT_TYPE getNum_from_LogText(void) const;
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Connection status for to ports
+ // ----------------------------------------------------------------------
+
+ //! Check whether port is connected
+ //!
+ //! Whether to_mathIn[portNum] is connected
+ //!
+ bool isConnected_to_mathIn(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Check whether port is connected
+ //!
+ //! Whether to_SchedIn[portNum] is connected
+ //!
+ bool isConnected_to_SchedIn(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Check whether port is connected
+ //!
+ //! Whether to_CmdDisp[portNum] is connected
+ //!
+ bool isConnected_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ // ----------------------------------------------------------------------
+ // Functions for sending commands
+ // ----------------------------------------------------------------------
+
+ protected:
+
+ // send command buffers directly - used for intentional command encoding errors
+ void sendRawCmd(FwOpcodeType opcode, U32 cmdSeq, Fw::CmdArgBuffer& args);
+
+ //! Send a MR_SET_FACTOR1 command
+ //!
+ void sendCmd_MR_SET_FACTOR1(
+ const NATIVE_INT_TYPE instance, /*!< The instance number*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ F32 val /*!< The first factor*/
+ );
+
+ //! Send a MR_CLEAR_EVENT_THROTTLE command
+ //!
+ void sendCmd_MR_CLEAR_EVENT_THROTTLE(
+ const NATIVE_INT_TYPE instance, /*!< The instance number*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Command response handling
+ // ----------------------------------------------------------------------
+
+ //! Handle a command response
+ //!
+ virtual void cmdResponseIn(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ const Fw::CommandResponse response /*!< The command response*/
+ );
+
+ //! A type representing a command response
+ //!
+ typedef struct {
+ FwOpcodeType opCode;
+ U32 cmdSeq;
+ Fw::CommandResponse response;
+ } CmdResponse;
+
+ //! The command response history
+ //!
+ History *cmdResponseHistory;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event dispatch
+ // ----------------------------------------------------------------------
+
+ //! Dispatch an event
+ //!
+ void dispatchEvents(
+ const FwEventIdType id, /*!< The event ID*/
+ Fw::Time& timeTag, /*!< The time*/
+ const Fw::LogSeverity severity, /*!< The severity*/
+ Fw::LogBuffer& args /*!< The serialized arguments*/
+ );
+
+ //! Clear event history
+ //!
+ void clearEvents(void);
+
+ //! The total number of events seen
+ //!
+ U32 eventsSize;
+
+#if FW_ENABLE_TEXT_LOGGING
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Text events
+ // ----------------------------------------------------------------------
+
+ //! Handle a text event
+ //!
+ virtual void textLogIn(
+ const FwEventIdType id, /*!< The event ID*/
+ Fw::Time& timeTag, /*!< The time*/
+ const Fw::TextLogSeverity severity, /*!< The severity*/
+ const Fw::TextLogString& text /*!< The event string*/
+ );
+
+ //! A history entry for the text log
+ //!
+ typedef struct {
+ U32 id;
+ Fw::Time timeTag;
+ Fw::TextLogSeverity severity;
+ Fw::TextLogString text;
+ } TextLogEntry;
+
+ //! The history of text log events
+ //!
+ History *textLogHistory;
+
+ //! Print a text log history entry
+ //!
+ static void printTextLogHistoryEntry(
+ const TextLogEntry& e,
+ FILE* file
+ );
+
+ //! Print the text log history
+ //!
+ void printTextLogHistory(FILE *const file);
+
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_SET_FACTOR1
+ // ----------------------------------------------------------------------
+
+ //! Handle event MR_SET_FACTOR1
+ //!
+ virtual void logIn_ACTIVITY_HI_MR_SET_FACTOR1(
+ F32 val /*!< The factor value*/
+ );
+
+ //! A history entry for event MR_SET_FACTOR1
+ //!
+ typedef struct {
+ F32 val;
+ } EventEntry_MR_SET_FACTOR1;
+
+ //! The history of MR_SET_FACTOR1 events
+ //!
+ History
+ *eventHistory_MR_SET_FACTOR1;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_UPDATED_FACTOR2
+ // ----------------------------------------------------------------------
+
+ //! Handle event MR_UPDATED_FACTOR2
+ //!
+ virtual void logIn_ACTIVITY_HI_MR_UPDATED_FACTOR2(
+ F32 val /*!< The factor value*/
+ );
+
+ //! A history entry for event MR_UPDATED_FACTOR2
+ //!
+ typedef struct {
+ F32 val;
+ } EventEntry_MR_UPDATED_FACTOR2;
+
+ //! The history of MR_UPDATED_FACTOR2 events
+ //!
+ History
+ *eventHistory_MR_UPDATED_FACTOR2;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_OPERATION_PERFORMED
+ // ----------------------------------------------------------------------
+
+ //! Handle event MR_OPERATION_PERFORMED
+ //!
+ virtual void logIn_ACTIVITY_HI_MR_OPERATION_PERFORMED(
+ Ref::MathOp val /*!< The operation*/
+ );
+
+ //! A history entry for event MR_OPERATION_PERFORMED
+ //!
+ typedef struct {
+ Ref::MathOp val;
+ } EventEntry_MR_OPERATION_PERFORMED;
+
+ //! The history of MR_OPERATION_PERFORMED events
+ //!
+ History
+ *eventHistory_MR_OPERATION_PERFORMED;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MR_THROTTLE_CLEARED
+ // ----------------------------------------------------------------------
+
+ //! Handle event MR_THROTTLE_CLEARED
+ //!
+ virtual void logIn_ACTIVITY_HI_MR_THROTTLE_CLEARED(
+ void
+ );
+
+ //! Size of history for event MR_THROTTLE_CLEARED
+ //!
+ U32 eventsSize_MR_THROTTLE_CLEARED;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Telemetry dispatch
+ // ----------------------------------------------------------------------
+
+ //! Dispatch telemetry
+ //!
+ void dispatchTlm(
+ const FwChanIdType id, /*!< The channel ID*/
+ const Fw::Time& timeTag, /*!< The time*/
+ Fw::TlmBuffer& val /*!< The channel value*/
+ );
+
+ //! Clear telemetry history
+ //!
+ void clearTlm(void);
+
+ //! The total number of telemetry inputs seen
+ //!
+ U32 tlmSize;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_OPERATION
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MR_OPERATION
+ //!
+ virtual void tlmInput_MR_OPERATION(
+ const Fw::Time& timeTag, /*!< The time*/
+ const Ref::MathOp& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MR_OPERATION
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ Ref::MathOp arg;
+ } TlmEntry_MR_OPERATION;
+
+ //! The history of MR_OPERATION values
+ //!
+ History
+ *tlmHistory_MR_OPERATION;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1S
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MR_FACTOR1S
+ //!
+ virtual void tlmInput_MR_FACTOR1S(
+ const Fw::Time& timeTag, /*!< The time*/
+ const U32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MR_FACTOR1S
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ U32 arg;
+ } TlmEntry_MR_FACTOR1S;
+
+ //! The history of MR_FACTOR1S values
+ //!
+ History
+ *tlmHistory_MR_FACTOR1S;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR1
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MR_FACTOR1
+ //!
+ virtual void tlmInput_MR_FACTOR1(
+ const Fw::Time& timeTag, /*!< The time*/
+ const F32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MR_FACTOR1
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ F32 arg;
+ } TlmEntry_MR_FACTOR1;
+
+ //! The history of MR_FACTOR1 values
+ //!
+ History
+ *tlmHistory_MR_FACTOR1;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MR_FACTOR2
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MR_FACTOR2
+ //!
+ virtual void tlmInput_MR_FACTOR2(
+ const Fw::Time& timeTag, /*!< The time*/
+ const F32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MR_FACTOR2
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ F32 arg;
+ } TlmEntry_MR_FACTOR2;
+
+ //! The history of MR_FACTOR2 values
+ //!
+ History
+ *tlmHistory_MR_FACTOR2;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Test time
+ // ----------------------------------------------------------------------
+
+ //! Set the test time for events and telemetry
+ //!
+ void setTestTime(
+ const Fw::Time& timeTag /*!< The time*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Parameter: factor2
+ // ----------------------------------------------------------------------
+
+ void paramSet_factor2(
+ const F32& val, /*!< The parameter value*/
+ Fw::ParamValid valid /*!< The parameter valid flag*/
+ );
+
+ void paramSend_factor2(
+ const NATIVE_INT_TYPE instance, /*!< The instance number*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
+ void paramSave_factor2(
+ const NATIVE_INT_TYPE instance, /*!< The instance number*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // To ports
+ // ----------------------------------------------------------------------
+
+ //! To port connected to mathIn
+ //!
+ Ref::OutputMathOpPort m_to_mathIn[1];
+
+ //! To port connected to SchedIn
+ //!
+ Svc::OutputSchedPort m_to_SchedIn[1];
+
+ //! To port connected to CmdDisp
+ //!
+ Fw::OutputCmdPort m_to_CmdDisp[1];
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ //! From port connected to mathOut
+ //!
+ Ref::InputMathResultPort m_from_mathOut[1];
+
+ //! From port connected to CmdStatus
+ //!
+ Fw::InputCmdResponsePort m_from_CmdStatus[1];
+
+ //! From port connected to CmdReg
+ //!
+ Fw::InputCmdRegPort m_from_CmdReg[1];
+
+ //! From port connected to ParamGet
+ //!
+ Fw::InputPrmGetPort m_from_ParamGet[1];
+
+ //! From port connected to ParamSet
+ //!
+ Fw::InputPrmSetPort m_from_ParamSet[1];
+
+ //! From port connected to Tlm
+ //!
+ Fw::InputTlmPort m_from_Tlm[1];
+
+ //! From port connected to Time
+ //!
+ Fw::InputTimePort m_from_Time[1];
+
+ //! From port connected to Log
+ //!
+ Fw::InputLogPort m_from_Log[1];
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! From port connected to LogText
+ //!
+ Fw::InputLogTextPort m_from_LogText[1];
+#endif
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Static functions for output ports
+ // ----------------------------------------------------------------------
+
+ //! Static function for port from_mathOut
+ //!
+ static void from_mathOut_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ );
+
+ //! Static function for port from_CmdStatus
+ //!
+ static void from_CmdStatus_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwOpcodeType opCode, /*!< Command Op Code*/
+ U32 cmdSeq, /*!< Command Sequence*/
+ Fw::CommandResponse response /*!< The command response argument*/
+ );
+
+ //! Static function for port from_CmdReg
+ //!
+ static void from_CmdReg_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwOpcodeType opCode /*!< Command Op Code*/
+ );
+
+ //! Static function for port from_ParamGet
+ //!
+ static Fw::ParamValid from_ParamGet_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwPrmIdType id, /*!< Parameter ID*/
+ Fw::ParamBuffer &val /*!< Buffer containing serialized parameter value*/
+ );
+
+ //! Static function for port from_ParamSet
+ //!
+ static void from_ParamSet_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwPrmIdType id, /*!< Parameter ID*/
+ Fw::ParamBuffer &val /*!< Buffer containing serialized parameter value*/
+ );
+
+ //! Static function for port from_Tlm
+ //!
+ static void from_Tlm_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwChanIdType id, /*!< Telemetry Channel ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::TlmBuffer &val /*!< Buffer containing serialized telemetry value*/
+ );
+
+ //! Static function for port from_Time
+ //!
+ static void from_Time_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Fw::Time &time /*!< The U32 cmd argument*/
+ );
+
+ //! Static function for port from_Log
+ //!
+ static void from_Log_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwEventIdType id, /*!< Log ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::LogSeverity severity, /*!< The severity argument*/
+ Fw::LogBuffer &args /*!< Buffer containing serialized log entry*/
+ );
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Static function for port from_LogText
+ //!
+ static void from_LogText_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwEventIdType id, /*!< Log ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::TextLogSeverity severity, /*!< The severity argument*/
+ Fw::TextLogString &text /*!< Text of log message*/
+ );
+#endif
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Test time
+ // ----------------------------------------------------------------------
+
+ //! Test time stamp
+ //!
+ Fw::Time m_testTime;
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Parameter validity flags
+ // ----------------------------------------------------------------------
+
+ //! True if parameter factor2 was successfully received
+ //!
+ Fw::ParamValid m_param_factor2_valid;
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Parameter variables
+ // ----------------------------------------------------------------------
+
+ //! Parameter factor2
+ //!
+ F32 m_param_factor2;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/main.cpp b/docs/Tutorials/MathComponent/MathReceiver/test/ut/main.cpp
new file mode 100644
index 0000000000..8e9a38374c
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/main.cpp
@@ -0,0 +1,35 @@
+// ----------------------------------------------------------------------
+// Main.cpp
+// ----------------------------------------------------------------------
+
+#include "Tester.hpp"
+
+TEST(Nominal, AddOperationTest) {
+ Ref::Tester tester;
+ tester.testAddCommand();
+}
+
+TEST(Nominal, SubOperationTest) {
+ Ref::Tester tester;
+ tester.testSubCommand();
+}
+
+TEST(Nominal, MultOperationTest) {
+ Ref::Tester tester;
+ tester.testMultCommand();
+}
+
+TEST(Nominal, DivideOperationTest) {
+ Ref::Tester tester;
+ tester.testDivCommand();
+}
+
+TEST(Nominal, ThrottleTest) {
+ Ref::Tester tester;
+ tester.testThrottle();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/mod.mk b/docs/Tutorials/MathComponent/MathReceiver/test/ut/mod.mk
new file mode 100644
index 0000000000..6f382258eb
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/mod.mk
@@ -0,0 +1,27 @@
+# ----------------------------------------------------------------------
+# mod.mk
+# ----------------------------------------------------------------------
+
+TEST_SRC = main.cpp \
+ Tester.cpp \
+ GTestBase.cpp \
+ TesterBase.cpp
+
+TEST_MODS = Ref/MathReceiver \
+ Ref/MathPorts \
+ Ref/MathTypes \
+ Svc/Sched \
+ Fw/Cmd \
+ Fw/Comp \
+ Fw/Port \
+ Fw/Prm \
+ Fw/Time \
+ Fw/Tlm \
+ Fw/Types \
+ Fw/Log \
+ Fw/Obj \
+ Fw/Com \
+ Os \
+ Utils/Hash \
+ gtest
+
diff --git a/docs/Tutorials/MathComponent/MathReceiver/test/ut/runtest_LINUX b/docs/Tutorials/MathComponent/MathReceiver/test/ut/runtest_LINUX
new file mode 100644
index 0000000000..a4e40e5e96
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathReceiver/test/ut/runtest_LINUX
@@ -0,0 +1,6 @@
+#!/bin/sh
+LOC=${BUILD_ROOT}/Ref/MathReceiver/test/ut
+cd ${LOC}
+echo "Running ${LOC}/$1/test_ut"
+${LOC}/$1/test_ut
+
diff --git a/docs/Tutorials/MathComponent/MathSender/Makefile b/docs/Tutorials/MathComponent/MathSender/Makefile
new file mode 100644
index 0000000000..b189cd748a
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/Makefile
@@ -0,0 +1,10 @@
+# derive module name from directory
+
+MODULE_DIR = Ref/MathSender
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
diff --git a/docs/Tutorials/MathComponent/MathSender/MathSenderComponentAi.xml b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentAi.xml
new file mode 100644
index 0000000000..9aae246e49
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentAi.xml
@@ -0,0 +1,104 @@
+
+ Ref/MathPorts/MathOpPortAi.xml
+ Ref/MathPorts/MathResultPortAi.xml
+ Component sending a math operation
+
+
+
+ Port for sending the math operation
+
+
+
+
+ Port for returning the math result
+
+
+
+
+
+
+ Do a math operation
+
+
+
+ The first value
+
+
+ The second value
+
+
+
+
+
+
+
+
+ The operation to perform
+
+
+
+
+
+
+
+ The first value
+
+
+
+
+ The second value
+
+
+
+
+
+
+
+
+
+
+ The operation
+
+
+
+
+ The result
+
+
+
+
+
+
+ Math command received
+
+
+
+ The val1 argument
+
+
+ The val2 argument
+
+
+ The requested operation
+
+
+
+
+
+
+
+
+
+
+
+ Received math result
+
+
+
+ The math result
+
+
+
+
+
+
diff --git a/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.cpp b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.cpp
new file mode 100644
index 0000000000..242c969f50
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.cpp
@@ -0,0 +1,123 @@
+// ======================================================================
+// \title MathSenderImpl.cpp
+// \author tcanham
+// \brief cpp file for MathSender component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+
+#include
+#include "Fw/Types/BasicTypes.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ MathSenderComponentImpl ::
+#if FW_OBJECT_NAMES == 1
+ MathSenderComponentImpl(
+ const char *const compName
+ ) :
+ MathSenderComponentBase(compName)
+#else
+ MathSenderImpl(void)
+#endif
+ {
+
+ }
+
+ void MathSenderComponentImpl ::
+ init(
+ const NATIVE_INT_TYPE queueDepth,
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ MathSenderComponentBase::init(queueDepth, instance);
+ }
+
+ MathSenderComponentImpl ::
+ ~MathSenderComponentImpl(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ this->tlmWrite_MS_RES(result);
+ this->log_ACTIVITY_HI_MS_RESULT(result);
+ }
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ void MathSenderComponentImpl ::
+ MS_DO_MATH_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ F32 val1,
+ F32 val2,
+ MathOp operation
+ )
+ {
+ MathOpTlm opTlm;
+ MathOperation opPort;
+ MathOpEv opEv;
+ switch (operation) {
+ case ADD:
+ opTlm = ADD_TLM;
+ opPort = MATH_ADD;
+ opEv = ADD_EV;
+ break;
+ case SUBTRACT:
+ opTlm = SUB_TLM;
+ opPort = MATH_SUB;
+ opEv = SUB_EV;
+ break;
+ case MULTIPLY:
+ opTlm = MULT_TLM;
+ opPort = MATH_MULTIPLY;
+ opEv = MULT_EV;
+ break;
+ case DIVIDE:
+ opTlm = DIV_TLM;
+ opPort = MATH_DIVIDE;
+ opEv = DIV_EV;
+ break;
+ default:
+ FW_ASSERT(0,operation);
+ break;
+ }
+
+ this->tlmWrite_MS_OP(opTlm);
+ this->tlmWrite_MS_VAL1(val1);
+ this->tlmWrite_MS_VAL2(val2);
+ this->log_ACTIVITY_LO_MS_COMMAND_RECV(val1,val2,opEv);
+ this->mathOut_out(0,val1,val2,opPort);
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.hpp b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.hpp
new file mode 100644
index 0000000000..3874d33904
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/MathSenderComponentImpl.hpp
@@ -0,0 +1,92 @@
+// ======================================================================
+// \title MathSenderImpl.hpp
+// \author tcanham
+// \brief hpp file for MathSender component implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathSender_HPP
+#define MathSender_HPP
+
+#include "Ref/MathSender/MathSenderComponentAc.hpp"
+
+namespace Ref {
+
+ class MathSenderComponentImpl :
+ public MathSenderComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathSender
+ //!
+ MathSenderComponentImpl(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName /*!< The component name*/
+#else
+ void
+#endif
+ );
+
+ //! Initialize object MathSender
+ //!
+ void init(
+ const NATIVE_INT_TYPE queueDepth, /*!< The queue depth*/
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ //! Destroy object MathSender
+ //!
+ ~MathSenderComponentImpl(void);
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ //! Handler implementation for mathIn
+ //!
+ void mathIn_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ );
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ //! Implementation for MS_DO_MATH command handler
+ //! Do a math operation
+ void MS_DO_MATH_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ F32 val1, /*!< The first value*/
+ F32 val2, /*!< The second value*/
+ MathOp operation /*!< The operation to perform*/
+ );
+
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathSender/docs/MathSender.md b/docs/Tutorials/MathComponent/MathSender/docs/MathSender.md
new file mode 100644
index 0000000000..8e4422af4f
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/docs/MathSender.md
@@ -0,0 +1,32 @@
+MathSender Component Dictionary
+# MathSender Component Dictionary
+
+
+## Command List
+
+|Mnemonic|ID|Description|Arg Name|Arg Type|Comment
+|---|---|---|---|---|---|
+|MS_DO_MATH|0 (0x0)|Do a math operation| | |
+| | | |val1|F32|The first value|
+| | | |val2|F32|The second value|
+| | | |operation|MathOp|The operation to perform|
+
+## Telemetry Channel List
+
+|Channel Name|ID|Type|Description|
+|---|---|---|---|
+|MS_VAL1|0 (0x0)|F32|The first value|
+|MS_VAL2|1 (0x1)|F32|The second value|
+|MS_OP|2 (0x2)|MathOpTlm|The operation|
+|MS_RES|3 (0x3)|F32|The result|
+
+## Event List
+
+|Event Name|ID|Description|Arg Name|Arg Type|Arg Size|Description
+|---|---|---|---|---|---|---|
+|MS_COMMAND_RECV|0 (0x0)|Math command received| | | | |
+| | | |val1|F32||The val1 argument|
+| | | |val2|F32||The val1 argument|
+| | | |op|MathOpEv||The requested operation|
+|MS_RESULT|1 (0x1)|Received math result| | | | |
+| | | |result|F32||The math result|
diff --git a/docs/Tutorials/MathComponent/MathSender/mod.mk b/docs/Tutorials/MathComponent/MathSender/mod.mk
new file mode 100644
index 0000000000..1e9e77ca3a
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/mod.mk
@@ -0,0 +1,5 @@
+SRC = MathSenderComponentAi.xml MathSenderComponentImpl.cpp
+
+HDR = MathSenderComponentImpl.hpp
+
+SUBDIRS = test
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/MathSender/test/mod.mk b/docs/Tutorials/MathComponent/MathSender/test/mod.mk
new file mode 100644
index 0000000000..2b9ea41e51
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/mod.mk
@@ -0,0 +1 @@
+SUBDIRS = ut
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.cpp b/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.cpp
new file mode 100644
index 0000000000..586b48b4c2
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.cpp
@@ -0,0 +1,520 @@
+// ======================================================================
+// \title MathSender/test/ut/GTestBase.cpp
+// \author Auto-generated
+// \brief cpp file for MathSender component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "GTestBase.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ MathSenderGTestBase ::
+ MathSenderGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+ MathSenderTesterBase (
+#if FW_OBJECT_NAMES == 1
+ compName,
+#endif
+ maxHistorySize
+ )
+ {
+
+ }
+
+ MathSenderGTestBase ::
+ ~MathSenderGTestBase(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Commands
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertCmdResponse_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ((unsigned long) size, this->cmdResponseHistory->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of command response history\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->cmdResponseHistory->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertCmdResponse(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ const Fw::CommandResponse response
+ )
+ const
+ {
+ ASSERT_LT(index, this->cmdResponseHistory->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into command response history\n"
+ << " Expected: Less than size of command response history ("
+ << this->cmdResponseHistory->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const CmdResponse& e = this->cmdResponseHistory->at(index);
+ ASSERT_EQ(opCode, e.opCode)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Opcode at index "
+ << index
+ << " in command response history\n"
+ << " Expected: " << opCode << "\n"
+ << " Actual: " << e.opCode << "\n";
+ ASSERT_EQ(cmdSeq, e.cmdSeq)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Command sequence number at index "
+ << index
+ << " in command response history\n"
+ << " Expected: " << cmdSeq << "\n"
+ << " Actual: " << e.cmdSeq << "\n";
+ ASSERT_EQ(response, e.response)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Command response at index "
+ << index
+ << " in command resopnse history\n"
+ << " Expected: " << response << "\n"
+ << " Actual: " << e.response << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Telemetry
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertTlm_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->tlmSize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all telemetry histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmSize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL1
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_VAL1_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MS_VAL1->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MS_VAL1\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MS_VAL1->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_VAL1(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MS_VAL1->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MS_VAL1\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MS_VAL1->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MS_VAL1& e =
+ this->tlmHistory_MS_VAL1->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MS_VAL1\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL2
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_VAL2_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MS_VAL2->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MS_VAL2\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MS_VAL2->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_VAL2(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MS_VAL2->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MS_VAL2\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MS_VAL2->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MS_VAL2& e =
+ this->tlmHistory_MS_VAL2->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MS_VAL2\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_OP
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_OP_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MS_OP->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MS_OP\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MS_OP->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_OP(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const MathSenderComponentBase::MathOpTlm& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MS_OP->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MS_OP\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MS_OP->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MS_OP& e =
+ this->tlmHistory_MS_OP->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MS_OP\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_RES
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_RES_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(this->tlmHistory_MS_RES->size(), size)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for telemetry channel MS_RES\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->tlmHistory_MS_RES->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertTlm_MS_RES(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32& val
+ )
+ const
+ {
+ ASSERT_LT(index, this->tlmHistory_MS_RES->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of telemetry channel MS_RES\n"
+ << " Expected: Less than size of history ("
+ << this->tlmHistory_MS_RES->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const TlmEntry_MS_RES& e =
+ this->tlmHistory_MS_RES->at(index);
+ ASSERT_EQ(val, e.arg)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value at index "
+ << index
+ << " on telmetry channel MS_RES\n"
+ << " Expected: " << val << "\n"
+ << " Actual: " << e.arg << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Events
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertEvents_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventsSize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all event histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventsSize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MS_COMMAND_RECV
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertEvents_MS_COMMAND_RECV_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventHistory_MS_COMMAND_RECV->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MS_COMMAND_RECV\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventHistory_MS_COMMAND_RECV->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertEvents_MS_COMMAND_RECV(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32 val1,
+ const F32 val2,
+ MathSenderComponentBase::MathOpEv op
+ ) const
+ {
+ ASSERT_GT(this->eventHistory_MS_COMMAND_RECV->size(), index)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of event MS_COMMAND_RECV\n"
+ << " Expected: Less than size of history ("
+ << this->eventHistory_MS_COMMAND_RECV->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const EventEntry_MS_COMMAND_RECV& e =
+ this->eventHistory_MS_COMMAND_RECV->at(index);
+ ASSERT_EQ(val1, e.val1)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument val1 at index "
+ << index
+ << " in history of event MS_COMMAND_RECV\n"
+ << " Expected: " << val1 << "\n"
+ << " Actual: " << e.val1 << "\n";
+ ASSERT_EQ(val2, e.val2)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument val2 at index "
+ << index
+ << " in history of event MS_COMMAND_RECV\n"
+ << " Expected: " << val2 << "\n"
+ << " Actual: " << e.val2 << "\n";
+ ASSERT_EQ(op, e.op)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument op at index "
+ << index
+ << " in history of event MS_COMMAND_RECV\n"
+ << " Expected: " << op << "\n"
+ << " Actual: " << e.op << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MS_RESULT
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertEvents_MS_RESULT_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->eventHistory_MS_RESULT->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for event MS_RESULT\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->eventHistory_MS_RESULT->size() << "\n";
+ }
+
+ void MathSenderGTestBase ::
+ assertEvents_MS_RESULT(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 index,
+ const F32 result
+ ) const
+ {
+ ASSERT_GT(this->eventHistory_MS_RESULT->size(), index)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Index into history of event MS_RESULT\n"
+ << " Expected: Less than size of history ("
+ << this->eventHistory_MS_RESULT->size() << ")\n"
+ << " Actual: " << index << "\n";
+ const EventEntry_MS_RESULT& e =
+ this->eventHistory_MS_RESULT->at(index);
+ ASSERT_EQ(result, e.result)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Value of argument result at index "
+ << index
+ << " in history of event MS_RESULT\n"
+ << " Expected: " << result << "\n"
+ << " Actual: " << e.result << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assertFromPortHistory_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistorySize)
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Total size of all from port histories\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistorySize << "\n";
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void MathSenderGTestBase ::
+ assert_from_mathOut_size(
+ const char *const __callSiteFileName,
+ const U32 __callSiteLineNumber,
+ const U32 size
+ ) const
+ {
+ ASSERT_EQ(size, this->fromPortHistory_mathOut->size())
+ << "\n"
+ << " File: " << __callSiteFileName << "\n"
+ << " Line: " << __callSiteLineNumber << "\n"
+ << " Value: Size of history for from_mathOut\n"
+ << " Expected: " << size << "\n"
+ << " Actual: " << this->fromPortHistory_mathOut->size() << "\n";
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.hpp b/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.hpp
new file mode 100644
index 0000000000..ac1137d8e3
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/GTestBase.hpp
@@ -0,0 +1,370 @@
+// ======================================================================
+// \title MathSender/test/ut/GTestBase.hpp
+// \author Auto-generated
+// \brief hpp file for MathSender component Google Test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathSender_GTEST_BASE_HPP
+#define MathSender_GTEST_BASE_HPP
+
+#include "TesterBase.hpp"
+#include "gtest/gtest.h"
+
+// ----------------------------------------------------------------------
+// Macros for command history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_CMD_RESPONSE_SIZE(size) \
+ this->assertCmdResponse_size(__FILE__, __LINE__, size)
+
+#define ASSERT_CMD_RESPONSE(index, opCode, cmdSeq, response) \
+ this->assertCmdResponse(__FILE__, __LINE__, index, opCode, cmdSeq, response)
+
+// ----------------------------------------------------------------------
+// Macros for telemetry history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_TLM_SIZE(size) \
+ this->assertTlm_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MS_VAL1_SIZE(size) \
+ this->assertTlm_MS_VAL1_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MS_VAL1(index, value) \
+ this->assertTlm_MS_VAL1(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MS_VAL2_SIZE(size) \
+ this->assertTlm_MS_VAL2_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MS_VAL2(index, value) \
+ this->assertTlm_MS_VAL2(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MS_OP_SIZE(size) \
+ this->assertTlm_MS_OP_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MS_OP(index, value) \
+ this->assertTlm_MS_OP(__FILE__, __LINE__, index, value)
+
+#define ASSERT_TLM_MS_RES_SIZE(size) \
+ this->assertTlm_MS_RES_size(__FILE__, __LINE__, size)
+
+#define ASSERT_TLM_MS_RES(index, value) \
+ this->assertTlm_MS_RES(__FILE__, __LINE__, index, value)
+
+// ----------------------------------------------------------------------
+// Macros for event history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_EVENTS_SIZE(size) \
+ this->assertEvents_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(size) \
+ this->assertEvents_MS_COMMAND_RECV_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MS_COMMAND_RECV(index, _val1, _val2, _op) \
+ this->assertEvents_MS_COMMAND_RECV(__FILE__, __LINE__, index, _val1, _val2, _op)
+
+#define ASSERT_EVENTS_MS_RESULT_SIZE(size) \
+ this->assertEvents_MS_RESULT_size(__FILE__, __LINE__, size)
+
+#define ASSERT_EVENTS_MS_RESULT(index, _result) \
+ this->assertEvents_MS_RESULT(__FILE__, __LINE__, index, _result)
+
+// ----------------------------------------------------------------------
+// Macros for typed user from port history assertions
+// ----------------------------------------------------------------------
+
+#define ASSERT_FROM_PORT_HISTORY_SIZE(size) \
+ this->assertFromPortHistory_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_mathOut_SIZE(size) \
+ this->assert_from_mathOut_size(__FILE__, __LINE__, size)
+
+#define ASSERT_from_mathOut(index, _val1, _val2, _operation) \
+ { \
+ ASSERT_GT(this->fromPortHistory_mathOut->size(), static_cast(index)) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Index into history of from_mathOut\n" \
+ << " Expected: Less than size of history (" \
+ << this->fromPortHistory_mathOut->size() << ")\n" \
+ << " Actual: " << index << "\n"; \
+ const FromPortEntry_mathOut& _e = \
+ this->fromPortHistory_mathOut->at(index); \
+ ASSERT_EQ(_val1, _e.val1) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Value of argument val1 at index " \
+ << index \
+ << " in history of from_mathOut\n" \
+ << " Expected: " << _val1 << "\n" \
+ << " Actual: " << _e.val1 << "\n"; \
+ ASSERT_EQ(_val2, _e.val2) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Value of argument val2 at index " \
+ << index \
+ << " in history of from_mathOut\n" \
+ << " Expected: " << _val2 << "\n" \
+ << " Actual: " << _e.val2 << "\n"; \
+ ASSERT_EQ(_operation, _e.operation) \
+ << "\n" \
+ << " File: " << __FILE__ << "\n" \
+ << " Line: " << __LINE__ << "\n" \
+ << " Value: Value of argument operation at index " \
+ << index \
+ << " in history of from_mathOut\n" \
+ << " Expected: " << _operation << "\n" \
+ << " Actual: " << _e.operation << "\n"; \
+ }
+
+namespace Ref {
+
+ //! \class MathSenderGTestBase
+ //! \brief Auto-generated base class for MathSender component Google Test harness
+ //!
+ class MathSenderGTestBase :
+ public MathSenderTesterBase
+ {
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathSenderGTestBase
+ //!
+ MathSenderGTestBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object MathSenderGTestBase
+ //!
+ virtual ~MathSenderGTestBase(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Commands
+ // ----------------------------------------------------------------------
+
+ //! Assert size of command response history
+ //!
+ void assertCmdResponse_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ //! Assert command response in history at index
+ //!
+ void assertCmdResponse(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ const Fw::CommandResponse response /*!< The command response*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Telemetry
+ // ----------------------------------------------------------------------
+
+ //! Assert size of telemetry history
+ //!
+ void assertTlm_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL1
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MS_VAL1_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MS_VAL1(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL2
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MS_VAL2_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MS_VAL2(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_OP
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MS_OP_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MS_OP(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const MathSenderComponentBase::MathOpTlm& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_RES
+ // ----------------------------------------------------------------------
+
+ //! Assert telemetry value in history at index
+ //!
+ void assertTlm_MS_RES_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertTlm_MS_RES(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32& val /*!< The channel value*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Events
+ // ----------------------------------------------------------------------
+
+ void assertEvents_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MS_COMMAND_RECV
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MS_COMMAND_RECV_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertEvents_MS_COMMAND_RECV(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32 val1, /*!< The val1 argument*/
+ const F32 val2, /*!< The val1 argument*/
+ MathSenderComponentBase::MathOpEv op /*!< The requested operation*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MS_RESULT
+ // ----------------------------------------------------------------------
+
+ void assertEvents_MS_RESULT_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ void assertEvents_MS_RESULT(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 index, /*!< The index*/
+ const F32 result /*!< The math result*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ void assertFromPortHistory_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void assert_from_mathOut_size(
+ const char *const __callSiteFileName, /*!< The name of the file containing the call site*/
+ const U32 __callSiteLineNumber, /*!< The line number of the call site*/
+ const U32 size /*!< The asserted size*/
+ ) const;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.cpp b/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.cpp
new file mode 100644
index 0000000000..e7f9ae51f8
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.cpp
@@ -0,0 +1,359 @@
+// ======================================================================
+// \title MathSender.hpp
+// \author tcanham
+// \brief cpp file for MathSender test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include "Tester.hpp"
+
+#define INSTANCE 0
+#define MAX_HISTORY_SIZE 10
+#define QUEUE_DEPTH 10
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ Tester ::
+ Tester(void) :
+#if FW_OBJECT_NAMES == 1
+ MathSenderGTestBase("Tester", MAX_HISTORY_SIZE),
+ component("MathSender")
+#else
+ MathSenderGTestBase(MAX_HISTORY_SIZE),
+ component()
+#endif
+ {
+ this->initComponents();
+ this->connectPorts();
+ }
+
+ Tester ::
+ ~Tester(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ testAddCommand(void)
+ {
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::ADD);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_ADD);
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::ADD_TLM);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::ADD_EV);
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+
+ // reset all telemetry and port history
+ this->clearHistory();
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expected value of the event arguments
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+ }
+
+ void Tester ::
+ testSubCommand(void)
+ {
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::SUBTRACT);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_SUB);
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::SUB_TLM);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::SUB_EV);
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+
+ // reset all telemetry and port history
+ this->clearHistory();
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expect value of the event
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+ }
+
+ void Tester ::
+ testMultCommand(void)
+ {
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::MULTIPLY);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_MULTIPLY);
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::MULT_TLM);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::MULT_EV);
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+
+ // reset all telemetry and port history
+ this->clearHistory();
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expect value of the event
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+ }
+
+ void Tester ::
+ testDivCommand(void)
+ {
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::DIVIDE);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_DIVIDE);
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::DIV_TLM);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::DIV_EV);
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+
+ // reset all telemetry and port history
+ this->clearHistory();
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expect value of the event
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+ }
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ this->pushFromPortEntry_mathOut(val1, val2, operation);
+ }
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ connectPorts(void)
+ {
+
+ // mathIn
+ this->connect_to_mathIn(
+ 0,
+ this->component.get_mathIn_InputPort(0)
+ );
+
+ // CmdDisp
+ this->connect_to_CmdDisp(
+ 0,
+ this->component.get_CmdDisp_InputPort(0)
+ );
+
+ // mathOut
+ this->component.set_mathOut_OutputPort(
+ 0,
+ this->get_from_mathOut(0)
+ );
+
+ // CmdStatus
+ this->component.set_CmdStatus_OutputPort(
+ 0,
+ this->get_from_CmdStatus(0)
+ );
+
+ // CmdReg
+ this->component.set_CmdReg_OutputPort(
+ 0,
+ this->get_from_CmdReg(0)
+ );
+
+ // Tlm
+ this->component.set_Tlm_OutputPort(
+ 0,
+ this->get_from_Tlm(0)
+ );
+
+ // Time
+ this->component.set_Time_OutputPort(
+ 0,
+ this->get_from_Time(0)
+ );
+
+ // Log
+ this->component.set_Log_OutputPort(
+ 0,
+ this->get_from_Log(0)
+ );
+
+ // LogText
+ this->component.set_LogText_OutputPort(
+ 0,
+ this->get_from_LogText(0)
+ );
+
+ }
+
+ void Tester ::
+ initComponents(void)
+ {
+ this->init();
+ this->component.init(
+ QUEUE_DEPTH, INSTANCE
+ );
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.hpp b/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.hpp
new file mode 100644
index 0000000000..7059cb2956
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/Tester.hpp
@@ -0,0 +1,102 @@
+// ======================================================================
+// \title MathSender/test/ut/Tester.hpp
+// \author tcanham
+// \brief hpp file for MathSender test harness implementation class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef TESTER_HPP
+#define TESTER_HPP
+
+#include "GTestBase.hpp"
+#include "Ref/MathSender/MathSenderComponentImpl.hpp"
+
+namespace Ref {
+
+ class Tester :
+ public MathSenderGTestBase
+ {
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ public:
+
+ //! Construct object Tester
+ //!
+ Tester(void);
+
+ //! Destroy object Tester
+ //!
+ ~Tester(void);
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ //! Test operation command
+ //!
+ void testAddCommand(void);
+ void testSubCommand(void);
+ void testMultCommand(void);
+ void testDivCommand(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Handlers for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler for from_mathOut
+ //!
+ void from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Helper methods
+ // ----------------------------------------------------------------------
+
+ //! Connect ports
+ //!
+ void connectPorts(void);
+
+ //! Initialize components
+ //!
+ void initComponents(void);
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Variables
+ // ----------------------------------------------------------------------
+
+ //! The component under test
+ //!
+ MathSenderComponentImpl component;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.cpp b/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.cpp
new file mode 100644
index 0000000000..381415144e
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.cpp
@@ -0,0 +1,1175 @@
+// ======================================================================
+// \title MathSender/test/ut/TesterBase.cpp
+// \author Auto-generated
+// \brief cpp file for MathSender component test harness base class
+//
+// \copyright
+// Copyright 2009-2016, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#include
+#include
+#include "TesterBase.hpp"
+
+namespace Ref {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ MathSenderTesterBase ::
+ MathSenderTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName,
+ const U32 maxHistorySize
+#else
+ const U32 maxHistorySize
+#endif
+ ) :
+#if FW_OBJECT_NAMES == 1
+ Fw::PassiveComponentBase(compName)
+#else
+ Fw::PassiveComponentBase()
+#endif
+ {
+ // Initialize command history
+ this->cmdResponseHistory = new History(maxHistorySize);
+ // Initialize telemetry histories
+ this->tlmHistory_MS_VAL1 =
+ new History(maxHistorySize);
+ this->tlmHistory_MS_VAL2 =
+ new History(maxHistorySize);
+ this->tlmHistory_MS_OP =
+ new History(maxHistorySize);
+ this->tlmHistory_MS_RES =
+ new History(maxHistorySize);
+ // Initialize event histories
+#if FW_ENABLE_TEXT_LOGGING
+ this->textLogHistory = new History(maxHistorySize);
+#endif
+ this->eventHistory_MS_COMMAND_RECV =
+ new History(maxHistorySize);
+ this->eventHistory_MS_RESULT =
+ new History(maxHistorySize);
+ // Initialize histories for typed user output ports
+ this->fromPortHistory_mathOut =
+ new History(maxHistorySize);
+ // Clear history
+ this->clearHistory();
+ }
+
+ MathSenderTesterBase ::
+ ~MathSenderTesterBase(void)
+ {
+ // Destroy command history
+ delete this->cmdResponseHistory;
+ // Destroy telemetry histories
+ delete this->tlmHistory_MS_VAL1;
+ delete this->tlmHistory_MS_VAL2;
+ delete this->tlmHistory_MS_OP;
+ delete this->tlmHistory_MS_RES;
+ // Destroy event histories
+#if FW_ENABLE_TEXT_LOGGING
+ delete this->textLogHistory;
+#endif
+ delete this->eventHistory_MS_COMMAND_RECV;
+ delete this->eventHistory_MS_RESULT;
+ }
+
+ void MathSenderTesterBase ::
+ init(
+ const NATIVE_INT_TYPE instance
+ )
+ {
+
+ // Initialize base class
+
+ Fw::PassiveComponentBase::init(instance);
+
+ // Attach input port mathOut
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_mathOut();
+ ++_port
+ ) {
+
+ this->m_from_mathOut[_port].init();
+ this->m_from_mathOut[_port].addCallComp(
+ this,
+ from_mathOut_static
+ );
+ this->m_from_mathOut[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_mathOut[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_mathOut[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port CmdStatus
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_CmdStatus();
+ ++_port
+ ) {
+
+ this->m_from_CmdStatus[_port].init();
+ this->m_from_CmdStatus[_port].addCallComp(
+ this,
+ from_CmdStatus_static
+ );
+ this->m_from_CmdStatus[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_CmdStatus[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_CmdStatus[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port CmdReg
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_CmdReg();
+ ++_port
+ ) {
+
+ this->m_from_CmdReg[_port].init();
+ this->m_from_CmdReg[_port].addCallComp(
+ this,
+ from_CmdReg_static
+ );
+ this->m_from_CmdReg[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_CmdReg[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_CmdReg[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Tlm
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Tlm();
+ ++_port
+ ) {
+
+ this->m_from_Tlm[_port].init();
+ this->m_from_Tlm[_port].addCallComp(
+ this,
+ from_Tlm_static
+ );
+ this->m_from_Tlm[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Tlm[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Tlm[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Time
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Time();
+ ++_port
+ ) {
+
+ this->m_from_Time[_port].init();
+ this->m_from_Time[_port].addCallComp(
+ this,
+ from_Time_static
+ );
+ this->m_from_Time[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Time[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Time[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port Log
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_Log();
+ ++_port
+ ) {
+
+ this->m_from_Log[_port].init();
+ this->m_from_Log[_port].addCallComp(
+ this,
+ from_Log_static
+ );
+ this->m_from_Log[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_Log[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_Log[_port].setObjName(_portName);
+#endif
+
+ }
+
+ // Attach input port LogText
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_from_LogText();
+ ++_port
+ ) {
+
+ this->m_from_LogText[_port].init();
+ this->m_from_LogText[_port].addCallComp(
+ this,
+ from_LogText_static
+ );
+ this->m_from_LogText[_port].setPortNum(_port);
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ (void) snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_from_LogText[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_from_LogText[_port].setObjName(_portName);
+#endif
+
+ }
+#endif
+
+ // Initialize output port mathIn
+
+ for (
+ NATIVE_INT_TYPE _port = 0;
+ _port < this->getNum_to_mathIn();
+ ++_port
+ ) {
+ this->m_to_mathIn[_port].init();
+
+#if FW_OBJECT_NAMES == 1
+ char _portName[80];
+ snprintf(
+ _portName,
+ sizeof(_portName),
+ "%s_to_mathIn[%d]",
+ this->m_objName,
+ _port
+ );
+ this->m_to_mathIn[_port].setObjName(_portName);
+#endif
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_mathOut(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_mathOut);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_to_mathIn(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_mathIn);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_to_CmdDisp(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_to_CmdDisp);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_CmdStatus(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_CmdStatus);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_CmdReg(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_CmdReg);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_Tlm(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Tlm);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_Time(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Time);
+ }
+
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_Log(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_Log);
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ NATIVE_INT_TYPE MathSenderTesterBase ::
+ getNum_from_LogText(void) const
+ {
+ return (NATIVE_INT_TYPE) FW_NUM_ARRAY_ELEMENTS(this->m_from_LogText);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Connectors for to ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ connect_to_mathIn(
+ const NATIVE_INT_TYPE portNum,
+ Ref::InputMathResultPort *const mathIn
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ this->m_to_mathIn[portNum].addCallPort(mathIn);
+ }
+
+ void MathSenderTesterBase ::
+ connect_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum,
+ Fw::InputCmdPort *const CmdDisp
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_CmdDisp(),static_cast(portNum));
+ this->m_to_CmdDisp[portNum].addCallPort(CmdDisp);
+ }
+
+
+ // ----------------------------------------------------------------------
+ // Invocation functions for to ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ invoke_to_mathIn(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ FW_ASSERT(portNum < this->getNum_to_mathIn(),static_cast(portNum));
+ this->m_to_mathIn[portNum].invoke(
+ result
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // Connection status for to ports
+ // ----------------------------------------------------------------------
+
+ bool MathSenderTesterBase ::
+ isConnected_to_mathIn(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_mathIn(), static_cast(portNum));
+ return this->m_to_mathIn[portNum].isConnected();
+ }
+
+ bool MathSenderTesterBase ::
+ isConnected_to_CmdDisp(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_to_CmdDisp(), static_cast(portNum));
+ return this->m_to_CmdDisp[portNum].isConnected();
+ }
+
+ // ----------------------------------------------------------------------
+ // Getters for from ports
+ // ----------------------------------------------------------------------
+
+ Ref::InputMathOpPort *MathSenderTesterBase ::
+ get_from_mathOut(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_mathOut(),static_cast(portNum));
+ return &this->m_from_mathOut[portNum];
+ }
+
+ Fw::InputCmdResponsePort *MathSenderTesterBase ::
+ get_from_CmdStatus(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_CmdStatus(),static_cast(portNum));
+ return &this->m_from_CmdStatus[portNum];
+ }
+
+ Fw::InputCmdRegPort *MathSenderTesterBase ::
+ get_from_CmdReg(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_CmdReg(),static_cast(portNum));
+ return &this->m_from_CmdReg[portNum];
+ }
+
+ Fw::InputTlmPort *MathSenderTesterBase ::
+ get_from_Tlm(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Tlm(),static_cast(portNum));
+ return &this->m_from_Tlm[portNum];
+ }
+
+ Fw::InputTimePort *MathSenderTesterBase ::
+ get_from_Time(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Time(),static_cast(portNum));
+ return &this->m_from_Time[portNum];
+ }
+
+ Fw::InputLogPort *MathSenderTesterBase ::
+ get_from_Log(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_Log(),static_cast(portNum));
+ return &this->m_from_Log[portNum];
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ Fw::InputLogTextPort *MathSenderTesterBase ::
+ get_from_LogText(const NATIVE_INT_TYPE portNum)
+ {
+ FW_ASSERT(portNum < this->getNum_from_LogText(),static_cast(portNum));
+ return &this->m_from_LogText[portNum];
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Static functions for from ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ from_mathOut_static(
+ Fw::PassiveComponentBase *const callComp,
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ FW_ASSERT(callComp);
+ MathSenderTesterBase* _testerBase =
+ static_cast(callComp);
+ _testerBase->from_mathOut_handlerBase(
+ portNum,
+ val1, val2, operation
+ );
+ }
+
+ void MathSenderTesterBase ::
+ from_CmdStatus_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ const Fw::CommandResponse response
+ )
+ {
+ MathSenderTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->cmdResponseIn(opCode, cmdSeq, response);
+ }
+
+ void MathSenderTesterBase ::
+ from_CmdReg_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ const FwOpcodeType opCode
+ )
+ {
+
+ }
+
+ void MathSenderTesterBase ::
+ from_Tlm_static(
+ Fw::PassiveComponentBase *const component,
+ NATIVE_INT_TYPE portNum,
+ FwChanIdType id,
+ Fw::Time &timeTag,
+ Fw::TlmBuffer &val
+ )
+ {
+ MathSenderTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->dispatchTlm(id, timeTag, val);
+ }
+
+ void MathSenderTesterBase ::
+ from_Log_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ FwEventIdType id,
+ Fw::Time &timeTag,
+ Fw::LogSeverity severity,
+ Fw::LogBuffer &args
+ )
+ {
+ MathSenderTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->dispatchEvents(id, timeTag, severity, args);
+ }
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ void MathSenderTesterBase ::
+ from_LogText_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ FwEventIdType id,
+ Fw::Time &timeTag,
+ Fw::TextLogSeverity severity,
+ Fw::TextLogString &text
+ )
+ {
+ MathSenderTesterBase* _testerBase =
+ static_cast(component);
+ _testerBase->textLogIn(id,timeTag,severity,text);
+ }
+#endif
+
+ void MathSenderTesterBase ::
+ from_Time_static(
+ Fw::PassiveComponentBase *const component,
+ const NATIVE_INT_TYPE portNum,
+ Fw::Time& time
+ )
+ {
+ MathSenderTesterBase* _testerBase =
+ static_cast(component);
+ time = _testerBase->m_testTime;
+ }
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ clearFromPortHistory(void)
+ {
+ this->fromPortHistorySize = 0;
+ this->fromPortHistory_mathOut->clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // From port: mathOut
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ pushFromPortEntry_mathOut(
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ FromPortEntry_mathOut _e = {
+ val1, val2, operation
+ };
+ this->fromPortHistory_mathOut->push_back(_e);
+ ++this->fromPortHistorySize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler base functions for from ports
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ from_mathOut_handlerBase(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ FW_ASSERT(portNum < this->getNum_from_mathOut(),static_cast(portNum));
+ this->from_mathOut_handler(
+ portNum,
+ val1, val2, operation
+ );
+ }
+
+ // ----------------------------------------------------------------------
+ // Command response handling
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ cmdResponseIn(
+ const FwOpcodeType opCode,
+ const U32 seq,
+ const Fw::CommandResponse response
+ )
+ {
+ CmdResponse e = { opCode, seq, response };
+ this->cmdResponseHistory->push_back(e);
+ }
+
+ // ----------------------------------------------------------------------
+ // Command: MS_DO_MATH
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ sendCmd_MS_DO_MATH(
+ const NATIVE_INT_TYPE instance,
+ const U32 cmdSeq,
+ F32 val1,
+ F32 val2,
+ MathSenderComponentBase::MathOp operation
+ )
+ {
+
+ // Serialize arguments
+
+ Fw::CmdArgBuffer buff;
+ Fw::SerializeStatus _status;
+ _status = buff.serialize(val1);
+ FW_ASSERT(_status == Fw::FW_SERIALIZE_OK,static_cast(_status));
+ _status = buff.serialize(val2);
+ FW_ASSERT(_status == Fw::FW_SERIALIZE_OK,static_cast(_status));
+ _status = buff.serialize((FwEnumStoreType) operation);
+ FW_ASSERT(_status == Fw::FW_SERIALIZE_OK,static_cast(_status));
+
+ // Call output command port
+
+ FwOpcodeType _opcode;
+ const U32 idBase = this->getIdBase();
+ _opcode = MathSenderComponentBase::OPCODE_MS_DO_MATH + idBase;
+
+ if (this->m_to_CmdDisp[0].isConnected()) {
+ this->m_to_CmdDisp[0].invoke(
+ _opcode,
+ cmdSeq,
+ buff
+ );
+ }
+ else {
+ printf("Test Command Output port not connected!\n");
+ }
+
+ }
+
+
+ void MathSenderTesterBase ::
+ sendRawCmd(FwOpcodeType opcode, U32 cmdSeq, Fw::CmdArgBuffer& args) {
+
+ const U32 idBase = this->getIdBase();
+ FwOpcodeType _opcode = opcode + idBase;
+ if (this->m_to_CmdDisp[0].isConnected()) {
+ this->m_to_CmdDisp[0].invoke(
+ _opcode,
+ cmdSeq,
+ args
+ );
+ }
+ else {
+ printf("Test Command Output port not connected!\n");
+ }
+
+ }
+
+ // ----------------------------------------------------------------------
+ // History
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ clearHistory()
+ {
+ this->cmdResponseHistory->clear();
+ this->clearTlm();
+ this->textLogHistory->clear();
+ this->clearEvents();
+ this->clearFromPortHistory();
+ }
+
+ // ----------------------------------------------------------------------
+ // Time
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ setTestTime(const Fw::Time& time)
+ {
+ this->m_testTime = time;
+ }
+
+ // ----------------------------------------------------------------------
+ // Telemetry dispatch
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ dispatchTlm(
+ const FwChanIdType id,
+ const Fw::Time &timeTag,
+ Fw::TlmBuffer &val
+ )
+ {
+
+ val.resetDeser();
+
+ const U32 idBase = this->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+
+ switch (id - idBase) {
+
+ case MathSenderComponentBase::CHANNELID_MS_VAL1:
+ {
+ F32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MS_VAL1: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MS_VAL1(timeTag, arg);
+ break;
+ }
+
+ case MathSenderComponentBase::CHANNELID_MS_VAL2:
+ {
+ F32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MS_VAL2: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MS_VAL2(timeTag, arg);
+ break;
+ }
+
+ case MathSenderComponentBase::CHANNELID_MS_OP:
+ {
+ FwEnumStoreType MS_OParg;
+ const Fw::SerializeStatus _status = val.deserialize(MS_OParg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MS_OP: %d\n", _status);
+ return;
+ }
+ MathSenderComponentBase::MathOpTlm arg =
+ static_cast(MS_OParg);
+ this->tlmInput_MS_OP(timeTag, arg);
+ break;
+ }
+
+ case MathSenderComponentBase::CHANNELID_MS_RES:
+ {
+ F32 arg;
+ const Fw::SerializeStatus _status = val.deserialize(arg);
+ if (_status != Fw::FW_SERIALIZE_OK) {
+ printf("Error deserializing MS_RES: %d\n", _status);
+ return;
+ }
+ this->tlmInput_MS_RES(timeTag, arg);
+ break;
+ }
+
+ default: {
+ FW_ASSERT(0, id);
+ break;
+ }
+
+ }
+
+ }
+
+ void MathSenderTesterBase ::
+ clearTlm(void)
+ {
+ this->tlmSize = 0;
+ this->tlmHistory_MS_VAL1->clear();
+ this->tlmHistory_MS_VAL2->clear();
+ this->tlmHistory_MS_OP->clear();
+ this->tlmHistory_MS_RES->clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL1
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ tlmInput_MS_VAL1(
+ const Fw::Time& timeTag,
+ const F32& val
+ )
+ {
+ TlmEntry_MS_VAL1 e = { timeTag, val };
+ this->tlmHistory_MS_VAL1->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL2
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ tlmInput_MS_VAL2(
+ const Fw::Time& timeTag,
+ const F32& val
+ )
+ {
+ TlmEntry_MS_VAL2 e = { timeTag, val };
+ this->tlmHistory_MS_VAL2->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_OP
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ tlmInput_MS_OP(
+ const Fw::Time& timeTag,
+ const MathSenderComponentBase::MathOpTlm& val
+ )
+ {
+ TlmEntry_MS_OP e = { timeTag, val };
+ this->tlmHistory_MS_OP->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_RES
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ tlmInput_MS_RES(
+ const Fw::Time& timeTag,
+ const F32& val
+ )
+ {
+ TlmEntry_MS_RES e = { timeTag, val };
+ this->tlmHistory_MS_RES->push_back(e);
+ ++this->tlmSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event dispatch
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ dispatchEvents(
+ const FwEventIdType id,
+ Fw::Time &timeTag,
+ const Fw::LogSeverity severity,
+ Fw::LogBuffer &args
+ )
+ {
+
+ args.resetDeser();
+
+ const U32 idBase = this->getIdBase();
+ FW_ASSERT(id >= idBase, id, idBase);
+ switch (id - idBase) {
+
+ case MathSenderComponentBase::EVENTID_MS_COMMAND_RECV:
+ {
+
+ Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
+#if FW_AMPCS_COMPATIBLE
+ // Deserialize the number of arguments.
+ U8 _numArgs;
+ _status = args.deserialize(_numArgs);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ // verify they match expected.
+ FW_ASSERT(_numArgs == 3,_numArgs,3);
+
+#endif
+ F32 val1;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(F32),_argSize,sizeof(F32));
+ }
+#endif
+ _status = args.deserialize(val1);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ F32 val2;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(F32),_argSize,sizeof(F32));
+ }
+#endif
+ _status = args.deserialize(val2);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(FwEnumStoreType),_argSize,sizeof(FwEnumStoreType));
+ }
+#endif
+ FwEnumStoreType opInt;
+ _status = args.deserialize(opInt);
+ MathSenderComponentBase::MathOpEv op = static_cast(opInt);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ this->logIn_ACTIVITY_LO_MS_COMMAND_RECV(val1, val2, op);
+
+ break;
+
+ }
+
+ case MathSenderComponentBase::EVENTID_MS_RESULT:
+ {
+
+ Fw::SerializeStatus _status = Fw::FW_SERIALIZE_OK;
+#if FW_AMPCS_COMPATIBLE
+ // Deserialize the number of arguments.
+ U8 _numArgs;
+ _status = args.deserialize(_numArgs);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ // verify they match expected.
+ FW_ASSERT(_numArgs == 1,_numArgs,1);
+
+#endif
+ F32 result;
+#if FW_AMPCS_COMPATIBLE
+ {
+ // Deserialize the argument size
+ U8 _argSize;
+ _status = args.deserialize(_argSize);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+ FW_ASSERT(_argSize == sizeof(F32),_argSize,sizeof(F32));
+ }
+#endif
+ _status = args.deserialize(result);
+ FW_ASSERT(
+ _status == Fw::FW_SERIALIZE_OK,
+ static_cast(_status)
+ );
+
+ this->logIn_ACTIVITY_HI_MS_RESULT(result);
+
+ break;
+
+ }
+
+ default: {
+ FW_ASSERT(0, id);
+ break;
+ }
+
+ }
+
+ }
+
+ void MathSenderTesterBase ::
+ clearEvents(void)
+ {
+ this->eventsSize = 0;
+ this->eventHistory_MS_COMMAND_RECV->clear();
+ this->eventHistory_MS_RESULT->clear();
+ }
+
+#if FW_ENABLE_TEXT_LOGGING
+
+ // ----------------------------------------------------------------------
+ // Text events
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ textLogIn(
+ const U32 id,
+ Fw::Time &timeTag,
+ const Fw::TextLogSeverity severity,
+ const Fw::TextLogString &text
+ )
+ {
+ TextLogEntry e = { id, timeTag, severity, text };
+ textLogHistory->push_back(e);
+ }
+
+ void MathSenderTesterBase ::
+ printTextLogHistoryEntry(
+ const TextLogEntry& e,
+ FILE* file
+ )
+ {
+ const char *severityString = "UNKNOWN";
+ switch (e.severity) {
+ case Fw::LOG_FATAL:
+ severityString = "FATAL";
+ break;
+ case Fw::LOG_WARNING_HI:
+ severityString = "WARNING_HI";
+ break;
+ case Fw::LOG_WARNING_LO:
+ severityString = "WARNING_LO";
+ break;
+ case Fw::LOG_COMMAND:
+ severityString = "COMMAND";
+ break;
+ case Fw::LOG_ACTIVITY_HI:
+ severityString = "ACTIVITY_HI";
+ break;
+ case Fw::LOG_ACTIVITY_LO:
+ severityString = "ACTIVITY_LO";
+ break;
+ case Fw::LOG_DIAGNOSTIC:
+ severityString = "DIAGNOSTIC";
+ break;
+ default:
+ severityString = "SEVERITY ERROR";
+ break;
+ }
+
+ fprintf(
+ file,
+ "EVENT: (%d) (%d:%d,%d) %s: %s\n",
+ e.id,
+ const_cast(e).timeTag.getTimeBase(),
+ const_cast(e).timeTag.getSeconds(),
+ const_cast(e).timeTag.getUSeconds(),
+ severityString,
+ e.text.toChar()
+ );
+
+ }
+
+ void MathSenderTesterBase ::
+ printTextLogHistory(FILE *file)
+ {
+ for (U32 i = 0; i < this->textLogHistory->size(); ++i) {
+ this->printTextLogHistoryEntry(
+ this->textLogHistory->at(i),
+ file
+ );
+ }
+ }
+
+#endif
+
+ // ----------------------------------------------------------------------
+ // Event: MS_COMMAND_RECV
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ logIn_ACTIVITY_LO_MS_COMMAND_RECV(
+ F32 val1,
+ F32 val2,
+ MathSenderComponentBase::MathOpEv op
+ )
+ {
+ EventEntry_MS_COMMAND_RECV e = {
+ val1, val2, op
+ };
+ eventHistory_MS_COMMAND_RECV->push_back(e);
+ ++this->eventsSize;
+ }
+
+ // ----------------------------------------------------------------------
+ // Event: MS_RESULT
+ // ----------------------------------------------------------------------
+
+ void MathSenderTesterBase ::
+ logIn_ACTIVITY_HI_MS_RESULT(
+ F32 result
+ )
+ {
+ EventEntry_MS_RESULT e = {
+ result
+ };
+ eventHistory_MS_RESULT->push_back(e);
+ ++this->eventsSize;
+ }
+
+} // end namespace Ref
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.hpp b/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.hpp
new file mode 100644
index 0000000000..53799e78dd
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/TesterBase.hpp
@@ -0,0 +1,827 @@
+// ======================================================================
+// \title MathSender/test/ut/TesterBase.hpp
+// \author Auto-generated
+// \brief hpp file for MathSender component test harness base class
+//
+// \copyright
+// Copyright 2009-2015, by the California Institute of Technology.
+// ALL RIGHTS RESERVED. United States Government Sponsorship
+// acknowledged. Any commercial use must be negotiated with the Office
+// of Technology Transfer at the California Institute of Technology.
+//
+// This software may be subject to U.S. export control laws and
+// regulations. By accepting this document, the user agrees to comply
+// with all U.S. export laws and regulations. User has the
+// responsibility to obtain export licenses, or other export authority
+// as may be required before exporting such information to foreign
+// countries or providing access to foreign persons.
+// ======================================================================
+
+#ifndef MathSender_TESTER_BASE_HPP
+#define MathSender_TESTER_BASE_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Ref {
+
+ //! \class MathSenderTesterBase
+ //! \brief Auto-generated base class for MathSender component test harness
+ //!
+ class MathSenderTesterBase :
+ public Fw::PassiveComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Initialization
+ // ----------------------------------------------------------------------
+
+ //! Initialize object MathSenderTesterBase
+ //!
+ virtual void init(
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Connectors for 'to' ports
+ // Connect these output ports to the input ports under test
+ // ----------------------------------------------------------------------
+
+ //! Connect mathIn to to_mathIn[portNum]
+ //!
+ void connect_to_mathIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Ref::InputMathResultPort *const mathIn /*!< The port*/
+ );
+
+ //! Connect CmdDisp to to_CmdDisp[portNum]
+ //!
+ void connect_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Fw::InputCmdPort *const CmdDisp /*!< The port*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for 'from' ports
+ // Connect these input ports to the output ports under test
+ // ----------------------------------------------------------------------
+
+ //! Get the port that receives input from mathOut
+ //!
+ //! \return from_mathOut[portNum]
+ //!
+ Ref::InputMathOpPort* get_from_mathOut(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from CmdStatus
+ //!
+ //! \return from_CmdStatus[portNum]
+ //!
+ Fw::InputCmdResponsePort* get_from_CmdStatus(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from CmdReg
+ //!
+ //! \return from_CmdReg[portNum]
+ //!
+ Fw::InputCmdRegPort* get_from_CmdReg(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Tlm
+ //!
+ //! \return from_Tlm[portNum]
+ //!
+ Fw::InputTlmPort* get_from_Tlm(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Time
+ //!
+ //! \return from_Time[portNum]
+ //!
+ Fw::InputTimePort* get_from_Time(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Get the port that receives input from Log
+ //!
+ //! \return from_Log[portNum]
+ //!
+ Fw::InputLogPort* get_from_Log(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Get the port that receives input from LogText
+ //!
+ //! \return from_LogText[portNum]
+ //!
+ Fw::InputLogTextPort* get_from_LogText(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object MathSenderTesterBase
+ //!
+ MathSenderTesterBase(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName, /*!< The component name*/
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#else
+ const U32 maxHistorySize /*!< The maximum size of each history*/
+#endif
+ );
+
+ //! Destroy object MathSenderTesterBase
+ //!
+ virtual ~MathSenderTesterBase(void);
+
+ // ----------------------------------------------------------------------
+ // Test history
+ // ----------------------------------------------------------------------
+
+ protected:
+
+ //! \class History
+ //! \brief A history of port inputs
+ //!
+ template class History {
+
+ public:
+
+ //! Create a History
+ //!
+ History(
+ const U32 maxSize /*!< The maximum history size*/
+ ) :
+ numEntries(0),
+ maxSize(maxSize)
+ {
+ this->entries = new T[maxSize];
+ }
+
+ //! Destroy a History
+ //!
+ ~History() {
+ delete[] this->entries;
+ }
+
+ //! Clear the history
+ //!
+ void clear() { this->numEntries = 0; }
+
+ //! Push an item onto the history
+ //!
+ void push_back(
+ T entry /*!< The item*/
+ ) {
+ FW_ASSERT(this->numEntries < this->maxSize);
+ entries[this->numEntries++] = entry;
+ }
+
+ //! Get an item at an index
+ //!
+ //! \return The item at index i
+ //!
+ T at(
+ const U32 i /*!< The index*/
+ ) const {
+ FW_ASSERT(i < this->numEntries);
+ return entries[i];
+ }
+
+ //! Get the number of entries in the history
+ //!
+ //! \return The number of entries in the history
+ //!
+ U32 size(void) const { return this->numEntries; }
+
+ private:
+
+ //! The number of entries in the history
+ //!
+ U32 numEntries;
+
+ //! The maximum history size
+ //!
+ const U32 maxSize;
+
+ //! The entries
+ //!
+ T *entries;
+
+ };
+
+ //! Clear all history
+ //!
+ void clearHistory(void);
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Handler prototypes for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Handler prototype for from_mathOut
+ //!
+ virtual void from_mathOut_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ ) = 0;
+
+ //! Handler base function for from_mathOut
+ //!
+ void from_mathOut_handlerBase(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Histories for typed from ports
+ // ----------------------------------------------------------------------
+
+ //! Clear from port history
+ //!
+ void clearFromPortHistory(void);
+
+ //! The total number of from port entries
+ //!
+ U32 fromPortHistorySize;
+
+ //! Push an entry on the history for from_mathOut
+ void pushFromPortEntry_mathOut(
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ //! A history entry for from_mathOut
+ //!
+ typedef struct {
+ F32 val1;
+ F32 val2;
+ MathOperation operation;
+ } FromPortEntry_mathOut;
+
+ //! The history for from_mathOut
+ //!
+ History
+ *fromPortHistory_mathOut;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Invocation functions for to ports
+ // ----------------------------------------------------------------------
+
+ //! Invoke the to port connected to mathIn
+ //!
+ void invoke_to_mathIn(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 result /*!< the result of the operation*/
+ );
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Getters for port counts
+ // ----------------------------------------------------------------------
+
+ //! Get the number of from_mathOut ports
+ //!
+ //! \return The number of from_mathOut ports
+ //!
+ NATIVE_INT_TYPE getNum_from_mathOut(void) const;
+
+ //! Get the number of to_mathIn ports
+ //!
+ //! \return The number of to_mathIn ports
+ //!
+ NATIVE_INT_TYPE getNum_to_mathIn(void) const;
+
+ //! Get the number of to_CmdDisp ports
+ //!
+ //! \return The number of to_CmdDisp ports
+ //!
+ NATIVE_INT_TYPE getNum_to_CmdDisp(void) const;
+
+ //! Get the number of from_CmdStatus ports
+ //!
+ //! \return The number of from_CmdStatus ports
+ //!
+ NATIVE_INT_TYPE getNum_from_CmdStatus(void) const;
+
+ //! Get the number of from_CmdReg ports
+ //!
+ //! \return The number of from_CmdReg ports
+ //!
+ NATIVE_INT_TYPE getNum_from_CmdReg(void) const;
+
+ //! Get the number of from_Tlm ports
+ //!
+ //! \return The number of from_Tlm ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Tlm(void) const;
+
+ //! Get the number of from_Time ports
+ //!
+ //! \return The number of from_Time ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Time(void) const;
+
+ //! Get the number of from_Log ports
+ //!
+ //! \return The number of from_Log ports
+ //!
+ NATIVE_INT_TYPE getNum_from_Log(void) const;
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Get the number of from_LogText ports
+ //!
+ //! \return The number of from_LogText ports
+ //!
+ NATIVE_INT_TYPE getNum_from_LogText(void) const;
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Connection status for to ports
+ // ----------------------------------------------------------------------
+
+ //! Check whether port is connected
+ //!
+ //! Whether to_mathIn[portNum] is connected
+ //!
+ bool isConnected_to_mathIn(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ //! Check whether port is connected
+ //!
+ //! Whether to_CmdDisp[portNum] is connected
+ //!
+ bool isConnected_to_CmdDisp(
+ const NATIVE_INT_TYPE portNum /*!< The port number*/
+ );
+
+ // ----------------------------------------------------------------------
+ // Functions for sending commands
+ // ----------------------------------------------------------------------
+
+ protected:
+
+ // send command buffers directly - used for intentional command encoding errors
+ void sendRawCmd(FwOpcodeType opcode, U32 cmdSeq, Fw::CmdArgBuffer& args);
+
+ //! Send a MS_DO_MATH command
+ //!
+ void sendCmd_MS_DO_MATH(
+ const NATIVE_INT_TYPE instance, /*!< The instance number*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ F32 val1, /*!< The first value*/
+ F32 val2, /*!< The second value*/
+ MathSenderComponentBase::MathOp operation /*!< The operation to perform*/
+ );
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Command response handling
+ // ----------------------------------------------------------------------
+
+ //! Handle a command response
+ //!
+ virtual void cmdResponseIn(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq, /*!< The command sequence number*/
+ const Fw::CommandResponse response /*!< The command response*/
+ );
+
+ //! A type representing a command response
+ //!
+ typedef struct {
+ FwOpcodeType opCode;
+ U32 cmdSeq;
+ Fw::CommandResponse response;
+ } CmdResponse;
+
+ //! The command response history
+ //!
+ History *cmdResponseHistory;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event dispatch
+ // ----------------------------------------------------------------------
+
+ //! Dispatch an event
+ //!
+ void dispatchEvents(
+ const FwEventIdType id, /*!< The event ID*/
+ Fw::Time& timeTag, /*!< The time*/
+ const Fw::LogSeverity severity, /*!< The severity*/
+ Fw::LogBuffer& args /*!< The serialized arguments*/
+ );
+
+ //! Clear event history
+ //!
+ void clearEvents(void);
+
+ //! The total number of events seen
+ //!
+ U32 eventsSize;
+
+#if FW_ENABLE_TEXT_LOGGING
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Text events
+ // ----------------------------------------------------------------------
+
+ //! Handle a text event
+ //!
+ virtual void textLogIn(
+ const FwEventIdType id, /*!< The event ID*/
+ Fw::Time& timeTag, /*!< The time*/
+ const Fw::TextLogSeverity severity, /*!< The severity*/
+ const Fw::TextLogString& text /*!< The event string*/
+ );
+
+ //! A history entry for the text log
+ //!
+ typedef struct {
+ U32 id;
+ Fw::Time timeTag;
+ Fw::TextLogSeverity severity;
+ Fw::TextLogString text;
+ } TextLogEntry;
+
+ //! The history of text log events
+ //!
+ History *textLogHistory;
+
+ //! Print a text log history entry
+ //!
+ static void printTextLogHistoryEntry(
+ const TextLogEntry& e,
+ FILE* file
+ );
+
+ //! Print the text log history
+ //!
+ void printTextLogHistory(FILE *const file);
+
+#endif
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MS_COMMAND_RECV
+ // ----------------------------------------------------------------------
+
+ //! Handle event MS_COMMAND_RECV
+ //!
+ virtual void logIn_ACTIVITY_LO_MS_COMMAND_RECV(
+ F32 val1, /*!< The val1 argument*/
+ F32 val2, /*!< The val1 argument*/
+ MathSenderComponentBase::MathOpEv op /*!< The requested operation*/
+ );
+
+ //! A history entry for event MS_COMMAND_RECV
+ //!
+ typedef struct {
+ F32 val1;
+ F32 val2;
+ MathSenderComponentBase::MathOpEv op;
+ } EventEntry_MS_COMMAND_RECV;
+
+ //! The history of MS_COMMAND_RECV events
+ //!
+ History
+ *eventHistory_MS_COMMAND_RECV;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Event: MS_RESULT
+ // ----------------------------------------------------------------------
+
+ //! Handle event MS_RESULT
+ //!
+ virtual void logIn_ACTIVITY_HI_MS_RESULT(
+ F32 result /*!< The math result*/
+ );
+
+ //! A history entry for event MS_RESULT
+ //!
+ typedef struct {
+ F32 result;
+ } EventEntry_MS_RESULT;
+
+ //! The history of MS_RESULT events
+ //!
+ History
+ *eventHistory_MS_RESULT;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Telemetry dispatch
+ // ----------------------------------------------------------------------
+
+ //! Dispatch telemetry
+ //!
+ void dispatchTlm(
+ const FwChanIdType id, /*!< The channel ID*/
+ const Fw::Time& timeTag, /*!< The time*/
+ Fw::TlmBuffer& val /*!< The channel value*/
+ );
+
+ //! Clear telemetry history
+ //!
+ void clearTlm(void);
+
+ //! The total number of telemetry inputs seen
+ //!
+ U32 tlmSize;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL1
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MS_VAL1
+ //!
+ virtual void tlmInput_MS_VAL1(
+ const Fw::Time& timeTag, /*!< The time*/
+ const F32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MS_VAL1
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ F32 arg;
+ } TlmEntry_MS_VAL1;
+
+ //! The history of MS_VAL1 values
+ //!
+ History
+ *tlmHistory_MS_VAL1;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_VAL2
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MS_VAL2
+ //!
+ virtual void tlmInput_MS_VAL2(
+ const Fw::Time& timeTag, /*!< The time*/
+ const F32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MS_VAL2
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ F32 arg;
+ } TlmEntry_MS_VAL2;
+
+ //! The history of MS_VAL2 values
+ //!
+ History
+ *tlmHistory_MS_VAL2;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_OP
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MS_OP
+ //!
+ virtual void tlmInput_MS_OP(
+ const Fw::Time& timeTag, /*!< The time*/
+ const MathSenderComponentBase::MathOpTlm& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MS_OP
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ MathSenderComponentBase::MathOpTlm arg;
+ } TlmEntry_MS_OP;
+
+ //! The history of MS_OP values
+ //!
+ History
+ *tlmHistory_MS_OP;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Channel: MS_RES
+ // ----------------------------------------------------------------------
+
+ //! Handle channel MS_RES
+ //!
+ virtual void tlmInput_MS_RES(
+ const Fw::Time& timeTag, /*!< The time*/
+ const F32& val /*!< The channel value*/
+ );
+
+ //! A telemetry entry for channel MS_RES
+ //!
+ typedef struct {
+ Fw::Time timeTag;
+ F32 arg;
+ } TlmEntry_MS_RES;
+
+ //! The history of MS_RES values
+ //!
+ History
+ *tlmHistory_MS_RES;
+
+ protected:
+
+ // ----------------------------------------------------------------------
+ // Test time
+ // ----------------------------------------------------------------------
+
+ //! Set the test time for events and telemetry
+ //!
+ void setTestTime(
+ const Fw::Time& timeTag /*!< The time*/
+ );
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // To ports
+ // ----------------------------------------------------------------------
+
+ //! To port connected to mathIn
+ //!
+ Ref::OutputMathResultPort m_to_mathIn[1];
+
+ //! To port connected to CmdDisp
+ //!
+ Fw::OutputCmdPort m_to_CmdDisp[1];
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // From ports
+ // ----------------------------------------------------------------------
+
+ //! From port connected to mathOut
+ //!
+ Ref::InputMathOpPort m_from_mathOut[1];
+
+ //! From port connected to CmdStatus
+ //!
+ Fw::InputCmdResponsePort m_from_CmdStatus[1];
+
+ //! From port connected to CmdReg
+ //!
+ Fw::InputCmdRegPort m_from_CmdReg[1];
+
+ //! From port connected to Tlm
+ //!
+ Fw::InputTlmPort m_from_Tlm[1];
+
+ //! From port connected to Time
+ //!
+ Fw::InputTimePort m_from_Time[1];
+
+ //! From port connected to Log
+ //!
+ Fw::InputLogPort m_from_Log[1];
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! From port connected to LogText
+ //!
+ Fw::InputLogTextPort m_from_LogText[1];
+#endif
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Static functions for output ports
+ // ----------------------------------------------------------------------
+
+ //! Static function for port from_mathOut
+ //!
+ static void from_mathOut_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ F32 val1,
+ F32 val2,
+ MathOperation operation /*!< operation argument*/
+ );
+
+ //! Static function for port from_CmdStatus
+ //!
+ static void from_CmdStatus_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwOpcodeType opCode, /*!< Command Op Code*/
+ U32 cmdSeq, /*!< Command Sequence*/
+ Fw::CommandResponse response /*!< The command response argument*/
+ );
+
+ //! Static function for port from_CmdReg
+ //!
+ static void from_CmdReg_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwOpcodeType opCode /*!< Command Op Code*/
+ );
+
+ //! Static function for port from_Tlm
+ //!
+ static void from_Tlm_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwChanIdType id, /*!< Telemetry Channel ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::TlmBuffer &val /*!< Buffer containing serialized telemetry value*/
+ );
+
+ //! Static function for port from_Time
+ //!
+ static void from_Time_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ Fw::Time &time /*!< The U32 cmd argument*/
+ );
+
+ //! Static function for port from_Log
+ //!
+ static void from_Log_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwEventIdType id, /*!< Log ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::LogSeverity severity, /*!< The severity argument*/
+ Fw::LogBuffer &args /*!< Buffer containing serialized log entry*/
+ );
+
+#if FW_ENABLE_TEXT_LOGGING == 1
+ //! Static function for port from_LogText
+ //!
+ static void from_LogText_static(
+ Fw::PassiveComponentBase *const callComp, /*!< The component instance*/
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ FwEventIdType id, /*!< Log ID*/
+ Fw::Time &timeTag, /*!< Time Tag*/
+ Fw::TextLogSeverity severity, /*!< The severity argument*/
+ Fw::TextLogString &text /*!< Text of log message*/
+ );
+#endif
+
+ private:
+
+ // ----------------------------------------------------------------------
+ // Test time
+ // ----------------------------------------------------------------------
+
+ //! Test time stamp
+ //!
+ Fw::Time m_testTime;
+
+ };
+
+} // end namespace Ref
+
+#endif
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/main.cpp b/docs/Tutorials/MathComponent/MathSender/test/ut/main.cpp
new file mode 100644
index 0000000000..039df54e45
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/main.cpp
@@ -0,0 +1,30 @@
+// ----------------------------------------------------------------------
+// Main.cpp
+// ----------------------------------------------------------------------
+
+#include "Tester.hpp"
+
+TEST(Nominal, AddOperationTest) {
+ Ref::Tester tester;
+ tester.testAddCommand();
+}
+
+TEST(Nominal, SubOperationTest) {
+ Ref::Tester tester;
+ tester.testSubCommand();
+}
+
+TEST(Nominal, MultOperationTest) {
+ Ref::Tester tester;
+ tester.testMultCommand();
+}
+
+TEST(Nominal, DivideOperationTest) {
+ Ref::Tester tester;
+ tester.testDivCommand();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/mod.mk b/docs/Tutorials/MathComponent/MathSender/test/ut/mod.mk
new file mode 100644
index 0000000000..3e5c1a5621
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/mod.mk
@@ -0,0 +1,25 @@
+# ----------------------------------------------------------------------
+# mod.mk
+# ----------------------------------------------------------------------
+
+TEST_SRC = main.cpp \
+ Tester.cpp \
+ GTestBase.cpp \
+ TesterBase.cpp
+
+TEST_MODS = Ref/MathSender \
+ Ref/MathPorts \
+ Fw/Cmd \
+ Fw/Comp \
+ Fw/Port \
+ Fw/Prm \
+ Fw/Time \
+ Fw/Tlm \
+ Fw/Types \
+ Fw/Log \
+ Fw/Obj \
+ Fw/Com \
+ Os \
+ Utils/Hash \
+ gtest
+
diff --git a/docs/Tutorials/MathComponent/MathSender/test/ut/runtest_LINUX b/docs/Tutorials/MathComponent/MathSender/test/ut/runtest_LINUX
new file mode 100644
index 0000000000..5d1104dcde
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathSender/test/ut/runtest_LINUX
@@ -0,0 +1,6 @@
+#!/bin/sh
+LOC=${BUILD_ROOT}/Ref/MathSender/test/ut
+cd ${LOC}
+echo "Running ${LOC}/$1/test_ut"
+${LOC}/$1/test_ut
+
diff --git a/docs/Tutorials/MathComponent/MathTypes/Makefile b/docs/Tutorials/MathComponent/MathTypes/Makefile
new file mode 100644
index 0000000000..f567376aa5
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathTypes/Makefile
@@ -0,0 +1,10 @@
+# derive module name from directory
+
+MODULE_DIR = Ref/MathTypes
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
diff --git a/docs/Tutorials/MathComponent/MathTypes/MathOpSerializableAi.xml b/docs/Tutorials/MathComponent/MathTypes/MathOpSerializableAi.xml
new file mode 100644
index 0000000000..41d7aa99f3
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathTypes/MathOpSerializableAi.xml
@@ -0,0 +1,18 @@
+
+
+ This value holds the values of a math operation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Tutorials/MathComponent/MathTypes/mod.mk b/docs/Tutorials/MathComponent/MathTypes/mod.mk
new file mode 100644
index 0000000000..167644ffd3
--- /dev/null
+++ b/docs/Tutorials/MathComponent/MathTypes/mod.mk
@@ -0,0 +1,3 @@
+SRC = MathOpSerializableAi.xml
+
+
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/Top/RefTopologyAppAi.xml b/docs/Tutorials/MathComponent/Top/RefTopologyAppAi.xml
new file mode 100644
index 0000000000..30abeb118d
--- /dev/null
+++ b/docs/Tutorials/MathComponent/Top/RefTopologyAppAi.xml
@@ -0,0 +1,115 @@
+ Ref/MathSender/MathSenderComponentAi.xml
+ Ref/MathReceiver/MathReceiverComponentAi.xml
+
+...
+
+
+
+
+...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/Tutorial.md b/docs/Tutorials/MathComponent/Tutorial.md
new file mode 100644
index 0000000000..0ff8fba93e
--- /dev/null
+++ b/docs/Tutorials/MathComponent/Tutorial.md
@@ -0,0 +1,2435 @@
+# Introduction
+
+The following example shows the steps to implement a simple pair of components connected by a pair of ports. The first, `MathSender`, will invoke the second, `MathReceiver`, via a `MathOp` port to perform a math operation and return the result via a `MathResult` port.
+
+
+
+All the code in this tutorial can be found in this directory. The actual location of the components will be in the `Ref` directory, where a demonstration reference application is located.
+
+The prerequisite skills to understand this totorial are as follows:
+
+1) Working knowledge of Linux; how to navigate in a shell and execute programs
+2) An understanding of C++, including class declarations and inheritance
+3) An understanding of how XML is structured
+
+Before beginning, please make sure that all the dependencies are installed. Please read the [User Guide](/docs/UsersGuide/FprimeUserGuide.pdf) for help installing these packages.
+
+Here is a description of the components:
+
+# 1 Component Descriptions
+
+## 1.1 MathSender
+`MathSender` must do the following:
+
+### 1.1.1 Commands
+
+`MathSender` should implement a `MS_DO_MATH` command. This command will have three arguments:
+1) A first value in the operation
+2) A second value in the operation
+3) An enumerated argument specifying the operation to perform
+
+### 1.1.2 Events
+`MathSender` should emit an event telling that a command was received to perform the operation. It should also emit an event when the result is received back from `MathReceiver`.
+
+### 1.1.3 Telemetry Channels
+MathSender should have four channels:
+1) The first value
+2) The second value
+3) The operation
+4) The result
+
+### 1.1.4 Parameters
+MathSender will have no parameters.
+
+`MathSender` should be an active (i.e. threaded) component, so it will process the commands immediately. The command will be *asynchronous*, which means the handler will be executed on the thread of the active component. It will delegate the operation to `MathReceiver`.
+
+## 1.2 MathReceiver
+
+`MathReceiver` will be a queued component that performs the requested operation and returns the result. `MathReceiver` will be connected to the 1Hz rate group that is part of the reference example. The simple operation in this component could have just as easily been done in a passive or active component; it is done here as a queued component to illustrate how to implement one.
+
+### 1.2.1 Commands
+
+`MathReceiver` should implement a MR_SET_FACTOR1 command. This command will set a factor used for any subsequent operations. The result of the commanded operation will be multipled by this factor. It should default to 0 if the command is never invoked.
+
+`MathReceiver` should also implement a MR_CLEAR_EVENT_THROTTLE command to clear the throttled MR_SET_FACTOR1 event (see below).
+
+### 1.2.2 Events
+
+`MathReceiver` should have the following events:
+
+1) MR_SET_FACTOR1 command event. When the command is received, `MathReceiver` should emit an event with the updated factor. The event should be throttled (i.e. stop emitting) after three invocations. Normally, throttling is used to prevent event floods if there a endlessly repeating condition.
+2) MR_UPDATED_FACTOR2 event. When the factor2 parameter (see below) is updated, `MathReceiver` should emit an event with the updated value.
+3) MR_OPERATION_PERFORMED event. When the component receives a request to perform the operation, it should emit an event with the arguments and operation.
+4) MR_THROTTLE_CLEARED in response to the MR_CLEAR_EVENT_THROTTLE command above.
+
+### 1.2.3 Channels
+
+`MathReceiver` should have the following channels:
+
+1) A channel that has a serializable structure argument that contains the two terms in the operation as well as the operation and the result. This will be used to illustrate an XML defined serializable as a single telemetry channel.
+2) A channel that counts the number of MR_SET_FACTOR1 commands received, so that a count can be known past the throttled event.
+3) A channel for each of the factors used in the operation.
+
+### 1.2.4 Parameters
+
+`MathReceiver` will have one parameter, a second factor used in the operation.
+
+## 1.3 Operation
+
+`MathReceiver` will perform the following operation when requested by `MathSender`:
+
+result = (value1 operation value2)*factor1/factor2
+
+# 2 Implementation
+
+The implementation of the component will will have the following steps:
+
+1) Define the `MathOpPort` and 'MathResultPort' ports that are used between the components.
+2) Define the `MathSender` component in XML and compile it.
+3) Implement the `MathSender` derived implementation class.
+4) Unit test the `MathSender` implementation component.
+5) Define the `MathReceiver` component in XML.
+6) Implement the `MathReceiver` implemenation class.
+7) Unit test the `MathReceiver` implemenation class.
+8) Connect the classes to the `Ref` topology.
+9) Run the ground system and exercise the commands and view the telemetry and events in the GUI.
+
+## 2.1 Port definition
+
+There are two ports to define in order to perform the operation between the components. The XML for the ports will be first shown in their entirety, and then the individual parts will be described.
+
+### 2.1.1 MathOpPort
+
+`MathOpPort` is responsible for passing the invocation of the operation from `MathSender` to `MathReceiver`. The new XML file should be placed in a new directory `Ref/MathPorts` with the name `MathOpPortAi.xml`. The XML for the port is as follows:
+
+```xml
+
+
+ Port to perform an operation on two numbers
+
+
+
+
+
+
+
+
+
+
+
+
+
+ operation argument
+
+
+
+```
+
+#### 2.1.1.1 Port Name Specification
+
+```xml
+
+
+ Port to perform an operation on two numbers
+
+...
+
+```
+
+The `interface` tag specifies that a port is being defined. The attributes are as follows:
+
+|Attribute|Description|
+|---|---|
+|name|The name of the component type. Becomes the C++ class name|
+|namespace|The namespace of the component. The C++ namespace the where the component class will appear|
+
+#### 2.1.1.2 Port Argument Specification
+
+The port arguments are passed from component to component when they are connected. The port argument XML is as follows:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+ operation argument
+
+
+```
+
+The `` tag begins the section of the XML defining the arguments, while the `` tag defines a particular argument. The port argument attributes are define as follows:
+
+|Attribute|Description|
+|---|---|
+|name|The name of the argument. Becomes the argument name in the C++ call|
+|type|The type of the arguments. Can be one of the built-in types, a user define type, or an enumeration|
+
+The enumerations are a special type of argument. When `type="ENUM"` is an attribute of the arguments, a further listing of the elements of the enumeration are needed. For each element of the array, a name is specified. These end up being C++ enumerated types.
+
+```xml
+
+
+
+
+
+
+ ```
+#### 2.1.1.3 Adding the port to the build
+
+The build system needs to be made aware of the port XML. To do this, edit the file `/mk/configs/modules/modules.mk`.
+
+Find the `REF_MODULES` variable and add the new port directory:
+
+```make
+REF_MODULES := \
+ Ref/Top \
+ Ref/RecvBuffApp \
+ Ref/SendBuffApp \
+ Ref/SignalGen \
+ Ref/PingReceiver \
+ Ref/MathPorts
+```
+
+Create a file named `mod.mk` in the `MathPorts` directory. This file tells the build system that a new file needs to be added to the build. Here are the contents:
+
+```make
+SRC = MathOpPortAi.xml
+```
+
+A second make file is needed to build the code in the local `MathPorts` directory. It should be named `Makefile` and have the following contents:
+
+```make
+# derive module name from directory
+
+MODULE_DIR = Ref/MathPorts
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
+```
+
+The `MODULE_DIR` path should always be the current directory of the `Makefile`.
+
+Now a make target can be called to include the module in the build. This only needs to be done once:
+
+```shell
+make gen_make
+Generating templates
+...
+Regenerating global Makefile
+Generating Makefiles in .../fprime/mk/makefiles
+Makefile generation complete.
+Build Time: 0:00.51
+```
+
+Now, the port code can be generated and compiled:
+
+```shell
+make
+Building module RefMathPorts code generation (level 4)
+...
+make[1]: Leaving directory '.../fprime/Ref/MathPorts'
+Build Time: 0:03.49
+```
+
+The code generation from the XML produces two files:
+
+```
+ MathOpPortAc.cpp
+ MathOpPortAc.hpp
+```
+These contain the C++ classes that implement the port functionality. The build system will automatically compile them when it is aware of the port XML file.
+
+### 2.1.2 MathResultPort
+
+`MathResultPort` is responsible for passing the result of the operation from `MathReceiver` to `MathSender`. The new XML file should be placed in the `Ref/MathPorts` directory with the name `MathResultPortAi.xml`. The XML for the port is as follows:
+
+```xml
+
+
+ Port to return the result of a math operation
+
+
+
+ the result of the operation
+
+
+
+
+```
+
+This file can be added to the `mod.mk` in the `Ref/MathPorts` directory:
+
+```make
+SRC = MathOpPortAi.xml \
+ MathResultPortAi.xml
+```
+
+Running `make gen_make` and `make` as before will make the build system aware of the new port XML file and compile it.
+
+The code generated to implement ports is complete. Developers do not need to add any implmentation code of their own.
+
+## 2.2 Serializable Definition
+
+A structure needs to be defined that represents the channel value needed by `MathReceiver`. All port calls, telemetry channels, events and parameters need to be comprised of `Serializable` values, or values that can be turned into a byte stream. This is needed to pass port arguments through message queues and to pass commands and telemetry to and from the ground system. Built-in basic types like integers, floating point numbers and boolean values are supported by the framework, but there are times when a developer wishes to use a custom-defined type, perhaps to keep members of a object consistent with each other. These structures can be defined in XML and the code generator will generate the C++ classes with all the neccessary serialization functions. Developers can hand-code their own, but they are not usable for telemetry since the ground sysmtem needs an XML definition to decode them.
+
+### 2.2.1 MathOp
+
+The `MathOp` serializable structure is needed by `MathReceiver` for a telemetry channel that gives the values of the operation. A new directory named `Ref/MathTypes` should be created for the structure, and the file should be named `MathOpSerializableAi.xml`. The XML is as follows:
+
+```xml
+
+
+ This value holds the values of a math operation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Add a mod.mk file for the serializable:
+
+```make
+SRC = MathOpSerializableAi.xml
+```
+
+#### 2.2.1.1 Serializable Name Specification
+
+The opening tag of the XML specifies the type name and namespace of the structure:
+
+```xml
+
+...
+
+```
+
+#### 2.2.1.2 Serializable Members
+
+The `members` tag starts the section of the XML that specifies the members of the structure:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+As with the arguments to port definitions, built-in types can be specified as well as enumerations.
+
+As before with the port definitions, the `Ref/MathTypes` directory needs to be added to `/mk/configs/modules/modules.mk`.
+
+```make
+REF_MODULES := \
+ Ref/Top \
+ Ref/RecvBuffApp \
+ Ref/SendBuffApp \
+ Ref/SignalGen \
+ Ref/PingReceiver \
+ Ref/MathPorts \
+ Ref/MathTypes
+```
+
+This XML defined structure compiles to a C++ class that has accessors for the members of the structure.
+
+## 2.3 Component Definition
+
+### 2.3.1 MathSender Component
+
+The `MathSender` component XML definition is as follows. The XML should be placed in a file `Ref/MathSender/MathSenderComponentAi.xml`
+
+```xml
+
+ Ref/MathPorts/MathOpPortAi.xml
+ Ref/MathPorts/MathResultPortAi.xml
+ Component sending a math operation
+
+
+
+ Port for sending the math operation
+
+
+
+
+ Port for returning the math result
+
+
+
+
+
+
+ Do a math operation
+
+
+
+ The first value
+
+
+ The second value
+
+
+
+
+
+
+
+
+ The operation to perform
+
+
+
+
+
+
+
+ The first value
+
+
+
+
+ The second value
+
+
+
+
+
+
+
+
+
+
+ The operation
+
+
+
+
+ The result
+
+
+
+
+
+
+ Math command received
+
+
+
+ The val1 argument
+
+
+ The val2 argument
+
+
+ The requested operation
+
+
+
+
+
+
+
+
+
+
+
+ Received math result
+
+
+
+ The math result
+
+
+
+
+
+```
+
+#### 2.3.1.1 Component Name Specification
+
+The component name is specified in the opening tag of the XML:
+
+```xml
+
+...
+
+```
+
+The attributes of the tag are as follows:
+
+|Attribute|Description|
+|---|---|
+|name|The component name|
+|kind|What the threading/queuing model of the component is. Can be `passive`, `queued`, or `active`|
+|namespace|The C++ namespace the component will be defined in|
+
+#### 2.3.1.2 Port Imports
+
+The ports needed for the component are imported using `import_port_type` tags:
+
+```xml
+ Ref/MathPorts/MathOpPortAi.xml
+ Ref/MathPorts/MathResultPortAi.xml
+```
+
+The path in the port import statement is relative to the root of the repository. There are a number of ports automatically included by the code generator when commands, telemetry, events or parameters are defined. They are:
+
+|Facility|Ports|
+|---|---|
+|Commands|`Fw/Command/CmdPortAi.xml`,`Fw/Command/CmdResponsePortAi.xml`,`Fw/Command/CmdRegPortAi.xml`|
+|Events|`Fw/Log/LogPortAi.xml`,`Fw/Log/LogTextPortAi.xml`|
+|Telemetry|`Fw/Tlm/TlmPortAi.xml`|
+|Parameters|`Fw/PrmGetPortAi.xml`,`Fw/PrmSetPortAi.xml`|
+
+#### 2.3.1.3 Port Declarations
+
+Ports and their attributes are declared once the port definitions are included.
+
+```xml
+
+
+
+ Port for sending the math operation
+
+
+
+
+ Port for returning the math result
+
+
+
+```
+
+The port attributes are:
+
+|Attribute|Description|
+|---|---|
+|name|The port name|
+|data_type|The type of the port as defined in the included port definitions, in the form `namepace::name`|
+|kind|The kind of port. Can be `sync_input`,`async_input`,`guarded_input`, or `output`|
+
+For `MathSender`, the request for the operation will be sent on the `mathOut` output port, and the result will be returned on the `mathIn` asynchronous port. Because the component is active and the result input port is asynchronous, the port handler will execute on the thread of `MathSender`.
+
+#### 2.3.1.4 Command Declarations
+
+The commands defined for the component are:
+
+```xml
+
+
+
+ Do a math operation
+
+
+
+ The first value
+
+
+ The second value
+
+
+
+
+
+
+
+
+ The operation to perform
+
+
+
+
+```
+
+The `` tag starts the section containing commands for `MathSender`. For each command, the following attributes are defined:
+
+|Attribute|Description|
+|---|---|
+|mnemonic|A text version of the command name, used in sequences and the ground tool|
+|opcode|A numeric value for the command. The value is relative to a base value set when the component is added to a topology|
+|kind|The kind of command. Can be `sync_input`,`async_input`,`guarded_input`, or `output`|
+
+#### 2.3.1.5 Telemetry
+
+The telemetry XML is as follows:
+
+```xml
+
+
+
+ The first value
+
+
+
+
+ The second value
+
+
+
+
+
+
+
+
+
+
+ The operation
+
+
+
+
+ The result
+
+
+
+```
+
+The `` tag starts the section containing telemetry channels for `MathSender`. For each channel, the following attributes are defined:
+
+|Attribute|Description|
+|---|---|
+|name|The channel name|
+|id|A numeric value for the channel. The value is relative to a base value set when the component is added to a topology|
+|data_type|The data type of the channel. Can be a built-in type, an enumeration or an externally defined serializable type|
+
+#### 2.3.1.6 Events
+
+The XML for the defined events is as follows:
+
+```xml
+
+
+
+ Math command received
+
+
+
+ The val1 argument
+
+
+ The val1 argument
+
+
+ The requested operation
+
+
+
+
+
+
+
+
+
+
+
+ Received math result
+
+
+
+ The math result
+
+
+
+
+```
+
+The `` tag starts the section containing events for `MathSender`. For each event, the following attributes are defined:
+
+|Attribute|Description|
+|---|---|
+|name|The event name|
+|severity|The severity of the event. Can be DIAGNOSTIC, ACTIVITY_LO, ACTIVITY_HI, WARNING_LO, WARNING_HI or FATAL.
+|id|A numeric value for the event. The value is relative to a base value set when the component is added to a topology|
+|format_string|A C-style format string for displaying the event and the argument values.|
+
+The directory containing the component XML can be added to the list of modules in `/mk/configs/modules/modules.mk`:
+
+```make
+REF_MODULES := \
+ Ref/Top \
+ Ref/RecvBuffApp \
+ Ref/SendBuffApp \
+ Ref/SignalGen \
+ Ref/PingReceiver \
+ Ref/MathPorts \
+ Ref/MathTypes \
+ Ref/MathSender
+```
+
+Create a `mod.mk` file in `Ref/MathSender` and add `MathSenderComponentAi.xml`.
+
+Create a `Makefile` file in `Ref/MathSender`, following the same structure as earlier:
+
+
+```make
+# derive module name from directory
+
+MODULE_DIR = Ref/MathSender
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+
+```
+
+
+Once it is added, add the directory to the build and build the component by typing `make rebuild` from the `Ref` directory.
+
+### 2.3.2 MathReceiver Component
+
+#### 2.3.2.1 Component Specification
+
+The `MathReceiver` component XML is as follows:
+
+```xml
+
+ Ref/MathPorts/MathOpPortAi.xml
+ Ref/MathPorts/MathResultPortAi.xml
+ Svc/Sched/SchedPortAi.xml
+ Ref/MathTypes/MathOpSerializableAi.xml
+ Component sending a math operation
+
+
+
+ Port for receiving the math operation
+
+
+
+
+ Port for returning the math result
+
+
+
+
+ The rate group scheduler input
+
+
+
+
+
+
+ Set operation multiplication factor1
+
+
+
+ The first factor
+
+
+
+
+ Clear the event throttle
+
+
+
+
+
+
+ The operation
+
+
+
+
+ The number of MR_SET_FACTOR1 commands
+
+
+
+
+ Factor 1 value
+
+
+
+
+ Factor 2 value
+
+
+
+
+
+
+ Operation factor 1
+
+
+
+ The factor value
+
+
+
+
+
+ Updated factor 2
+
+
+
+ The factor value
+
+
+
+
+
+ Math operation performed
+
+
+
+ The operation
+
+
+
+
+
+ Event throttle cleared
+
+
+
+
+
+
+ A test parameter
+
+
+
+
+
+```
+The mod.mk file for this component is as follows:
+
+```make
+SRC = MathReceiverComponentAi.xml
+```
+
+Don't forget to create a `Makefile` and add `Ref/MathReceiver` to `/mk/configs/modules/modules.mk`.
+
+
+Many of the elements are the same as described in `MathSender`, so this section will highlight the differences.
+
+#### 2.3.2.1 Queued component
+
+The `MathReceiver` component is queued, which means it can receive asynchronous port invocations as messages, but needs an external thread to dequeue them.
+
+#### 2.3.2.2 Importing the serializable type
+
+The telemetry channels and events use a serializable type, `Ref::MathOp` to illustrate the use of those types. The following line specifies the import for this type:
+
+```xml
+ Ref/MathTypes/MathOpSerializableAi.xml
+```
+
+This type is then available for events and channels, but are not available for parameters and command arguments.
+
+#### 2.3.2.3 Scheduler port
+
+The queued component has a scheduler port that is `sync_input`. That means the port invocation is not put on a message queue, but calls the handler on the thread of the caller of the port:
+
+```xml
+
+
+ The rate group scheduler input
+
+
+
+```
+
+This synchronous call allows the caller to pull any pending messages of the message queue using the thread of the component invoking the `SchedIn` port.
+
+#### 2.3.2.4 Throttled Event
+
+The `MR_SET_FACTOR1` event has a new argument `throttle = "3"` that specifies how many events will be emitted before the event is throttled so no more appear.
+
+```xml
+
+
+ Operation factor 1
+
+
+
+ The factor value
+
+
+
+```
+
+#### 2.3.2.5 Parameters
+
+The `MathReceiver` component has a declaration for a parameter:
+
+```xml
+
+
+
+ A test parameter
+
+
+
+
+```
+
+The `parameter` attributes are as follows:
+
+|Attribute|Description|
+|---|---|
+|id|The unique parameter ID. Relative to base ID set for the component in the topology|
+|name|The parameter name|
+|data_type|The data type of the parameter. Must be a built-in type|
+|default|Default value assigned to the parameter if there is an error retrieving it.|
+|set_opcode|The opcode of the command to set the parameter. Must not overlap with any of the command opcodes|
+|save_opcode|The opcode of the command to save the parameter. Must not overlap with any of the command opcodes|
+
+
+
+## 2.4 Component Implementation
+
+The component implementation consists of writing a class that is derived from the code-generated base class and filling in member functions that implement the port calls.
+
+### 2.4.1 MathSender Implementation
+
+#### 2.4.1.1 Stub Generation
+
+There is a make target that will generate stubs that the developer can fill in. The command to generate the stubs is: `make impl`. This will generate two files:
+
+```
+MathSenderComponentImpl.hpp-template
+MathSenderComponentImpl.cpp-template
+```
+
+Rename the files by removing the `-template` from the end of the file names.
+
+```
+MathSenderComponentImpl.hpp
+MathSenderComponentImpl.cpp
+```
+
+Add the new files to the `mod.mk` file:
+
+```make
+SRC = MathSenderComponentAi.xml MathSenderComponentImpl.cpp
+
+HDR = MathSenderComponentImpl.hpp
+```
+
+Make the build system aware of the new files and build:
+
+```
+make rebuild
+```
+
+The stub files should sucessfully compile.
+
+#### 2.4.1.2 Handler implementation
+
+The next step is to fill in the handler with implementation code.
+
+First, find the empty command handler in the `MathSenderComponentImpl.cpp` file:
+
+```c++
+ void MathSenderComponentImpl ::
+ MS_DO_MATH_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ F32 val1,
+ F32 val2,
+ MathOp operation
+ )
+ {
+ // TODO
+ }
+```
+Then, fill in the function with the code to perform the functions described at the beginning of the tutorial:
+
+```c++
+ void MathSenderComponentImpl ::
+ MS_DO_MATH_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ F32 val1,
+ F32 val2,
+ MathOp operation
+ )
+ {
+ MathOpTlm opTlm;
+ MathOperation opPort;
+ MathOpEv opEv;
+ switch (operation) {
+ case ADD:
+ opTlm = ADD_TLM;
+ opPort = MATH_ADD;
+ opEv = ADD_EV;
+ break;
+ case SUBTRACT:
+ opTlm = SUB_TLM;
+ opPort = MATH_SUB;
+ opEv = SUB_EV;
+ break;
+ case MULTIPLY:
+ opTlm = MULT_TLM;
+ opPort = MATH_MULTIPLY;
+ opEv = MULT_EV;
+ break;
+ case DIVIDE:
+ opTlm = DIV_TLM;
+ opPort = MATH_DIVIDE;
+ opEv = DIV_EV;
+ break;
+ default:
+ FW_ASSERT(0,operation);
+ break;
+ }
+
+ this->tlmWrite_MS_OP(opTlm);
+ this->tlmWrite_MS_VAL1(val1);
+ this->tlmWrite_MS_VAL2(val2);
+ this->log_ACTIVITY_LO_MS_COMMAND_RECV(val1,val2,opEv);
+ this->mathOut_out(0,val1,val2,opPort);
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+
+```
+
+The handler will send the appropriate events and telemetry values, then invoke the output math operation port to request the operation.
+Note that each channel and event argument that has an enumeration has a unique type declaration.
+Finally, note that the output command response port must be called with a command status in order to let the framework components know that the command is complete.
+If the completion status isn't sent, it will stall any sequences the command was part of.
+There are command error status along with successfull completions.
+Most commands return this status at the end of the handler, but component implementations can store the `opCode` and `cmdSeq` values to return later, but those specific values must be returned in order to match the status with the command originally sent.
+
+Find the empty result handler:
+
+```c++
+ void MathSenderComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ // TODO
+ }
+```
+
+Fill in the result handler with code that reports telemetry and an event:
+
+```c++
+ void MathSenderComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 result
+ )
+ {
+ this->tlmWrite_MS_RES(result);
+ this->log_ACTIVITY_HI_MS_RESULT(result);
+ }
+
+```
+
+This handler reports the result via a telemetry channel and an event.
+
+Once complete, add the directory to the build and build the component by typing `make rebuild` from the `Ref` directory.
+
+#### 2.4.1.3 Unit Tests
+
+Unit Tests are used to exercise the component's functions by invoking input ports and commands and checking the values of output ports, telemetry and events.
+
+##### 2.4.1.3.1 Test Code Generation
+
+The code generator will generate test components that can be connected to the component to enable a set of unit tests to check functionality and to get coverage of all the code. To generate a set of files for testing, from the module directory type:
+
+```shell
+make testcomp
+```
+
+The files that are generated are:
+
+```
+Tester.hpp
+Tester.cpp
+TesterBase.hpp
+TesterBase.cpp
+GTestBase.hpp
+GTestBase.cpp
+```
+
+The functions of the files are:
+
+|File|Function|
+|---|---|
+|TesterBase.*|Base class for test class. Defines necessary handlers as well as helper functions
+|GTestBase.*|Helper class derived from TesterBase that has macros that use Google Test to test interfaces|
+|Tester.*|Derived tester class that inherits from GTestBase. Includes instance of the component and helpers to connect ports|
+
+Unit tests are built in subdirectories of the module, so the unit test file must be copied there. The build system supports a standard subdirectory of `test/ut` below the module being tested. While in the MathSender directory, create the `test/ut` directory:
+
+```
+mkdir -p test/ut
+```
+
+Move the above set of files into that subdirectory.
+
+The new unit test files have to be registered with the build system, so modifications to the `mod.mk` files are necessary. Here are the steps:
+
+1) Add the following entry to the `mod.mk` file in `Ref/MathSender`:
+
+```
+SUBDIRS = test
+```
+
+2) Add a `mod.mk` file to the new `test` subdirectory:
+
+```
+SUBDIRS = ut
+```
+
+3) Finally, add a `mod.mk` file to the `test/ut` directory:
+
+```make
+TEST_SRC = main.cpp \
+ Tester.cpp \
+ GTestBase.cpp \
+ TesterBase.cpp
+
+TEST_MODS = Ref/MathSender \
+ Ref/MathPorts \
+ Fw/Cmd \
+ Fw/Comp \
+ Fw/Port \
+ Fw/Prm \
+ Fw/Time \
+ Fw/Tlm \
+ Fw/Types \
+ Fw/Log \
+ Fw/Obj \
+ Fw/Com \
+ Os \
+ Utils/Hash \
+ gtest
+```
+
+The `TEST_SRC` variable includes any source code needed to run the test. It usually only includes the generated test code and a `main.cpp`, but it can include any code the user needs to test.
+
+The `TEST_MODS` variable must have all the modules that the component depends on, including itself. The test binary links against the modules in the list.
+
+##### 2.4.1.3.2 Test Code Implementation
+
+The `main.cpp` file must be added. For this test, it appears like this:
+
+```c++
+#include "Tester.hpp"
+
+TEST(Nominal, AddOperationTest) {
+ Ref::Tester tester;
+ tester.testAddCommand();
+}
+
+TEST(Nominal, SubOperationTest) {
+ Ref::Tester tester;
+ tester.testSubCommand();
+}
+
+TEST(Nominal, MultOperationTest) {
+ Ref::Tester tester;
+ tester.testMultCommand();
+}
+
+TEST(Nominal, DivideOperationTest) {
+ Ref::Tester tester;
+ tester.testDivCommand();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
+```
+
+F' uses the Google Test framework to run unit tests. For more information about the Google Test Framework see here:
+
+https://github.com/google/googletest
+
+
+In the Google Test framework, the following lines of code are standard:
+
+```c++
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+```
+
+For each test, there is a Google Test macro defined:
+
+```c++
+TEST(Name1, Name2) {
+ // run some code
+}
+```
+
+The code in each of the macros defined this way will automatically be run be the framework.
+
+In this case, the tests are defined as follows:
+
+```c++
+TEST(Nominal, AddOperationTest) {
+ Ref::Tester tester;
+ tester.testAddCommand();
+}
+
+TEST(Nominal, SubOperationTest) {
+ Ref::Tester tester;
+ tester.testSubCommand();
+}
+
+TEST(Nominal, MultOperationTest) {
+ Ref::Tester tester;
+ tester.testMultCommand();
+}
+
+TEST(Nominal, DivideOperationTest) {
+ Ref::Tester tester;
+ tester.testDivCommand();
+}
+```
+For each unit test, the Google Test test case for F' components looks like:
+
+```c++
+TEST(Nominal, DivideOperationTest) {
+ NameSpace::Tester tester;
+ tester.someUnitTestFunc();
+}
+```
+The test component is instantiated here:
+
+```c++
+ NameSpace::Tester tester;
+```
+
+This allows the component to start from an newly initialized state for each unit test.
+
+The unit test is executed by calling a member function of the `tester` class:
+
+```c++
+ tester.someUnitTestFunc();
+```
+
+The `Tester.hpp` stub can be updated to include the declarations of the unit test functions:
+
+```c++
+ ...
+ public:
+
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ //! Test operation command
+ //!
+ void testAddCommand(void);
+ void testSubCommand(void);
+ void testMultCommand(void);
+ void testDivCommand(void);
+
+ private:
+ ...
+```
+
+The next step is to add the specific test cases to the `Tester.cpp` implementation file. It is important to note that the unit tests are designed to be single-threaded. The active components do not have their threads started, so any messages to asynchronous ports are manually retrieved from the message queue and dispatched to handlers. This makes testing simpler since the execution of the thread in reponse to port calls or commands does not need to be managed. Examples of this will be seen in the test code.
+
+The first test case will be to test the `MS_DO_MATH` command for the addition operation. In the example component implementation, `MS_DO_MATH` command calls the `mathOut` output port and emits some channelized telmetry and events. The test component provides methods for invoking the command and checking that the telemetry and events were emitted as expected. The steps to write the test case are as follows:
+
+Add a member function to the implementation class in `Tester.cpp` to implement the test case:
+
+```c++
+ // ----------------------------------------------------------------------
+ // Tests
+ // ----------------------------------------------------------------------
+
+ void Tester ::
+ testAddCommand(void)
+ {
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::ADD);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_ADD);
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::ADD_TLM);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::ADD_EV);
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+
+ // reset all telemetry and port history
+ this->clearHistory();
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expected value of the event arguments
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+ }
+
+```
+
+Some highlights are:
+
+Send the `MS_DO_MATH` command:
+
+```c++
+ // send MS_DO_MATH command
+ this->sendCmd_MS_DO_MATH(0,10,1.0,2.0,MathSenderComponentBase::ADD);
+ // retrieve the message from the message queue and dispatch
+ this->component.doDispatch();
+```
+
+Verify that the operation port was called as expected:
+
+```c++
+ // verify that that only one output port was called
+ ASSERT_FROM_PORT_HISTORY_SIZE(1);
+ // verify that the math operation port was only called once
+ ASSERT_from_mathOut_SIZE(1);
+ // verify the arguments of the operation port
+ ASSERT_from_mathOut(0,1.0,2.0,MATH_ADD);
+```
+
+The first call verifies that one and only one port call was made. This can be used to confirm that there were no other ports called besides the expected one.
+
+The second call verifies that the port call that was made was the expected one.
+
+The third call looks at a stored history of calls to this port and verifies the expected call arguments were made. The history can store multiple calls, so the first argument indicates which index in the history to examine.
+
+Verify that the telemetry channels were written:
+
+```c++
+ // verify telemetry - 3 channels were written
+ ASSERT_TLM_SIZE(3);
+ // verify that the desired telemetry values were only sent once
+ ASSERT_TLM_MS_VAL1_SIZE(1);
+ ASSERT_TLM_MS_VAL2_SIZE(1);
+ ASSERT_TLM_MS_OP_SIZE(1);
+ // verify that the correct telemetry values were sent
+ ASSERT_TLM_MS_VAL1(0,1.0);
+ ASSERT_TLM_MS_VAL2(0,2.0);
+ ASSERT_TLM_MS_OP(0,MathSenderComponentBase::ADD_TLM);
+```
+The first statement verifies that three channels were written as expected. The following statements verify that the correct channels were written with the expected values.
+
+Verify that the event for the command was sent:
+
+```c++
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_COMMAND_RECV_SIZE(1);
+ // verify the correct event arguments were sent
+ ASSERT_EVENTS_MS_COMMAND_RECV(0,1.0,2.0,MathSenderComponentBase::ADD_EV);
+
+```
+
+Next, verify that the correct response to the command was sent:
+
+```c++
+ // verify command response was sent
+ ASSERT_CMD_RESPONSE_SIZE(1);
+ // verify the command response was correct as expected
+ ASSERT_CMD_RESPONSE(0,MathSenderComponentBase::OPCODE_MS_DO_MATH,10,Fw::COMMAND_OK);
+```
+
+Next, prepare for calling `MathSender`'s result port by clearing the port and telemetry history:
+
+```c++
+ // reset all telemetry and port history
+ this->clearHistory();
+```
+
+As ports and commands are invoked in the component, the test component stores the history of calls. This function clears the history, in order to provide a clean slate for the next test. There are calls to clear individual histories as well. See `TesterBase.hpp` for a list. The `this->clearHistory()` call will clear them all, so is generally preferable.
+
+The next step is to invoke the port that the `MathReceiver` component will call in the example program. For the unit test, the `MathReceiver` is not present to send the result back, so the unit test will emulate that call.
+
+First, the port invocation is made:
+
+```c++
+ // call result port. We don't care about the value being correct since MathSender doesn't
+ this->invoke_to_mathIn(0,10.0);
+ // retrieve the message from the message queue and dispatch the command to the handler
+ this->component.doDispatch();
+```
+
+Next, the test checks for the expected telemetry and events:
+
+```c++
+ // verify only one telemetry value was written
+ ASSERT_TLM_SIZE(1);
+ // verify the desired telemetry channel was sent only once
+ ASSERT_TLM_MS_RES_SIZE(1);
+ // verify the values of the telemetry channel
+ ASSERT_TLM_MS_RES(0,10.0);
+ // verify only one event was sent
+ ASSERT_EVENTS_SIZE(1);
+ // verify the expected event was only sent once
+ ASSERT_EVENTS_MS_RESULT_SIZE(1);
+ // verify the expected value of the event
+ ASSERT_EVENTS_MS_RESULT(0,10.0);
+```
+
+The other test cases are similarly implemented for the other operations. See the tutorial code for their implementation.
+
+To build the unit test, type:
+
+```
+make gen_make
+make ut
+```
+
+The build system looks for a script with a specific name in order to run the unit test. The script has the form `runtest_`, where `` is the build target. For example on a Linux host, the unit test will build a Linux binary so the script would be `runtest_LINUX`.
+The build system calls a script rather than the binary directly so developers who are writing unit tests can do any necessary setup for the test like generating files, executing other scripts, etc.
+The developer writes this script and places it in the `/test/ut directory.
+
+A basic `runtest_LINUX` script looks like the following:
+
+```shell
+#!/bin/sh
+LOC=${BUILD_ROOT}/Ref/MathSender/test/ut
+cd ${LOC}
+echo "Running ${LOC}/$1/test_ut"
+${LOC}/$1/test_ut
+```
+
+The `$1` variable is the path to the test binary that is built for the local target and is provided by the build system. The binary output subdirectories are names based on the target and compiler, so using the `$1` variable allows the script to be portable.
+
+Once the files and scripts are in place, the unit test can be run by typing the following in the `MathSender` (not `test/ut`) directory:
+
+```shell
+$ make ut run_ut
+Compiling ut_LINUX unit test for RefMathSender
+make[1]: Entering directory '/mnt/c/data/source2/fprime/Ref/MathSender'
+make[1]: Nothing to be done for 'test_RefMathSendertestut'.
+make[1]: Leaving directory '/mnt/c/data/source2/fprime/Ref/MathSender'
+Build Time: 0:02.11
+Running unit test for RefMathSender
+make[1]: Entering directory '/mnt/c/data/source2/fprime/Ref/MathSender'
+Running test/ut/runtest_LINUX with output dir linux-linux-x86-debug-gnu-ut-bin
+test/ut/runtest_LINUX linux-linux-x86-debug-gnu-ut-bin
+Running /mnt/c/data/source2/fprime/Ref/MathSender/test/ut/linux-linux-x86-debug-gnu-ut-bin/test_ut
+[==========] Running 4 tests from 1 test case.
+[----------] Global test environment set-up.
+[----------] 4 tests from Nominal
+[ RUN ] Nominal.AddOperationTest
+[ OK ] Nominal.AddOperationTest (2 ms)
+[ RUN ] Nominal.SubOperationTest
+[ OK ] Nominal.SubOperationTest (0 ms)
+[ RUN ] Nominal.MultOperationTest
+[ OK ] Nominal.MultOperationTest (0 ms)
+[ RUN ] Nominal.DivideOperationTest
+[ OK ] Nominal.DivideOperationTest (0 ms)
+[----------] 4 tests from Nominal (3 ms total)
+
+[----------] Global test environment tear-down
+[==========] 4 tests from 1 test case ran. (3 ms total)
+[ PASSED ] 4 tests.
+
+```
+
+Once the test code is complete, the test can be executed with coverage checking enabled:
+
+```
+make ut run_ut cov
+```
+
+The test should pass, and the file `Ref/MathSender/MathSenderComponentImpl.cpp.gcov` can be examined to test for coverage. The coverage file has codes that indicate whether the code has been executed or not. See the `gcov` man page for details. Any code that has not been covered can be seen with `#####` at the beginning of the line.
+
+### 2.4.2 MathReceiver Implementation
+
+#### 2.4.2.1 Component Implementation
+
+As before, a stub can be generated:
+
+```
+make impl
+mv MathReceiverComponentImpl.cpp-template MathReceiverComponentImpl.cpp
+mv MathReceiverComponentImpl.hpp-template MathReceiverComponentImpl.hpp
+```
+
+Add the stub files to `mod.mk`:
+
+```make
+SRC = MathReceiverComponentAi.xml MathReceiverComponentImpl.cpp
+
+HDR = MathReceiverComponentImpl.hpp
+
+```
+
+Add the files and compile them: `make rebuild`
+
+##### 2.4.2.1.1 Port handler
+
+Look for the empty port hander in the sub class:
+
+```c++
+ void MathReceiverComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ // TODO
+ }
+```
+
+Fill the handler in with the computation of the result. The handler will also update telemetry and events:
+
+```c++
+ void MathReceiverComponentImpl ::
+ mathIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ F32 val1,
+ F32 val2,
+ MathOperation operation
+ )
+ {
+ // declare result serializable
+ Ref::MathOp op;
+ F32 res = 0.0;
+ switch (operation) {
+ case MATH_ADD:
+ op.setop(ADD);
+ res = (val1 + val2)*this->m_factor1;
+ break;
+ case MATH_SUB:
+ op.setop(SUB);
+ res = (val1 - val2)*this->m_factor1;
+ break;
+ case MATH_MULTIPLY:
+ op.setop(MULT);
+ res = (val1 * val2)*this->m_factor1;
+ break;
+ case MATH_DIVIDE:
+ op.setop(DIVIDE);
+ res = (val1 / val2)*this->m_factor1;
+ break;
+ default:
+ FW_ASSERT(0,operation);
+ break;
+ }
+ Fw::ParamValid valid;
+ res = res/paramGet_factor2(valid);
+
+ op.setval1(val1);
+ op.setval2(val2);
+ op.setresult(res);
+ this->log_ACTIVITY_HI_MR_OPERATION_PERFORMED(op);
+ this->tlmWrite_MR_OPERATION(op);
+ this->mathOut_out(0,res);
+ }
+
+```
+
+If needed, add `m_factor1` and `m_factor1s` as private variables in `MathReceiverComponentImpl.hpp`:
+
+
+```c++
+//! Implementation for MR_CLEAR_EVENT_THROTTLE command handler
+//! Clear the event throttle
+void MR_CLEAR_EVENT_THROTTLE_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq /*!< The command sequence number*/
+);
+
+// stored factor1
+F32 m_factor1;
+// number of times factor1 has been written
+U32 m_factor1s;
+```
+
+
+
+In this handler, the operation is done based on the port arguments from `MathSender`.
+The `op` structure is populated for the event and telemetry calls, and the `mathOut` port is called to send the result back to `MathSender`.
+The parameter value is retrieved during initialization and is returned via the `paramGet_factor2()` call.
+The commands to set and save the factor2 parameter run entirely in the code generated base classes.
+
+##### 2.4.2.1.2 Commands
+
+The command handler to update the value of `factor1` is as follows:
+
+```c++
+ void MathReceiverComponentImpl ::
+ MR_SET_FACTOR1_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq,
+ F32 val
+ )
+ {
+ this->m_factor1 = val;
+ this->log_ACTIVITY_HI_MR_SET_FACTOR1(val);
+ this->tlmWrite_MR_FACTOR1(val);
+ this->tlmWrite_MR_FACTOR1S(++this->m_factor1s);
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+
+```
+
+The telemetry and log values are sent, and the command response is sent.
+Note that after three calls to the handler, the `this->log_ACTIVITY_HI_MR_SET_FACTOR1(val)` call will not actually send any events until the throttle is cleared.
+The throttled state is part of the generated code.
+
+The handler to clear the throttle is as follows:
+
+```c++
+ void MathReceiverComponentImpl ::
+ MR_CLEAR_EVENT_THROTTLE_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq
+ )
+ {
+ // clear throttle
+ this->log_ACTIVITY_HI_MR_SET_FACTOR1_ThrottleClear();
+ // send event that throttle is cleared
+ this->log_ACTIVITY_HI_MR_THROTTLE_CLEARED();
+ // reply with completion status
+ this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
+ }
+```
+##### 2.4.2.1.3 Scheduler Call
+
+The port invoked by the scheduler retrieves the messages from the message queue and dispatches them.
+The message dispatches invoke the command and input port handlers that were implemented earlier in the tutorial.
+
+```c++
+ void MathReceiverComponentImpl ::
+ SchedIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context
+ )
+ {
+ QueuedComponentBase::MsgDispatchStatus stat = QueuedComponentBase::MSG_DISPATCH_OK;
+ // empty message queue
+ while (stat != MSG_DISPATCH_EMPTY) {
+ stat = this->doDispatch();
+ }
+ }
+
+```
+
+##### 2.4.2.1.4 Parameter Updates
+
+The developer can optionally receive a notification that a parameter has been updated by overriding a virtual function in the code generated base class:
+
+```c++
+ void MathReceiverComponentImpl ::
+ parameterUpdated(
+ FwPrmIdType id /*!< The parameter ID*/
+ ) {
+ if (id == PARAMID_FACTOR2) {
+ Fw::ParamValid valid;
+ F32 val = this->paramGet_factor2(valid);
+ this->log_ACTIVITY_HI_MR_UPDATED_FACTOR2(val);
+ }
+ }
+```
+
+Add the function to the header file:
+
+```c++
+ // stored factor1
+ F32 m_factor1;
+ // number of times factor1 has been written
+ U32 m_factor1s;
+
+ void parameterUpdated(
+ FwPrmIdType id /*!< The parameter ID*/
+ );
+```
+
+Once it is added, add the directory to the build and build the component by typing `make rebuild` from the `Ref` directory.
+
+#### 2.4.2.2 Unit Tests
+
+See section `2.4.1.3.1` for directions on how to generate unit test stubs and copy them to the correct subdirectory.
+The `MathReceiver` tests are similar to `MathSender`.
+
+##### 2.4.2.2.1 Test Code Implementation
+
+The full unit test code for the `MathReceiver` component can be found in the `docs/Tutorials/MathComponent/MathReceiver/test/ut` directory. Many of the patterns are the same. Following are some highlights:
+
+##### 2.4.2.2.2 Parameter Initialization
+
+`Tester.cpp`, line 60:
+
+```c++
+ void Tester ::
+ testAddCommand(void)
+ {
+ // load parameters
+ this->component.loadParameters();
+ ...
+```
+
+The `loadParameters()` call will attempt to load any parameters that the component needs.
+The `this->paramSet_*` functions in the `*TesterBase` base classes allow the developer to set parameter and status values prior to the `loadParameters()`
+With no manually set parameter values preceding the call, in this test case the parameter value is set to the default value.
+It is a way to test default settings for parameters.
+
+`Tester.cpp`, line 206:
+
+```c++
+ void Tester ::
+ testSubCommand(void)
+ {
+ // set the test value for the parameter before loading - it will be initialized to this value
+ this->paramSet_factor2(5.0,Fw::PARAM_VALID);
+
+ // load parameters
+ this->component.loadParameters();
+
+```
+
+In this test case, the parameter value was set prior to the `loadParameters()` call. A `Fw::PARAM_VALID` status is also set, which allows the component consider the value valid and use it.
+
+##### 2.4.2.2.3 Serializable Usage
+
+`Tester.cpp`, line 78:
+
+```c++
+ ...
+ // verify the result of the operation was returned
+ F32 result = (2.0-3.0)*2.0/5.0;
+ // the event and telemetry channel use the Ref::MathOp type for values
+ Ref::MathOp checkOp(2.0,3.0,Ref::SUB,result);
+ ...
+```
+
+The `Ref::Mathop` class is the C++ implementation of the serializable type defined in `2.2.1`. When checking event and telemetry histories against the expected values, simply instantiate the serializable class in the test code and use it for comparisons.
+
+##### 2.4.2.2.4 Event Throttling
+
+`Tester.cpp`, line 395:
+
+```c++
+ void Tester ::
+ testThrottle(void)
+ {
+```
+
+This unit test demonstrates how event throttling works. The event is repeatedly issued until it reaches the throttle count and then is suppressed from then on. The throttle is reset by the `MR_CLEAR_EVENT_THROTTLE` command:
+
+`Tester.cpp`, line 446:
+
+```c++
+ // send the command to clear the throttle
+ this->sendCmd_MR_CLEAR_EVENT_THROTTLE(0,10);
+```
+
+
+# 3 Topology
+
+Now that the two components are defined, implemented and unit tested they can to be added to the `Ref` topology.
+The topology describes the interconnection of all the components so the system operates as intended.
+They consist of the core Command and Data Handling (C&DH) components that are part of the reusable set of components that come with the F` repository as well as custom components written for the `Ref` reference example including the ones in this tutorial.
+The `Ref` topology has already been developed as an example.
+The tutorial will add the `MathSender` and `MathReceiver` components to the existing demonstration.
+It involves modification of a topology description XML file as well as accompanying C++ code to instantiate and initialize the components.
+
+## 3.1 Define C++ Component Instances
+
+The first step is to include the implementation files in the topology source code.
+
+### 3.1.1 Components.hpp
+
+There is a C++ header file that declares all the component instances as externals for use by the initialization code and the generated code that interconnects the components. The two new components can be added to this file. First, include the header files for the implementation classes:
+
+`Ref/Top/Components.hpp`, line 30:
+
+```c++
+#include
+
+#include
+#include
+```
+
+`extern` declarations need to be made in this header file for use by the topology connection file that is discussed later as well as initialization code.
+
+`Ref/Top/Components.hpp`, line 61:
+
+```c++
+extern Ref::PingReceiverComponentImpl pingRcvr;
+
+extern Ref::MathSenderComponentImpl mathSender;
+extern Ref::MathReceiverComponentImpl mathReceiver;
+```
+
+### 3.1.2 Topology.cpp
+
+This C++ file is where the instances of the all the components are declared and initialized. The generated topology connection function is called from this file.
+
+#### 3.1.2.1 Component Instantiation
+
+Put these declarations after the declarations for the other `Ref` components:
+
+`Ref/Top/Topology.cpp`, line 187:
+
+```c++
+Ref::MathSenderComponentImpl mathSender
+#if FW_OBJECT_NAMES == 1
+ ("mathSender")
+#endif
+;
+
+Ref::MathReceiverComponentImpl mathReceiver
+#if FW_OBJECT_NAMES == 1
+ ("mathReceiver")
+#endif
+;
+```
+
+Where the other components are initialzed, add `MathSender` and `MathReceiver`:
+
+`Ref/Top/Topology.cpp`, line 286:
+
+```c++
+ pingRcvr.init(10);
+
+ mathSender.init(10,0);
+ mathReceiver.init(10,0);
+```
+
+The first argument is the queue message depth.
+This is the number of messages that can be pending while other messages are being dispatched.
+
+After all the components are initialized, the generated function `constructRefArchitecture()` (see `RefTopologyAppAc.cpp`) can be called to connect the components together. How this function is generated will be seen later in the tutorial.
+
+`Ref/Top/Topology.cpp`, line 291:
+
+```c++
+ // call generated function to connect components
+ constructRefArchitecture();
+
+```
+
+Next, the components commands are registered.
+
+`Ref/Top/Topology.cpp`, line 308:
+
+```c++
+ health.regCommands();
+ pingRcvr.regCommands();
+
+ mathSender.regCommands();
+ mathReceiver.regCommands();
+```
+
+Component parameters are retrieved from disk by `prmDb` prior to the components requesting them:
+
+`Ref/Top/Topology.cpp`, line 314:
+
+```c++
+ // read parameters
+ prmDb.readParamFile();
+```
+
+Once the parameters are read by `prmDb`, the components can request them:
+
+`Ref/Top/Topology.cpp`, line 300:
+
+```c++
+ sendBuffComp.loadParameters();
+
+ mathReceiver.loadParameters();
+```
+
+The thread for the active `MathSender` component needs to be started:
+
+`Ref/Top/Topology.cpp`, line 357:
+
+```c++
+ pingRcvr.start(0, 100, 10*1024);
+
+ mathSender.start(0,100,10*1024);
+```
+
+The arguments to the `start()` function is as follows:
+
+|Argument|Usage|
+|---|---|
+|1|Thread ID, unique value for each thread. Not used for Linux|
+|2|Thread priority. Passed to underlying OS|
+|3|Thread stack size. Passed to underlying OS|
+
+
+The `MathReceiver` queued component will execute on the thread of the 1Hz rate group, which will be shown later.
+It does not need to to have a thread started, since queued components do not have threads.
+
+The `exitTasks()` function is called when the process is shut down.
+It contains `exit()` calls to all the active components.
+These functions internally send a message to the component's thread to shut down.
+
+`Ref/Top/Topology.cpp`, line 396:
+
+```c++
+ cmdSeq.exit();
+
+ mathSender.exit();
+```
+## 3.2 Define Component Connections
+
+Components need to be connected to invoke each other via ports.
+The connections are specified via a topology XML file.
+The file for the Ref example is located in `Ref/Top/RefTopologyAppAi.xml`
+The connections for the new components will be added to the existing connections.
+
+### 3.2.1 Component Imports
+
+The component XML definitions must be imported into the topology file:
+
+`Ref/Top/RefTopologyAppAi.xml`, line 32:
+
+```xml
+ Svc/PassiveTextLogger/PassiveTextLoggerComponentAi.xml
+
+ Ref/MathSender/MathSenderComponentAi.xml
+ Ref/MathReceiver/MathReceiverComponentAi.xml
+```
+
+### 3.2.2 Component Instances
+
+The Component instances must be declared.
+
+`Ref/Top/RefTopologyAppAi.xml`, line 92:
+
+```xml
+
+
+
+
+```
+
+The name in the `name=` attribute must match the one declared previously in `Ref/Top/Components.hpp`. For example:
+
+```c++
+extern Ref::MathSenderComponentImpl mathSender;
+```
+
+The type must match the type declared in the component XML:
+
+`Ref/MathSender/MathSenderComponentAi.xml`:
+
+```xml
+
+```
+
+The `base_id` attribute specifies the beginning range of the assigned IDs for commands, telemetry, events, and parameters.
+The values declared in the component XML are added to this base address.
+This allows multiple instances of components to be declared with unique ID ranges.
+The `base_id_window` attribute is used to set a limit on ID ranges for spacing the base IDs from different components sufficiently apart.
+If the IDs exceed the limit, the code generator will issue a warning.
+
+### 3.2.3 Command connections
+
+The command connections should follow these rules:
+
+1. The port number of the command registration port on the `cmdDisp` component connection from the commanded components must be unique for all components.
+2. The port number of the command dispatch port connection from the `cmdDisp` component to the commanded component must match the registration port number.
+3. The command status from the components can go to port 0 of the command status port of the `cmdDisp` component.
+
+The following XML shows the command connection for the tutorial components.
+
+The port number used for the registration and dispatch ports is selected as 20,
+a unique number that hasn't been used yet in the `Ref` example.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 817:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3.2.4 Event Connections
+
+The output connections for log ports are connected to the `eventLogger` component.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 845:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+There are two kinds of connections for logging: One for a binary form that will be sent to the ground system, and a text version for displaying on standard output of the target machine.
+
+### 3.2.5 Telemetry Connections
+
+The telemetry output ports are connected to the `chanTlm` component.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 872:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3.2.6 Parameter Connections
+
+There are two parameter connections, a `PrmGet` connection for reading parameters during software initialization and a `PrmSet` for updating parameters in the component that manages parameter values. F' has a basic parameter storage component `prmDb` that stores parameters in files. Upon bootup, they are read from a file specified in the constructor and stored in memory. Subsequent to this, components request their parameters via the `PrmGet` connection. If they are updated by command, they can be saved to storage by issuing a command to call the `PrmSet` with the new value and issuing the `PRM_SAVE_FILE` command.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 883:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3.2.7 Time Connections
+
+Components that have telemetry or events need to be able to time stamp the events. The time connections connect the components to a time source to provide the time stamps.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 894:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3.2.8 Scheduler Connection
+
+The `MathReceiver` component does not have a thread of its own, but relies on the thread of another component to drive it via the `SchedIn` port. The `SchedIn` port is connected to the 1Hz rate group component that is part of the `Ref` example. This means that every second the component gets a call and can unload messages from its message queue and dispatch them to handlers.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 894:
+
+```xml
+
+
+
+
+
+```
+
+### 3.2.9 The Math Operation Connection
+
+The final connection is the connection that performs the math operation. It goes from `MathSender` to `MathReceiver`.
+
+`Ref/MathSender/MathSenderComponentAi.xml`, line 911:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Once all the updates to the topology file have been made, the module can be built by typing `make` at the command line in the `Ref/Top` directory.
+If the updates were correct, the module should compile with no errors.
+The overall `Ref` deployment can be built by changing to the `Ref` directory and typing `make`.
+To build the command/telemetry GUI dictionary files, run `make dict_install`.
+
+
+If running `make` builds on the wrong platform, you can specify the build target by typing `make `. The different build targets can be viewed with `make help`.
+
+# 4 Executing the Example
+
+## 4.1 Running the Ground System
+
+Once the `Ref` example has successfully built, the ground system and executable can be run by typing `./scripts/run_ref.sh`. The ground system GUI should appear:
+
+
+
+### 4.1.1 Executing Commands
+
+Commands can be executed by selecting the `Commands` tab and clicking on the `Cmds` drop-down list.
+
+
+
+For the tutorial example, select the `MathSender` command `MS_DO_MATH` and fill in the arguments.
+
+
+
+Clicking on the `Send` button will send the command to the software. When the command is sent, it is placed in the command history. It can be selected and sent again if the user desires.
+
+
+
+### 4.1.2 Checking Events
+
+The `Log Events` tab shows events that are generated by the software. For the tutorial, the events tab shows the events that were sent by the `MS_DO_MATH` command:
+
+
+
+It shows the F' `CmdDispatcher` event indicating a command was dispatched and completed. It also has the events defined by the tutorial example that are sent as a results of requesting a math operation. The result is zero, since the `factor1` value is zero, as shown in the unit testing in section `2.4.2.2`.
+
+The events are also echoed to `stdout` of the application:
+
+
+
+### 4.1.3 Checking Telemetry
+
+The `Channel Telemetry` tab shows channelized telemetry sent by the software. The channels defined by the tutorial have the last values and time they were updated:
+
+
+
+### 4.1.5 Updating `factor1`
+
+In order to get a non-zero result, `factor1` needs to be updated. The tutorial defined a command to update it, `MR_SET_FACTOR1`. It can be selected from the command tab:
+
+
+
+When the command is executed, the `Log Events` tab will show the event indicating the value was updated:
+
+
+
+The `Channel Telemetry` tab shows the two channels related to the update. `MR_FACTOR1` shows the new value, while `MR_FACTOR1S` show how many times the value has been updated.
+
+
+
+### 4.1.6 Running the Command Again
+
+After `factor1` has been updated, the command can be repeated:
+
+
+
+### 4.1.7 Updated Events and Telemetry
+
+The new events will appear in the `Log Events` tab:
+
+
+
+Notice that the updated events are added to the end of the log, since events are meant to be a record of events in the software.
+
+The `Channel Telemetry` tab will also show the updated values:
+
+
+
+Notice that the `MS_OP`, `MS_VAL1`, `MS_VAL2`, `MR_OPERATION`, and `MS_RESULT` are updated to the latest value with a more recent time stamp, since telemetry channels are meant to show the latest value. The new result is `10.0` now that `factor1` has been updated.
+
+### 4.1.8 Parameter Updates
+
+The tutorial defined a `factor2` parameter in the `MathReceiver` component. The code generator creates two commands for each parameter: `XXXX_PRM_SET` and `XXX_PRM_SAVE` where `XXX` is an upper case version of the parameter name. The `FACTOR2_PRM_SET` command will set the value in `MathReceiver`, while `FACTOR2_PRM_SAVE` will send the current value to `PrmDb` for storage. `PrmDb` is an F' infrastructure component that reads and writes parameters to storage. It is important to note that `PrmDb` does not immediately write the value to storage. There is an explicit `PRM_SAVE_FILE` command that will take all the parameter values currently in RAM and write them.
+
+#### 4.1.8.1 Setting the Parameter Value
+
+The `FACTOR1_PRM_SET` command can be sent to the software:
+
+
+
+The notification function that was implemented as part of the tutorial will send an event indicating the value was updated:
+
+
+
+The `MS_DO_MATH` command can now be executed with the new value:
+
+
+
+The `MathReceiver` component sends the events with the new result:
+
+
+
+The new result is `1.0` with the new value of `factor2`. The "Channel Telemetry" tab also shows the new values:
+
+
+
+#### 4.1.8.2 Saving the Parameter Value
+
+Once the parameter value has been tested to the user's satisfaction, it can be saved to `PrmDb` by sending the `FACTOR2_PRM_SAVE` command:
+
+
+
+The `Log Events` tab has an event from `PrmDb` indicating that the `FACTOR2` parameter value was added:
+
+
+
+#### 4.1.8.3 Writing the Parameter to Storage
+
+The parameter can be written to storage by sending the `PRM_SAVE_FILE` command:
+
+
+
+`PrmDb` sends an event indicating that the parameters in RAM were stored:
+
+
+
+### 4.1.9 Ground System Logs
+
+The ground system keeps logs of all received events and telemetry. They can be found in the directories `/logs//channel/Channel.log` and `/logs//event/Event.log`, where `` is the location the ground system was run from. For the tutorial, it is `Ref`. The `` part of the path is a string contructed of the date and time the ground system was started.
+
+### 4.1.10 Ground System Scripting
+
+As an alternative to executing commands by selecting them from the GUI, users can write script files that contain the commands in text form. They run through the ground system and dispatch a specified set of commands. They are executed when the ground system is up and running. The syntax of the script file is as follows:
+
+```
+# Comment
+
+CMD_NAME, arg1, arg2, arg3 # end of line comment
+WAIT, 2
+ANOTHER_CMD
+
+```
+
+The `#` token denotes a comment. Any text from the token to the end of the line is ignored.
+
+Lines can be blank.
+
+A line with a command starts with the command mnemonic. It is followed by a comma then a comma separated list of command arguments.
+
+There is a one second delay between the execution of each command in the list. If a longer delay is desired, a special command `WAIT, ` can be added to the list.
+
+To recreate the set of tutorial commands that were executed manually via the GUI (see `4.1.1`), the script file would look like:
+
+```
+# Run this script to replicate the MathComponent tutorial
+
+MS_DO_MATH, 2.0, 3.0, ADD # Add two numbers together
+MR_SET_FACTOR1, 2.0 # Set factor1 to 2.0
+MS_DO_MATH, 2.0, 3.0, ADD # Re-run math operation with new factor1 value
+WAIT, 2 # Wait two seconds
+FACTOR2_PRM_SET, 10.0 # Set factor2 to 10.0
+MS_DO_MATH, 2.0, 3.0, ADD # Re-run math operation with new factor2 value
+FACTOR2_PRM_SAVE # Save parameter
+PRM_SAVE_FILE # Save parameters to disk
+```
+
+Save this file as `Ref/scripts/math_scripts.txt", and then from the `Ref` directory, run:
+
+```
+./scripts/run_ref_cmds.sh scripts/math_script.txt
+```
+
+The output should appear as follows:
+
+```
+BUILD_ROOT is: xxxxxx/fprime
+PYTHON_BASE: /usr
+NATIVE_BUILD: LINUX
+OUTPUT_DIR: linux-linux-x86-debug-gnu-bin
+None
+Connecting to host addr 127.0.0.1, port 50000
+
+Parsing command file scripts/math_script.txt
+Sent command MS_DO_MATH with arguments ['2.0', '3.0', 'ADD']
+Sent command MR_SET_FACTOR1 with arguments ['2.0']
+Sent command MS_DO_MATH with arguments ['2.0', '3.0', 'ADD']
+Wait 2
+Wait 1
+Sent command FACTOR2_PRM_SET with arguments ['10.0']
+Sent command MS_DO_MATH with arguments ['2.0', '3.0', 'ADD']
+Sent command FACTOR2_PRM_SAVE with arguments []
+Sent command PRM_SAVE_FILE with arguments []
+```
+
+The script will execute and show the same events and telemetry channels as manually executing the commands through the GUI.
+
+## 4.2 Sequences
+
+Sequences are a list of commands that are compiled to a binary form and executed in order via the `CmdSequencer` component. The binary file is compiled during ground operations and uploaded to the target hardware. `CmdSequencer` dispatches each command, and if one of them returns a failure the sequence is aborted.
+
+### 4.2.1 Writing a Sequence
+
+The sequence file has the following syntax:
+
+```
+; This is a comment line
+
+A-T::,,...
+R::,,...
+```
+
+Blank lines and any characters past the `;` token are ignored.
+
+The `A` token denotes an absolute time to run the command on that line. If the time has not arrived, the sequencer will wait until the time arrives to dispatch the command. If the time has passed, the command will dispatched immediately.
+
+The `R` token specifies a relative time from the current time when the command will be dispatched. It is relative to the time the line in the sequence is processed rather than the start of the sequence. A value of `R00:00:00` means that the command will be dispactched immediately.
+
+The `` and `` fields are the command mnemonic and arguments.
+
+The sequence to execute the tutorial commands would be as follows:
+
+```
+; Run this sequence to replicate the MathComponent tutorial
+
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Add two numbers together
+R00:00:00 MR_SET_FACTOR1 2.0 ; Set factor1 to 2.0
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Re-run math operation with new factor1 value
+R00:00:02 FACTOR2_PRM_SET 10.0 ; Set factor2 to 10.0
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Re-run math operation with new factor2 value
+R00:00:00 FACTOR2_PRM_SAVE ; Save parameter
+R00:00:00 PRM_SAVE_FILE ; Save parameters to disk
+```
+
+Save this sequence file as `Ref/sequences/math_sequence.seq`.
+
+### 4.2.2 Compiling the Sequence
+
+The file can be compiled by executing the following from the `Ref` directory:
+
+```
+./scripts/compile_ref_sequence.sh ./sequences/math_sequence.seq
+```
+The output should appear as follows:
+
+```
+BUILD_ROOT is: XXXXXX/fprime
+PYTHON_BASE: /usr
+Sequence is 191 bytes
+CRC: 3121812285 (0xBA13133D)
+```
+
+The sequence compiler generates a file `Ref/sequences/math_sequence.bin`, which is the binary form of the sequence.
+
+### 4.2.3 Executing the Sequence
+
+Sequences are run by invoking the `CS_Run` command while the software is running. The F' `CmdSequencer` infrastructure component loads the sequence from the target's file system and executes it. Normally for a flight project there is a process of uplinking the file to the flight vehicle, but the `Ref` example can access the binary file directly.
+
+The sequence run command can be sent via the GUI:
+
+
+
+The `Log Events` panel will show the expected events from the tutorial example. In addition, it shows the events sent by the sequencer as it executes each command in the sequence:
+
+
+
+Likewise, the `Channel Telemetry` tab shows the tutorial channels as well as channels updated by the sequencer:
+
+
+
+# Conclusion
+
+This tutorial is an attempt to communicate the concepts and implementation. If there are aspects that are confusing, feel free to submit GitHub issues asking for clarification or to report errors:
+
+https://github.com/nasa/fprime/issues
\ No newline at end of file
diff --git a/docs/Tutorials/MathComponent/img/App1.jpg b/docs/Tutorials/MathComponent/img/App1.jpg
new file mode 100644
index 0000000000..0075170ae1
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/App1.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/App2.jpg b/docs/Tutorials/MathComponent/img/App2.jpg
new file mode 100644
index 0000000000..78ffdfe719
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/App2.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Comp.jpg b/docs/Tutorials/MathComponent/img/Comp.jpg
new file mode 100644
index 0000000000..659b115357
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Comp.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/CompDiag.pptx b/docs/Tutorials/MathComponent/img/CompDiag.pptx
new file mode 100644
index 0000000000..86f9051351
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/CompDiag.pptx differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd1.jpg b/docs/Tutorials/MathComponent/img/Gnd1.jpg
new file mode 100644
index 0000000000..e3c6762f67
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd1.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd10.jpg b/docs/Tutorials/MathComponent/img/Gnd10.jpg
new file mode 100644
index 0000000000..94d06f685c
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd10.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd11.jpg b/docs/Tutorials/MathComponent/img/Gnd11.jpg
new file mode 100644
index 0000000000..b0539bfc5f
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd11.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd12.jpg b/docs/Tutorials/MathComponent/img/Gnd12.jpg
new file mode 100644
index 0000000000..446cb043c3
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd12.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd13.jpg b/docs/Tutorials/MathComponent/img/Gnd13.jpg
new file mode 100644
index 0000000000..2bc52c523e
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd13.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd14.jpg b/docs/Tutorials/MathComponent/img/Gnd14.jpg
new file mode 100644
index 0000000000..65a76fb9c8
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd14.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd15.jpg b/docs/Tutorials/MathComponent/img/Gnd15.jpg
new file mode 100644
index 0000000000..ed7ff8e392
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd15.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd16.jpg b/docs/Tutorials/MathComponent/img/Gnd16.jpg
new file mode 100644
index 0000000000..771097f681
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd16.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd17.jpg b/docs/Tutorials/MathComponent/img/Gnd17.jpg
new file mode 100644
index 0000000000..65cef6efd8
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd17.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd18.jpg b/docs/Tutorials/MathComponent/img/Gnd18.jpg
new file mode 100644
index 0000000000..ebf44548ff
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd18.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd19.jpg b/docs/Tutorials/MathComponent/img/Gnd19.jpg
new file mode 100644
index 0000000000..a42395fe2a
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd19.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd2.jpg b/docs/Tutorials/MathComponent/img/Gnd2.jpg
new file mode 100644
index 0000000000..b2012a8991
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd2.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd20.jpg b/docs/Tutorials/MathComponent/img/Gnd20.jpg
new file mode 100644
index 0000000000..3bab0f4119
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd20.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd21.jpg b/docs/Tutorials/MathComponent/img/Gnd21.jpg
new file mode 100644
index 0000000000..4c5123972c
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd21.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd3.jpg b/docs/Tutorials/MathComponent/img/Gnd3.jpg
new file mode 100644
index 0000000000..5e3786659f
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd3.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd30.jpg b/docs/Tutorials/MathComponent/img/Gnd30.jpg
new file mode 100644
index 0000000000..83c2f8d462
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd30.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd31.jpg b/docs/Tutorials/MathComponent/img/Gnd31.jpg
new file mode 100644
index 0000000000..ce3a9de845
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd31.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd32.jpg b/docs/Tutorials/MathComponent/img/Gnd32.jpg
new file mode 100644
index 0000000000..07171935dc
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd32.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd4.jpg b/docs/Tutorials/MathComponent/img/Gnd4.jpg
new file mode 100644
index 0000000000..9a6181575a
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd4.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd5.jpg b/docs/Tutorials/MathComponent/img/Gnd5.jpg
new file mode 100644
index 0000000000..bb822627b8
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd5.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd6.jpg b/docs/Tutorials/MathComponent/img/Gnd6.jpg
new file mode 100644
index 0000000000..6b69ba6518
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd6.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd7.jpg b/docs/Tutorials/MathComponent/img/Gnd7.jpg
new file mode 100644
index 0000000000..b61f4315b6
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd7.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd8.jpg b/docs/Tutorials/MathComponent/img/Gnd8.jpg
new file mode 100644
index 0000000000..95f6ede5d3
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd8.jpg differ
diff --git a/docs/Tutorials/MathComponent/img/Gnd9.jpg b/docs/Tutorials/MathComponent/img/Gnd9.jpg
new file mode 100644
index 0000000000..8c52bc532c
Binary files /dev/null and b/docs/Tutorials/MathComponent/img/Gnd9.jpg differ
diff --git a/docs/Tutorials/MathComponent/scripts/math_script.txt b/docs/Tutorials/MathComponent/scripts/math_script.txt
new file mode 100644
index 0000000000..ab32cbecb0
--- /dev/null
+++ b/docs/Tutorials/MathComponent/scripts/math_script.txt
@@ -0,0 +1,10 @@
+# Run this script to replicate the MathComponent tutorial
+
+MS_DO_MATH, 2.0, 3.0, ADD # Add two numbers together
+MR_SET_FACTOR1, 2.0 # Set factor1 to 2.0
+MS_DO_MATH, 2.0, 3.0, ADD # Re-run math operation with new factor1 value
+WAIT, 2 # Wait two seconds
+FACTOR2_PRM_SET, 10.0 # Set factor2 to 10.0
+MS_DO_MATH, 2.0, 3.0, ADD # Re-run math operation with new factor2 value
+FACTOR2_PRM_SAVE # Save parameter
+PRM_SAVE_FILE # Save parameters to disk
diff --git a/docs/Tutorials/MathComponent/sequences/math_sequence.seq b/docs/Tutorials/MathComponent/sequences/math_sequence.seq
new file mode 100644
index 0000000000..1df43f876b
--- /dev/null
+++ b/docs/Tutorials/MathComponent/sequences/math_sequence.seq
@@ -0,0 +1,9 @@
+; Run this sequence to replicate the MathComponent tutorial
+
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Add two numbers together
+R00:00:00 MR_SET_FACTOR1 2.0 ; Set factor1 to 2.0
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Re-run math operation with new factor1 value
+R00:00:02 FACTOR2_PRM_SET 10.0 ; Set factor2 to 10.0
+R00:00:00 MS_DO_MATH 2.0, 3.0, ADD ; Re-run math operation with new factor2 value
+R00:00:00 FACTOR2_PRM_SAVE ; Save parameter
+R00:00:00 PRM_SAVE_FILE ; Save parameters to disk
diff --git a/docs/Tutorials/README.md b/docs/Tutorials/README.md
new file mode 100644
index 0000000000..89deda53ed
--- /dev/null
+++ b/docs/Tutorials/README.md
@@ -0,0 +1,5 @@
+## Tutorial List
+
+1. [MathComponent](MathComponent/Tutorial.md)
+
+A tutorial that creates two trivial "math" components that illustrates the process of specifying ports, components, and topologies. It also shows developer implementation and unit tests.
\ No newline at end of file
diff --git a/docs/UsersGuide/FprimeUserGuide.docx b/docs/UsersGuide/FprimeUserGuide.docx
index bac71abaaa..47eb610923 100644
Binary files a/docs/UsersGuide/FprimeUserGuide.docx and b/docs/UsersGuide/FprimeUserGuide.docx differ
diff --git a/docs/UsersGuide/FprimeUserGuide.pdf b/docs/UsersGuide/FprimeUserGuide.pdf
index 050412ea22..10be729ee0 100644
Binary files a/docs/UsersGuide/FprimeUserGuide.pdf and b/docs/UsersGuide/FprimeUserGuide.pdf differ
diff --git a/docs/_config.yml b/docs/_config.yml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
new file mode 100644
index 0000000000..0033e986b6
--- /dev/null
+++ b/docs/_layouts/default.html
@@ -0,0 +1,49 @@
+
+
+
+
+ {{ page.title }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ content }}
+
+
+
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 0000000000..64fa43902c
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,1952 @@
+---
+title: Getting Started
+layout: default
+---
+# Getting Started with F'
+
+In this guide, we will cover the basics of working with F'. To start with, we retrieve the code, build the reference application, and verify
+that the reference application will run. After that we will create a custom F' component and create our own application. Along the way
+we will cover: Components, Topologies, Events, Telemetry, and Commands. In addition, we will see how to modify the build system to include our
+new components and topologies.
+
+## Getting Started with F' and the Reference Application
+
+The first step to running F' is to ensure that the required build tools are available on your system. At its most basic, F' requires
+several tools to be installed: Git, GNU make, lxml, and python 2 w/ cheetah. In order, to run the ground-system several more packages are required (see: Gse/bin/required.txt). Make is available on most systems, as well as git and lxml.
+
+### Cloning the Software and Building the Reference Application
+
+The first step is to clone the software from GitHub. The following command will clone the software straight from NASA's GitHub project page.
+
+```
+git clone https://github.com/nasa/fprime.git
+```
+
+### Installation
+
+The next step is to install the software. Make sure git, and lxml are installed on your system. Then, using Python 2's pip tool the python dependencies can be installed. Both these steps can be accomplished on Ubuntu with the following commands:
+
+#### Ubuntu Installation (sudo may be required)
+```
+sh fprime/mk/os-pkg/ubuntu-packages.sh
+pip install numpy
+pip install -r fprime/mk/python/pip_required_build.txt
+pip install -r fprime/mk/python/pip_required_gui.txt
+```
+*Note:* other installation and setup instructions are availabe in the [user guide.](https://github.com/nasa/fprime/blob/master/docs/UsersGuide/FprimeUserGuide.pdf)
+*Note 2:* numpy is required for some packages setup scripts, and thus must be install first.
+
+### Building the Reference Application
+
+The reference application is used to help developers develop F Prime applications by showing various features. It is also a useful test of the
+installation and thus we will run it here.
+
+Once the software is cloned and packages installed, the reference-application can be built by changing into the reference directory, generating make files,
+cleaning and makeing the code.
+
+```
+cd fprime/Ref
+make gen_make
+make clean
+make
+```
+
+If the build progresses to success, the reference application has been successfully built. The binary outputs can be found in a new directory named with
+the architecture for which you built the reference application. i.e. *darwin-darwin-x86-debug-llvm-bin* or *linux-linux-x86-debug-gnu-bin*
+
+### Running the Reference Application
+
+In order to run the reference application, one needs to run the binary named *Ref* in the above created target directory. Running the application will
+show that the reference application was successfully built and runnable. Replace *darwin-darwin-x86-debug-llvm-bin* in the below commands by the target
+used in building the reference application
+
+**Running with the GUI:**
+```
+cd fprime/Ref
+./scripts/run_ref.sh
+```
+
+**Note:** running with the gui is the recommended way of running the application. However, one can run the application directly from target output directory if desired.
+
+Success!!! We have now successfully run the reference application, showing that the build tools work. We are ready to proceed to a custom application.
+
+## Custom Application Goals
+
+In the DIY electronics community there is an abundace of cheap GPS receivers based around the NMEA protocol. These receivers often suport a USB interface
+pretending to be am ACM device for basic serial communication. The messages these receivers send are NMEA formatted text.
+
+
+
+This quick-start guide will show how to integrate one of these GPS receivers with the F' framework by wrapping it in a Component and defining commands,
+telemetry, and log events. Finally, we will modify the reference Topology to include this new component such that we can downlink our telemetry to
+the F' supplied ground station (GSE).
+
+**Note:** all the sample files, and a working deployment are available at [https://github.com/LeStarch/fprime/tree/gps-application](https://github.com/LeStarch/fprime/tree/gps-application).
+
+## Creating a Custom F' Component
+
+In this next section we will create a custom F' component for reading GPS data off a UART based GPS module. We will then downlink this data as telemetry
+and finish up by adding an event to report GPS lock status and a command to report lock-status on demand.
+
+### Designing the GPS Component
+
+The F’ designs are specified by XML files that are compiled by code generators. An XML file represents a single component including the ports it uses
+to communicate with other components as well as references to the dictonaries that define events/log messages, telmetry, and commands. Further discussion
+of components, ports, events, telemetry, and commands can be found in the F' user guide. [User Guide](docs/UsersGuide/FprimeUserGuide.pdf). *Side note:*
+Ports are also defined with XML, however; this application does not need any customized ports and thus we need not elaborate here.
+
+The first step to making a compnent is to make a project directory to hold our project's components, and a component directory for our GPS. This is do
+as follows:
+
+```
+cd fprime
+mkdir -p GpsApp/Gps
+cd GpsApp/Gps
+```
+
+Next, in this directory, we will create a file called *GpsComponentAi.xml* filled with the below text. This represents our component's design by defining
+the ports it uses to connect with other components and the files used to specify commands, telemetry, and events. As can be seen, we are creating our component
+to have 5 ports:
+
+1. **cmdRegOut**: an output port of *Fw::CmdReg* type used to register this component's commands with the command dispatcher
+2. **eventOut**: an output port of *Fw::Log* type used to log events
+3. **cmdIn**: an input port of *Fw::Cmd* type used to process commands sent to this component
+4. **tlmOut**: an output port of *Fw::Tlm* type used to send out telemetry items
+5. **cmdResponseOut**: an output port of *Fw::CmdResponse* type used to signal a command has finished
+
+
+In addition, our component imports the above port types, and imports 3 dictionaries: Commands.xml, Events.xml, and Telemetry.xml. The GpsComponentAi.xml
+file should look like this:
+
+```
+
+
+
+
+
+ Fw/Cmd/CmdRegPortAi.xml
+ Fw/Log/LogPortAi.xml
+ Fw/Cmd/CmdPortAi.xml
+ Svc/Sched/SchedPortAi.xml
+ Fw/Tlm/TlmPortAi.xml
+ Fw/Cmd/CmdResponsePortAi.xml
+ GpsApp/Gps/Commands.xml
+ GpsApp/Gps/Telemetry.xml
+ GpsApp/Gps/Events.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Connecting these components together is done at the system level, enabling the individual components to be reused in different applications. We will
+see this step later.
+
+## Creating Commands.xml, Events.xml and Telemetry.xml Dictionaries
+
+These three XML dictionaries define the structure of commands, events, and telemetry that our component uses. This allows the auto-coding system
+to automatically generate the needed code to process commands, and emit events and telemetry. This allows the developer to concentrate on the specific code for the component.
+
+First we will create a command dictionary. The purpose of our command is to report the lock status of the GPS unit. This command will trigger an event
+which will report if the GPS is locked or not. Commands.xml should look like the following:
+
+```
+
+
+
+
+
+
+
+
+ A command to force an EVR reporting lock status.
+
+
+
+```
+
+Next we will create an Events.xml dictionary that setup the events our component can log. In this case we have two events, GPS locked and GPS lock lost.
+Here again we have and ID base allowing us to fill in the event offsets later. The Events.xml file should look like:
+
+```
+
+
+
+
+
+
+
+
+ A notification on GPS lock aquired
+
+
+
+ A notification on GPS lock lost
+
+
+
+```
+
+Finally, we should create a Telemetry.xml dictionary. It will specify that we will downlink latitude, longitude, altitude, time, and current number of
+satellites visible to the GPS unit. These are all standard fields emitted by a UART based GPS unit. Our file should look like:
+
+```
+
+
+
+
+
+
+
+
+ The current latitude
+
+
+
+ The current longitude
+
+
+
+ The current altitude
+
+
+
+ The current number of satilites
+
+
+
+```
+
+## Setting Up the Build System for Gps and GpsApp
+
+The make system is configured to use *fprime/mk/configs/modules/modules.mk* as a place for specifying builds and various deployments. If we look
+into this file, we can see REF_ and Ref_ setups for the Reference applications. We can replicate this for our GpsApp by adding the following lines
+to the file right before the Autocoder sections.
+
+```
+...
+GPS_MODULES := \
+ GpsApp/Top \
+ GpsApp/Gps
+
+GpsApp_MODULES := \
+ \
+ $(GPS_MODULES) \
+ \
+ $(SVC_MODULES) \
+ \
+ $(DRV_MODULES) \
+ \
+ $(FW_MODULES) \
+ \
+ $(OS_MODULES) \
+ \
+ $(CFDP_MODULES) \
+ \
+ $(UTILS_MODULES)
+...
+```
+This adds our (future) topology to the make system as well as the component we just created. This allows us to generate make files and make our component. In
+addition, we will be able to build our project's topology one we add that. *Note:* since we already added a folder for our Topology to the make system we'll need
+to create a placeholder folder (below) before we can build.
+
+In addition, the line defining *DEPLOYMENTS :=* should be modified to add GpsApp like the following:
+
+```
+DEPLOYMENTS := Ref GpsApp acdev
+```
+
+Given that we have already defined our *Topology* folder in the *GpsApp/Top* line above, we will need to add a placeholder for the Topology of our
+GpsApp, which we will fill later. Make the folder *fprime/GpsApp/Top* and add an empty file *mod.mk*. We will fill this folder and mod.mk file
+later, but creating it here enables us to build our component. Now our make system should be ready for us to build our new module and take advantage of
+ the code-generation that is available.
+
+## Setting Up Module Make Files and Code
+
+The first thing to do is to setup the Gps components's make files. Each module (component, port, topology) has two files: a Makefile and a mod.mk file. The makefile contains the module name and little else. The mod.mk file contains a list of all the files and submodules that makeup this module. We should now create the two file, *Makefile* and *mod.mk* using the following content in the *fprime/GpsApp/Gps* folder.
+
+The makefile, called *Makefile*, looks like:
+```
+# ----------------------------------------------------------------------
+# Makefile
+# ----------------------------------------------------------------------
+
+MODULE_DIR = GpsApp/Gps
+MODULE = $(subst /,,$(MODULE_DIR))
+
+BUILD_ROOT ?= $(subst /$(MODULE_DIR),,$(CURDIR))
+export BUILD_ROOT
+
+include $(BUILD_ROOT)/mk/makefiles/module_targets.mk
+```
+Apart from the *MODULE_DIR* variable, most Makefiles look the same.
+
+The mod.mk file, called *mod.mk*, looks like:
+```
+# ----------------------------------------------------------------------
+# mod.mk
+# ----------------------------------------------------------------------
+
+SRC = \
+ GpsComponentAi.xml
+
+# GpsComponentImpl.cpp
+
+HDR = \
+
+# GpsComponentImpl.hpp
+
+#SUBDIRS = test
+```
+*Note:* since we have not created the code files yet, we leave them commented out. This allows us to test the make commands, without erring for
+missing files. We can test the make system by running the following commands. *make gen_make* will auto-generate parts of the make system, *make
+clean* cleans the module, and *make* builds the module.
+
+```
+make gen_make
+make clean
+make
+```
+If these commands pass without errors, we are ready to start coding our module.
+
+## Coding Our Module
+
+Now it is time to code our module to read the GPS module and downlink the GPS telemetry. This is where the framework will help us considerably. All
+these previous steps set us up to use the auto-coding features of F'. We can generate the basic implementation of the code by using the make
+command *make impl*, which generates needed *GpsComponentImpl.cpp-tmpl* and *GpsComponentImpl.hpp-tmpl* files. We can use these as the basis for our
+implementation. In addition, the framework will also generate * *Ac.?pp* files, which handle the work of connecting ports allowing us to write
+minimal code to support the component interface. First we generate code templates, and move them into place (because
+don't already have implementations we can safely rename the template files).
+
+```
+make impl
+mv GpsComponentImpl.cpp-template GpsComponentImpl.cpp
+mv GpsComponentImpl.hpp-template GpsComponentImpl.hpp
+```
+
+*Note:* If the developer regenerates the templates, care must be taken to not overwrite already implemented code by copying the templates to the implementation files.
+
+These template file contents are in the following sections.
+
+### GpsComponentImpl.hpp
+```
+#ifndef Gps_HPP
+#define Gps_HPP
+
+#include "GpsApp/Gps/GpsComponentAc.hpp"
+
+namespace GpsApp {
+
+ class GpsComponentImpl :
+ public GpsComponentBase
+ {
+
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object Gps
+ //!
+ GpsComponentImpl(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName /*!< The component name*/
+#else
+ void
+#endif
+ );
+
+ //! Initialize object Gps
+ //!
+ void init(
+ const NATIVE_INT_TYPE queueDepth, /*!< The queue depth*/
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ //! Destroy object Gps
+ //!
+ ~GpsComponentImpl(void);
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ //! Handler implementation for schedIn
+ //!
+ void schedIn_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ NATIVE_UINT_TYPE context /*!< The call order*/
+ );
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ //! Implementation for Gps_ReportLockStatus command handler
+ //! A command to force an EVR reporting lock status.
+ void Gps_ReportLockStatus_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+
+
+ };
+
+} // end namespace GpsApp
+
+#endif
+```
+
+### GpsComponentImpl.cpp
+```
+#include
+#include "Fw/Types/BasicTypes.hpp"
+
+namespace GpsApp {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ GpsComponentImpl ::
+#if FW_OBJECT_NAMES == 1
+ GpsComponentImpl(
+ const char *const compName
+ ) :
+ GpsComponentBase(compName)
+#else
+ GpsImpl(void)
+#endif
+ {
+
+ }
+
+ void GpsComponentImpl ::
+ init(
+ const NATIVE_INT_TYPE queueDepth,
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ GpsComponentBase::init(queueDepth, instance);
+ }
+
+ GpsComponentImpl ::
+ ~GpsComponentImpl(void)
+ {
+
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ void GpsComponentImpl ::
+ schedIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context
+ )
+ {
+ // TODO
+ }
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ void GpsComponentImpl ::
+ Gps_ReportLockStatus_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq
+ )
+ {
+ // TODO
+ }
+
+} // end namespace GpsApp
+```
+
+### Implementation
+
+Here it can be seen that we have two actions "TODO". First we will need to implement a function called *schedIn_handler* and
+the second is to implement a command handler for *Gps_ReportLockStatus_cmdHandler*. Both are port calls that will be made
+into our component. Ports are found in the GpsComponentAi.xml, however; only our *schedIn* port is used directly. The
+rest are called as part of telemetry, event logging, or command processing and thus have helpful wrappers (seen below).
+schedIn represents a call from a rate group driver. It is called at a set rate, e.g. 10Hz based on the rate group to which it
+is connected. We will use this schedIn call to read the UART interface at a set rate of 1Hz. *Gps_ReportLockStatus_cmdHandler* is a
+handler that implements the function for the command we defined in Command.xml. We also have the following outgoing port calls,
+and events that can be used as part of our code.
+
+1. log_ACTIVITY_HI_Gps_LockAquired: used to emit the event *Gps_Lock_aquired* as defined in Events.xml
+2. log_WARNING_HI_Gps_LockLost: used to emit the event *Gps_LockLost* as defined in Events.xml
+3. tlmWrite_Gps_Latitude: used to send down *Latitude* telemetry as defined in Telemetry.xml
+4. tlmWrite_Gps_Longitude: used to send down *Longitude* telemetry as defined in Telemetry.xml
+5. tlmWrite_Gps_Altitude: used to send down *Altitude* telemetry as defined in Telemetry.xml
+6. tlmWrite_Gps_Count: used to send down *Count* telemetry as defined in Telemetry.xml
+7. sendCommandResponse: used to respond to a sent command. Call this in the above cmdHandler.
+
+In order to make a GPS processor, we need to take the following steps:
+
+0. Implement the schedIn function (called at 1Hz)
+1. (Re)initialize the UART in the call to schedIn
+2. Read UART in schedIn
+3. Parse UART data in schedIn
+4. Downlink telmetry in schedIn
+5. If lock is newly found, downlink a *LockAquired* EVR
+6. If lock is newly lost, downlink a *LockLost* EVR
+7. Downlink a *LockAquired* EVR in commandHandler, if lock is currently held
+8. Downlink a *LockLost* EVR in commandHandler, if lock is not currently held
+9. Respond from commandHandler with a sendCommandResponse call
+
+These steps are called out in the following implementations of these two files. Since the purpose of the getting-started tutorial is not to demonstrate
+how to write each line of code, the steps above are called out in comments in the code.
+
+### GpsComponentImpl.cpp (Sample)
+```
+#include
+#include "Fw/Types/BasicTypes.hpp"
+
+//File path to UART device on UNIX system
+#define UART_FILE_PATH "/dev/ttyACM0"
+#include
+#include
+//POSIX includes for UART communication
+extern "C" {
+ #include
+ #include
+ #include
+}
+
+namespace GpsApp {
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ GpsComponentImpl ::
+#if FW_OBJECT_NAMES == 1
+ GpsComponentImpl(
+ const char *const compName
+ ) :
+ GpsComponentBase(compName),
+#else
+ GpsComponentBase(void),
+#endif
+ m_setup(false),
+ m_locked(false),
+ m_fh(-1)
+ {
+
+ }
+
+ void GpsComponentImpl ::
+ init(
+ const NATIVE_INT_TYPE queueDepth,
+ const NATIVE_INT_TYPE instance
+ )
+ {
+ GpsComponentBase::init(queueDepth, instance);
+ }
+
+ GpsComponentImpl ::
+ ~GpsComponentImpl(void)
+ {
+
+ }
+
+ //Step 1: setup
+ //
+ // Each second, we should ensure that the UART is initialized
+ // and if not, we should try to initialize it again.
+ void GpsComponentImpl ::
+ setup(void)
+ {
+ if (m_setup) {
+ return;
+ }
+ //Open the GPS, and configure it for a raw-socket in read-only mode
+ m_fh = open(UART_FILE_PATH, O_RDONLY);
+ if (m_fh < 0) {
+ std::cout << "[ERROR] Failed to open file: " << UART_FILE_PATH << std::endl;
+ return;
+ }
+ //Setup the struct for termios configuration
+ struct termios options;
+ std::memset(&options, 0, sizeof(options));
+ //Set to raw socket, remove modem control, allow input
+ cfmakeraw(&options);
+ options.c_cflag |= (CLOCAL | CREAD);
+ //Set to 9600 baud
+ cfsetispeed(&options, B9600);
+ //Make the above options stick
+ NATIVE_INT_TYPE status = tcsetattr(m_fh, TCSANOW, &options);
+ if (status != 0) {
+ std::cout << "[ERROR] Failed to setup UART options" << std::endl;
+ return;
+ }
+ m_setup = true;
+ }
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ // Step 0: schedIn
+ //
+ // By implementing this "handler" we can respond to the 1Hz call allowing
+ // us to read the GPS UART every 1 second.
+ void GpsComponentImpl ::
+ schedIn_handler(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context
+ )
+ {
+ int status = 0;
+ float lat = 0.0f, lon = 0.0f;
+ GpsPacket packet;
+ char buffer[1024];
+ char* pointer = buffer;
+ //During each cycle, attempt to setup if not setup
+ //Step 1: setup
+ // Each second, we should ensure that the UART is initialized
+ // and if not, we should try to initialize it again.
+ setup();
+ if (!m_setup) {
+ return;
+ }
+ //Then receive data from the GPS. Should block until available
+ //and thus, this module should not be driven at a rate faster than 1Hz
+ //Step 2: read the UART
+ // Read the GPS message from the UART
+ ssize_t size = read(m_fh, buffer, sizeof(buffer));
+ if (size <= 0) {
+ std::cout << "[ERROR] Failed to read from UART with: " << size << std::endl;
+ return;
+ }
+ //Look for a recognized GPS location packet and parse it
+ //Step 3:
+ // Parse the GPS message from the UART (looking for $GPPA messages)
+ for (U32 i = 0; i < sizeof(buffer) - 6; i++) {
+ status = sscanf(pointer, "$GPGGA,%f,%f,%c,%f,%c,%u,%u,%f,%f",
+ &packet.utcTime, &packet.dmNS, &packet.northSouth,
+ &packet.dmEW, &packet.eastWest, &packet.lock,
+ &packet.count, &packet.filler, &packet.altitude);
+ //Break when all GPS items are found
+ if (status == 9) {
+ break;
+ }
+ pointer = pointer + 1;
+ }
+ //If we failed to find the packet, or failed to extract data then return
+ if (status != 9) {
+ std::cout << "[ERROR] GPS parsing failed: " << status << std::endl;
+ return;
+ }
+ //GPS packet locations are of the form: ddmm.mmmm
+ //We will convert to lat/lon in degrees only before downlinking
+ //Latitude degrees, add on minutes (converted to degrees), multiply by direction
+ lat = (U32)(packet.dmNS/100.0f);
+ lat = lat + (packet.dmNS - (lat * 100.0f))/60.0f;
+ lat = lat * ((packet.northSouth == 'N') ? 1 : -1);
+ //Longitude degrees, add on minutes (converted to degrees), multiply by direction
+ lon = (U32)(packet.dmEW/100.0f);
+ lon = lon + (packet.dmEW - (lon * 100.0f))/60.f;
+ lon = lon * ((packet.eastWest == 'E') ? 1 : -1);
+ //Step 4: downlink
+ // Call the downlink functions to send down data
+ std::cout << "[INFO] Current lat, lon: (" << lat << "," << lon << ")" << std::endl;
+ tlmWrite_Gps_Latitude(lat);
+ tlmWrite_Gps_Longitude(lon);
+ tlmWrite_Gps_Altitude(packet.altitude);
+ tlmWrite_Gps_Count(packet.count);
+ //Lock status update only if changed
+ //Step 7,8: note changed lock status
+ // Emit an event if the lock has been aquired, or lost
+ if (packet.lock == 0 && m_locked) {
+ m_locked = false;
+ log_WARNING_HI_Gps_LockLost();
+ } else if (packet.lock == 1 && !m_locked) {
+ m_locked = true;
+ log_ACTIVITY_HI_Gps_LockAquired();
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+ //Step 9: respond to status command
+ //
+ // When a status command is received, respond by emitting the
+ // current lock status as an Event.
+ void GpsComponentImpl ::
+ Gps_ReportLockStatus_cmdHandler(
+ const FwOpcodeType opCode,
+ const U32 cmdSeq
+ )
+ {
+ //Locked-force print
+ if (m_locked) {
+ log_ACTIVITY_HI_Gps_LockAquired();
+ } else {
+ log_WARNING_HI_Gps_LockLost();
+ }
+ }
+} // end namespace GpsApp
+```
+### GpsComponentImpl.hpp (Sample)
+```
+#ifndef Gps_HPP
+#define Gps_HPP
+
+#include "GpsApp/Gps/GpsComponentAc.hpp"
+
+namespace GpsApp {
+
+ class GpsComponentImpl :
+ public GpsComponentBase
+ {
+ /**
+ * GpsPacket:
+ * A structure containing the information in the GPS location pacaket
+ * received via the NMEA GPS receiver.
+ */
+ struct GpsPacket {
+ float utcTime;
+ float dmNS;
+ char northSouth;
+ float dmEW;
+ char eastWest;
+ unsigned int lock;
+ unsigned int count;
+ float filler;
+ float altitude;
+ };
+ public:
+
+ // ----------------------------------------------------------------------
+ // Construction, initialization, and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct object Gps
+ //!
+ GpsComponentImpl(
+#if FW_OBJECT_NAMES == 1
+ const char *const compName /*!< The component name*/
+#else
+ void
+#endif
+ );
+
+ //! Initialize object Gps
+ //!
+ void init(
+ const NATIVE_INT_TYPE queueDepth, /*!< The queue depth*/
+ const NATIVE_INT_TYPE instance = 0 /*!< The instance number*/
+ );
+
+ //! Destroy object Gps
+ //!
+ ~GpsComponentImpl(void);
+
+ PRIVATE:
+ //! Setup the UART interface for taking with the GPS module. Note: this
+ //! is currently implemented using standard Unix /dev/tty* devices.
+ //!
+ void setup(void);
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ //! Handler implementation for schedIn
+ //!
+ void schedIn_handler(
+ const NATIVE_INT_TYPE portNum, /*!< The port number*/
+ NATIVE_UINT_TYPE context /*!< The call order*/
+ );
+
+ PRIVATE:
+
+ // ----------------------------------------------------------------------
+ // Command handler implementations
+ // ----------------------------------------------------------------------
+
+ //! Implementation for Gps_ReportLockStatus command handler
+ //! A command to force an EVR reporting lock status.
+ void Gps_ReportLockStatus_cmdHandler(
+ const FwOpcodeType opCode, /*!< The opcode*/
+ const U32 cmdSeq /*!< The command sequence number*/
+ );
+ //!< Is the GPS UART setup
+ bool m_setup;
+ //!< Has the device acquired GPS lock?
+ bool m_locked;
+ //!< File handle of UART
+ NATIVE_INT_TYPE m_fh;
+ };
+
+} // end namespace GpsApp
+
+#endif
+```
+
+Next, we need to add (or uncomment) our .cpp and .hpp to the mod.mk in the GpsApp directory. The final version will look like this:
+
+### fprime/GpsApp/Gps/mod.mk (final)
+```
+# ----------------------------------------------------------------------
+# mod.mk
+# ----------------------------------------------------------------------
+
+SRC = \
+ GpsComponentAi.xml \
+ GpsComponentImpl.cpp
+
+HDR = \
+ GpsComponentImpl.hpp
+
+#SUBDIRS = test
+```
+
+Finally, regenerate the makefiles, clean, and build. We will use this pattern a lot.
+```
+make gen_make
+make clean
+make
+```
+
+We are now ready to make a Topology for this application, and test it!
+
+## Topology
+
+We are finally ready to build our topology to connect the GPS module up to the rate converter, and logger. Then we can see
+if this will work. Generally, this process is done with a design tool like MagicDraw, but because the user may or may not
+have access to this tool, the topology Ai is provided below. The user may then edit it to make changes.
+
+First, the Reference application's topology is copied into the *Top* folder of *GpsApp* application and we'll grab the deployment makefile
+too. We do this as a convienence to save time during this tutorial. It is easier and faster to start with the Reference application's files
+and modify them to construct our topology.
+
+```
+cp -r fprime/Ref/Top fprime/GpsApp/Top
+cp fprime/Ref/Makefile fprime/GpsApp
+```
+
+Then update *fprime/GpsApp/Makefile* to set the following line to our deployment's name *GpsApp*.
+
+```
+DEPLOYMENT := GpsApp
+```
+
+After this adjustment to the make system, we need to add 3 custom files that represent our Topology. These files are the following:
+
+1. **GpsTopologyAppAi.xml**: the design file showing the list of components, and the connections between components. This file is based
+on RefTopologyAppAi.xml from the reference application. GpsTopologyAppAi.xml should replace RefTopologyAppAi.xml.
+2. **Components.hpp**: the header file declaring in code the same components as listed in the topology ai XML, along with includes
+of the headers that define them.
+3. **Topology.cpp**: top level code, main function, and initialization of the components, threads, and registration of commands.
+
+Essentially, GpsTopologyAppAi.xml is the design, Components.hpp is the definitions, and Topology.cpp is the implementation code. All of these
+files are referenced by the make files we inherited from the reference app. Building the distribution (fprime/GpsApp) will include the
+topology (fprime/GpsApp/Top) as its entry-point creating a single application, which represents our software.
+
+Sample versions of these files are provided below, and are annotated with comments representing the changes
+made to support the Gps Application. **Note:** these files are available in a working repository at:
+[https://github.com/LeStarch/fprime/tree/gps-application](https://github.com/LeStarch/fprime/tree/gps-application) in case the user prefers a direct checkout of working code.
+
+We will also need to update the mod.mk in the Top directory to change the name of "RefTopologyAppAi.xml" to "GpsTopologyAppAi.xml".
+
+Once these files have been added to the *fprime/GpsApp/Top* folder, we have a complete project. The project can be built
+by changing directory to the deployment directory, issuing our build commands and then running the executable.
+
+```
+cd fprime/GpsApp
+make gen_make
+make clean
+make
+./linux-linux-x86-debug-gnu-bin/GpsApp
+```
+
+If you see output similar to the following, when running with the UART GPS you have successfully, completed the tutorial. If running without the GPS, you should see GPS setup errors every 1 second.
+
+#### Successful Output
+```
+[INFO] Current lat, lon: (41.758,-72.6492)
+[INFO] Current lat, lon: (41.758,-72.6492)
+[INFO] Current lat, lon: (41.758,-72.6492)
+[INFO] Current lat, lon: (41.758,-72.6492)
+
+-- or --
+
+[ERROR] Failed to open file: /dev/ttyACM0
+[ERROR] Failed to open file: /dev/ttyACM0
+[ERROR] Failed to open file: /dev/ttyACM0
+[ERROR] Failed to open file: /dev/ttyACM0
+```
+
+### Topology.cpp (Sample)
+```
+#include
+
+
+#include
+#include
+#include
+#include
+#include
+
+#if defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN
+#include
+#include
+#include
+#endif
+// List of context IDs
+
+// GPS Application:
+// For GPS application specific items, look for GPS-- comments below
+enum {
+ DOWNLINK_PACKET_SIZE = 500,
+ DOWNLINK_BUFFER_STORE_SIZE = 2500,
+ DOWNLINK_BUFFER_QUEUE_SIZE = 5,
+ UPLINK_BUFFER_STORE_SIZE = 3000,
+ UPLINK_BUFFER_QUEUE_SIZE = 30
+};
+
+enum {
+ ACTIVE_COMP_1HZ_RG,
+ ACTIVE_COMP_P5HZ_RG,
+ ACTIVE_COMP_P25HZ_RG,
+ ACTIVE_COMP_CMD_DISP,
+ ACTIVE_COMP_CMD_SEQ,
+ ACTIVE_COMP_LOGGER,
+ ACTIVE_COMP_TLM,
+ ACTIVE_COMP_PRMDB,
+ ACTIVE_COMP_FILE_DOWNLINK,
+ ACTIVE_COMP_FILE_UPLINK,
+
+ ACTIVE_COMP_BLKDRV,
+ ACTIVE_COMP_PING_RECEIVER,
+ // GPS-- our component is an active component, thus it needs a thread-id. Thread IDs come from this
+ // enumeration to keep them unique.
+ ACTIVE_COMP_GPS,
+
+ CYCLER_TASK,
+ NUM_ACTIVE_COMPS
+};
+
+// Registry
+#if FW_OBJECT_REGISTRATION == 1
+static Fw::SimpleObjRegistry simpleReg;
+#endif
+
+// Component instance pointers
+static NATIVE_INT_TYPE rgDivs[] = {1,2,4};
+Svc::RateGroupDriverImpl rateGroupDriverComp(
+#if FW_OBJECT_NAMES == 1
+ "RGDvr",
+#endif
+ rgDivs,FW_NUM_ARRAY_ELEMENTS(rgDivs));
+
+static NATIVE_UINT_TYPE rg1Context[] = {0,0,0,0,0,0,0,0,0,0};
+Svc::ActiveRateGroupImpl rateGroup1Comp
+#if FW_OBJECT_NAMES == 1
+ ("RG1",rg1Context,FW_NUM_ARRAY_ELEMENTS(rg1Context));
+#else
+ (rg1Context,FW_NUM_ARRAY_ELEMENTS(rg1Context));
+#endif
+;
+
+static NATIVE_UINT_TYPE rg2Context[] = {0,0,0,0,0,0,0,0,0,0};
+Svc::ActiveRateGroupImpl rateGroup2Comp
+#if FW_OBJECT_NAMES == 1
+ ("RG2",rg2Context,FW_NUM_ARRAY_ELEMENTS(rg2Context));
+#else
+ (rg2Context,FW_NUM_ARRAY_ELEMENTS(rg2Context));
+#endif
+;
+
+static NATIVE_UINT_TYPE rg3Context[] = {0,0,0,0,0,0,0,0,0,0};
+Svc::ActiveRateGroupImpl rateGroup3Comp
+#if FW_OBJECT_NAMES == 1
+ ("RG3",rg3Context,FW_NUM_ARRAY_ELEMENTS(rg3Context));
+#else
+ (rg3Context,FW_NUM_ARRAY_ELEMENTS(rg3Context));
+#endif
+;
+
+// Command Components
+Svc::SocketGndIfImpl sockGndIf
+#if FW_OBJECT_NAMES == 1
+ ("SGIF")
+#endif
+;
+
+//GPS-- GPS Component construction, notice if compiled with names, a name should be given.
+GpsApp::GpsComponentImpl gpsImpl
+#if FW_OBJECT_NAMES == 1
+ ("GPS")
+#endif
+;
+
+#if FW_ENABLE_TEXT_LOGGING
+Svc::ConsoleTextLoggerImpl textLogger
+#if FW_OBJECT_NAMES == 1
+ ("TLOG")
+#endif
+;
+#endif
+
+Svc::ActiveLoggerImpl eventLogger
+#if FW_OBJECT_NAMES == 1
+ ("ELOG")
+#endif
+;
+
+Svc::LinuxTimeImpl linuxTime
+#if FW_OBJECT_NAMES == 1
+ ("LTIME")
+#endif
+;
+
+Svc::TlmChanImpl chanTlm
+#if FW_OBJECT_NAMES == 1
+ ("TLM")
+#endif
+;
+
+Svc::CommandDispatcherImpl cmdDisp
+#if FW_OBJECT_NAMES == 1
+ ("CMDDISP")
+#endif
+;
+
+Fw::MallocAllocator seqMallocator;
+Svc::CmdSequencerComponentImpl cmdSeq
+#if FW_OBJECT_NAMES == 1
+ ("CMDSEQ")
+#endif
+;
+
+Svc::PrmDbImpl prmDb
+#if FW_OBJECT_NAMES == 1
+ ("PRM","PrmDb.dat")
+#else
+ ("PrmDb.dat")
+#endif
+;
+
+
+Svc::FileUplink fileUplink ("fileUplink");
+Svc::FileDownlink fileDownlink ("fileDownlink", DOWNLINK_PACKET_SIZE);
+Svc::BufferManager fileDownlinkBufferManager("fileDownlinkBufferManager", DOWNLINK_BUFFER_STORE_SIZE, DOWNLINK_BUFFER_QUEUE_SIZE);
+Svc::BufferManager fileUplinkBufferManager("fileUplinkBufferManager", UPLINK_BUFFER_STORE_SIZE, UPLINK_BUFFER_QUEUE_SIZE);
+Svc::HealthImpl health("health");
+
+Svc::AssertFatalAdapterComponentImpl fatalAdapter
+#if FW_OBJECT_NAMES == 1
+("fatalAdapter")
+#endif
+;
+
+Svc::FatalHandlerComponentImpl fatalHandler
+#if FW_OBJECT_NAMES == 1
+("fatalHandler")
+#endif
+;
+
+
+#if FW_OBJECT_REGISTRATION == 1
+
+void dumparch(void) {
+ simpleReg.dump();
+}
+
+#if FW_OBJECT_NAMES == 1
+void dumpobj(const char* objName) {
+ simpleReg.dump(objName);
+}
+#endif
+
+#endif
+
+void constructApp(int port_number, char* hostname) {
+
+ localTargetInit();
+
+#if FW_PORT_TRACING
+ Fw::PortBase::setTrace(false);
+#endif
+
+ // Initialize rate group driver
+ rateGroupDriverComp.init();
+
+ // Initialize the rate groups
+ rateGroup1Comp.init(10,0);
+
+ rateGroup2Comp.init(10,1);
+
+ rateGroup3Comp.init(10,2);
+ //GPS-- Here we initialize the component with a queue size, and instance number. The queue size governs how
+ // many waiting port calls can queue up before the system asserts, and the instance number is a unique
+ // number given to every instance of a given type.
+ gpsImpl.init(10, 1);
+#if FW_ENABLE_TEXT_LOGGING
+ textLogger.init();
+#endif
+
+ eventLogger.init(10,0);
+
+ linuxTime.init(0);
+
+ chanTlm.init(10,0);
+
+ cmdDisp.init(20,0);
+
+ cmdSeq.init(10,0);
+ cmdSeq.allocateBuffer(0,seqMallocator,5*1024);
+
+ prmDb.init(10,0);
+
+ sockGndIf.init(0);
+
+ fileUplink.init(30, 0);
+ fileDownlink.init(30, 0);
+ fileUplinkBufferManager.init(0);
+ fileDownlinkBufferManager.init(1);
+ fatalAdapter.init(0);
+ fatalHandler.init(0);
+ health.init(25,0);
+ // Connect rate groups to rate group driver
+ constructRefArchitecture();
+
+ /* Register commands */
+ cmdSeq.regCommands();
+ cmdDisp.regCommands();
+ eventLogger.regCommands();
+ prmDb.regCommands();
+ fileDownlink.regCommands();
+ health.regCommands();
+
+ // read parameters
+ prmDb.readParamFile();
+
+ // set health ping entries
+
+ Svc::HealthImpl::PingEntry pingEntries[] = {
+ {3,5,rateGroup1Comp.getObjName()}, // 0
+ {3,5,rateGroup2Comp.getObjName()}, // 1
+ {3,5,rateGroup3Comp.getObjName()}, // 2
+ {3,5,cmdDisp.getObjName()}, // 3
+ {3,5,eventLogger.getObjName()}, // 4
+ {3,5,cmdSeq.getObjName()}, // 5
+ {3,5,chanTlm.getObjName()}, // 6
+ {3,5,fileUplink.getObjName()}, // 7
+ {3,5,fileDownlink.getObjName()}, // 8
+ };
+
+ // register ping table
+ health.setPingEntries(pingEntries,FW_NUM_ARRAY_ELEMENTS(pingEntries),0x123);
+
+ // Active component startup
+ // start rate groups
+ rateGroup1Comp.start(ACTIVE_COMP_1HZ_RG, 120,10 * 1024);
+ rateGroup2Comp.start(ACTIVE_COMP_P5HZ_RG, 119,10 * 1024);
+ rateGroup3Comp.start(ACTIVE_COMP_P25HZ_RG, 118,10 * 1024);
+ // start dispatcher
+ cmdDisp.start(ACTIVE_COMP_CMD_DISP,101,10*1024);
+ // start sequencer
+ cmdSeq.start(ACTIVE_COMP_CMD_SEQ,100,10*1024);
+ // start telemetry
+ eventLogger.start(ACTIVE_COMP_LOGGER,98,10*1024);
+ chanTlm.start(ACTIVE_COMP_TLM,97,10*1024);
+ prmDb.start(ACTIVE_COMP_PRMDB,96,10*1024);
+ //GPS-- GPS thread starting. The GPS component is active, so its governing thread must be started
+ // with the unique id, defined above, a priority 256 (highest) - 0 (lowest) set here to 99, and
+ // a stack size for the thread, here 10KB is used.
+ gpsImpl.start(ACTIVE_COMP_GPS, 99, 10*1024);
+
+ fileDownlink.start(ACTIVE_COMP_FILE_DOWNLINK, 100, 10*1024);
+ fileUplink.start(ACTIVE_COMP_FILE_UPLINK, 100, 10*1024);
+
+ // Initialize socket server
+ sockGndIf.startSocketTask(100, port_number, hostname);
+
+}
+//GPS-- Given the application's lack of a specific timing element, we
+// force a call to the rate group driver every second here.
+// More complex applications may drive this from a system oscillator.
+void run1cycle(void) {
+ // get timer to call rate group driver
+ Svc::TimerVal timer;
+ timer.take();
+ rateGroupDriverComp.get_CycleIn_InputPort(0)->invoke(timer);
+ Os::Task::TaskStatus delayStat = Os::Task::delay(1000);
+ FW_ASSERT(Os::Task::TASK_OK == delayStat,delayStat);
+}
+
+
+
+void runcycles(NATIVE_INT_TYPE cycles) {
+ if (cycles == -1) {
+ while (true) {
+ run1cycle();
+ }
+ }
+
+ for (NATIVE_INT_TYPE cycle = 0; cycle < cycles; cycle++) {
+ run1cycle();
+ }
+
+}
+
+void exitTasks(void) {
+ rateGroup1Comp.exit();
+ rateGroup2Comp.exit();
+ rateGroup3Comp.exit();
+ cmdDisp.exit();
+ eventLogger.exit();
+ chanTlm.exit();
+ prmDb.exit();
+ fileUplink.exit();
+ fileDownlink.exit();
+ cmdSeq.exit();
+}
+
+void print_usage() {
+ (void) printf("Usage: ./Ref [options]\n-p\tport_number\n-a\thostname/IP address\n");
+}
+
+
+#include
+#include
+
+volatile sig_atomic_t terminate = 0;
+
+static void sighandler(int signum) {
+ terminate = 1;
+}
+
+int main(int argc, char* argv[]) {
+ U32 port_number;
+ I32 option;
+ char *hostname;
+ port_number = 0;
+ option = 0;
+ hostname = NULL;
+
+ while ((option = getopt(argc, argv, "hp:a:")) != -1){
+ switch(option) {
+ case 'h':
+ print_usage();
+ return 0;
+ break;
+ case 'p':
+ port_number = atoi(optarg);
+ break;
+ case 'a':
+ hostname = optarg;
+ break;
+ case '?':
+ return 1;
+ default:
+ print_usage();
+ return 1;
+ }
+ }
+
+ (void) printf("Hit Ctrl-C to quit\n");
+
+ constructApp(port_number, hostname);
+ //dumparch();
+
+ signal(SIGINT,sighandler);
+ signal(SIGTERM,sighandler);
+
+ int cycle = 0;
+
+ while (!terminate) {
+// (void) printf("Cycle %d\n",cycle);
+ runcycles(1);
+ cycle++;
+ }
+
+ // stop tasks
+ exitTasks();
+ // Give time for threads to exit
+ (void) printf("Waiting for threads...\n");
+ Os::Task::delay(1000);
+
+ (void) printf("Exiting...\n");
+
+ return 0;
+}
+```
+
+### Components.hpp (Sample)
+```
+#ifndef __LITS_COMPONENTS_HEADER__
+#define __LITS_COMPONENTS_HEADER__
+void constructRefArchitecture(void);
+void exitTasks(void);
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+
+//Gps Inclusion:
+// Here we include the header definition of our GPS component, not the GPS is declared
+// further down in the file.
+#include
+
+extern Svc::RateGroupDriverImpl rateGroupDriverComp;
+extern Svc::ActiveRateGroupImpl rateGroup1Comp, rateGroup2Comp, rateGroup3Comp;
+extern Svc::CmdSequencerComponentImpl cmdSeq;
+extern Svc::SocketGndIfImpl sockGndIf;
+extern Svc::ConsoleTextLoggerImpl textLogger;
+extern Svc::ActiveLoggerImpl eventLogger;
+extern Svc::LinuxTimeImpl linuxTime;
+extern Svc::TlmChanImpl chanTlm;
+extern Svc::CommandDispatcherImpl cmdDisp;
+extern Svc::PrmDbImpl prmDb;
+extern Svc::FileUplink fileUplink;
+extern Svc::FileDownlink fileDownlink;
+extern Svc::BufferManager fileDownlinkBufferManager;
+extern Svc::BufferManager fileUplinkBufferManager;
+extern Svc::AssertFatalAdapterComponentImpl fatalAdapter;
+extern Svc::FatalHandlerComponentImpl fatalHandler;
+extern Svc::HealthImpl health;
+//Our new GPS Driver
+extern GpsApp::GpsComponentImpl gpsImpl;
+#endif
+```
+
+### GpsTopologyAppAi.xml (Sample)
+```
+
+
+
+
+
+ Svc/ActiveRateGroup/ActiveRateGroupComponentAi.xml
+ Svc/FileUplink/FileUplinkComponentAi.xml
+ Svc/BufferManager/BufferManagerComponentAi.xml
+ Svc/FatalHandler/FatalHandlerComponentAi.xml
+ Svc/AssertFatalAdapter/AssertFatalAdapterComponentAi.xml
+ Svc/ActiveRateGroup/ActiveRateGroupComponentAi.xml
+ Svc/TlmChan/TlmChanComponentAi.xml
+ Svc/Health/HealthComponentAi.xml
+ Svc/GndIf/GndIfComponentAi.xml
+ Svc/BufferManager/BufferManagerComponentAi.xml
+ Svc/ActiveLogger/ActiveLoggerComponentAi.xml
+ Svc/Time/TimeComponentAi.xml
+ GpsApp/Gps/GpsComponentAi.xml
+ Svc/CmdDispatcher/CommandDispatcherComponentAi.xml
+ Svc/PrmDb/PrmDbComponentAi.xml
+ Svc/ActiveRateGroup/ActiveRateGroupComponentAi.xml
+ Svc/RateGroupDriver/RateGroupDriverComponentAi.xml
+ Drv/BlockDriver/BlockDriverComponentAi.xml
+ Svc/CmdSequencer/CmdSequencerComponentAi.xml
+ Svc/FileDownlink/FileDownlinkComponentAi.xml
+ Svc/PassiveTextLogger/PassiveTextLoggerComponentAi.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/docs/img/usb-gps.jpg b/docs/img/usb-gps.jpg
new file mode 100755
index 0000000000..5e1c8f86a0
Binary files /dev/null and b/docs/img/usb-gps.jpg differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000000..005066b9b9
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,42 @@
+---
+title: F Prime: A Flight-Proven, Multi-Platform, Open-Source Flight Software Framework
+layout: default
+---
+# F Prime: A Flight-Proven, Multi-Platform, Open-Source Flight Software Framework
+
+F Prime (Fʹ) is a component-driven framework that enables rapid development and deployment of spaceflight and other embedded software applications. Originally developed at the Jet Propulsion Laboratory, F Prime has been successfully deployed on several space applications. It is tailored, but not limited, to small-scale spaceflight systems such as CubeSats, SmallSats, and instruments.
+
+F Prime comprises several elements:
+
+* An architecture that decomposes flight software into discrete components with well-defined interfaces
+* A C++ framework that provides core capabilities such as message queues and threads
+* Modeling tools for specifying components and connections and automatically generating code
+* A growing collection of ready-to-use components
+* Testing tools for testing flight software at the unit and integration levels.
+
+F Prime has the following key features:
+
+### Reusability
+
+F Prime’s component-based architecture enables a high degree of modularity and software reuse.
+
+### Rapid Deployment
+
+F Prime provides a complete development ecosystem, including modeling tools, testing tools, and a ground data system. Developers use the modeling tools to write high-level specifications, automatically generate implementations in C++, and fill in the implementations with domain-specific code. The framework and the code generators provide all the “boilerplate” code required in an F Prime deployment, including code for thread management, code for communication between components, and code for handling commands, telemetry, and parameters. The testing tools and the ground data system simplify software testing, both on workstations and on flight hardware in the lab.
+
+### Portability
+
+F Prime runs on a wide range of processors, from microcontrollers to multicore computers, and on several operating systems. Porting F Prime to new operating systems is straightforward.
+
+### High Performance
+
+F Prime utilizes a point-to-point architecture. The architecture minimizes the use of computational resources and is well suited for smaller processors.
+
+### Adaptability
+
+F Prime is tailored to the level of complexity required for small missions. This makes it accessible and easy to use, while still supporting a wide variety of missions.
+
+### Analyzability
+
+The typed port connections provide strong compile-time guarantees of correctness.
+
diff --git a/docs/projects.md b/docs/projects.md
new file mode 100644
index 0000000000..e357443b6b
--- /dev/null
+++ b/docs/projects.md
@@ -0,0 +1,15 @@
+---
+title: F' - Projects
+layout: default
+---
+# F'- Projects
+
+F' has been used by a number of projects for both embedded and flight purposes.
+
+### Project A
+
+Some text. An image maybe.
+
+### Project B
+
+Again a text.
diff --git a/mk/bin/gen_deployment_doc.py b/mk/bin/gen_deployment_doc.py
old mode 100644
new mode 100755
index 2c2ac2bc85..5aac461c15
--- a/mk/bin/gen_deployment_doc.py
+++ b/mk/bin/gen_deployment_doc.py
@@ -1,5 +1,6 @@
import sys
import os
+import os.path
deployment_title = """
@@ -72,11 +73,11 @@ md_title = '''
[$deployment SDD](sdd.md)
### Modules
-|Module|Link]
-|---|---|
+|Module|SDD|Dictionary|
+|---|---|---|
'''
-md_doc_line ='''|%s|[Link](%s)|
+md_doc_line ='''|%s|[Link](%s)|[Link](%s)|
'''
@@ -123,7 +124,9 @@ for module in sys.argv[2:]:
"../../" + module + "/docs/sdd.md")
)
md_doc.write(md_doc_line % (module,
- "../../" + module + "/docs/sdd.md")
+ "../../" + module + "/docs/sdd.md",
+ "../../" + module + "/docs/" + os.path.basename(module) + ".md"
+ )
)
# "../../" + module +"/docs/dox.html",
# "../../" + module +"/docs/scrub.html"))
diff --git a/mk/bin/gen_git_version.py b/mk/bin/gen_git_version.py
index 72c9fd2672..6a6da2b2a1 100644
--- a/mk/bin/gen_git_version.py
+++ b/mk/bin/gen_git_version.py
@@ -13,7 +13,7 @@ output_file = sys.argv[1]
print "Writing version to %s"%output_file
-hash = subprocess.check_output(["git","log","--pretty=format:%h","-n","1"])
+hash = subprocess.check_output(["git","log","--pretty=format:%h","-n","1","--abbrev=8"])
try:
tag = subprocess.check_output(["git","describe","--abbrev=0","--tags"]).strip()
except:
diff --git a/mk/bin/run_file_hash.py b/mk/bin/run_file_hash.py
old mode 100644
new mode 100755
index 2c201c2de7..6755895a82
--- a/mk/bin/run_file_hash.py
+++ b/mk/bin/run_file_hash.py
@@ -4,12 +4,13 @@ import sys
import os
filename = "%s"%sys.argv[1]
-hash_no = "0x%08X"%(hash(filename)% 0xFFFFFFFF) # force to 32-bits
+hash_val = hash(filename)% 0xFFFFFFFF # force to 32-bits
+hash_arg = "0x%08X"%(hash_val)
# open local hash file
-open("%s/mk/hash/%s"%(os.environ["BUILD_ROOT"],filename.replace(".","_")+".hash"),"w").write("%s: %s"%(hash_no,filename))
+open("%s/mk/hash/%s"%(os.environ["BUILD_ROOT"],filename.replace(".","_")+".hash"),"w").write("%s: %s"%(hash_arg,filename))
# open fragment file
-#open("%s/mk/xml/%s"%(os.environ["BUILD_ROOT"],filename.replace(".","_")+".xml_frag"),"w").write(" \n"%(filename.replace(".","_").replace("-","_").replace("+","_"),hash_no,filename,filename))
+#open("%s/mk/xml/%s"%(os.environ["BUILD_ROOT"],filename.replace(".","_")+".xml_frag"),"w").write(" \n"%(filename.replace(".","_").replace("-","_").replace("+","_"),hash_val,filename,filename))
-print(hash_no)
+print("%s"%hash_arg)
#sys.stderr.write("file: %s hash: %d\n"%(sys.argv[1],hash(sys.argv[1])))
\ No newline at end of file
diff --git a/mk/bin/run_tlm_packetizer.sh b/mk/bin/run_tlm_packetizer.sh
new file mode 100755
index 0000000000..1304623fe9
--- /dev/null
+++ b/mk/bin/run_tlm_packetizer.sh
@@ -0,0 +1,9 @@
+#!/bin/csh
+# **********************************************************************
+# *
+
+setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib:/usr/lib:/lib
+setenv PATH ${PYTHON_BASE}/bin:/tps/bin:/usr/bin:/bin
+setenv PYTHONPATH ${BUILD_ROOT}/actools:${BUILD_ROOT}/Gse/src
+${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Autocoders/bin/tlmPackets.py $*
+
diff --git a/mk/ci/README.md b/mk/ci/README.md
new file mode 100644
index 0000000000..91a11efffe
--- /dev/null
+++ b/mk/ci/README.md
@@ -0,0 +1,64 @@
+# F´Continuous Integration
+
+F´continuous integration was developed to work with Jenkins. The continuous integration project is
+designed to checkout a new pull request that has been submitted to F´, merge it with the base
+branch, and then build the merged construct. Then the unit tests are built and run against this
+merge. This proves that the build is ready for review and merge.
+
+## Jenkins Description
+
+The Jenkins setup exists in the `config.xml` file in this directory. It should be noted that the
+secrets (passwords, keys, etc.) have been stripped and should be replaced.
+
+The Jenkins CI is configured with the expressed purpose of checking the build and unit tests for
+a given pull request. It does not build on a set interval, nor does it build a specific branch
+(master, devel) but rather whatever branch the pull request was based on.
+
+The Jenkins CI is setup to be built inside a docker container. This docker container is used to
+encapsulate the exact build environment without needing to setup a specific Jenkins machine with
+this build environment. It needs to be run on a Docker capable Jenkins machine. The Docker setup
+that powers this is at: [mk/docker](../docker/).
+
+Once Jenkins CI builds the Docker container from the Dockerfile, it runs the Python Test Framework,
+[ptf](/ptf), which includes the following test suites:
+
+ 1. Reference Build and Unit Tests
+ 2. Autocoder Unit Tests
+
+## Using Jenkins
+
+In order to use the existing Jenkins configuration, one can post it to the server of their choice
+using the following basic command. This command may need to be altered to supply credentials or
+setup proxies, but this is outside this guide.
+
+This `config.xml` contains `FILL-ME` tokens where various project specific configuration items
+belong. These mostly represent passwords, or other secrets that should not be exposed. A user can
+edit the config.xml file directly before POSTing the XML to the server. Alternatively, the user can
+POST the XML and make the edits in the Jenkins GUI.
+
+
+**POST Jenkins Config as New Job**
+```bash
+fprime>curl -X POST http:///createItem?name=' --header "Content-Type: application/xml" -d mk/ci/config.xml
+```
+Here the user must supply the `