X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=results.mtask.tex;h=50cd1d6a6fe1ad4bb867a4aa5a588d7e964f52c9;hb=36149fe97302e46248ceecfd8ef39faaea19991b;hp=20a51f1702c6d9ab8d065109e74517d343d0ab3a;hpb=209f5ef51d0f63ed47230a5a0e4226b4c2487fff;p=msc-thesis1617.git diff --git a/results.mtask.tex b/results.mtask.tex index 20a51f1..50cd1d6 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 @@ -151,7 +150,7 @@ and avoid label lookups at runtime. | BCReturn \end{lstlisting} -All single byte instructions can be converted automatically using the generic +All single byte instructions are converted automatically using the generic function \CI{consIndex} which returns the index of the constructor. The index of the constructor is the byte value for all instructions. The last step of the compilation is transforming the list of bytecode instructions to actual bytes. @@ -225,10 +224,30 @@ BCIfStmt (BC b) (BC t) (BC e) = BC ( t >>| tell [BCJmp endif, BCLab else] >>| e >>| tell [BCLab endif] ) + instance noOp ByteCode where noOp = tell` [BCNop] \end{lstlisting} +The semantics for the \glspl{mTask} bytecode view are different than the +semantics for the \gls{C} view. \glspl{Task} in the \gls{C} view can start new +\gls{Task} or themselves to continue, while in the bytecode view, \gls{Task} +run idefinitly, one-shot or on interrupt. To allow interval and interrupt +\glspl{Task} to terminate, a return instruction is added. This class was not +available in the original system and is thus added. It just writes a single +instruction so that the interpreter knows to stop execution. +Listing~\ref{lst:return} shows the classes and implementation for the return +expression. + +\begin{lstlisting}[label={lst:return},% + caption={Bytecode view for the return instruction}] +class retrn v where + retrn :: v () Expr + +instance retrn ByteCode where + retrn = tell` [BCReturn] +\end{lstlisting} + \subsection{Shared Data Sources \& Assignment} Shared data sources must be acquired from the state and constructing one involves multiple steps. First, a fresh identifier is grabbed from the state. @@ -274,7 +293,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 +330,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 +346,4 @@ 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}