Sweeping through the archg
authorMart Lubbers <mart@martlubbers.net>
Fri, 23 Jun 2017 15:28:27 +0000 (17:28 +0200)
committerMart Lubbers <mart@martlubbers.net>
Fri, 23 Jun 2017 15:28:27 +0000 (17:28 +0200)
results.arch.tex

index dda1247..0573033 100644 (file)
-\section{Overview \& Terminology}
-The goal of the architecture is to facilitate an ecosystem in which an
+The goal of the total system is to facilitate an ecosystem in which an
 \gls{iTasks}-system can add, change and remove devices at runtime. Moreover,
 the \gls{iTasks}-system can send \glspl{mTask} --- compiled at runtime to
-bytecode --- to the device. The device runs an interpreter which can execute
-the \gls{Task}'s bytecode. Devices are persistent during reboots of the
-\gls{iTasks}-system. The methods of interacting with \glspl{mTask} is analogous
-to interacting with \gls{iTasks}-\glspl{Task} and programmers can access the
-\glspl{SDS} made for a device in the same way as a regular \glspl{SDS}. The
-following terms will be used throughout the architecture description.
-
+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 \glspl{mTask} should be analogous to interacting with
+\gls{iTasks}-\glspl{Task}. Meaning that programmers can access the \glspl{SDS}
+made for a device in the same way as a regular \gls{SDS} and they can execute
+\glspl{mTask} as if it where a normal \gls{iTasks}-\gls{Task}.
+
+The following terms will be used throughout the following chapter:
 \begin{itemize}
        \item Device, Client
 
-               This is 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.
+               This 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
 
-               The actual executable serving the \gls{iTasks} application. The system
-               will contain \glspl{Task} taking care of the communication with the
+               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 complete ecosystem, thus containing both the server and client
-               programs.
+               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. This program handles the
-               communication with the server and interprets the \glspl{Task}.
+               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}
-The engine 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
+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 for the
+first time with a server 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 \gls{TCP}.
 
                This includes systems running \emph{Linux} and \emph{MacOS}.
-       \item \texttt{STM32} family microcontrollers supported by \texttt{ChibiOS}.
+       \item \texttt{STM32} family microcontrollers supported by \texttt{ChibiOS}
+               connected via serial communication.
 
                This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
                development board.
-       \item Microcontrollers who are programmable in the \gls{Arduino} \gls{IDE}.\\
+       \item Microcontrollers who are programmable in the \gls{Arduino} \gls{IDE}
+               connected via serial communication or via \gls{TCP} over WiFi.
 
                This does not only include \gls{Arduino} compatible boards but also
-               other boards capable of running \gls{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 \gls{Arduino}
-               \emph{UNO} board that only boasts a meager \emph{2K} of \emph{RAM}.
+               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} of \emph{RAM}.  The stack size and storage for such
+               small amount of \emph{RAM} have to be smaller than default but it still
+               suitable to hold a hand full of \glspl{Task}.
 \end{itemize}
 
-\subsection{Interpreter}
-\todo{Structuur}
-The client contains an interpreter to execute a \gls{Task}'s bytecode.
+\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}.
+
+\todo{make algorithm}
+\begin{algorithm}[H]
+       \KwData{\textbf{stack} stack, \textbf{time} $t, t_p$}
+
+       $t\leftarrow\text{now}()$\;
+       \Begin{
+               \While{true}{
+                       $t_p\leftarrow t$\;
+                       $t\leftarrow\text{now}()$\;
+                       \If{notEmpty$($queue$)$}{
+                               $task\leftarrow \text{queue.pop}()$\;
+                               $task$.wait $\leftarrow task$.wait $-(t-t_p)$\;
+                               \eIf{$task.wait>t_0$}{
+                                       queue.append$(task)$\;
+                               }{
+                                       run\_task$(task)$\;
+                               }
+                       }
+               }
+       }
+       \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 fully allocated 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} are relocated in the memory space to not leave
+holes. Both \glspl{Task} and \glspl{SDS} are stored as structs and helper
+functions are available to loop through them without having to fiddle in the
+memory space. The instance for \glspl{Task} and \glspl{SDS} are shown in
+Listing~\ref{lst:structs} accompanied by the helper functions for \glspl{Task}.
+\Glspl{Task} consist the length, interval, last run time, id and the bytecode.
+\Glspl{SDS} consist just 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}
 
-Before execution some preparatory work is done. The stack will be initialized
-and the program counter and stack pointer are set to zero and the bottom
-respectively. Then, the interpreter executes one step at the time while the
-program counter is smaller than the program length. The code for this is listed
-in Listing~\ref{lst:interpr}. One execution step is basically a big switch
+\subsubsection*{Interpretation}
+Execution of a \gls{Task} always start with prepared the stack and the program
+counter and stack pointer are set 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. The code for this is listed in
+Listing~\ref{lst:interpr}. One execution step is basically a big switch
 statement going over all possible bytecode instructions. Some instructions are
 detailed upon in the listing. The \CI{BCPush} instruction is a little more
-complicated in real life because some decoding will take place as not all
-\CI{BCValue}'s are of the same length.
+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}]