Merge branch 'master' of git.martlubbers.net:msc-thesis1617
[msc-thesis1617.git] / results.arch.tex
index cd9918d..b6b0b3d 100644 (file)
-\section{Architecture}
-\subsection{Devices}
-The client code for the devices is compiled from one codebase. For a device to
-be eligible for \glspl{mTask} it must be able to compile the shared codebase
-and 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
-for the first time with a server the specifications of what is implemented is
+The goal of the system as a whole is to offer a framework of functions with
+which an \gls{iTasks}-system can add, change and remove devices at runtime.
+Moreover, the \gls{iTasks}-system can send \gls{mTask}-\glspl{Task} ---
+compiled at runtime to bytecode by the \gls{mTask}-view --- to the device. The
+device runs an interpreter which can execute the \gls{Task}'s bytecode. Device
+profiles should be persistent during reboots of the \gls{iTasks}-system. The
+methods of interacting with \gls{mTask}-\gls{Task} should be 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 \gls{mTask}-\glspl{Task} as if they where normal
+\gls{iTasks}-\glspl{Task}.
+
+The following terms will be used throughout the following chapter:
+\begin{itemize}
+       \item Device, Client
+
+               These terms denotes the actual device connected to the system. This can be a
+               real device such as a microcontroller but it can also just be a program
+               on the same machine as the server functioning as a client.
+       \item Server, \gls{iTasks}-System
+
+               This is the actual executable serving the \gls{iTasks} application. The
+               system contains \glspl{Task} taking care of the communication with the
+               clients.
+       \item System
+
+               The system describes the complete ecosystem, containing both the server
+               and the clients including the communication between them.
+       \item Engine
+
+               The runtime system of the client is called the engine. This program
+               handles communicating with the server and runs the interpreter for the
+               \glspl{Task} on the client.
+\end{itemize}
+
+\section{Devices}
+A device is suitable for the system if it can run the engine.
+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.
 
 At the time of writing the following device families are supported and can run
 the device software.
 \begin{itemize}
-       \item \texttt{POSIX} compatible systems
-               
+       \item \texttt{POSIX} compatible systems connected via the \gls{TCP}.
+
                This includes systems running \emph{Linux} and \emph{MacOS}.
-       \item \texttt{STM32} family microcontrollers supported by \texttt{ChibiOS}.
+       \item The \texttt{STM32} microcontrollers family supported by
+               \texttt{ChibiOS} connected via serial communication.
 
                This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
                development board.
-       \item Microcontrollers programmable by the \emph{Arduino} \gls{IDE}.\\
-               
-               This does not only include \emph{Arduino} compatible boards but also
-               other boards capable of running \emph{Arduino} code. The code
-               has been found working on the \texttt{ESP8266} powered \emph{NodeMCU}.
-               It is tested on devices as small as the regular \emph{Arduino UNO}
-               board that only boasts a meager \emph{2K} of \emph{RAM}.
+       \item Microcontrollers which are programmable in the \gls{Arduino} \gls{IDE}
+               connected via serial communication or via \gls{TCP} over WiFi or
+               Ethernet.
+
+               This does not only include \gls{Arduino} compatible boards but also
+               other boards capable of running \gls{Arduino} code. A port of the
+               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
+               but are still suitable to hold a hand full of \glspl{Task}.
 \end{itemize}
 
