1 \documentclass[../thesis.tex
]{subfiles
}
4 \ifSubfilesClassLoaded{
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.
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
}.
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.
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.
35 \begin{subfigure
}[b
]{.5\linewidth}
36 \begin{lstArduino
}[caption=
{Blink program.
},label=
{lst:arduinoBlink
}]
42 digitalWrite(D2, HIGH);
44 digitalWrite(D2, LOW);
48 \begin{subfigure
}[b
]{.5\linewidth}
49 \begin{lstClean
}[caption=
{Blink program.
},label=
{lst:blinkImp
}]
50 blink :: Main (MTask v ()) | mtask v
52 declarePin D2 PMOutput
\d2->
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
}
67 \begin{lstArduino
}[caption=
{Naive approach to multiple blinking patterns.
},label=
{lst:blinkthreadno
}]
70 void blink (int pin, int wait)
{
71 digitalWrite(pin, HIGH);
73 digitalWrite(pin, LOW);
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.
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;
99 void blink(int pin, int delay, long *lastrun, bool *st)
{
100 if (millis() - *lastrun > delay)
{
101 digitalWrite(pin, *st = !*st);
107 blink(D1,
500, &led1, &st1);
108 blink(D2,
300, &led2, &st1);
109 blink(D3,
800, &led3, &st1);
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.
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
}.
124 \begin{lstClean
}[label=
{lst:blinkthreadmtask
},caption=
{Threaded blinking.
}]
125 blinktask :: MTask v () | mtask v
127 declarePin D1 PMOutput
\d1->
128 declarePin D2 PMOutput
\d2->
129 declarePin D3 PMOutput
\d3->
130 fun
\blink=(\(st, pin, wait)->
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)
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
}
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
}.
152 This interpretation converts the expression to a string representation.
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.
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.
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
}).
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.
181 \gls{CLEAN
}/
\gls{MTASK
} &
\gls{CPP
} type &
\textnumero{}bits\\
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\\
191 \caption{Mapping from
\gls{CLEAN
}/
\gls{MTASK
} data types to
\gls{CPP
} datatypes.
}%
192 \label{tbl:mtask-c-datatypes
}
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
}.
199 \Cref{lst:constraints
} contains the definitions for the type constraints and shows some example type signatures for typical
\gls{MTASK
} expressions and tasks.
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
206 class type t | iTask, ... ,fromByteCode, toByteCode t
207 class basicType t | type t where ...
209 class mtask v | expr, ..., int, real, long v
211 someExpr :: v Int | mtask v
214 someTask :: MTask v Int | mtask v
216 sensor1 config1
\sns1->
217 sensor2 config2
\sns2->
219 In fun
\fun2= ( ... )
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.
227 \begin{lstClean
}[caption=
{The
\gls{MTASK
} class for expressions
},label=
{lst:expressions
}]
229 lit :: t -> v t | type t
230 (+.) infixl
6 :: (v t) (v t) -> v t | basicType, +, zero t
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
237 If :: (v Bool) (v t) (v t) -> v t | type t
240 Conversion to-and-fro data types is available through the overloaded functions
\cleaninline{int
},
\cleaninline{long
} and
\cleaninline{real
}.
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
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.
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.
257 \begin{lstClean
}[label=
{lst:example_exprs
},caption=
{Example
\gls{MTASK
} expressions.
}]
261 e1 :: v Real | expr v
262 e1 = lit
38.0 + real (lit
4)
265 e2 = if' (e0 ==. int e1)
268 approxEqual :: (v Real) (v Real) (v Real) -> v Real | expr v
269 approxEqual x y eps = if' (x == y) true
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.
287 \begin{lstClean
}[label=
{lst:tuple_exprs
},caption=
{Tuple constructor and field selectors in
\gls{MTASK
}.
}]
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
293 tupopen f :==
\v->f (first v, second v)
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:
306 \begin{lstClean
}[caption=
{Functions in
\gls{MTASK
}.
}]
307 class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
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 ...
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.
325 \begin{lstClean
}[label=
{lst:function_examples
},caption=
{Function examples in
\gls{MTASK
}.
}]
326 factorial :: Main (v Int) | mtask v
328 fun
\fac=(
\i->if' (i <. lit
1)
330 (i *. fac (i -. lit
1)))
331 In
{main = fac (lit
5)
}
333 factorialtail :: Main (v Int) | mtask v & fun (v Int, v Int) v
335 fun
\facacc=(\(acc, i)->if' (i <. lit
1)
337 (fac (acc *. i, i -. lit
1)))
338 In fun
\fac=(
\i->facacc (lit
1, i))
339 In
{main = fac (lit
5)
}
341 zeroarity :: Main (v Int) | mtask v
343 fun
\fourtytwo=(\()->lit
42)
344 In fun
\add=(\(x, y)->x +. y)
345 In
{main = add (fourtytwo (), lit
9)
}
347 swapTuple :: Main (v (Int, Bool)) | mtask v
349 fun
\swap=(tupopen \(x, y)->tupl y x)
350 In
{main = swap (tupl true (lit
42))
}
353 \section{Tasks
}\label{sec:top
}
354 \Gls{MTASK
}'s task language can be divided into three categories, namely
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.
363 As
\gls{MTASK
} is integrated with
\gls{ITASK
}, the same stability distinction is made for task values.
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.
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
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
}.
}
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.
387 \begin{lstClean
}[label=
{lst:dht
},caption
{The
\gls{MTASK
} interface for
\glspl{DHT
} sensors.
}]
390 = DHT_DHT Pin DHTtype
392 :: DHTtype = DHT11 | DHT21 | DHT22
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
398 measureTemp :: Main (MTask v Real) | mtask v & dht v
399 measureTemp = DHT (DHT_SHT (i2c
0x36))
\dht->
400 {main=temperature dht
}
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.
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
424 writeA :: (v APin) (v Int) -> MTask v Int
425 readA :: (v APin) -> MTask v Int
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
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
435 \todo{onder Task Combinators verplaatsen zodat de voorbeeldjes leuker kunnen zijn?
}
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
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
]
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)
463 \subsubsection{Miscellaneous
}
464 \begin{lstClean
}[label=
{lst:mtask_misc
},caption
{Miscellaneous task combinators in
\gls{MTASK
}.
}]
467 * Executes the task until it yields a stable value, after which it is restarted.
470 * @param the transformed task
472 rpeat :: (MTask v a) -> MTask v a | type a
473 rpeat t :== rpeatEvery Default t
475 * Executes the task until it yields a stable value, after which it is restarted at most once every given timing interval.
477 * @param restarting interval
479 * @param the transformed task
481 rpeatEvery :: (TimingInterval v) (MTask v a) -> MTask v a | type a
484 * The basic task that waits for a specified amount of time
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
492 class delay v :: (v n) -> MTask v Long | type n & long v n
495 \subsection{\texorpdfstring{\Acrlongpl{SDS
}}{Shared data sources
}}
497 \mychapter{chp:green_computing_mtask
}{Green computing with
\texorpdfstring{\gls{MTASK
}}{mTask
}}
499 \mychapter{chp:integration_with_itask
}{Integration with
\texorpdfstring{\gls{ITASK
}}{iTask
}}
501 \section{Lifting tasks
}
502 \section{Lifting
\texorpdfstring{\acrlongpl{SDS
}}{shared data sources
}}
504 \mychapter{chp:implementation
}{Implementation
}
505 IFL19 paper, bytecode instructieset~
\cref{chp:bytecode_instruction_set
}
507 \section{Integration with
\texorpdfstring{\gls{ITASK
}}{iTask
}}
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
}.
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
}.
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
}.
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
}.
543 In
2023, the SusTrainable summer school in Coimbra, Portugal will host a course on
\gls{MTASK
} as well.
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
551 \input{subfilepostamble
}