bdc8100fd7bba2656f1f9d61c3fc05321ea90760
[phd-thesis.git] / top / top.tex
1 \documentclass[../thesis.tex]{subfiles}
2
3 \input{subfilepreamble}
4
5 \begin{document}
6 \input{subfileprefix}
7
8 \chapter{Edge device programming}%
9 \label{chp:top4iot}
10 \begin{chapterabstract}
11 This chapter:
12 \begin{itemize}
13 \item shows how to create the \emph{Hello World!} application for microcontrollers using \gls{ARDUINO};
14 \item extends this idea with multithreading, demonstrating the difficulty programming multi-tasking applications;
15 \item describes a comparative variant in \gls{MTASK} and shows that upgrading to a multi-tasking variant is straightforward
16 \item demonstrates that the complexity of running multiple tasks;
17 \item and concludes with the history of \gls{MTASK}'s development.
18 \end{itemize}
19 \end{chapterabstract}
20
21 The edge layer of \gls{IOT} system mostly consists of microcontrollers.
22 Microcontrollers are tiny computers designed specifically for embedded applications.
23 They therefore only have a soup\c{c}on of memory, have a slow processor, come with many energy efficient sleep modes and have a lot of peripheral support such as \gls{GPIO} pins.
24 Usually, programming microcontrollers requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to compile and run a program.
25 The programs are usually cyclic executives instead of tasks running in an operating system, i.e.\ there is only a single task that continuously runs on the bare metal.
26 \Cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two very popular microcontrollers.
27
28 \begin{table}
29 \begin{tabular}{llll}
30 \toprule
31 & Laptop & Atmega328P & ESP8266\\
32 \midrule
33 CPU speed & \qtyrange{2}{4}{\giga\hertz} & \qty{16}{\mega\hertz} & \qty{80}{\mega\hertz} or \qty{160}{\mega\hertz}\\
34 \textnumero{} cores & \numrange{4}{8} & 1 & 1\\
35 Storage & \qty{1}{\tebi\byte} & \qty{32}{\kibi\byte} & \qtyrange{0.5}{4}{\mebi\byte}\\
36 \gls{RAM} & \qtyrange{4}{16}{\gibi\byte} & \qty{2}{\kibi\byte} & \qty{160}{\kibi\byte}\\
37 Power & \qtyrange{50}{100}{\watt} & \qtyrange{0.13}{250}{\milli\watt} & \qtyrange{0.1}{350}{\milli\watt}\\
38 Price & \euro{1500} & \euro{3} & \euro{4}\\
39 \bottomrule
40 \end{tabular}
41 \caption{Hardware characteristics of typical microcontrollers and laptops.}%
42 \label{tbl:mcu_laptop}
43 \end{table}
44
45 Each type of microcontrollers comes with vendor-provided drivers, compilers and \glspl{RTS} but there are many platform that abstract away from this such as \gls{MBED} and \gls{ARDUINO} of which \gls{ARDUINO} is specifically designed for education and prototyping and hence used here.
46 The popular \gls{ARDUINO} \gls{C}\slash\gls{CPP} dialect and accompanying libraries provide an abstraction layer for common microcontroller behaviour allowing the programmer to program multiple types of microcontrollers using a single language.
47 Originally it was designed for the in-house developed open-source hardware with the same name but the setup allows porting to many architectures.
48 It provides an \gls{IDE} and toolchain automation to perform all steps of the toolchain with a single command.
49
50 \section{Hello world!}
51 Traditionally, the first program that one writes when trying a new language is the so called \emph{Hello World!} program.
52 This program has the single task of printing the text \emph{Hello World!} to the screen and exiting again, useful to become familiarised with the syntax and verify that the toolchain and runtime environment is working.
53 On microcontrollers, there usually is no screen for displaying text.
54 Nevertheless, almost always there is a built-in monochrome $1\times1$ pixel screen, namely \pgls{LED}.
55 The \emph{Hello World!} equivalent on microcontrollers blinks this \gls{LED}.
56
57 \Cref{lst:arduinoBlink} shows how the logic of a blink program might look when using \gls{ARDUINO}'s \gls{C}\slash\gls{CPP} dialect.
58 Every \gls{ARDUINO} program contains a \arduinoinline{setup} and a \arduinoinline{loop} function.
59 The \arduinoinline{setup} function is executed only once on boot, the \arduinoinline{loop} function is continuously called afterwards and contains the event loop.
60 After setting the \gls{GPIO} pin to the correct mode, blink's \arduinoinline{loop} function alternates the state of the pin representing the \gls{LED} between \arduinoinline{HIGH} and \arduinoinline{LOW}, turning the \gls{LED} off and on respectively.
61 In between it waits for \qty{500}{\ms} so that the blinking is actually visible for the human eye.
62
63 Translating the traditional blink program to \gls{MTASK} can almost be done by simply substituting some syntax as seen in \cref{lst:blinkImp}.
64 E.g.\ \arduinoinline{digitalWrite} becomes \cleaninline{writeD}, literals are prefixed with \cleaninline{lit} and the pin to blink is changed to represent the actual pin for the builtin \gls{LED} of the device used in the exercises.
65 In contrast to the imperative \gls{CPP} dialect, \gls{MTASK} is a \gls{TOP} language and therefore there is no such thing as a loop, only task combinators to combine tasks.
66 To simulate a loop, the \cleaninline{rpeat} task combinator can be used as this task combinator executes the argument task and, when stable, reinstates it.
67 The body of the \cleaninline{rpeat} contains similarly named tasks to write to the pins and to wait in between.
68 The tasks are connected using the sequential \cleaninline{>>|.} combinator that for all current intents and purposes executes the tasks after each other.
69
70 \begin{figure}[ht]
71 \begin{subfigure}[b]{.5\linewidth}
72 \begin{lstArduino}[caption={Blink program.},label={lst:arduinoBlink}]
73 void setup() {
74 pinMode(D2, OUTPUT);
75 }
76
77 void loop() {
78 digitalWrite(D2, HIGH);
79 delay(500);
80 digitalWrite(D2, LOW);
81 delay(500);
82 }
83 \end{lstArduino}
84 \end{subfigure}%
85 \begin{subfigure}[b]{.5\linewidth}
86 \begin{lstClean}[caption={Blink program.},label={lst:blinkImp}]
87 blink :: Main (MTask v ()) | mtask v
88 blink =
89 declarePin D2 PMOutput \d2->
90 {main = rpeat (
91 writeD d2 true
92 >>|. delay (lit 500)
93 >>|. writeD d2 false
94 >>|. delay (lit 500)
95 )
96 }
97 \end{lstClean}
98 \end{subfigure}
99 \end{figure}
100
101 \section{Threaded blinking}
102 Now say that we want to blink multiple blinking patterns on different \glspl{LED} concurrently.
103 For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of \qtylist{500;300;800}{\ms}.
104 Intuitively you want to lift the blinking behaviour to a function and call this function three times with different parameters as done in \cref{lst:blinkthreadno}
105
106 \begin{lstArduino}[caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}]
107 void setup () { ... }
108
109 void blink (int pin, int wait) {
110 digitalWrite(pin, HIGH);
111 delay(wait);
112 digitalWrite(pin, LOW);
113 delay(wait);
114 }
115
116 void loop() {
117 blink (D1, 500);
118 blink (D2, 300);
119 blink (D3, 800);
120 }\end{lstArduino}
121
122 Unfortunately, this does not work because the \arduinoinline{delay} function blocks all further execution.
123 The resulting program will blink the \glspl{LED} after each other instead of at the same time.
124 To overcome this, it is necessary to slice up the blinking behaviour in very small fragments so it can be manually interleaved \citep{feijs_multi-tasking_2013}.
125 Listing~\ref{lst:blinkthread} shows how three different blinking patterns might be achieved in \gls{ARDUINO} using the slicing method.
126 If we want the blink function to be a separate parametrizable function we need to explicitly provide all references to the required state.
127 Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
128 The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller.
129 Some devices use very little energy when in \arduinoinline{delay} or sleep state.
130 Resulting in \arduinoinline{millis} potentially affects power consumption since the processor is basically busy looping all the time.
131 In the simple case of blinking three \glspl{LED} on fixed intervals, it might be possible to calculate the delays in advance using static analysis and generate the appropriate \arduinoinline{delay} code.
132 Unfortunately, this is very hard when for example the blinking patterns are determined at runtime.
133
134 \begin{lstArduino}[label={lst:blinkthread},caption={Threading three blinking patterns.}]
135 long led1 = 0, led2 = 0, led3 = 0;
136 bool st1 = false, st2 = false, st3 = false;
137
138 void blink(int pin, int dlay, long *lastrun, bool *st) {
139 if (millis() - *lastrun > dlay) {
140 digitalWrite(pin, *st = !*st);
141 *lastrun += dlay;
142 }
143 }
144
145 void loop() {
146 blink(D1, 500, &led1, &st1);
147 blink(D2, 300, &led2, &st1);
148 blink(D3, 800, &led3, &st1);
149 }\end{lstArduino}
150
151 This method is very error prone, requires a lot of pointer juggling and generally results into spaghetti code.
152 Furthermore, it is very difficult to represent dependencies between threads, often state machines have to be explicitly programmed by hand to achieve this.
153
154 \section{Blinking in \texorpdfstring{\gls{MTASK}}{mTask}}
155 The \cleaninline{delay} \emph{task} does not block the execution but \emph{just} emits no value when the target waiting time has not yet passed and emits a stable value when the time is met.
156 In contrast, the \arduinoinline{delay()} \emph{function} on the \gls{ARDUINO} is blocking which prohibits interleaving.
157 To make code reuse possible and make the implementation more intuitive, the blinking behaviour is lifted to a recursive function instead of using the imperative \cleaninline{rpeat} construct.
158 The function is parametrized with the current state, the pin to blink and the waiting time.
159 Creating recursive functions like this is not possible in the \gls{ARDUINO} language because the program would run out of stack in an instant and nothing can be interleaved.
160 With a parallel combinator, tasks can be executed in an interleaved fashion.
161 Therefore, blinking three different blinking patterns is as simple as combining the three calls to the \cleaninline{blink} function with their arguments as seen in \cref{lst:blinkthreadmtask}.
162
163 % VimTeX: SynIgnore on
164 \begin{lstClean}[label={lst:blinkthreadmtask},caption={Threaded blinking.}]
165 blinktask :: MTask v () | mtask v
166 blinktask =
167 declarePin D1 PMOutput \d1->
168 declarePin D2 PMOutput \d2->
169 declarePin D3 PMOutput \d3->
170 fun \blink=(\(st, pin, wait)->
171 delay wait
172 >>|. writeD d13 st
173 >>|. blink (Not st, pin, wait)) In
174 {main = blink (true, d1, lit 500)
175 .||. blink (true, d2, lit 300)
176 .||. blink (true, d3, lit 800)
177 }\end{lstClean}
178 % VimTeX: SynIgnore off
179
180 \section{\texorpdfstring{\Gls{MTASK}}{MTask} history}
181 \subsection{Generating \texorpdfstring{\gls{C}/\gls{CPP}}{C/C++} code}
182 A first throw at a class-based shallowly \gls{EDSL} for microcontrollers was made by \citet{plasmeijer_shallow_2016}.
183 The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
184 A \gls{CPP} code generation backend was available together with an \gls{ITASK} simulation backend.
185 There was no support for tasks or even functions.
186 Some time later in the 2015 \gls{CEFP} summer school, an extended version was created that allowed the creation of imperative tasks, \glspl{SDS} and the usage of functions \citep{koopman_type-safe_2019}.
187 The name then changed from \gls{ARDSL} to \gls{MTASK}.
188
189 \subsection{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
190 \Citet{lubbers_task_2017} extended this in his Master's Thesis by adding integration with \gls{ITASK} and a bytecode compiler to the language.
191 \Gls{SDS} in \gls{MTASK} could be accessed on the \gls{ITASK} server.
192 In this way, entire \gls{IOT} systems could be programmed from a single source.
193 However, this version used a simplified version of \gls{MTASK} without functions.
194 This was later improved upon by creating a simplified interface where \glspl{SDS} from \gls{ITASK} could be used in \gls{MTASK} and the other way around \citep{lubbers_task_2018}.
195 It was shown by \citet{amazonas_cabral_de_andrade_developing_2018} that it was possible to build real-life \gls{IOT} systems with this integration.
196 Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 \gls{CEFP}/\gls{3COWS} winter school in Ko\v{s}ice, Slovakia \citep{koopman_simulation_2018}.
197
198 \section{Transition to \texorpdfstring{\gls{TOP}}{TOP}}
199 The \gls{MTASK} language as it is now was introduced in 2018 \citep{koopman_task-based_2018}.
200 This paper updated the language to support functions, tasks and \glspl{SDS} but still compiled to \gls{CPP} \gls{ARDUINO} code.
201 Later the bytecode compiler and \gls{ITASK} integration was added to the language \citep{lubbers_interpreting_2019}.
202 Moreover, it was shown that it is very intuitive to write microcontroller applications in a \gls{TOP} language \citep{lubbers_multitasking_2019}.
203 One reason for this is that a lot of design patterns that are difficult using standard means are for free in \gls{TOP} (e.g.\ multithreading).
204 In 2019, the \gls{CEFP} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well \citep{lubbers_writing_2019}.
205
206 \subsection{\texorpdfstring{\Glsxtrshort{TOP}}{TOP}}
207 In 2022, the SusTrainable summer school in Rijeka, Croatia hosted a course on developing greener \gls{IOT} applications using \gls{MTASK} as well (the lecture notes are to be written).
208 Several students worked on extending \gls{MTASK} with many useful features:
209 \Citet{veen_van_der_mutable_2020} did preliminary work on a green computer analysis, built a simulator and explored the possibilities for adding bounded datatypes; \citet{boer_de_secure_2020} investigated the possibilities for secure communication channels; and \citet{crooijmans_reducing_2021} added abstractions for low-power operation to \gls{MTASK} such as hardware interrupts and power efficient scheduling (resulting in a paper as well \citet{crooijmans_reducing_2022}).
210 \Citet{antonova_mtask_2022} defined a preliminary formal semantics for a subset of \gls{MTASK}.
211 Moreover, plans for student projects and improvements include exploring integrating \gls{TINYML} into \gls{MTASK}; and adding intermittent computing support to \gls{MTASK}.
212
213 In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course on \gls{MTASK} as well.
214
215 \subsection{\texorpdfstring{\gls{MTASK}}{mTask} in practise}
216 Funded by the Radboud-Glasgow Collaboration Fund, collaborative work was executed with Phil Trinder, Jeremy Singer, and Adrian Ravi Kishore Ramsingh.
217 An existing smart campus application was developed using \gls{MTASK} and quantitively and qualitatively compared to the original application that was developed using a traditional \gls{IOT} stack \citep{lubbers_tiered_2020}.
218 This research was later extended to include a four-way comparison: \gls{PYTHON}, \gls{MICROPYTHON}, \gls{ITASK} and \gls{MTASK} \citep{lubbers_could_2022}.
219 Currently, power efficiency behaviour of traditional versus \gls{TOP} \gls{IOT} stacks is being compared as well adding a \gls{FREERTOS} implementation to the mix as well.
220
221 \chapter{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\glsxtrshort{DSL}}{DSL}}%
222 \label{chp:mtask_dsl}
223 \begin{chapterabstract}
224 This chapter introduces the \gls{MTASK} language more technically by:
225 \begin{itemize}
226 \item introducing the setup of the \gls{EDSL};
227 \item and showing the language interface and examples for:
228 \begin{itemize}
229 \item data types
230 \item expression
231 \item task and their combinators.
232 \end{itemize}
233 \end{itemize}
234 \end{chapterabstract}
235
236 The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microcontrollers.
237 It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (see \cref{sec:tagless-final_embedding}).
238
239 Due to the nature of the embedding technique, it is possible to have multiple views on-programs written in the \gls{MTASK} language.
240 The following interpretations are available for \gls{MTASK}.
241
242 \begin{description}
243 \item[Pretty printer]
244
245 This interpretation converts the expression to a string representation.
246 \item[Simulator]
247
248 The simulator converts the expression to a ready-for-work \gls{ITASK} simulation in which the user can inspect and control the simulated peripherals and see the internal state of the tasks.
249 \item[Byte code compiler]
250
251 The compiler compiles the \gls{MTASK} program at runtime to a specialised byte code.
252 Using a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks.
253 Furthermore, with special language constructs, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs.
254 \end{description}
255
256 When using the compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
257 I.e.\ some components---e.g.\ the \gls{RTS} on the microcontroller---is largely unaware of the other components in the system, and it is executed on a completely different architecture.
258 The \gls{MTASK} language is an enriched simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definition; and a task language (see \cref{sec:top}).
259
260 \section{Types}
261 To leverage the type checker of the host language, types in the \gls{MTASK} language are expressed as types in the host language, to make the language type safe.
262 However, not all types in the host language are suitable for microcontrollers that may only have \qty{2}{\kibi\byte} of \gls{RAM} so class constraints are therefore added to the \gls{DSL} functions.
263 The most used class constraint is the \cleaninline{type} class collection containing functions for serialization, printing, \gls{ITASK} constraints, \etc.
264 Many of these functions can be derived using generic programming.
265 An even stronger restriction on types is defined for types that have a stack representation.
266 This \cleaninline{basicType} class has instances for many \gls{CLEAN} basic types such as \cleaninline{Int}, \cleaninline{Real} and \cleaninline{Bool}.
267 The class constraints for values in \gls{MTASK} are omnipresent in all functions and therefore often omitted throughout throughout the chapters for brevity and clarity.
268
269 \begin{table}[ht]
270 \centering
271 \begin{tabular}{lll}
272 \toprule
273 \gls{CLEAN}/\gls{MTASK} & \gls{CPP} type & \textnumero{}bits\\
274 \midrule
275 \cleaninline{Bool} & \cinline{bool} & 16\\
276 \cleaninline{Char} & \cinline{char} & 16\\
277 \cleaninline{Int} & \cinline{int16_t} & 16\\
278 \cleaninline{:: Long} & \cinline{int32_t} & 32\\
279 \cleaninline{Real} & \cinline{float} & 32\\
280 \cleaninline{:: T = A \| B \| C} & \cinline{enum} & 16\\
281 \bottomrule
282 \end{tabular}
283 \caption{Mapping from \gls{CLEAN}/\gls{MTASK} data types to \gls{CPP} datatypes.}%
284 \label{tbl:mtask-c-datatypes}
285 \end{table}
286
287 \Cref{lst:constraints} contains the definitions for the auxiliary types and type constraints (such as \cleaninline{type} an \cleaninline{basicType}) that are used to construct \gls{MTASK} expressions.
288 The \gls{MTASK} language interface consists of a core collection of type classes bundled in the type class \cleaninline{class mtask}.
289 Every interpretation implements the type classes in the \cleaninline{mtask} class
290 There are also \gls{MTASK} extensions that not every interpretation implements such as peripherals and \gls{ITASK} integration.
291 \begin{lstClean}[caption={Classes and class collections for the \gls{MTASK} language.},label={lst:constraints}]
292 class type t | iTask, ... ,fromByteCode, toByteCode t
293 class basicType t | type t where ...
294
295 class mtask v | expr, ..., int, real, long v
296
297 \end{lstClean}
298
299 Sensors, \glspl{SDS}, functions, \etc{} may only be defined at the top level.
300 The \cleaninline{Main} type is used that is used to distinguish the top level from the main expression.
301 Some top level definitions, such as functions, are defined using \gls{HOAS}.
302 To make their syntax friendlier, the \cleaninline{In} type---an infix tuple---is used to combine these top level definitions as can be seen in \cleaninline{someTask} (\cref{lst:mtask_types}).
303
304 \begin{lstClean}[caption={Example task and auxiliary types in the \gls{MTASK} language.},label={lst:mtask_types}]
305 :: Main a = { main :: a }
306 :: In a b = (In) infix 0 a b
307
308 someTask :: MTask v Int | mtask v & liftsds v & sensor1 v & ...
309 someTask =
310 sensor1 config1 \sns1->
311 sensor2 config2 \sns2->
312 sds \s1=initial
313 In liftsds \s2=someiTaskSDS
314 In fun \fun1= ( ... )
315 In fun \fun2= ( ... )
316 In { main = mainexpr }
317 \end{lstClean}
318
319 \section{Expressions}\label{sec:expressions}
320 \Cref{lst:expressions} shows the \cleaninline{expr} class containing the functionality to lift values from the host language to the \gls{MTASK} language (\cleaninline{lit}); perform number and boolean arithmetics; do comparisons; and conditional execution.
321 For every common boolean and arithmetic operator in the host language, an \gls{MTASK} variant is present, suffixed by a period to not clash with \gls{CLEAN}'s builtin operators.
322
323 \begin{lstClean}[caption={The \gls{MTASK} class for expressions},label={lst:expressions}]
324 class expr v where
325 lit :: t -> v t | type t
326 (+.) infixl 6 :: (v t) (v t) -> v t | basicType, +, zero t
327 ...
328 (&.) infixr 3 :: (v Bool) (v Bool) -> v Bool
329 (|.) infixr 2 :: (v Bool) (v Bool) -> v Bool
330 Not :: (v Bool) -> v Bool
331 (==.) infix 4 :: (v a) (v a) -> v Bool | Eq, basicType a
332 ...
333 If :: (v Bool) (v t) (v t) -> v t | type t
334 \end{lstClean}
335
336 Conversion to-and-fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real} that will convert the argument to the respective type similar to casting in \gls{C}.
337
338 \begin{lstClean}[caption={Type conversion functions in \gls{MTASK}.}]
339 class int v a :: (v a) -> v Int
340 class real v a :: (v a) -> v Real
341 class long v a :: (v a) -> v Long
342 \end{lstClean}
343
344 Values from the host language must be explicitly lifted to the \gls{MTASK} language using the \cleaninline{lit} function.
345 For convenience, there are many lower-cased macro definitions for often used constants such as \cleaninline{true :== lit True}, \cleaninline{false :== lit False}, \etc.
346
347 \Cref{lst:example_exprs} shows some examples of these expressions.
348 Since they are only expressions, there is no need for a \cleaninline{Main}.
349 \cleaninline{e0} defines the literal $42$, \cleaninline{e1} calculates the literal $42.0$ using real numbers.
350 \cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns the \cleaninline{e2}$/2$ and \cleaninline{e0} otherwise.
351
352 \begin{lstClean}[label={lst:example_exprs},caption={Example \gls{MTASK} expressions.}]
353 e0 :: v Int | expr v
354 e0 = lit 42
355
356 e1 :: v Real | expr v
357 e1 = lit 38.0 + real (lit 4)
358
359 e2 :: v Int | expr v
360 e2 = if' (e0 ==. int e1)
361 (int e1 /. lit 2) e0
362 \end{lstClean}
363
364 \Gls{MTASK} is shallowly embedded in \gls{CLEAN} and the terms are constructed at runtime.
365 This means that \gls{MTASK} programs can also be tailor-made at runtime or constructed using \gls{CLEAN} functions maximising the linguistic reuse \citep{krishnamurthi_linguistic_2001}
366 \cleaninline{approxEqual} in \cref{lst:example_macro} performs an approximate equality---albeit not taking into account all floating point pecularities---.
367 When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
368
369 \begin{lstClean}[label={lst:example_macro},caption={Example linguistic reuse in the \gls{MTASK} language.}]
370 approxEqual :: (v Real) (v Real) (v Real) -> v Real | expr v
371 approxEqual x y eps = if' (x ==. y) true
372 ( if' (x >. y)
373 (y -. x < eps)
374 (x -. y < eps)
375 )
376 \end{lstClean}
377
378 \subsection{Data types}
379 Most of \gls{CLEAN}'s basic types have been mapped on \gls{MTASK} types.
380 However, it can be useful to have access to compound types as well.
381 All types in \gls{MTASK} must have a fixed size representation on the stack so sum types are not (yet) supported.
382 While it is possible to lift types using the \cleaninline{lit} function, you cannot do anything with the types besides passing them around but they are being produced by some parallel task combinators (see \cref{sssec:combinators_parallel}).
383 To be able to use types as first class citizens, constructors and field selectors are required (see \cref{chp:first-class_datatypes}).
384 \Cref{lst:tuple_exprs} shows the scaffolding for supporting tuples in \gls{MTASK}.
385 Besides the constructors and field selectors, there is also a helper function available that transforms a function from a tuple of \gls{MTASK} expressions to an \gls{MTASK} expression of a tuple.
386 Examples for using tuple can be found in \cref{sec:mtask_functions}.
387
388 \begin{lstClean}[label={lst:tuple_exprs},caption={Tuple constructor and field selectors in \gls{MTASK}.}]
389 class tupl v where
390 tupl :: (v a) (v b) -> v (a, b) | type a & type b
391 first :: (v (a, b)) -> v a | type a & type b
392 second :: (v (a, b)) -> v b | type a & type b
393
394 tupopen f :== \v->f (first v, second v)
395 \end{lstClean}
396
397 \subsection{Functions}\label{sec:mtask_functions}
398 Adding functions to the language is achieved by type class to the \gls{DSL}.
399 By using \gls{HOAS}, both the function definition and the calls to the function can be controlled by the \gls{DSL} \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
400 The \gls{MTASK} only allows first-order functions and does not allow partial function application.
401 This is restricted by using a multi-parameter type class where the first parameter represents the arguments and the second parameter the view.
402 By providing a single instance per function arity instead of providing one instance for all functions and using tuples for the arguments this constraint can be enforced.
403 Also, \gls{MTASK} only supports top-level functions which is enforced by the \cleaninline{Main} box.
404 The definition of the type class and the instances for an example interpretation (\cleaninline{:: Inter}) are as follows:
405
406 \begin{lstClean}[caption={Functions in \gls{MTASK}.}]
407 class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
408 -> Main (MTask v u)
409
410 instance fun () Inter where ...
411 instance fun (Inter a) Inter | type a where ...
412 instance fun (Inter a, Inter b) Inter | type a, type b where ...
413 instance fun (Inter a, Inter b, Inter c) Inter | type a, ... where ...
414 ...
415 \end{lstClean}
416
417 Deriving how to define and use functions from the type is quite the challenge even though the resulting syntax is made easier using the infix type \cleaninline{In}.
418 \Cref{lst:function_examples} show the factorial function, a tail-call optimised factorial function and a function with zero arguments to demonstrate the syntax.
419 Splitting out the function definition for each single arity means that that for every function arity and combination of arguments, a separate class constraint must be created.
420 Many of the often used functions are already bundled in the \cleaninline{mtask} class constraint collection.
421 \cleaninline{factorialtail} shows a manually added class constraint.
422 Definiting zero arity functions is shown in the \cleaninline{zeroarity} expression.
423 Finally, \cleaninline{swapTuple} shows an example of a tuple being swapped.
424
425 % VimTeX: SynIgnore on
426 \begin{lstClean}[label={lst:function_examples},caption={Function examples in \gls{MTASK}.}]
427 factorial :: Main (v Int) | mtask v
428 factorial =
429 fun \fac=(\i->if' (i <. lit 1)
430 (lit 1)
431 (i *. fac (i -. lit 1)))
432 In {main = fac (lit 5) }
433
434 factorialtail :: Main (v Int) | mtask v & fun (v Int, v Int) v
435 factorialtail =
436 fun \facacc=(\(acc, i)->if' (i <. lit 1)
437 acc
438 (fac (acc *. i, i -. lit 1)))
439 In fun \fac=(\i->facacc (lit 1, i))
440 In {main = fac (lit 5) }
441
442 zeroarity :: Main (v Int) | mtask v
443 zeroarity =
444 fun \fourtytwo=(\()->lit 42)
445 In fun \add=(\(x, y)->x +. y)
446 In {main = add (fourtytwo (), lit 9)}
447
448 swapTuple :: Main (v (Int, Bool)) | mtask v
449 swapTuple =
450 fun \swap=(tupopen \(x, y)->tupl y x)
451 In {main = swap (tupl true (lit 42)) }
452 \end{lstClean}
453 % VimTeX: SynIgnore off
454
455 \section{Tasks and task combinators}\label{sec:top}
456 \Gls{MTASK}'s task language can be divided into three categories, namely
457 \begin{enumerate*}
458 \item Basic tasks, in most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
459 In \gls{MTASK}, there are no \emph{editors} in that sense but there is interaction with the outside world through microcontroller peripherals such as sensors and actuators.
460 \item Task combinators provide a way of describing the workflow.
461 They combine one or more tasks into a compound task.
462 \item \glspl{SDS} in \gls{MTASK} can be seen as references to data that can be shared using many-to-many communication and are only accessible from within the task language to ensure atomicity.
463 \end{enumerate*}
464
465 As \gls{MTASK} is integrated with \gls{ITASK}, the same stability distinction is made for task values.
466 A task in \gls{MTASK} is denoted by the \gls{DSL} type synonym shown in \cref{lst:task_type}.
467
468 \begin{lstClean}[label={lst:task_type},caption={Task type in \gls{MTASK}.}]
469 :: MTask v a :== v (TaskValue a)
470 :: TaskValue a
471 = NoValue
472 | Value a Bool
473 \end{lstClean}
474
475 \subsection{Basic tasks}
476 The most rudimentary basic tasks are the \cleaninline{rtrn} and \cleaninline{unstable} tasks.
477 They lift the value from the \gls{MTASK} expression language to the task domain either as a stable value or an unstable value.
478 There is also a special type of basic task for delaying execution.
479 The \cleaninline{delay} task---given a number of milliseconds---yields an unstable value while the time has not passed.
480 Once the specified time has passed, the time it overshot the planned time is yielded as a stable task value.
481 See \cref{sec:repeat} for an example task using \cleaninline{delay}.
482
483 \begin{lstClean}[label={lst:basic_tasks},caption={Function examples in \gls{MTASK}.}]
484 class rtrn v :: (v t) -> MTask v t
485 class unstable v :: (v t) -> MTask v t
486 class delay v :: (v n) -> MTask v n | long v n
487 \end{lstClean}
488
489 \subsubsection{Peripherals}\label{sssec:peripherals}
490 For every sensor or actuator, basic tasks are available that allow interaction with the specific peripheral.
491 The type classes for these tasks are not included in the \cleaninline{mtask} class collection as not all devices nor all language interpretations have such peripherals connected.
492 %\todo{Historically, peripheral support has been added \emph{by need}.}
493
494 \Cref{lst:dht,lst:gpio} show the type classes for \glspl{DHT} sensors and \gls{GPIO} access.
495 Other peripherals have similar interfaces, they are available in the \cref{sec:aux_peripherals}.
496 For the \gls{DHT} sensor there are two basic tasks, \cleaninline{temperature} and \cleaninline{humidity}, that---will given a \cleaninline{DHT} object---produce a task that yields the observed temperature in \unit{\celcius} or relative humidity as a percentage as an unstable value.
497 Currently, two different types of \gls{DHT} sensors are supported, the \emph{DHT} family of sensors connect through $1$-wire protocol and the \emph{SHT} family of sensors connected using \gls{I2C} protocol.
498 Creating such a \cleaninline{DHT} object is very similar to creating functions in \gls{MTASK} and uses \gls{HOAS} to make it type safe.
499
500 \begin{lstClean}[label={lst:dht},caption{The \gls{MTASK} interface for \glspl{DHT} sensors.}]
501 :: DHT //abstract
502 :: DHTInfo
503 = DHT_DHT Pin DHTtype
504 | DHT_SHT I2CAddr
505 :: DHTtype = DHT11 | DHT21 | DHT22
506 class dht v where
507 DHT :: DHTInfo ((v DHT) -> Main (v b)) -> Main (v b) | type b
508 temperature :: (v DHT) -> MTask v Real
509 humidity :: (v DHT) -> MTask v Real
510
511 measureTemp :: Main (MTask v Real) | mtask v & dht v
512 measureTemp = DHT (DHT_SHT (i2c 0x36)) \dht->
513 {main=temperature dht}
514 \end{lstClean}
515
516 \Gls{GPIO} access is divided into three classes: analog, digital and pin modes.
517 For all pins and pin modes an \gls{ADT} is available that enumerates the pins.
518 The analog \gls{GPIO} pins of a microcontroller are connected to an \gls{ADC} that translates the voltage to an integer.
519 Analog \gls{GPIO} pins can be either read or written to.
520 Digital \gls{GPIO} pins only report a high or a low value.
521 The type class definition is a bit more complex since analog \gls{GPIO} pins can be used as digital \gls{GPIO} pins as well.
522 Therefore, if the \cleaninline{p} type implements the \cleaninline{pin} class---i.e.\ either \cleaninline{APin} or \cleaninline{DPin}---the \cleaninline{dio} class can be used.
523 \Gls{GPIO} pins usually operate according to a certain pin mode that states whether the pin acts as an input pin, an input with an internal pull-up resistor or an output pin.
524 This setting can be applied using the \cleaninline{pinMode} class by hand or by using the \cleaninline{declarePin} \gls{GPIO} pin constructor.
525 Setting the pin mode is a task that immediately finisheds and fields a stable unit value.
526 Writing to a pin is also a task that immediately finishes but yields the written value instead.
527 Reading a pin is a task that yields an unstable value---i.e.\ the value read from the actual pin.
528
529 \begin{lstClean}[label={lst:gpio},caption={The \gls{MTASK} interface for \gls{GPIO} access.}]
530 :: APin = A0 | A1 | A2 | A3 | A4 | A5
531 :: DPin = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | D11 | D12 | D13
532 :: PinMode = PMInput | PMOutput | PMInputPullup
533 :: Pin = AnalogPin APin | DigitalPin DPin
534 class pin p :: p -> Pin
535
536 class aio v where
537 writeA :: (v APin) (v Int) -> MTask v Int
538 readA :: (v APin) -> MTask v Int
539
540 class dio p v | pin p where
541 writeD :: (v p) (v Bool) -> MTask v Bool
542 readD :: (v p) -> MTask v Bool | pin p
543
544 class pinMode v where
545 pinMode :: (v PinMode) (v p) -> MTask v () | pin p
546 declarePin :: p PinMode ((v p) -> Main (v a)) -> Main (v a) | pin p
547 \end{lstClean}
548
549 \begin{lstClean}[label={lst:gpio_examples},caption={\Gls{GPIO} example in \gls{MTASK}.}]
550 task1 :: MTask v Int | mtask v
551 task1 = declarePin A3 PMInput \a3->{main=readA a3}
552
553 task2 :: MTask v Int | mtask v
554 task2 = declarePin D3 PMOutput \d3->{main=writeD d3 true}
555 \end{lstClean}
556
557 \subsection{Task combinators}
558 Task combinators are used to combine multiple tasks into one to describe workflows.
559 There are three main types of task combinators, namely:
560 \begin{enumerate*}
561 \item Sequential combinators that execute tasks one after the other, possibly using the result of the left hand side.
562 \item Parallel combinators that execute tasks at the same time combining the result.
563 \item Miscellaneous combinators that change the semantics of a task---e.g.\ repeat it or delay execution.
564 \end{enumerate*}
565
566 \subsubsection{Sequential}
567 Sequential task combination allows the right-hand side task to observe the left-hand side task value.
568 All seqential task combinators are expressed in the \cleaninline{expr} class and can be---and are by default---derived from the Swiss army knife step combinator \cleaninline{>>*.}.
569 This combinator has a single task on the left-hand side and a list of \emph{task continuations} on the right-hand side.
570 The list of task continuations is checked every rewrite step and if one of the predicates matches, the task continues with the result of this combination.
571 \cleaninline{>>=.} is a shorthand for the bind operation, if the left-hand side is stable, the right-hand side function is called to produce a new task.
572 \cleaninline{>>|.} is a shorthand for the sequence operation, if the left-hand side is stable, it continues with the right-hand side task.
573 The \cleaninline{>>~.} and \cleaninline{>>..} combinators are variants of the ones above that ignore the stability and continue on an unstable value as well.
574
575 \begin{lstClean}[label={lst:mtask_sequential},caption={Sequential task combinators in \gls{MTASK}.}]
576 class step v | expr v where
577 (>>*.) infixl 1 :: (MTask v t) [Step v t u] -> MTask v u
578 (>>=.) infixl 0 :: (MTask v t) ((v t) -> MTask v u) -> MTask v u
579 (>>|.) infixl 0 :: (MTask v t) (MTask v u) -> MTask v u
580 (>>~.) infixl 0 :: (MTask v t) ((v t) -> MTask v u) -> MTask v u
581 (>>..) infixl 0 :: (MTask v t) (MTask v u) -> MTask v u
582
583 :: Step v t u
584 = IfValue ((v t) -> v Bool) ((v t) -> MTask v u)
585 | IfStable ((v t) -> v Bool) ((v t) -> MTask v u)
586 | IfUnstable ((v t) -> v Bool) ((v t) -> MTask v u)
587 | Always (MTask v u)
588 \end{lstClean}
589
590 \todo{more examples step?}
591
592 The following listing shows an example of a step in action.
593 The \cleaninline{readPinBin} function produces an \gls{MTASK} task that classifies the value of an analogue pin into four bins.
594 It also shows that the nature of embedding allows the host language to be used as a macro language.
595 Furthermore
596
597 \begin{lstClean}[label={lst:mtask_readpinbin},caption={Read an analog pin and bin the value in \gls{MTASK}.}]
598 readPinBin :: Int -> Main (MTask v Int) | mtask v
599 readPinBin lim = declarePin PMInput A2 \a2->
600 { main = readA a2 >>*.
601 [ IfValue (\x->x <. lim) (\_->rtrn (lit bin))
602 \\ lim <-[64,128,192,256]
603 & bin <- [0..]]}
604 \end{lstClean}
605
606 \subsubsection{Parallel}\label{sssec:combinators_parallel}
607 The result of a parallel task combination is a compound that actually executes the tasks at the same time.
608
609 There are two types of parallel task combinators (see \cref{lst:mtask_parallel}).
610 The conjunction combinator (\cleaninline{.&&.}) combines the result by putting the values from both sides in a tuple.
611 The stability of the task depends on the stability of both children.
612 If both children are stable, the result is stable, otherwise the result is unstable.
613 The disjunction combinator (\cleaninline{.\|\|.}) combines the results by picking the leftmost, most stable task.
614 The semantics are easily described using \gls{CLEAN} functions shown in \cref{lst:semantics_con,lst:semantics_dis}.
615
616 \begin{figure}[ht]
617 \centering
618 \begin{subfigure}[t]{.5\textwidth}
619 \begin{lstClean}[caption={Semantics of the\\conjunction combinator.},label={lst:semantics_con}]
620 con :: (TaskValue a) (TaskValue b)
621 -> TaskValue (a, b)
622 con NoValue r = NoValue
623 con l NoValue = NoValue
624 con (Value l ls) (Value r rs)
625 = Value (l, r) (ls && rs)
626
627 \end{lstClean}
628 \end{subfigure}%
629 \begin{subfigure}[t]{.5\textwidth}
630 \begin{lstClean}[caption={Semantics of the\\disjunction combinator.},label={lst:semantics_dis}]
631 dis :: (TaskValue a) (TaskValue a)
632 -> TaskValue a
633 dis NoValue r = r
634 dis l NoValue = l
635 dis (Value l ls) (Value r rs)
636 | rs = Value r True
637 | otherwise = Value l ls
638 \end{lstClean}
639 \end{subfigure}
640 \end{figure}
641
642 \begin{lstClean}[label={lst:mtask_parallel},caption={Parallel task combinators in \gls{MTASK}.}]
643 class (.&&.) infixr 4 v :: (MTask v a) (MTask v b) -> MTask v (a, b)
644 class (.||.) infixr 3 v :: (MTask v a) (MTask v a) -> MTask v a
645 \end{lstClean}
646
647 \Cref{lst:mtask_parallel_example} gives an example of the parallel task combinator.
648 This program will read two pins at the same time, returning when one of the pins becomes \arduinoinline{HIGH}.
649 If the combinator was the \cleaninline{.&&.} instead, the type would be \cleaninline{MTask v (Bool, Bool)} and the task would only return when both pins have been \arduinoinline{HIGH} but not necessarily at the same time.
650
651 \begin{lstClean}[label={lst:mtask_parallel_example},caption={Parallel task combinator example in \gls{MTASK}.}]
652 task :: MTask v Bool
653 task =
654 declarePin D0 PMInput \d0->
655 declarePin D1 PMInput \d1->
656 let monitor pin = readD pin >>*. [IfValue (\x->x) \x->rtrn x]
657 In {main = monitor d0 .||. monitor d1}
658 \end{lstClean}
659
660 \subsubsection{Repeat}\label{sec:repeat}
661 The \cleaninline{rpeat} combinator executes the child task.
662 If a stable value is observed, the task is reinstated.
663 The functionality of \cleaninline{rpeat} can also be simulated by using functions and sequential task combinators and even made to be stateful as can be seen in \cref{lst:blinkthreadmtask}.
664
665 \begin{lstClean}[label={lst:mtask_repeat},caption={Repeat task combinators in \gls{MTASK}.}]
666 class rpeat v where
667 rpeat :: (MTask v a) -> MTask v a
668 \end{lstClean}
669
670 To demonstrate the combinator, \cref{lst:mtask_repeat_example} show \cleaninline{rpeat} in use.
671 This task will mirror the value read from analog \gls{GPIO} pin \cleaninline{A1} to pin \cleaninline{A2} by constantly reading the pin and writing the result.
672
673 \begin{lstClean}[label={lst:mtask_repeat_example},caption={Exemplatory repeat task in \gls{MTASK}.}]
674 task :: MTask v Int | mtask v
675 task =
676 declarePin A1 PMInput \a1->
677 declarePin A2 PMOutput \a2->
678 {main = rpeat (readA a1 >>~. writeA a2 >>|. delay (lit 1000))}
679 \end{lstClean}
680
681 \subsection{\texorpdfstring{\Glsxtrlongpl{SDS}}{Shared data sources}}
682 \Glspl{SDS} in \gls{MTASK} are by default references to shared memory but can also be references to \glspl{SDS} in \gls{ITASK} (see \cref{sec:liftsds}).
683 Similar to peripherals (see \cref{sssec:peripherals}), they are constructed at the top level and are accessed through interaction tasks.
684 The \cleaninline{getSds} task yields the current value of the \gls{SDS} as an unstable value.
685 This behaviour is similar to the \cleaninline{watch} task in \gls{ITASK}.
686 Writing a new value to \pgls{SDS} is done using \cleaninline{setSds}.
687 This task yields the written value as a stable result after it is done writing.
688 Getting and immediately after setting \pgls{SDS} is not necessarily an \emph{atomic} operation in \gls{MTASK} because it is possible that another task accesses the \gls{SDS} in between.
689 To circumvent this issue, \cleaninline{updSds} is created, this task atomically updates the value of the \gls{SDS}.
690 The \cleaninline{updSds} task only guarantees atomicity within \gls{MTASK}.
691
692 \begin{lstClean}[label={lst:mtask_sds},caption={\Glspl{SDS} in \gls{MTASK}.}]
693 :: Sds a // abstract
694 class sds v where
695 sds :: ((v (Sds t)) -> In t (Main (MTask v u))) -> Main (MTask v u)
696 getSds :: (v (Sds t)) -> MTask v t
697 setSds :: (v (Sds t)) (v t) -> MTask v t
698 updSds :: (v (Sds t)) ((v t) -> v t) -> MTask v t
699 \end{lstClean}
700
701 \Cref{lst:mtask_sds_examples} shows an example using \glspl{SDS}.
702 The \cleaninline{count} function takes a pin and returns a task that counts the number of times the pin is observed as high by incrementing the \cleaninline{share} \gls{SDS}.
703 In the \cleaninline{main} expression, this function is called twice and the results are combined using the parallel or combinator (\cleaninline{.||.}).
704 Using a sequence of \cleaninline{getSds} and \cleaninline{setSds} would be unsafe here because the other branch might write their old increment value immediately after writing, effectively missing a count.\todo{beter opschrijven}
705
706 \begin{lstClean}[label={lst:mtask_sds_examples},caption={Examples with \glspl{SDS} in \gls{MTASK}.}]
707 task :: MTask v Int | mtask v
708 task = declarePin D3 PMInput \d3->
709 declarePin D5 PMInput \d5->
710 sds \share=0
711 In fun \count=(\pin->
712 readD pin
713 >>* [IfValue (\x->x) (\_->updSds (\x->x +. lit 1) share)]
714 >>| delay (lit 100) // debounce
715 >>| count pin)
716 In {main=count d3 .||. count d5}
717 \end{lstClean}
718
719 \chapter{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}%
720 \label{chp:integration_with_itask}
721 \begin{chapterabstract}
722 This chapter shows the integration of \gls{MTASK} with \gls{ITASK} by showing:
723 \begin{itemize}
724 \item an architectural overview of \gls{MTASK};
725 \item on the interface for connecting devices;
726 \item the interface for lifting \gls{MTASK} tasks to \gls{ITASK} tasks;
727 \item and interface for lifting \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS}.
728 \end{itemize}
729 \end{chapterabstract}
730
731 The \gls{MTASK} language is a multi-view \gls{DSL}, i.e.\ there are multiple interpretations possible for a single \gls{MTASK} term.
732 Using the byte code compiler (\cleaninline{BCInterpret}) \gls{DSL} interpretation, \gls{MTASK} tasks can be fully integrated in \gls{ITASK}.
733 They are executed as if they are regular \gls{ITASK} tasks and they communicate may access \glspl{SDS} from \gls{ITASK} as well.
734 \Gls{MTASK} devices contain a domain-specific \gls{OS} (\gls{RTS}) and are little \gls{TOP} engines in their own respect, being able to execute tasks.
735 \Cref{fig:mtask_integration} shows the architectural layout of a typical \gls{IOT} system created with \gls{ITASK} and \gls{MTASK}.
736 The entire system is written as a single \gls{CLEAN} specification where multiple tasks are executed at the same time.
737 Tasks can access \glspl{SDS} according to many-to-many communication and multiple clients can work on the same task.
738 Devices are integrated into the system using the \cleaninline{withDevice} function (see \cref{sec:withdevice}).
739 Using \cleaninline{liftmTask}, \gls{MTASK} tasks are lifted to a device (see \cref{sec:liftmtask}).
740 \Gls{ITASK} \glspl{SDS} are lifted to the \gls{MTASK} device using \cleaninline{liftsds} (see \cref{sec:liftmtask}).
741
742 \begin{figure}[ht]
743 \centering
744 \includestandalone{mtask_integration}
745 \caption{\Gls{MTASK}'s integration with \gls{ITASK}.}%
746 \label{fig:mtask_integration}
747 \end{figure}
748
749 \section{Devices}\label{sec:withdevice}
750 When interpreted by the byte code compiler view, an \gls{MTASK} task produces a compiler.
751 This compiler is exceuted at run time so that the resulting byte code can be sent to an edge device.
752 All communication with this device happens through a so-called \emph{channels} \gls{SDS}.
753 The channels contain three fields, a queue of messages that are received, a queue of messages to send and a stop flag.
754 Every communication method that implements the \cleaninline{channelSync} class can provide the communication with an \gls{MTASK} device.
755 As of now, serial port communication, direct \gls{TCP} communication and \gls{MQTT} over \gls{TCP} are supported as communication providers.
756 The \cleaninline{withDevice} function transforms a communication provider and a task that does something with this device to an \gls{ITASK} task.
757 This task sets up the communication, exchanges specifications, handles errors and cleans up after closing.
758 \Cref{lst:mtask_device} shows the types and interface to connecting devices.
759
760 \begin{lstClean}[label={lst:mtask_device},caption={Device communication interface in \gls{MTASK}.}]
761 :: MTDevice //abstract
762 :: Channels :== ([MTMessageFro], [MTMessageTo], Bool)
763
764 class channelSync a :: a (Shared sds Channels) -> Task () | RWShared sds
765
766 withDevice :: (a (MTDevice -> Task b) -> Task b) | iTask b & channelSync, iTask a
767 \end{lstClean}
768
769 \section{Lifting tasks}\label{sec:liftmtask}
770 Once the connection with the device is established, \ldots
771 \begin{lstClean}
772 liftmTask :: (Main (BCInterpret (TaskValue u))) MTDevice -> Task u | iTask u
773 \end{lstClean}
774
775 \section{Lifting \texorpdfstring{\glsxtrlongpl{SDS}}{shared data sources}}\label{sec:liftsds}
776 \begin{lstClean}[label={lst:mtask_itasksds},caption={Lifted \gls{ITASK} \glspl{SDS} in \gls{MTASK}.}]
777 class liftsds v where
778 liftsds :: ((v (Sds t)) -> In (Shared sds t) (Main (MTask v u)))
779 -> Main (MTask v u) | RWShared sds
780 \end{lstClean}
781
782 \chapter{Implementation}%
783 \label{chp:implementation}
784 \begin{chapterabstract}
785 This chapter shows the implementation of the \gls{MTASK} system.
786 It is threefold: first it shows the implementation of the byte code compiler for \gls{MTASK}'s \gls{TOP} language, then is details of the implementation of \gls{MTASK}'s \gls{TOP} engine that executes the \gls{MTASK} tasks on the microcontroller, and finally it shows how the integration of \gls{MTASK} tasks and \glspl{SDS} is implemented both on the server and on the device.
787 \end{chapterabstract}
788 IFL19 paper, bytecode instructieset~\cref{chp:bytecode_instruction_set}
789
790 \section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
791 IFL18 paper stukken
792
793 \subfile{green}
794
795 \input{subfilepostamble}
796 \end{document}