+\subsection{Client}
+\subsubsection{Engine}
+The client is in a constant loop listening for input and waiting to execute
+\gls{Task}. The pseudocode for this is shown in Algorithm~\ref{alg:client}. The
+\CI{input\_available} function waits for input, but has a timeout set which can
+be interrupted. The timeout of the function determines the amount of loops per
+time interval and is a parameter that can be set during compilation for a
+device.
+
+\begin{algorithm}[H]
+       \KwData{
+               \textbf{list} $tasks$,
+               \textbf{time} $t$
+       }
+
+       \Begin{
+               \While{true}{
+                       \If{input\_available$()$}{
+                               receive\_data()\;
+                       }
+
+                       $t\leftarrow \text{now}()$\;
+                       \ForEach{$t\leftarrow tasks$}{
+                               \uIf{is\_interrupt$(t)$ \textbf{and} had\_interrupt$(t)$}{
+                                       run\_task$(t)$\;
+                               }
+                               \ElseIf{$t-t.\text{lastrun} > t.\text{interval}$}{
+                                       run\_task$(t)$\;
+                                       \uIf{$t.\text{interval}==0$}{
+                                               delete\_task$(t)$\;
+                                       }\Else{
+                                               $t.\text{lastrun}\leftarrow t$\;
+                                       }
+                               }
+                       }
+               }
+       }
+       \caption{Engine pseudocode}\label{alg:client}
+\end{algorithm}
+
+\subsubsection{Storage}
+\glspl{Task} and \glspl{SDS} are stored on the client in one big memory space
+that is reserved at the start of the program. The space could also have been
+dynamically allocated but that would require using the heap which is unwanted
+in small memory environments. \Glspl{Task} grow from the bottom up and
+\glspl{SDS} grow from the top down. When a \gls{Task} or \gls{SDS} is removed,
+all \glspl{Task} residing in higher areas of the memory are relocated in the
+memory space to not leave holes. Both \glspl{Task} and \glspl{SDS} are stored
+as structures that are linked in the memory space, helper functions are
+available to loop through them without having to fiddle in the memory space
+itself. The instances for \glspl{Task} and \glspl{SDS} are shown in
+Listing~\ref{lst:structs} accompanied by the helper functions for \glspl{Task}.
+\Glspl{Task} consists of the length, interval, last run time, id and the
+bytecode. \Glspl{SDS} consist only of an id, value and type. The pointer to the
+bytecode of the \gls{Task} always points to the location in the memory space.
+
+\begin{lstlisting}[language=C,label={lst:structs},%
+       caption={The data type storing the \glspl{Task}}]
+struct task {
+       uint16_t tasklength;
+       uint16_t interval;
+       unsigned long lastrun;
+       uint8_t taskid;
+       uint8_t *bc;
+};
+
+struct task *task_head(void);
+struct task *task_next(struct task *t);
+
+struct sds {
+       int id;
+       int value;
+       char type;
+};
+
+struct sds *sds_head(void);
+struct sds *sds_next(struct sds *s);
+\end{lstlisting}
+
+\subsubsection{Interpretation}
+The execution of a \gls{Task} is started by running the \CI{run\_task} function
+and always starts with setting the program counter and stack
+pointer to zero and the bottom respectively. When finished, the
+interpreter executes one step at the time while the program counter is smaller
+than the program length. This code is listed in Listing~\ref{lst:interpr}. One
+execution step is basically a big switch statement going over all possible
+bytecode instructions. Of some instructions, the implementations are shown in
+the listing. The \CI{BCPush} instruction is a little more complicated in the
+real code because some decoding will take place as not all \CI{BCValue}s are of
+the same length and are encoded.
+
+\begin{lstlisting}[language=C,label={lst:interpr},%
+       caption={Rough code outline for interpretation}]
+#define f16(p) program[pc]*265+program[pc+1]
+
+void run_task(struct task *t){
+       uint8_t *program = t->bc;
+       int plen = t->tasklength;
+       int pc = 0;
+       int sp = 0;
+       while(pc < plen){
+               switch(program[pc++]){
+               case BCNOP:
+                       break;
+               case BCPUSH:
+                       stack[sp++] = pc++ //Simplified
+                       break;
+               case BCPOP:
+                       sp--;
+                       break;
+               case BCSDSSTORE:
+                       sds_store(f16(pc), stack[--sp]);
+                       pc+=2;
+                       break;
+               // ...
+               case BCADD: trace("add");
+                       stack[sp-2] = stack[sp-2] + stack[sp-1];
+                       sp -= 1;
+                       break;
+               // ...
+               case BCJMPT: trace("jmpt to %d", program[pc]);
+                       pc = stack[--sp] ? program[pc]-1 : pc+1;
+                       break;
+}
+\end{lstlisting}
+
 \subsection{Specification}
-Devices are stored in a record type and all devices in the system are stored in
-a \gls{SDS} containing all devices. From the macro settings in the interface
-file a profile is created for the device that describes the specification. When
-a connection between the server and a client is established the server will
-send a request for specification. The client will serialize his specification
-and send it to the server so that the server knows what the client is capable
-of. The exact specification is listed in Listing~\ref{lst:devicespec}
-
-\begin{lstlisting}[language=Clean,label={lst:devicespec},
-       caption={Device specification for \glspl{mTask}}]
+The server stores a description for every device available in a record type.
+From the macro settings in the interface file, a profile is created that
+describes the specification of the device. When the connection between the
+server and a client is established, the server will send a request for
+specification. The client serializes its specification and send it to the
+server so that the server knows what the client is capable of.  The exact
+specification is shown in Listing~\ref{lst:devicespec} and stores the
+peripheral availability, the memory available for storing \glspl{Task} and
+\glspl{SDS} and the size of the stack.
+
+\begin{lstlisting}[label={lst:devicespec},
+       caption={Device specification for \gls{mTask}-\glspl{Task}}]
 :: MTaskDeviceSpec =
-       {haveLed     :: Bool
-       ,haveAio     :: Bool
-       ,haveDio     :: Bool
-       ,bytesMemory :: Int
+       { haveLed     :: Bool
+       , haveLCD     :: Bool
+       , have...
+       , bytesMemory :: Int
+       , stackSize   :: Int
+       , aPins       :: Int
+       , dPins       :: Int
        }
 \end{lstlisting}
 
-\subsection{Memory Management}
-\todo{Explain specification, combine task and share space}
-
-\subsection{Communication}
-The communication to and fro a device runs via a single \gls{SDS}. Every
-device has a specific resource that is used to connect to the device. The
-current system supports connecting devices via a serial connection and via a
-\gls{TCP} connection. Every device has the type \CI{MTaskDevice} and which
-is listed in Listing~\ref{lst:mtaskdevice}. When a device is added a background
-task is started that runs the \CI{synFun}. The \CI{synFun} is the task that
-synchronizes the channel \gls{SDS} with the actual device. For the \gls{TCP}
-device this is a simple \CI{tcpconnect}. The \CI{TaskId} of the background task
-is saved to be able to stop the task in the future. When the task is unable to
-connect it will set the \CI{deviceError} field to notify the user.
-\todo{netter maken}
-
-\begin{lstlisting}[language=Clean,caption={Device type},label={lst:mtaskdevice}]
+\section{iTasks}
+The server part of the system is written in \gls{iTasks}. Functions for
+managing devices, \glspl{Task} and \glspl{SDS} have been created to support the
+functionality. An interactive web application has been created that provides an
+interactive management console for the \gls{mTask} system. This interface
+provides functionality to list \glspl{SDS}, add and remove \glspl{Task},
+administrate devices and view the state of the system.
+
+\subsection{Device Storage}
+Everything that a device encompasses is stored in the \CI{MTaskDevice} record
+type. 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.
+
+\begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}]
 :: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
-:: MTaskResource 
+:: BCState = ... // Compiler state, explained in later sections
+:: MTaskResource
        = TCPDevice TCPSettings
        | SerialDevice TTYSettings
+       | ...
 :: MTaskDevice =
                { deviceTask :: Maybe TaskId
                , deviceError :: Maybe String
                , deviceChannels :: String
                , deviceName :: String
+               , deviceState :: BCState
                , deviceTasks :: [MTaskTask]
                , deviceData :: MTaskResource
                , deviceSpec :: Maybe MTaskDeviceSpec
+               , deviceShares :: [MTaskShare]
        }
 
+channels :: MTaskDevice -> Shared Channels
+
 class MTaskDuplex a where
        synFun :: a (Shared Channels) -> Task ()
 \end{lstlisting}
+
+The \CI{deviceResource} component of the record must implement the
+\CI{MTaskDuplex} interface that provides a function that launches a \gls{Task}
+used for synchronizing the channels. The \CI{deviceTask} stores the
+\gls{Task}-id for this \gls{Task} when active so that it can be checked upon.
+This top-level task has the duty to report exceptions and errors as they are
+thrown by setting the \CI{deviceError} field. All communication goes via these
+channels. To send a message to the device, the system just puts it
+in the channels. Messages sent from the client to the server are also placed
+in there. In the case of the \gls{TCP} device type, the \gls{Task} is just a
+simple wrapper around the existing \CI{tcpconnect} function in \gls{iTasks}. In
+case of a device connected by a serial connection, it uses the newly developed
+serial port library of \gls{Clean}\footnote{\url{%
+https://gitlab.science.ru.nl/mlubbers/CleanSerial}}.
+
+Besides all the communication information, the record also keeps track of the
+\glspl{Task} currently on the device, the compiler state (see
+Section~\ref{sec:compiler}) and the according \glspl{SDS}. Finally, it stores
+the specification of the device that is received when connecting. All of this
+is given in Listing~\ref{lst:mtaskdevice}. The definitions of the message
+format are explained in the following section.
+
+\subsection{Shares}
+The system keeps track of the \glspl{SDS} stored on
+the client in a big \gls{SDS} containing a list of devices. Client-\glspl{SDS}
+can be stored on one device at the same time. This means that if an \gls{SDS}
+updates, everyone watching it will be notified. This would result in a lot
+of notifications that are not meant for the watcher. Moreover, when a client
+updates the \gls{SDS} this is processed by the connection handler and results
+in an update of the real \gls{SDS}. Finally, the \gls{SDS} of a client must be
+synchronized with the actual device. Thus, when an \gls{iTasks}-\gls{Task}
+writes the client-\gls{SDS}, it must be propagated to the real device. There
+are several ways of tackling this problem each with their own level of
+granularity.
+
+First an actual \gls{iTasks}-\gls{SDS} for every \gls{SDS} used in a client can
+be instantiated with one \gls{iTasks}-\gls{Task} listening to the \gls{SDS} and
+synchronizing it with the device when an update occurred. This approach is very
+expensive as it requires a lot of listening \glspl{Task}.
+
+Improved on this, a single \gls{iTasks}-\gls{SDS} can be created for every
+devices that stores the respective \glspl{SDS}. Using the \CI{mapReadWrite}
+functions, a single \gls{SDS} per device can be created as a lens that allows
+mapping on a single client-\gls{SDS}. However, this approach still requires
+\glspl{Task} listening to the \gls{SDS} and when an \gls{SDS} is written,
+everyone is notified, even if the \gls{Task} only uses the value of a single
+different \gls{SDS}.
+
+Finally, the current approach --- a single \gls{SDS} for the entire system
+--- was explored. To create \glspl{SDS} per device or per client-\glspl{SDS} a
+\CI{mapReadWrite} can be used but it suffers from the same problem as mentioned
+before. Moreover, a \gls{Task} still has to watch the \gls{SDS} and communicate
+the client-\gls{SDS} updates to the actual device. Both of these problems can
+be solved by using a tailor made \gls{SDS} that heavily depends on parametric
+lenses.
+
+\subsection{Parametric Lenses}
+The type for the parametric lens of the big \gls{SDS} is \CI{Maybe
+(MTaskDevice, Int)}. The \gls{SDS} is responsible for storing the entire list
+of devices, from now on global.  Moreover, the \gls{SDS} can focus on a single
+device, from now on local. A local \gls{SDS} can also specifically focus on a
+single \gls{SDS} on a single device, from now on called local-share. The
+implementation of the real \gls{SDS} is given in Listing~\ref{lst:actualdev}.
+The \gls{SDS} is a lens on an actual \gls{SDS} that writes to a file or memory.
+Reading the \gls{SDS} is nothing more than reading the real \gls{SDS}. Writing
+the \gls{SDS} is a little bit more involved. If the write operation originated
+from an \gls{SDS} focussed on a single client-\gls{SDS}, the write action must
+also be relayed to the actual device. If the write originated from an \gls{SDS}
+focussed the devices or on one device only, nothing needs to be done. The
+notification predicate determines whether a watcher gets a notification update.
+
+\begin{lstlisting}[label={lst:actualdev},%
+       caption={Device \gls{SDS}}]
+deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]
+deviceStore = SDSSource {SDSSource | name="deviceStore", read = realRead, write= realWrite}
+where
+       realRead :: (Maybe (MTaskDevice,Int)) *IWorld -> (MaybeError TaskException [MTaskDevice], *IWorld)
+       realRead p iw = read realDeviceStore iw
+
+       realWrite :: (Maybe (MTaskDevice,Int)) [MTaskDevice] *IWorld -> (MaybeError TaskException (SDSNotifyPred (Maybe (MTaskDevice,Int))), *IWorld)
+       realWrite mi w iw
+       # (merr, iw) = write w realDeviceStore iw
+       | isError merr || isNothing mi = (merr $> notifyPred mi, iw)
+       # (Just (dev, ident)) = mi
+       | ident == -1 = (merr $> notifyPred mi, iw)
+       = case find ((==)dev) w of
+               Nothing = (Error $ exception "Device lost", iw)
+               Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of
+                       Nothing = (Error $ exception "Share lost", iw)
+                       Just s = case sendMessagesIW [MTUpd ident s.MTaskShare.value] dev iw of
+                               (Error e, iw) = (Error e, iw)
+                               (Ok _, iw) = (Ok $ notifyPred mi, iw)
+
+       notifyPred :: (Maybe (MTaskDevice, Int)) (Maybe (MTaskDevice, Int)) -> Bool
+       notifyPred Nothing Nothing = True    // Global watcher looking at a global event
+       notifyPred Nothing (Just _) = False  // Global watcher looking at a local event
+       notifyPred (Just _) Nothing = False  // Local watcher looking at a global event
+       // Local device watcher looking at a local event
+       notifyPred (Just (d1, -1)) (Just (d2, _)) = d1 == d2
+       // Local share watcher looking at a local share event
+       notifyPred (Just (d1, i1)) (Just (d2, i2)) = d1 == d2 && i1 == i2
+
+       realDeviceStore :: Shared [MTaskDevice]
+       realDeviceStore = sharedStore "mTaskDevices" []
+\end{lstlisting}
+
+\subsubsection{Global \glspl{SDS}}
+Accessing the global \gls{SDS} is just a matter of focussing the
+\CI{deviceStore} with the \CI{Nothing} parameter as follows:
+
+\begin{lstlisting}[caption={Global \gls{SDS}}]
+deviceStoreNP :: Shared [MTaskDevice]
+deviceStoreNP = sdsFocus Nothing deviceStore
+\end{lstlisting}
+
+\subsubsection{Local \glspl{SDS}}
+Accessing a single device can be done using the \CI{mapReadWrite} function.
+Since device comparison is shallow, the device that is given is allowed to be
+an old version. The identification of devices is solely done on the name of the
+channels and is unique throughout the system. The implementation is as follows:
+
+\begin{lstlisting}[caption={Local \gls{SDS}}]
+deviceShare :: MTaskDevice -> Shared MTaskDevice
+deviceShare d = mapReadWriteError
+       ( \ds->case find ((==)d) of
+               Nothing = exception "Device lost"
+               Just d = Ok d)
+       , \w ds->case splitWith ((==)d) ds of
+               ([], _) = Error $ exception "Device lost"
+               ([_:_], ds) = Ok $ Just [w:ds])
+       $ sdsFocus (Just (d, -1)) deviceStore
+\end{lstlisting}
+
+\subsubsection{Local-\gls{SDS} specific \glspl{SDS}}
+A single \gls{SDS} on a single device can be accessed using the \CI{shareShare}
+function. This function focusses the real big \gls{SDS} on a single \gls{SDS}
+and uses the \CI{mapReadWrite} functions to serve the correct part of the
+information.
+
+\begin{lstlisting}[caption={Local \gls{SDS}}]
+shareShare :: MTaskDevice MTaskShare -> Shared BCValue
+shareShare dev share = sdsFocus ()
+       $ mapReadWriteError (read, write)
+       $ sdsFocus (Just (dev, share.identifier))
+       $ deviceStore
+where
+       read :: [MTaskDevice] -> MaybeError TaskException BCValue
+       read devs = case find ((==)dev) devs of
+               Nothing = exception "Device lost"
+               Just d = case find ((==)share) d.deviceShares of
+                       Nothing = exception "Share lost"
+                       Just s = Ok s.MTaskShare.value
+       
+       write :: BCValue [MTaskDevice] -> MaybeError TaskException (Maybe [MTaskDevice])
+       write val devs = case partition ((==)dev) devs of
+               ([], _) = Error $ exception "Device doesn't exist anymore"
+               ([_,_:_], _) = Error $ exception "Multiple matching devices"
+               ([d=:{deviceShares}], devs) = case partition ((==)share) deviceShares of
+                       ([], _) = Error $ exception "Share doesn't exist anymore"
+                       ([_,_:_], _) = Error $ exception "Multiple matching shares"
+                       ([s], shares) = Ok $ Just [{MTaskDevice | d & 
+                               deviceShares=[{MTaskShare | s & value=val}:shares]}:devs]
+\end{lstlisting}
+
+\section{Communication}
+The communication from the server to the client and vice versa is just a
+character stream containing encoded \gls{mTask} messages. The \CI{synFun}
+belonging to the device is responsible for sending the content in the left
+channel and putting received messages in the right channel. Moreover, the
+boolean value should be set to \CI{True} when the connection is terminated. The
+specific encoding of the messages is visible in
+Appendix~\ref{app:communication-protocol}. The type holding the messages is
+shown in Listing~\ref{lst:avmsg}. Detailed explanation about the message types
+and according actions will be given in the following subsections.
+
+\begin{lstlisting}[label={lst:avmsg},caption={Available messages}]
+:: MTaskId :== Int
+:: MSDSId :== Int
+:: MTaskFreeBytes :== Int
+:: MTaskMSGRecv
+       = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
+       | MTSDSAck MSDSId                  | MTSDSDelAck MSDSId
+       | MTPub MSDSId BCValue             | MTMessage String
+       | MTDevSpec MTaskDeviceSpec        | MTEmpty
+
+:: MTaskMSGSend
+       = MTTask MTaskInterval String | MTTaskDel MTaskId
+       | MTShutdown                  | MTSds MSDSId BCValue
+       | MTUpd MSDSId BCValue        | MTSpec
+
+:: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int
+\end{lstlisting}
+
+\subsection{Add a device}
+A device can be added by filling in the \CI{MTaskDevice} record as much as
+possible and running the \CI{connectDevice} function. This function grabs the
+channels, starts the synchronization \gls{Task} (\CI{synFun}), makes sure the
+errors are handled when needed and runs a processing function in parallel to
+react on the incoming messages. Moreover, it sends a specification request to
+the device in question to determine the details of the device and updates the
+record to contain the top-level \gls{Task}-id. All device functionality
+heavily depends on the specific \CI{deviceShare} function that generates an
+\gls{SDS} for a specific device. This allows giving an old device record to the
+function and still update the latest instance. Listing~\ref{lst:connectDevice}
+shows the connection function.
+
+\begin{lstlisting}[label={lst:connectDevice},%
+       caption={Connect a device}]
+connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels
+connectDevice procFun device = let ch = channels device
+       in traceValue "connectDevice" >>| appendTopLevelTask 'DM'.newMap True
+               (       procFun device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
+               >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
+               >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch
+where
+       errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
+\end{lstlisting}
+
+Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
+the server with their device specification. This is detected by the processing
+function and the record is updated accordingly.
+
+\begin{figure}[H]
+       \centering
+       \begin{sequencediagram}
+               \newthread{s}{Server}
+               \newinst[4]{c}{Client}
+               \begin{call}{s}{MTSpec}{c}{MTDevSpec}
+               \end{call}
+       \end{sequencediagram}
+       \caption{Connect a device}\label{fig:handshake}
+\end{figure}
+
+\subsection{\glspl{Task} \& \glspl{SDS}}
+When a \gls{Task} is sent to the device it is added to the device record
+without an identifier. The actual identifier is added to the record when the
+acknowledgement of the \gls{Task} by the device is received. The connection
+diagram is shown in Figure~\ref{fig:tasksend}.
+
+\begin{figure}[H]
+       \centering
+       \begin{sequencediagram}
+               \newthread{s}{Server}
+               \newinst[4]{c}{Client}
+               \begin{call}{s}{MTSDS}{c}{MTSDSAck}
+               \end{call}
+               \begin{call}{s}{MTTask}{c}{MTTaskAck}
+               \end{call}
+       \end{sequencediagram}
+       \caption{Sending a \gls{Task} to a device}\label{fig:tasksend}
+\end{figure}
+
+The function for sending a \gls{Task} to the device is shown in
+Listing~\ref{lst:sendtask}. First the \gls{Task} is compiled into messages. The
+details of the compilation process are given in Section~\ref{sec:compiler}.
+The new \glspl{SDS} that were generated during compilation are merged with the
+existing device's \glspl{SDS}. Furthermore the messages are placed in the
+channel \gls{SDS} of the device. This will result in sending the actual \gls{SDS}
+specification and \gls{Task} specifications to the device. A \gls{Task} record
+is created with the identifier $-1$ to denote a \gls{Task} not yet
+acknowledged. Finally the device itself is updated with the new state and with
+the new \gls{Task}.  After waiting for the acknowledgement the device is
+updated again and the \gls{Task} returns.
+
+\begin{lstlisting}[label={lst:sendtask},%
+       caption={Sending a \gls{Task} to a device}]
+makeTask :: String Int -> Task MTaskTask
+makeTask name ident = get currentDateTime @ \dt->{MTaskTask | name=name, ident=ident, dateAdded=dt}
+
+makeShare :: String Int BCValue -> MTaskShare
+makeShare withTask identifier value = {MTaskShare | withTask=[withTask], identifier=identifier, value=value}
+
+sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval) -> Task MTaskTask
+sendTaskToDevice wta mTask (device, timeout)
+# (msgs, newState=:{sdss}) = toMessages timeout mTask device.deviceState
+# shares = [makeShare wta "" sdsi sdsval\\{sdsi,sdsval}<-sdss, (MTSds sdsi` _)<-msgs | sdsi == sdsi`]
+= updateShares device ((++) shares)
+       >>| sendMessages msgs device
+       >>| makeTask wta -1
+       >>= \t->upd (addTaskUpState newState t) (deviceShare device)
+       >>| wait "Waiting for task to be acked" (taskAcked t) (deviceShare device)
+       >>| treturn t
+where
+       addTaskUpState :: BCState MTaskTask MTaskDevice -> MTaskDevice
+       addTaskUpState st task device = {MTaskDevice | device & deviceState=st, deviceTasks=[task:device.deviceTasks]}
+       taskAcked t d = maybe True (\t->t.ident <> -1) $ find (eq t) d.deviceTasks
+       eq t1 t2 = t1.dateAdded == t2.dateAdded && t1.MTaskTask.name == t2.MTaskTask.name
+\end{lstlisting}
+
+\subsection{Miscellaneous Messages}
+One special type of message is available which is sent to the device only when
+it needs to reboot. When the server wants to stop the bond with the device it
+sends the \CI{MTShutdown} message. The device will then clear its memory, thus
+losing all the \glspl{SDS} and \glspl{Task} that were stored and reset itself.
+Shortly after the shutdown message a new server can connect to the device
+because the device is back in listening mode.
+
+\subsection{Integration}
+When the system starts up, the devices from the previous execution still
+residing in the \gls{SDS} must be cleaned up. It might be the case that they
+contain \glspl{Task}, \glspl{SDS} or errors that are no longer applicable in
+this run. A user or programmer can later choose to reconnect to some devices.
+
+\begin{lstlisting}[caption={Starting up the devices},%
+       label={lst:startupdevs}]
+startupDevices :: Task [MTaskDevice]
+startupDevices = upd (map reset) deviceStoreNP
+       where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
+\end{lstlisting}
+
+The system's management is done through the interface of a single \gls{Task}
+called \CI{mTaskManager}. To manage the system, a couple of different
+functionalities are necessary and are launched. An image of the management
+interface is shown in Figure~\ref{lst:manage}. The left sidebar of the
+interface shows the list of example \glspl{Task} that are present in the
+system. When clicking a \gls{Task}, a dialog opens in which a device can be
+selected to send the \gls{Task} to. The dialog might contain user specified
+variables. All example \gls{mTask}-\glspl{Task} are of the type \CI{Task (Main
+(ByteCode () Stmt))} and can thus ask for user input first if needed for
+parameterized \gls{mTask}-\glspl{Task}. The bottom panel shows the device
+information. In this panel, the devices can be created and modified. Moreover,
+this panel allows the user to reconnect with a device after a restart of the
+server application.
+
+\begin{figure}[H]
+       \centering
+       \includegraphics[width=\linewidth]{manage}
+       \caption{The device management interface}\label{lst:manage}
+\end{figure}
+
+\section[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
+an \gls{iTasks}-\glspl{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.
+
+\begin{lstlisting}[caption={Starting up the devices}]
+liftmTask :: String (Main (ByteCode () Stmt)) (MTaskDevice, MTaskInterval) -> Task ()
+liftmTask wta mTask c=:(dev, _)= sendTaskToDevice wta mTask c
+       >>= \t->wait "Waiting for mTask to return" (taskRemoved t) (deviceShare dev)
+       >>| viewInformation "Done!" [] ()
+where
+       taskRemoved t d = isNothing $ find (\t1->t1.ident==t.ident) d.deviceTasks
+\end{lstlisting}
+
+\section{Examples}
+Here comes a description of the demo program.