The engine is compiled from one codebase and devices implement (part of) the
device specific interface. The shared codebase only uses standard \gls{C} and
no special libraries or tricks are used. Therefore, the code is compilable for
-almost any device or system. Note that it is not needed to implement a full
-interface. The full interface --- excluding the device specific settings --- is
-listed in Appendix~\ref{app:device-interface}. The interface works in a
-similar fashion as the \gls{EDSL}. Devices do not have to implement all
-functionality, this is analogous to the fact that views do not have to
-implement all type classes in the \gls{EDSL}. When the device connects with
-the server for the first time, the specifications of what is implemented is
-communicated. Devices must be available throughout sessions and cannot always
-be kept in scope and therefore they are stored in an \gls{SDS}.
+almost any device or system. The full interface --- excluding the device
+specific settings --- is listed in Appendix~\ref{app:device-interface}. The
+interface works in a similar fashion as the \gls{EDSL}. Devices do not have to
+implement all functionality, this is analogous to the fact that views do not
+have to implement all type classes in the \gls{EDSL}. When the device connects
+with the server for the first time, the specifications of what is implemented
+is communicated. Devices must be available throughout sessions and cannot
+always be kept in scope and therefore they are stored in an \gls{SDS}.
At the time of writing the following device families are supported and can run
the device software. Porting the client software to a new device does not
-require a lot of work. For example, porting to the \texttt{mbed} device family
+require a lot of work. For example, porting to the \gls{mbed} device family
only took about an hour.
\begin{itemize}
\item \texttt{POSIX} compatible systems connected via the \gls{TCP}.
This port only uses functionality from the standard \gls{C} library and
therefore runs on \emph{Linux} and \emph{MacOS}.
\item Microcontrollers supported by the
- \texttt{mbed}\footnote{\url{https://mbed.com}} environment.
+ \gls{mbed}\footnote{\url{https://mbed.com}} environment.
This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
development board.
client has been made for the \texttt{ESP8266} powered \emph{NodeMCU}
that is connected via \gls{TCP} over WiFi. A port also has been made
for the regular \gls{Arduino} \emph{Uno} board which only boasts a
- meager \emph{2K} \emph{RAM}. The stack size and storage available for
- devices boasting this little \emph{RAM} has to be smaller than default
+ meager \emph{2KB} RAM. The stack size and storage available for
+ devices boasting this little RAM has to be smaller than default
but are still suitable to hold a hand full of \glspl{Task}.
\end{itemize}
practice this means that if the first received \gls{Task} is removed, all
\glspl{Task} received later will have to move back. Obviously, this is quite
time intensive but it can not be permitted to leave holes in the memory since
-the memory space is so limited. This techniques allows for even the smallest
-tested microcontrollers with only $2K$ \emph{RAM} to hold several \glspl{Task}
-and \glspl{SDS}. Without this technique, the memory space will decrease over
-time and the client can then not run for very long since holes are evidently
-created at some point.
+the memory space is so limited. With this technique, even the smallest
+tested microcontrollers with only $2K$ RAM can hold several \glspl{Task} and
+\glspl{SDS}. Without this technique, the memory space will decrease over time
+and the client can then not run for very long since holes are evidently created
+at some point.
The structure instances and helper functions for traversing for \glspl{Task}
and \glspl{SDS} are shown in Listing~\ref{lst:structs}.
\subsection{Framework}
-Systems built with support for \gls{mTask} are often following the same design
+Systems built with support for \gls{mTask} often follow the same design
pattern. First the devices are created --- with or without the interaction of
the user --- and they are then connected. When all devices are registered, the
\gls{mTask}-\glspl{Task} can be sent and \gls{iTasks}-\glspl{Task} can be
peripherals. The following program shows a system containing two devices. The
first device --- the sensor --- contains a temperature sensor that measures the
room temperature. The second device --- the actor --- contains a heater,
-connected to the digital pin \CI{D5}. Moreover, this device contains a led to
-indicate whether the heater is on. The following code shows an implementation
-for this. The code fully uses the framework. Note that a little bit of type
-twiddling is required to fully us the result from the \gls{SDS}. This approach
-is still type safe due to the type safety of \CI{Dynamic}s.
+connected to the digital pin \CI{D5}. Moreover, this device contains an
+\gls{LED} to indicate whether the heater is on. The following code shows an
+implementation for this. The code makes use of all the aspects of the
+framework. Note that a little bit of type twiddling is required to fully use
+the result from the \gls{SDS}. This approach is still type safe due to the type
+safety of \CI{Dynamic}s.
\begin{lstlisting}[caption={Thermostat example}]
thermos :: Task ()
\subsection[Lifting mTasks to iTasks-Tasks]%
{Lifting \gls{mTask}-\glspl{Task} to \gls{iTasks}-\glspl{Task}}
-If the user does not want to know where and when a \gls{mTask} is actually
-executed and is just interested in the results it can lift the \gls{mTask} to
+If the user does not want to know where and when an \gls{mTask} is actually
+executed and is just interested in the results, it can lift the \gls{mTask} to
an \gls{iTasks}-\gls{Task}. The function is called with a name, \gls{mTask},
device and interval specification and it will return a \gls{Task} that finishes
if and only if the \gls{mTask} has returned.
\end{lstlisting}
The factorial function example from Chapter~\ref{chp:mtaskcont} can then be
-lifted to a real \gls{iTasks}-\gls{mTask} with the following code:
+lifted to a real \gls{iTasks}-\gls{Task} with the following code:
\begin{lstlisting}[caption={Lifting the factorial \gls{Task} to \gls{iTasks}}]
factorial :: MTaskDevice -> Task BCValue
factorial dev = enterInformation "Factorial of ?" []
and oxygen saturation sensor add-on is a \textsc{PCB} the size of a fingernail
with a red \gls{LED} and a light sensor on it. Moreover, it contains an
\textsc{I2C} chip to communicate. The company producing the chip provides the
-programmer with example code for \gls{Arduino} and \textsc{mbed}. The sensor
-emits red light and measures the returning light intensity. The microcontroller
-hosting the device has to keep track of four seconds of samples to determine
-the heartbeat. In the \gls{mTask}-system, an abstraction is made. The current
-implementation runs on \textsc{mbed} supported devices.
+programmer with example code for \gls{Arduino} and \gls{mbed}. The sensor
+emits red light and measures the intensity of the light returned. The
+microcontroller hosting the device has to keep track of four seconds of samples
+to determine the heartbeat. In the \gls{mTask}-system, an abstraction is made.
+The current implementation runs on \gls{mbed} supported devices.
\subsubsection{\gls{mTask} Classes}
First, a class has to be devised to store the functionality of the sensor. The
heartbeat sensor updates four values continuously, namely the heartbeat, the
-validity of the reading, the oxygen saturation and the validity of it. For
-every value a function is added to the new \CI{hb} class. Moreover, the
-introduced datatype housing the values should implement the \CI{mTaskType}
-classes. The definition is as follows:
+oxygen saturation and the validity of the two. For every value a function is
+added to the new \CI{hb} class. Moreover, the introduced datatype housing the
+values should implement the \CI{mTaskType} classes. The definition is as
+follows:
\begin{lstlisting}[caption={The \texttt{hb} class}]
:: Heartbeat = HB Int
\subsection{Device Storage}
Everything that a device encompasses is stored in the \CI{MTaskDevice} record
-type which is in turn stored in a \gls{SDS}. This includes management for the
+type which is in turn stored in an \gls{SDS}. This includes management for the
\glspl{SDS} and \glspl{Task} stored on the device. The \CI{MTaskDevice}
definition is shown in Listing~\ref{lst:mtaskdevice} accompanied with the
necessary classes and sub types. Devices added to the system must be reachable
However, this is by design and well documented. In the current system, an
\gls{SDS} can only reside on a single device.
-% TODO
% Single share per share
There are several possible approaches for storing \glspl{SDS} on the server
each with their own level of control. A possible way is to --- in the device
\CI{set} and \CI{upd} functions directory on the actual \gls{SDS}.
% Single share per device
-Another approach would be to have reference to a \gls{SDS} containing a table
-of \gls{SDS} values per device. This approach poses the same orphan problem as
-before. Accessing a single \gls{SDS} on the device happens by calling the
+Another approach would be to have reference to an \gls{SDS} containing a table
+of \gls{SDS} values per device. This approach suffers the same orphan problem
+as before. Accessing a single \gls{SDS} on the device happens by calling the
\CI{get}, \CI{set} and \CI{upd} functions on the actual table \gls{SDS} with an
-applied \CI{mapReadWrite}. Using parametric lenses can circumvent problem of
-watchers getting notified for other shares that are written. Error handling is
-better than the previously mentioned approach because a \gls{SDS} can know
+applied \CI{mapReadWrite}. Using parametric lenses can circumvent the problem
+of watchers getting notified for other shares that are written. Error handling
+is better than the previously mentioned approach because an \gls{SDS} can know
whether the \gls{SDS} has really gone because it will not be available anymore
in the table. It still does not know whether the device is still available.
The type for the parametric lens of the \gls{SDS} containing all devices is
\CI{Maybe (MTaskDevice, Int)}. There are several levels of abstraction that
have to be introduced. First, the \gls{SDS} responsible for storing the entire
-list of devices is called the global \gls{SDS}. Secondly, a \gls{SDS} can focus
-on a single device, such \glspl{SDS} are called local \glspl{SDS}. Finally, a
+list of devices is called the global \gls{SDS}. Secondly, an \gls{SDS} can focus
+on a single device, such \glspl{SDS} are called local \glspl{SDS}. Finally, an
\gls{SDS} can focus on a single \gls{SDS} on a single device. These \glspl{SDS}
are called share \glspl{SDS}. Using parametric lenses, the notifications can be
directed to only the watchers interested. Moreover, using parametric lenses,
scheduling strategy. Devices added to the system are stored and get a profile
for identification. These profiles are persistent during reboots of the
\gls{iTasks}-system to allow for easy reconnecting with old devices. The way of
-interacting with \gls{mTask}-\gls{Task} is analogous to interacting with
+interacting with \gls{mTask}-\glspl{Task} is analogous to interacting with
\gls{iTasks}-\glspl{Task}. This means that programmers can access the
\glspl{SDS} made for a device in the same way as regular \glspl{SDS} and they
can execute, combine and transform \gls{mTask}-\glspl{Task} as if they where
browsers}}
\newglossaryentry{LED}{name={LED},
description={Lighting Emitting Diode}}
+\newglossaryentry{mbed}{name={\textsc{mbed}},
+ description={is a programming framework for microcontrollers.}}
\newcommand{\newglossacr}[2]{\newglossaryentry{#1}{
name={#1},
first={#2 (#1)},%
functionality --- are shown in Listing~\ref{lst:exmtask}. The
\gls{mTask}-\glspl{Task} shown in the example do not belong to a particular
view and therefore are of the type \CI{View t r}. The \CI{blink} \gls{mTask}
-show the classic \gls{Arduino} blinking led application that blinks a certain
-\gls{LED} every second. The \CI{thermostat} expression will enable a digital
-pin powering a cooling fan when the analog pin representing a temperature
-sensor is too high. \CI{thermostat`} shows the same expression but now using
-the assignment style \gls{GPIO} technique. The \CI{thermostat} example also
-shows that it is not necessary to run everything as a \CI{task}. The main
-program code can also just consist of the contents of the root \CI{main}
-itself.
+show the classic \gls{Arduino} blinking \gls{LED} application that blinks a
+certain \gls{LED} every second. The \CI{thermostat} expression will enable a
+digital pin powering a cooling fan when the analog pin representing a
+temperature sensor is too high. \CI{thermostat`} shows the same expression but
+now using the assignment style \gls{GPIO} technique. The \CI{thermostat}
+example also shows that it is not necessary to run everything as a \CI{task}.
+The main program code can also just consist of the contents of the root
+\CI{main} itself.
\begin{lstlisting}[%
label={lst:exmtask},caption={Some example \gls{mTask}-\glspl{Task}}]
Moreover, \glspl{SDS} in the \gls{mTask}-\gls{EDSL} are always anonymous. There
is no way of labeling it since it is not a real entity, it is just a function.
-When a \gls{SDS} is sent to the device it must be retrievable and identifiable.
-It is not always clear which instantiated \gls{SDS} is which. Therefore, an
-added class named \CI{namedsds} is added that provides the exact same
-functionality as the \gls{SDS} class but adds a \CI{String} parameter that can
-later be used to identify a \gls{SDS}. The types for this class are as follows:
+When an \gls{SDS} is sent to the device it must be retrievable and
+identifiable. It is not always clear which instantiated \gls{SDS} is which.
+Therefore, an added class named \CI{namedsds} is added that provides the exact
+same functionality as the \gls{SDS} class but adds a \CI{String} parameter that
+can later be used to identify an \gls{SDS}. The types for this class are as
+follows:
\begin{lstlisting}[caption={The \texttt{namedsds} class}]
class namedsds v where