Merge remote-tracking branch 'refs/remotes/origin/master'
authorMart Lubbers <mart@martlubbers.net>
Thu, 29 Jun 2017 14:28:49 +0000 (16:28 +0200)
committerMart Lubbers <mart@martlubbers.net>
Thu, 29 Jun 2017 14:28:49 +0000 (16:28 +0200)
1  2 
results.arch.tex

diff --combined results.arch.tex
@@@ -14,9 -14,9 +14,9 @@@ The following terms will be used throug
  \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.
+               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
@@@ -60,7 -60,7 +60,7 @@@ the device software
                development board.
        \item Microcontrollers which are programmable in the \gls{Arduino} \gls{IDE}
                connected via serial communication or via \gls{TCP} over WiFi or
-               ethernet.
+               Ethernet.
  
                This does not only include \gls{Arduino} compatible boards but also
                other boards capable of running \gls{Arduino} code. A port of the
  \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
+ \glspl{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]
+ \begin{algorithm}
        \KwData{
                \textbf{list} $tasks$,
-               \textbf{time} $t$
+               \textbf{time} $tm$
        }
  
        \Begin{
                                receive\_data()\;
                        }
  
-                       $t\leftarrow \text{now}()$\;
+                       $tm\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}$}{
+                               \ElseIf{$tm-t.\text{lastrun} > t.\text{interval}$}{
                                        run\_task$(t)$\;
                                        \uIf{$t.\text{interval}==0$}{
                                                delete\_task$(t)$\;
  \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.
+ \glspl{Task} and \glspl{SDS} are stored on the client in memory. Some devices
+ have very little memory and therefore memory space is very expensive and needs
+ to be used optimally. Almost all microcontrollers support heaps nowadays,
+ however, the functions for allocating and freeing the memory on the heap are
+ not very space optimal and often leave holes in the heap if allocations are not
+ freed in reverse order. To overcome this problem the client will allocate a big
+ memory segment in the global data block. This block of memory resides under the
+ stack and its size can be set in the interface implementation. This block of
+ memory will be managed in a similar way as the entire memory space of the
+ device is managed. \Glspl{Task} will grow from the bottom up and \glspl{SDS}
+ will grow from the top down.
+ When a \gls{Task} is received, the program will traverse the memory space from
+ the bottom up, jumping over all \glspl{Task}. A \gls{Task} is stored as the
+ structure followed directly by its bytecode. Therefore it only takes two jumps
+ to determine the size of the \gls{Task}. When the program arrived at the last
+ \gls{Task}, this place is returned and the newly received \gls{Task} can be
+ copied to there. This method is analogously applied for \glspl{SDS}, however,
+ the \glspl{SDS} grow from the bottom down.
+ When a \gls{Task} or \gls{SDS} is removed, all remaining objects are compressed
+ again. 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}. If this technique would not be used 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 them in memory for
+ \glspl{Task} and \glspl{SDS} are shown in Listing~\ref{lst:structs}.
  
  \begin{lstlisting}[language=C,label={lst:structs},%
-       caption={The data type storing the \glspl{Task}}]
+       caption={The data type storing the \glspl{Task}},float]
  struct task {
        uint16_t tasklength;
        uint16_t interval;
@@@ -245,15 -263,15 +263,15 @@@ types
        | SerialDevice TTYSettings
        | ...
  :: MTaskDevice =
-               { deviceTask :: Maybe TaskId
-               , deviceError :: Maybe String
+               { deviceTask     :: Maybe TaskId
+               , deviceError    :: Maybe String
                , deviceChannels :: String
-               , deviceName :: String
-               , deviceState :: BCState
-               , deviceTasks :: [MTaskTask]
-               , deviceData :: MTaskResource
-               , deviceSpec :: Maybe MTaskDeviceSpec
-               , deviceShares :: [MTaskShare]
+               , deviceName     :: String
+               , deviceState    :: BCState
+               , deviceTasks    :: [MTaskTask]
+               , deviceResource :: MTaskResource
+               , deviceSpec     :: Maybe MTaskDeviceSpec
+               , deviceShares   :: [MTaskShare]
        }
  
  channels :: MTaskDevice -> Shared Channels
@@@ -470,14 -488,13 +488,14 @@@ 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
 +connectDevice procFun device = set ([], [], False) ch
 +              >>| 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) @! ()
 +      ch = channels device
  \end{lstlisting}
  
  Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
@@@ -596,7 -613,7 +614,7 @@@ server application
        {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},
+ 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.
  
@@@ -610,4 -627,4 +628,4 @@@ wher
  \end{lstlisting}
  
  \section{Examples}
- \todo{example program (demo)}
+ Here comes a description of the demo program.