change citations to citep
[phd-thesis.git] / mtask / mtask.tex
1 \documentclass[../thesis.tex]{subfiles}
2
3 \begin{document}
4 \ifSubfilesClassLoaded{
5 \pagenumbering{arabic}
6 }{}
7
8 \mychapter{chp:top4iot}{Introduction to \texorpdfstring{\gls{IOT}}{IoT} programming}
9 \todo{betere chapter naam}
10 \begin{chapterabstract}
11 This chapter introduces \gls{MTASK} and puts it into perspective compared to traditional microprocessor programming.
12 \end{chapterabstract}
13
14 Traditionally, the first program that one writes when trying a new language is the so called \emph{Hello World!} program.
15 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.
16 On microprocessors, there often is no screen for displaying text.
17 Nevertheless, almost always there is a monochrome $1\times1$ pixel screen, namely an---often builtin---\gls{LED}.
18 The \emph{Hello World!} equivalent on microprocessors blinks this \gls{LED}.
19
20 \Cref{lst:arduinoBlink} shows how the logic of a blink program might look when using \gls{ARDUINO}'s \gls{CPP} dialect.
21 Every \gls{ARDUINO} program contains a \arduinoinline{setup} and a \arduinoinline{loop} function.
22 The \arduinoinline{setup} function is executed only once on boot, the \arduinoinline{loop} function is continuously called afterwards and contains the event loop.
23 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.
24 In between it waits for 500 milliseconds so that the blinking is actually visible for the human eye.
25 Compiling this results in a binary firmware that needs to be flashed onto the program memory.
26
27 Translating the traditional blink program to \gls{MTASK} can almost be done by simply substituting some syntax as seen in \cref{lst:blinkImp}.
28 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.
29 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.
30 To simulate a loop, the \cleaninline{rpeat} task can be used, this task executes the argument task and, when stable, reinstates it.
31 The body of the \cleaninline{rpeat} contains similarly named tasks to write to the pins and to wait in between.
32 The tasks are connected using the sequential \cleaninline{>>|.} combinator that for all current intents and purposes executes the tasks after each other.
33
34 \begin{figure}[ht]
35 \begin{subfigure}[b]{.5\linewidth}
36 \begin{lstArduino}[caption={Blink program.},label={lst:arduinoBlink}]
37 void setup() {
38 pinMode(D2, OUTPUT);
39 }
40
41 void loop() {
42 digitalWrite(D2, HIGH);
43 delay(500);
44 digitalWrite(D2, LOW);
45 delay(500);
46 }\end{lstArduino}
47 \end{subfigure}%
48 \begin{subfigure}[b]{.5\linewidth}
49 \begin{lstClean}[caption={Blink program.},label={lst:blinkImp}]
50 blink :: Main (MTask v ()) | mtask v
51 blink =
52 declarePin D2 PMOutput \d2->
53 {main = rpeat (
54 writeD d2 true
55 >>|. delay (lit 500)
56 >>|. writeD d2 false
57 >>|. delay (lit 500)
58 )}\end{lstClean}
59 \end{subfigure}
60 \end{figure}
61
62 \section{Threaded blinking}
63 Now say that we want to blink multiple blinking patterns on different \glspl{LED} concurrently.
64 For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of $500,300$ and $800$ milliseconds.
65 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}
66
67 \begin{lstArduino}[caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}]
68 void setup () { ... }
69
70 void blink (int pin, int wait) {
71 digitalWrite(pin, HIGH);
72 delay(wait);
73 digitalWrite(pin, LOW);
74 delay(wait);
75 }
76
77 void loop() {
78 blink (D1, 500);
79 blink (D2, 300);
80 blink (D3, 800);
81 }\end{lstArduino}
82
83 Unfortunately, this does not work because the \arduinoinline{delay} function blocks all further execution.
84 The resulting program will blink the \glspl{LED} after each other instead of at the same time.
85 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}.
86 Listing~\ref{lst:blinkthread} shows how three different blinking patterns might be achieved in \gls{ARDUINO} using the slicing method.
87 If we want the blink function to be a separate parametrizable function we need to explicitly provide all references to the required state.
88 Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
89 The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microprocessor.
90 Some devices use very little energy when in \arduinoinline{delay} or sleep state.
91 Resulting in \arduinoinline{millis} potentially affects power consumption since the processor is basically busy looping all the time.
92 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.
93 Unfortunately, this is very hard when for example the blinking patterns are determined at runtime.
94
95 \begin{lstArduino}[label={lst:blinkthread},caption={Threading three blinking patterns.}]
96 long led1 = 0, led2 = 0, led3 = 0;
97 bool st1 = false, st2 = false, st3 = false;
98
99 void blink(int pin, int delay, long *lastrun, bool *st) {
100 if (millis() - *lastrun > delay) {
101 digitalWrite(pin, *st = !*st);
102 *lastrun += delay;
103 }
104 }
105
106 void loop() {
107 blink(D1, 500, &led1, &st1);
108 blink(D2, 300, &led2, &st1);
109 blink(D3, 800, &led3, &st1);
110 }\end{lstArduino}
111
112 This method is very error prone, requires a lot of pointer juggling and generally results into spaghetti code.
113 Furthermore, it is very difficult to represent dependencies between threads, often state machines have to be explicitly programmed by hand to achieve this.
114
115 \section{Blinking in \texorpdfstring{\gls{MTASK}}{mTask}}
116 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.
117 In contrast, the \cleaninline{delay} \emph{function} on the \gls{ARDUINO} is blocking which prohibits interleaving.
118 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.
119 The function is parametrized with the current state, the pin to blink and the waiting time.
120 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.
121 With a parallel combinator, tasks can be executed in an interleaved fashion.
122 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}.
123
124 \begin{lstClean}[label={lst:blinkthreadmtask},caption={Threaded blinking.}]
125 blinktask :: MTask v () | mtask v
126 blinktask =
127 declarePin D1 PMOutput \d1->
128 declarePin D2 PMOutput \d2->
129 declarePin D3 PMOutput \d3->
130 fun \blink=(\(st, pin, wait)->
131 delay wait
132 >>|. writeD d13 st
133 >>|. blink (Not st, pin, wait)) In
134 {main = blink (true, d1, lit 500)
135 .||. blink (true, d2, lit 300)
136 .||. blink (true, d3, lit 800)
137 }\end{lstClean}
138
139 \mychapter{chp:mtask_dsl}{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\gls{DSL}}{DSL}}
140 \begin{chapterabstract}
141 This chapter serves as a complete guide to the \gls{MTASK} language, from an \gls{MTASK} programmer's perspective.
142 \end{chapterabstract}
143
144 The \gls{MTASK} system is a \gls{TOP} programming environment for programming microprocessors.
145 It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (See \cref{ssec:tagless}).
146 Due to the nature of the embedding technique, it is possible to have multiple interpretations of---or views on---programs written in the \gls{MTASK} language.
147 The following interpretations are available for \gls{MTASK}.
148
149 \begin{itemize}
150 \item Pretty printer
151
152 This interpretation converts the expression to a string representation.
153 \item Simulator
154
155 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.
156 \item Compiler
157
158 The compiler compiles the \gls{MTASK} program at runtime to a specialised bytecode.
159 Using a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microprocessors and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks.
160 Furthermore, with special language constructs, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs.
161 \end{itemize}
162
163 When using the compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
164 I.e.\ some components---e.g.\ the \gls{RTS} on the microprocessor---is largely unaware of the other components in the system.
165 Furthermore, it is executed on a completely different architecture.
166 The \gls{MTASK} language consists of a host language---a simply-typed $\lambda$-calculua with support for some basic types, function definition and data types (see \cref{sec:expressions})---enriched with a task language (see \cref{sec:top}).
167
168 \section{Types}
169 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.
170 However, not all types in the host language are suitable for microprocessors that may only have \qty{2}{\kibi\byte} of \gls{RAM} so class constraints are therefore added to the \gls{DSL} functions.
171 The most used class constraint is the \cleaninline{type} class collection containing functions for serialization, printing, \gls{ITASK} constraints etc.
172 Many of these functions can be derived using generic programming.
173 An even stronger restriction on types is defined for types that have a stack representation.
174 This \cleaninline{basicType} class has instances for many \gls{CLEAN} basic types such as \cleaninline{Int}, \cleaninline{Real} and \cleaninline{Bool}.
175 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.
176
177 \begin{table}[ht]
178 \centering
179 \begin{tabular}{lll}
180 \toprule
181 \gls{CLEAN}/\gls{MTASK} & \gls{CPP} type & \textnumero{}bits\\
182 \midrule
183 \cleaninline{Bool} & \cinline{bool} & 16\\
184 \cleaninline{Char} & \cinline{char} & 16\\
185 \cleaninline{Int} & \cinline{int16_t} & 16\\
186 \cleaninline{:: Long} & \cinline{int32_t} & 32\\
187 \cleaninline{Real} & \cinline{float} & 32\\
188 \cleaninline{:: T = A \| B \| C} & \cinline{enum} & 16\\
189 \bottomrule
190 \end{tabular}
191 \caption{Mapping from \gls{CLEAN}/\gls{MTASK} data types to \gls{CPP} datatypes.}%
192 \label{tbl:mtask-c-datatypes}
193 \end{table}
194
195 The \gls{MTASK} language consists of a core collection of type classes bundled in the type class \cleaninline{class mtask}.
196 Every interpretation implements the type classes in the \cleaninline{mtask} class
197 There are also \gls{MTASK} extensions that not every interpretation implements such as peripherals and integration with \gls{ITASK}.
198
199 \Cref{lst:constraints} contains the definitions for the type constraints and shows some example type signatures for typical \gls{MTASK} expressions and tasks.
200 \todo{uitleggen}
201
202 \begin{lstClean}[caption={Classes and class collections for the \gls{MTASK} language.},label={lst:constraints}]
203 :: Main a = { main :: a }
204 :: In a b = (In) infix 0 a b
205
206 class type t | iTask, ... ,fromByteCode, toByteCode t
207 class basicType t | type t where ...
208
209 class mtask v | expr, ..., int, real, long v
210
211 someExpr :: v Int | mtask v
212 someExpr = ...
213
214 someTask :: MTask v Int | mtask v
215 someTask =
216 sensor1 config1 \sns1->
217 sensor2 config2 \sns2->
218 fun \fun1= ( ... )
219 In fun \fun2= ( ... )
220 In {main=mainexpr}
221 \end{lstClean}
222
223 \section{Expressions}\label{sec:expressions}
224 \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.
225 For every common 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.
226
227 \begin{lstClean}[caption={The \gls{MTASK} class for expressions},label={lst:expressions}]
228 class expr v where
229 lit :: t -> v t | type t
230 (+.) infixl 6 :: (v t) (v t) -> v t | basicType, +, zero t
231 ...
232 (&.) infixr 3 :: (v Bool) (v Bool) -> v Bool
233 (|.) infixr 2 :: (v Bool) (v Bool) -> v Bool
234 Not :: (v Bool) -> v Bool
235 (==.) infix 4 :: (v a) (v a) -> v Bool | Eq, basicType a
236 ...
237 If :: (v Bool) (v t) (v t) -> v t | type t
238 \end{lstClean}
239
240 Conversion to-and-fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real}.
241
242 \begin{lstClean}[caption={Type conversion functions in \gls{MTASK}.}]
243 class int v a :: (v a) -> v Int
244 class real v a :: (v a) -> v Real
245 class long v a :: (v a) -> v Long
246 \end{lstClean}
247
248 Finally, values from the host language must be explicitly lifted to the \gls{MTASK} language using the \cleaninline{lit} function.
249 For convenience, there are many lower-cased macro definitions for often used constants such as \cleaninline{true :== lit True}, \cleaninline{false :== lit False}, \etc.
250
251 \Cref{lst:example_exprs} shows some examples of these expressions.
252 \cleaninline{e0} defines the literal $42$, \cleaninline{e1} calculates the literal $42.0$ using real numbers.
253 \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.
254 \cleaninline{approxEqual} performs an approximate equality---albeit not taking into account all floating point pecularities---and demonstrates that \gls{CLEAN} can be used as a macro language.
255 When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
256
257 \begin{lstClean}[label={lst:example_exprs},caption={Example \gls{MTASK} expressions.}]
258 e0 :: v Int | expr v
259 e0 = lit 42
260
261 e1 :: v Real | expr v
262 e1 = lit 38.0 + real (lit 4)
263
264 e2 :: v Int | expr v
265 e2 = if' (e0 ==. int e1)
266 (int e1 /. lit 2) e0
267
268 approxEqual :: (v Real) (v Real) (v Real) -> v Real | expr v
269 approxEqual x y eps = if' (x == y) true
270 ( if' (x > y)
271 (y -. x < eps)
272 (x -. y < eps)
273 )
274 \end{lstClean}
275 %jona
276 %jaunda
277
278 \subsection{Data Types}
279 Most of \gls{CLEAN}'s basic types have been mapped on \gls{MTASK} types.
280 However, it can be useful to have access to compound types as well.
281 All types in \gls{MTASK} must have a fixed size representation on the stack so sum types are not (yet) supported.
282 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}).
283 To be able to use types as first class citizens, constructors and field selectors are required.
284 \Cref{lst:tuple_exprs} shows the scaffolding for supporting tuples in \gls{MTASK}.
285 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.
286
287 \begin{lstClean}[label={lst:tuple_exprs},caption={Tuple constructor and field selectors in \gls{MTASK}.}]
288 class tupl v where
289 tupl :: (v a) (v b) -> v (a, b) | type a & type b
290 first :: (v (a, b)) -> v a | type a & type b
291 second :: (v (a, b)) -> v b | type a & type b
292
293 tupopen f :== \v->f (first v, second v)
294 \end{lstClean}
295
296 \subsection{Functions}
297 Adding functions to the language is achieved by one multi-parameter class to the \gls{DSL}.
298 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}.
299 As \gls{MTASK} only supports first-order functions and does not allow partial function application.
300 Using a type class of this form, this restriction can be enforced on the type level.
301 Instead of providing one instance for all functions, a single instance per function arity is defined.
302 Also, \gls{MTASK} only supports top-level functions which is enforced by the \cleaninline{Main} box.
303 The definition of the type class and the instances for an example interpretation are as follows:
304 \todo{uitbreiden}
305
306 \begin{lstClean}[caption={Functions in \gls{MTASK}.}]
307 class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
308 -> Main (MTask v u)
309
310 instance fun () Inter where ...
311 instance fun (Inter a) Inter | type a where ...
312 instance fun (Inter a, Inter b) Inter | type a where ...
313 instance fun (Inter a, Inter b, Inter c) Inter | type a where ...
314 ...
315 \end{lstClean}
316
317 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}.
318 \Cref{lst:function_examples} show the factorial function, a tail-call optimised factorial function and a function with zero arguments to demonstrate the syntax.
319 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.
320 Many of the often used functions are already bundled in the \cleaninline{mtask} class constraint collection.
321 \cleaninline{factorialtail} shows a manually added class constraint.
322 Definiting zero arity functions is shown in the \cleaninline{zeroarity} expression.
323 Finally, \cleaninline{swapTuple} shows an example of a tuple being swapped.
324
325 \begin{lstClean}[label={lst:function_examples},caption={Function examples in \gls{MTASK}.}]
326 factorial :: Main (v Int) | mtask v
327 factorial =
328 fun \fac=(\i->if' (i <. lit 1)
329 (lit 1)
330 (i *. fac (i -. lit 1)))
331 In {main = fac (lit 5) }
332
333 factorialtail :: Main (v Int) | mtask v & fun (v Int, v Int) v
334 factorialtail =
335 fun \facacc=(\(acc, i)->if' (i <. lit 1)
336 acc
337 (fac (acc *. i, i -. lit 1)))
338 In fun \fac=(\i->facacc (lit 1, i))
339 In {main = fac (lit 5) }
340
341 zeroarity :: Main (v Int) | mtask v
342 zeroarity =
343 fun \fourtytwo=(\()->lit 42)
344 In fun \add=(\(x, y)->x +. y)
345 In {main = add (fourtytwo (), lit 9)}
346
347 swapTuple :: Main (v (Int, Bool)) | mtask v
348 swapTuple =
349 fun \swap=(tupopen \(x, y)->tupl y x)
350 In {main = swap (tupl true (lit 42)) }
351 \end{lstClean}
352
353 \section{Tasks}\label{sec:top}
354 \Gls{MTASK}'s task language can be divided into three categories, namely
355 \begin{enumerate*}
356 \item Basic tasks, in most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
357 In \gls{MTASK}, there are no \emph{editors} in that sense but there is interaction with the outside world through microprocessor peripherals such as sensors and actuators.
358 \item Task combinators provide a way of describing the workflow.
359 They combine one or more tasks into a compound task.
360 \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.
361 \end{enumerate*}
362
363 As \gls{MTASK} is integrated with \gls{ITASK}, the same stability distinction is made for task values.
364
365 \subsection{Basic tasks}
366 The most rudimentary basic tasks are the \cleaninline{rtrn} and \cleaninline{unstable} tasks.
367 They lift the value from the \gls{MTASK} expression language to the task domain either as a stable value or an unstable value.
368
369 \begin{lstClean}[label={lst:basic_tasks},caption={Function examples in \gls{MTASK}.}]
370 class rtrn v :: (v t) -> MTask v t | type t
371 class unstable v :: (v t) -> MTask v t | type t
372 \end{lstClean}
373
374 \todo{examples}
375
376 \subsubsection{Peripherals}
377 For every sensor or actuator, basic tasks are available that allow interaction with the specific peripheral.
378 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.
379 \todo{Historically, peripheral support has been added \emph{by need}.}
380
381 \Cref{lst:dht} and \cref{lst:gpio} show the type classes for \glspl{DHT} sensors and \gls{GPIO} access.
382 Other peripherals have similar interfaces, they are available in the \cref{sec:aux_peripherals}.
383 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.
384 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.
385 Creating such a \cleaninline{DHT} object is very similar to creating functions in \gls{MTASK} and uses \gls{HOAS} to make it type safe.
386
387 \begin{lstClean}[label={lst:dht},caption{The \gls{MTASK} interface for \glspl{DHT} sensors.}]
388 :: DHT //abstract
389 :: DHTInfo
390 = DHT_DHT Pin DHTtype
391 | DHT_SHT I2CAddr
392 :: DHTtype = DHT11 | DHT21 | DHT22
393 class dht v where
394 DHT :: DHTInfo ((v DHT) -> Main (v b)) -> Main (v b) | type b
395 temperature :: (v DHT) -> MTask v Real
396 humidity :: (v DHT) -> MTask v Real
397
398 measureTemp :: Main (MTask v Real) | mtask v & dht v
399 measureTemp = DHT (DHT_SHT (i2c 0x36)) \dht->
400 {main=temperature dht}
401 \end{lstClean}
402
403 \Gls{GPIO} access is divided into three classes: analog, digital and pin modes.
404 For all pins and pin modes an \gls{ADT} is available that enumerates the pins.
405 The analog \gls{GPIO} pins of a microprocessor are connected to an \gls{ADC} that translates the voltage to an integer.
406 Analog \gls{GPIO} pins can be either read or written to.
407 Digital \gls{GPIO} pins only report a high or a low value.
408 The type class definition is a bit more complex since analog \gls{GPIO} pins can be used as digital \gls{GPIO} pins as well.
409 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.
410 \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.
411 This setting can be applied using the \cleaninline{pinMode} class by hand or by using the \cleaninline{declarePin} \gls{GPIO} pin constructor.
412 Setting the pin mode is a task that immediately finisheds and fields a stable unit value.
413 Writing to a pin is also a task that immediately finishes but yields the written value instead.
414 Reading a pin is a task that yields an unstable value---i.e.\ the value read from the actual pin.
415
416 \begin{lstClean}[label={lst:gpio},caption{The \gls{MTASK} interface for \gls{GPIO} access.}]
417 :: APin = A0 | A1 | A2 | A3 | A4 | A5
418 :: DPin = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | D11 | D12 | D13
419 :: PinMode = PMInput | PMOutput | PMInputPullup
420 :: Pin = AnalogPin APin | DigitalPin DPin
421 class pin p :: p -> Pin
422
423 class aio v where
424 writeA :: (v APin) (v Int) -> MTask v Int
425 readA :: (v APin) -> MTask v Int
426
427 class dio p v | pin p where
428 writeD :: (v p) (v Bool) -> MTask v Bool
429 readD :: (v p) -> MTask v Bool | pin p
430
431 class pinMode v where
432 pinMode :: (v PinMode) (v p) -> MTask v () | pin, type p
433 declarePin :: p PinMode ((v p) -> Main (v a)) -> Main (v a) | pin p & type a
434 \end{lstClean}
435 \todo{onder Task Combinators verplaatsen zodat de voorbeeldjes leuker kunnen zijn?}
436
437 \subsection{Task combinators}
438 \subsubsection{Parallel}\label{sssec:combinators_parallel}
439 \begin{lstClean}[label={lst:mtask_parallel},caption{Parallel task combinators in \gls{MTASK}.}]
440 class (.&&.) infixr 4 v :: (MTask v a) (MTask v b) -> MTask v (a, b) | type a & type b
441 class (.||.) infixr 3 v :: (MTask v a) (MTask v a) -> MTask v a | type a
442 \end{lstClean}
443
444 \subsubsection{Sequential}
445 \begin{lstClean}[label={lst:mtask_sequential},caption{Sequential task combinators in \gls{MTASK}.}]
446 class step v | expr v where
447 (>>*.) infixl 1 :: (MTask v t) [Step v t u] -> MTask v u | type u & type t
448 (>>=.) infixl 0 :: (MTask v t) ((v t) -> MTask v u) -> MTask v u | expr v & type u & type t
449 (>>|.) infixl 0 :: (MTask v t) (MTask v u) -> MTask v u | expr v & type u & type t
450 (>>|.) ma mb = ma >>*. [IfStable (\_->lit True) \_->mb]
451 (>>~.) infixl 0 :: (MTask v t) ((v t) -> MTask v u) -> MTask v u | expr v & type u & type t
452 (>>~.) ma amb = ma >>*. [IfValue (\_->lit True) amb]
453 (>>..) infixl 0 :: (MTask v t) (MTask v u) -> MTask v u | expr v & type u & type t
454 (>>..) ma mb = ma >>*. [IfValue (\_->lit True) \_->mb]
455
456 :: Step v t u
457 = IfValue ((v t) -> v Bool) ((v t) -> MTask v u)
458 | IfStable ((v t) -> v Bool) ((v t) -> MTask v u)
459 | IfUnstable ((v t) -> v Bool) ((v t) -> MTask v u)
460 | Always (MTask v u)
461 \end{lstClean}
462
463 \subsubsection{Miscellaneous}
464 \begin{lstClean}[label={lst:mtask_misc},caption{Miscellaneous task combinators in \gls{MTASK}.}]
465 class rpeat v where
466 /**
467 * Executes the task until it yields a stable value, after which it is restarted.
468 *
469 * @param task
470 * @param the transformed task
471 */
472 rpeat :: (MTask v a) -> MTask v a | type a
473 rpeat t :== rpeatEvery Default t
474 /**
475 * Executes the task until it yields a stable value, after which it is restarted at most once every given timing interval.
476 *
477 * @param restarting interval
478 * @param task
479 * @param the transformed task
480 */
481 rpeatEvery :: (TimingInterval v) (MTask v a) -> MTask v a | type a
482
483 /**
484 * The basic task that waits for a specified amount of time
485 *
486 * @var view
487 * @param number of milliseconds to wait
488 * @result task that yields
489 * - when the time has passed: a stable value with the number of milliseconds it overshot the waiting time
490 * - when the time has not passed: an unstable value with the number of milliseconds it still needs to wait
491 */
492 class delay v :: (v n) -> MTask v Long | type n & long v n
493 \end{lstClean}
494
495 \subsection{\texorpdfstring{\Acrlongpl{SDS}}{Shared data sources}}
496
497 \mychapter{chp:green_computing_mtask}{Green computing with \texorpdfstring{\gls{MTASK}}{mTask}}
498
499 \mychapter{chp:integration_with_itask}{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
500 \section{Devices}
501 \section{Lifting tasks}
502 \section{Lifting \texorpdfstring{\acrlongpl{SDS}}{shared data sources}}
503
504 \mychapter{chp:implementation}{Implementation}
505 IFL19 paper, bytecode instructieset~\cref{chp:bytecode_instruction_set}
506
507 \section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
508 IFL18 paper stukken
509
510 \chapter{\texorpdfstring{\gls{MTASK}}{mTask} history}
511 \section{Generating \texorpdfstring{\gls{C}/\gls{CPP}}{C/C++} code}
512 A first throw at a class-based shallowly \gls{EDSL} for microprocessors was made by Pieter Koopman and Rinus Plasmijer in 2016~\citep{plasmeijer_shallow_2016}.
513 The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
514 A \gls{CPP} code generation backend was available together with an \gls{ITASK} simulation backend.
515 There was no support for tasks or even functions.
516 Some time later in the 2015 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}.
517 The name then changed from \gls{ARDSL} to \gls{MTASK}.
518
519 \section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
520 Mart Lubbers extended this in his Master's Thesis by adding integration with \gls{ITASK} and a bytecode compiler to the language~\citep{lubbers_task_2017}.
521 \Gls{SDS} in \gls{MTASK} could be accessed on the \gls{ITASK} server.
522 In this way, entire \gls{IOT} systems could be programmed from a single source.
523 However, this version used a simplified version of \gls{MTASK} without functions.
524 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}.
525 It was shown by Matheus Amazonas Cabral de Andrade that it was possible to build real-life \gls{IOT} systems with this integration~\citep{amazonas_cabral_de_andrade_developing_2018}.
526 Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 CEFP/3COWS winter school in Ko\v{s}ice, Slovakia~\citep{koopman_simulation_2018}.
527
528 \section{Transition to \texorpdfstring{\gls{TOP}}{TOP}}
529 The \gls{MTASK} language as it is now was introduced in 2018~\citep{koopman_task-based_2018}.
530 This paper updated the language to support functions, tasks and \glspl{SDS} but still compiled to \gls{CPP} \gls{ARDUINO} code.
531 Later the bytecode compiler and \gls{ITASK} integration was added to the language~\citep{lubbers_interpreting_2019}.
532 Moreover, it was shown that it is very intuitive to write \gls{MCU} applications in a \gls{TOP} language~\citep{lubbers_multitasking_2019}.
533 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).
534 In 2019, the CEFP summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well~\citep{lubbers_writing_2019}.
535
536 \section{\texorpdfstring{\gls{TOP}}{TOP}}
537 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).
538 Several students worked on extending \gls{MTASK} with many useful features:
539 Erin van der Veen did preliminary work on a green computer analysis, built a simulator and explored the possibilities for adding bounded datatypes~\citep{veen_van_der_mutable_2020}; Michel de Boer investigated the possibilities for secure communication channels~\citep{boer_de_secure_2020}; and Sjoerd Crooijmans added abstractions for low-power operation to \gls{MTASK} such as hardware interrupts and power efficient scheduling~\citep{crooijmans_reducing_2021}.
540 Elina Antonova defined a preliminary formal semantics for a subset of \gls{MTASK}~\citep{antonova_MTASK_2022}.
541 Moreover, plans for student projects and improvements include exploring integrating \gls{TINYML} into \gls{MTASK}; and adding intermittent computing support to \gls{MTASK}.
542
543 In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course on \gls{MTASK} as well.
544
545 \section{\texorpdfstring{\gls{MTASK}}{mTask} in practise}
546 Funded by the Radboud-Glasgow Collaboration Fund, collaborative work was executed with Phil Trinder, Jeremy Singer and Adrian Ravi Kishore Ramsingh.
547 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}.
548 The collaboration is still ongoing and a journal article is under review comparing four approaches for the edge layer: \gls{PYTHON}, \gls{MICROPYTHON}, \gls{ITASK} and \gls{MTASK}.
549 Furthermore, 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
550
551 \input{subfilepostamble}
552 \end{document}