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