From a182f0a12fdb361d341337ce8240cbcd6ca96ebc Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Fri, 23 Jun 2017 11:54:32 +0200 Subject: [PATCH] change document structure to a more intuitive one --- appendix-protocol.tex | 6 +- listings/interface.h | 6 +- results.arch.tex | 187 +++++++++++++++++++++++++++++++++++++++--- results.itasks.tex | 121 --------------------------- results.mtask.tex | 61 ++------------ thesis.pre | 1 + thesis.tex | 8 +- 7 files changed, 192 insertions(+), 198 deletions(-) delete mode 100644 results.itasks.tex diff --git a/appendix-protocol.tex b/appendix-protocol.tex index 41e82d0..00d2ced 100644 --- a/appendix-protocol.tex +++ b/appendix-protocol.tex @@ -8,7 +8,7 @@ the message is not acknowledged or responded upon. Multibyte values are interpreted as \gls{MSB} first integers. \section{Handshake} -\begin{table}[!ht] +\begin{table}[H] \centering \begin{subfigure}[t]{.48\textwidth} \begin{tabular}{ll} @@ -35,7 +35,7 @@ interpreted as \gls{MSB} first integers. \newpage \section{mTasks} -\begin{table}[!ht] +\begin{table}[H] \centering \begin{subfigure}[t]{.48\textwidth} \begin{tabular}{ll} @@ -80,7 +80,7 @@ interpreted as \gls{MSB} first integers. \end{table} \section{SDSs} -\begin{table}[!ht] +\begin{table}[H] \centering \begin{subfigure}[t]{.2\textwidth} \begin{tabular}{ll} diff --git a/listings/interface.h b/listings/interface.h index 7b199b1..7faaab2 100644 --- a/listings/interface.h +++ b/listings/interface.h @@ -11,8 +11,6 @@ #define STACKSIZE 1024 #define MEMSIZE 1024 #define HAVELED 1 -#define HAVEAIO 1 -#define HAVEDIO 1 #elif defined STM ... #endif @@ -23,11 +21,11 @@ uint8_t read_byte(void); void write_byte(uint8_t b); /* Analog and digital pins */ -#if HAVEDIO == 1 +#if DPINS > 0 void write_dpin(uint8_t i, bool b); bool read_dpin(uint8_t i); #endif -#if HAVEAIO == 1 +#if APINS > 0 void write_apin(uint8_t i, uint8_t a); uint8_t read_apin(uint8_t i); #endif diff --git a/results.arch.tex b/results.arch.tex index d5e975d..dda1247 100644 --- a/results.arch.tex +++ b/results.arch.tex @@ -13,11 +13,11 @@ following terms will be used throughout the architecture description. \item Device, Client This is the actual device connected to the system. This can be a real - device such as a microcontroller but also just a program on the same - machine as the server. + device such as a microcontroller but it can also just be a program on + the same machine as the server. \item Server, \gls{iTasks}-System - The actual executable serving the \gls{iTasks} interfaces. The system + The actual executable serving the \gls{iTasks} application. The system will contain \glspl{Task} taking care of the communication with the clients. \item System @@ -26,8 +26,8 @@ following terms will be used throughout the architecture description. programs. \item Engine - The runtime system of the client. This system handles the communication - with the server and interprets the \glspl{Task}. + The runtime system of the client. This program handles the + communication with the server and interprets the \glspl{Task}. \end{itemize} \section{Devices} @@ -63,7 +63,56 @@ the device software. \emph{UNO} board that only boasts a meager \emph{2K} of \emph{RAM}. \end{itemize} -\section{Specification} +\subsection{Interpreter} +\todo{Structuur} +The client contains an interpreter to execute a \gls{Task}'s bytecode. + +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 +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. + +\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} The server stores a description for every device available in a record type which are stored in a \gls{SDS}. From the macro settings in the interface file, a profile is created for the device that describes the @@ -78,8 +127,8 @@ available for storing \glspl{Task} and \glspl{SDS} and the size of the stack. caption={Device specification for \glspl{mTask}}] :: MTaskDeviceSpec = { haveLed :: Bool - , haveAio :: Bool - , haveDio :: Bool + , haveLcd :: Bool + , have... , bytesMemory :: Int , stackSize :: Int , aPins :: Int @@ -87,7 +136,7 @@ available for storing \glspl{Task} and \glspl{SDS} and the size of the stack. } \end{lstlisting} -\section{Device Storage} +\subsection{Device Storage} All devices available in the system are stored in a big \gls{SDS} that contains a list of \CI{MTaskDevice}s. The exact specification is defined as in Listing~\ref{lst:mtaskdevice} accompanied with the used classes and types. @@ -111,10 +160,13 @@ Besides all the communication information, the record also keeps track of the 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. +format are explained in the following section. Specialized shares are available +per device. The internal mechanism for this is given in +Chapter~\ref{chp:itasksint}. \begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}] deviceStoreNP :: Shared [MTaskDevice] +deviceShare :: MTaskDevice -> Shared MTaskDevice :: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool) :: BCState = ... // Compiler state, explained in later sections @@ -139,6 +191,113 @@ class MTaskDuplex a where synFun :: a (Shared Channels) -> Task () \end{lstlisting} +\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 application has been created that allows an +interactive management console for the \gls{mTask} system. This interface +provides functionality to list \glspl{SDS}, add \glspl{Task}, remove +\glspl{Task}, administrate devices and view the state of the system. + +\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} + +An image of the management interface is shown in Figure~\ref{lst:manage}. +The system management is done by a single \gls{Task} called \CI{mTaskManager}. +To manage the system, a couple of different functionalities are needed and +are launched. 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 you can select the device to send the \gls{Task} to. The +dialog might contain user specified variables. All example \glspl{mTask} are of +the type \CI{Task (Main (ByteCode () Stmt))} and can thus ask for user input +first. + +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} + +\subsection{Shares} +The architecture of the system needs to keep track of the \glspl{SDS} stored on +the client. \glspl{SDS} can be stored on only one device at the same time. +that also stores the of devices. This means that if a \gls{SDS} updates, +everyone watching it will be notified. This would result in to a lot of +notifications that are not ment to be for the listener. 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. +There are several ways of tackling this problem each with their own pros and +cons and their own level of abstraction. + +\begin{itemize} + \item Instantiate an actual \gls{iTasks}-\gls{SDS} for every \gls{SDS} used + in a client. + + \item Instantiate a \gls{iTasks}-\gls{SDS} for every device that stores all + their \glspl{SDS}. + + \item Use only one \gls{iTasks}-\gls{SDS} for all devices. +\end{itemize} + +\begin{lstlisting}[label={lst:actualdev},% + caption={Real types for the device \gls{SDS}}] +deviceStoreNP :: Shared [MTaskDevice] +deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice] +\end{lstlisting} + +\subsection{Parametric Lenses} +The type of the parametric lens is \CI{Maybe (MTaskDevice, Int)}. The \gls{SDS} +can be responsible for 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. + +\paragraph{Global \glspl{SDS}: } +Accessing the global \gls{SDS} is just a matter of focussing the +\CI{deviceStore} with the \CI{Nothing} parameter. The signature for +\CI{deviceStore} was given in Chapter~\ref{chp:arch}. The actual implementation +is as in Listing~\ref{lst:global} + +\begin{lstlisting}[label={lst:shareimpl},% + caption={Base share implementation}] +deviceStoreNP :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice] +deviceStoreNP = sdsFocus Nothing deviceStore +\end{lstlisting} + + + + +\paragraph{Local \glspl{SDS}: } +\paragraph{Local-share specific \glspl{SDS}: } + +The implementation for the share is shown in Listing~\ref{lst:shareimpl}. The +\CI{realDeviceStore} \gls{SDS} is not exported through the header files. This +\gls{SDS} contains the actual \gls{SDS} that writes to disk or memory. +\CI{Int} is the identifier of the \gls{SDS}. The \gls{iTasks} way of applying +lenses is through the \CI{sdsFocus} function and through the \CI{sdsLens} +functions. \CI{sdsFocus} allows the programmer to fix the parameter. +\CI{sdsLens} is basically a \CI{mapReadWrite} that has access to the parameter. +This allows the programmer to create filters and lenses. Both of the methods +are not good enough for the device \gls{SDS} because they do not achieve the +writing to the actual device. Writing to a device requires being able to write +to \glspl{SDS}. To solve this problem, a real base \gls{SDS} is created. All +the details are visible in Listing~\ref{lst:shareimpl}. + \section{Communication} The communication from the server to the client and vice versa is just a character stream containing encoded \gls{mTask} messages. The specific encoding @@ -172,7 +331,7 @@ 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 the device functionality heavily -depends on the \CI{withDevices} function that applies a function a device in +depends on the specific \CI{deviceShare} function that applies a function a device in the \gls{SDS} when they are equal. Device equality is defined as equality on their channels. This allows you to give an old device record to the function and still update the latest instance. Listing~\ref{lst:connectDevice} shows the @@ -268,3 +427,9 @@ sends the \CI{MTShutdown} message. The device will then clear his 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. + +\section{Lifting mTask to iTasks} +\todo{task lifting} + +\section{Examples} +\todo{example program (demo)} diff --git a/results.itasks.tex b/results.itasks.tex deleted file mode 100644 index f157d20..0000000 --- a/results.itasks.tex +++ /dev/null @@ -1,121 +0,0 @@ -The server side 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 application has been created that allows an -interactive management console for the \gls{mTask} system. This interface -provides functionality to list \glspl{SDS}, add \glspl{Task}, remove -\glspl{Task}, administrate devices and view the state of the system. - -\section{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} - -An image of the management interface is shown in Figure~\ref{lst:manage}. -The system management is done by a single \gls{Task} called \CI{mTaskManager}. -To manage the system, a couple of different functionalities are needed and -are launched. 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 you can select the device to send the \gls{Task} to. The -dialog might contain user specified variables. All example \glspl{mTask} are of -the type \CI{Task (Main (ByteCode () Stmt))} and can thus ask for user input -first. - -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{Shares} -The architecture of the system needs to keep track of the \glspl{SDS} stored on -the client. \glspl{SDS} can be stored on only one device at the same time. -that also stores the of devices. This means that if a \gls{SDS} updates, -everyone watching it will be notified. This would result in to a lot of -notifications that are not ment to be for the listener. 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. -There are several ways of tackling this problem each with their own pros and -cons and their own level of abstraction. - -\begin{itemize} - \item Instantiate an actual \gls{iTasks}-\gls{SDS} for every \gls{SDS} used - in a client. - - - \item Instantiate a \gls{iTasks}-\gls{SDS} for every device that stores all - their \glspl{SDS}. - - \item Use only one \gls{iTasks}-\gls{SDS} for all devices. -\end{itemize} - -\begin{lstlisting}[label={lst:actualdev},% - caption={Real types for the device \gls{SDS}}] -deviceStoreNP :: Shared [MTaskDevice] -deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice] -\end{lstlisting} - -\subsection{Parametric Lens} -The type of the parametric lens is \CI{Maybe (MTaskDevice, Int)}. The \gls{SDS} -can either be focussed on the entire share, 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. - -The implementation for the share is shown in Listing~\ref{lst:shareimpl}. The -\CI{realDeviceStore} \gls{SDS} is not exported through the header files. This -\gls{SDS} contains the actual \gls{SDS} that writes to disk or memory. -\CI{Int} is the identifier of the \gls{SDS}. The \gls{iTasks} way of applying -lenses is through the \CI{sdsFocus} function and through the \CI{sdsLens} -functions. \CI{sdsFocus} allows the programmer to fix the parameter. -\CI{sdsLens} is basically a \CI{mapReadWrite} that has access to the parameter. -This allows the programmer to create filters and lenses. Both of the methods -are not good enough for the device \gls{SDS} because they do not achieve the -writing to the actual device. Writing to a device requires being able to write -to \glspl{SDS}. To solve this problem, a real base \gls{SDS} is created. All -the details are visible in Listing~\ref{lst:shareimpl}. - -\begin{lstlisting}[label={lst:shareimpl},% - caption={Base share implementation}] -realDeviceStore :: Shared [MTaskDevice] -realDeviceStore = memoryShare "mTaskDevices" [] - -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 doesn't exist anymore", iw) - Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of - Nothing = (Error $ exception $ "deviceStore: Share doesn't exist: " +++ toString ident, 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 - notifyPred Nothing (Just _) = False - notifyPred (Just _) Nothing = False - notifyPred (Just (d1, -1)) (Just (d2, _)) = d1 == d2 - notifyPred (Just (d1, i1)) (Just (d2, i2)) = d1 == d2 && i1 == i2 -\end{lstlisting} diff --git a/results.mtask.tex b/results.mtask.tex index 888b0d6..a939d4f 100644 --- a/results.mtask.tex +++ b/results.mtask.tex @@ -7,7 +7,7 @@ solve. A type --- housing the \gls{EDSL} --- does not have to implement all the available classes. Moreover, classes can be added at will without interfering with the existing views. -\section{Semantics} +\section{\gls{Task} Semantics} The current \gls{mTask} engine for devices does not support \glspl{Task} in the sense that the \gls{C}-view does. \Glspl{Task} used with the \gls{C}-view are a main program that executes code and launches \glspl{Task}. It was also possible @@ -38,7 +38,7 @@ reflected in the \CI{MTTask} message type. press of a button. \end{itemize} -\subsection{\glspl{SDS}} +\section{\gls{SDS} semantics} \Glspl{SDS} on a client are available on the server as well as regular \gls{SDS}. However, the same freedom is not given on the \glspl{SDS} that reside on the client. Not all types are suitable to be located on a client. @@ -60,7 +60,7 @@ class sdspub v where pub :: (v t Upd) -> v t Expr | type t \end{lstlisting} -\section{Bytecode compilation}\label{sec:compiler} +\section{Bytecode compilation view}\label{sec:compiler} The \glspl{mTask} are sent to the device in bytecode and are saved in the memory of the device. To compile the \gls{EDSL} code to bytecode, a view is added to the \gls{mTask}-system encapsulated in the type \CI{ByteCode}. As @@ -113,7 +113,6 @@ instance arith ByteCode instance serial ByteCode \end{lstlisting} -\section{Implementation} \subsection{Instruction Set} The instruction set is given in Listing~\ref{bc:instr}. The instruction set is kept large, but under $255$, to get the highest expressively while keeping all @@ -274,7 +273,7 @@ makeStore [BCDigitalRead i] = [BCDigitalWrite i] makeStore [...] = [...] \end{lstlisting} -\section{Actual Compilation} +\subsection{Actual Compilation} All the previous functions are tied together with the \CI{toMessages} function. This function compiles the bytecode and transforms the \gls{Task} in a message. The \glspl{SDS} that were not already sent to the device are also added as @@ -311,7 +310,7 @@ toMessages interval x oldstate = ([MTSds sdsi e\\{sdsi,sdsval=e}<-newsdss] ++ [MTTask interval bc], newstate) \end{lstlisting} -\section{Example} +\section{Examples} The heating example given previously in Listing~\ref{lst:exmtask} would be compiled to the following code. The left column indicates the position in the program memory. @@ -327,51 +326,5 @@ position in the program memory. 17-19: BCPush (Bool 0) //Else label 20 : BCDigitalWrite (Digital D0) \end{lstlisting} - -\section{Interpreter} -The client contains an interpreter to execute a \gls{Task}'s bytecode. - -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 -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. - -\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} +\todo{More elaborate example} +\todo{Add return instruction} diff --git a/thesis.pre b/thesis.pre index 2bb1289..3a863bd 100644 --- a/thesis.pre +++ b/thesis.pre @@ -15,6 +15,7 @@ \usepackage{pgf-umlsd} % Connection diagrams \usepackage{graphicx} % Graphics \usepackage{epstopdf} % Eps graphics +\usepackage{todonotes} % Todo notes \usetikzlibrary{arrows,shadows} diff --git a/thesis.tex b/thesis.tex index fa81dff..611367f 100644 --- a/thesis.tex +++ b/thesis.tex @@ -11,6 +11,7 @@ %Titlepage \input{titlepage} +\listoftodos \glsaddall{} %Abstract @@ -48,14 +49,11 @@ \chapter{The mTask EDSL}\label{chp:mtask} \input{methods.mtask} -\chapter{System Architecture}\label{chp:arch} -\input{results.arch} - \chapter{Extending the mTask EDSL}\label{chp:mtaskcont} \input{results.mtask} -\chapter{Integration with iTasks}\label{chp:itasksint} -\input{results.itasks} +\chapter{System Architecture}\label{chp:arch} +\input{results.arch} \chapter{Discussion \& Conclusion}\label{chp:conclusion} \input{conclusion} -- 2.20.1