+\documentclass[../thesis.tex]{subfiles}
+
+\input{subfilepreamble}
+
+\begin{document}
+\input{subfileprefix}
+
+\chapter{Green computing with \texorpdfstring{\gls{MTASK}}{mTask}}%
+\label{chp:green_computing_mtask}
+\begin{chapterabstract}
+ This chapter demonstrate the energy saving features of \gls{MTASK}.
+ First it gives an overview of general green computing measures for edge devices.
+ Then \gls{MTASK}'s task scheduling is explained and it is shown how to customise it so suit the applications and energy needs.
+ Finally it shows how to use interrupts in \gls{MTASK} to reduce the need for polling.
+\end{chapterabstract}
+
+The edge layer of the \gls{IOT} contains small devices that sense and interact with the world and it is crucial to lower their energy consumption.
+While individual devices consume little energy, the sheer number of devices in total amounts to a lot.
+Furthermore, many \gls{IOT} devices operate on batteries and higher energy consumption increases the amount of e-waste as \gls{IOT} edge devices are often hard to reach and consequently hard to replace \citep{NIZETIC2020122877}.
+
+To reduce the power consumption of an \gls{IOT} device, the specialized low-power sleep modes of the microprocessors can be leveraged.
+Different sleep modes achieve different power reductions because of their different run time characteristics.
+These specifics range from disabling or suspending WiFi; stopping powering (parts) of the \gls{RAM}; disabling peripherals; or even turning off the processor completely, requiring an external signal to wake up again.
+Determining when exactly and for how long it is possible to sleep is expensive in the general case and often requires annotations in the source code, a real-time operating system or a handcrafted scheduler.
+
+\begin{table}
+ \centering
+ \small
+ \begin{tabular}{ccccccccc}
+ \toprule
+ & \multicolumn{4}{c}{Wemos D1 mini} & \multicolumn{4}{c}{Adafruit Feather M0 Wifi} \\
+ \midrule
+ & active & modem & light & deep & active & modem & light & deep \\
+ & & sleep & sleep & sleep & & sleep & sleep & sleep \\
+ \midrule
+ WiFi & on & off & off & off & on & off & off & off \\
+ CPU & on & on & pending & off & on & on & idle & idle \\
+ \gls{RAM} & on & on & on & off & on & on & on & on\\%low power \\
+ \midrule
+ current & 100--240 & 15 & 0.5 & 0.002 & 90--300 & 5 & 2 & 0.005\\
+ \bottomrule
+ \end{tabular}
+ \caption{Current use in \unit{\milli\ampere} of two microprocessor boards in various sleep modes.}%
+ \label{tbl:top_sleep}
+\end{table}
+
+\Cref{tbl:top_sleep} shows the properties and current consumption of two commonly used microcontrollers.
+It shows that switching the WiFi radio off yields the biggest energy savings.
+In most \gls{IOT} applications, we need WiFi for communications.
+It is fine to switch it off, but after switching it on, the WiFi protocol needs to transmit a number of messages to re-establish the connection.
+This implies that it is only worthwhile to switch the radio off when this can be done for some time.
+The details vary per system and situation.
+As a rule of thumb, it is only worthwhile to switch the WiFi off when it is not needed for at least some tens of seconds.
+
+\section{Green \texorpdfstring{\glsxtrshort{IOT}}{IoT} computing}
+The data in \cref{tbl:top_sleep} shows that it is worthwhile to put the system in some sleep mode when there is temporarily no work to be done.
+A deeper sleep mode saves more energy, but also requires more work to restore the software to its working state.
+A processor like the ESP8266 driving the Wemos D1 mini loses the content of its \gls{RAM} in deep sleep mode.
+As a result, after waking up, the program itself is preserved, since it is stored in flash memory, but the program state is lost.
+When there is a program state to be preserved, we must either store it elsewhere, limit us to light sleep, or use a microcontroller that keeps the \gls{RAM} intact during deep sleep.
+
+For \gls{IOT} nodes executing a single task, explicit sleeping to save energy can be achieved without too much hassle.
+This becomes much more challenging as soon as multiple independent tasks run on the same node.
+Sleeping of the entire node induced by one task prevents progress of all tasks.
+This is especially annoying when the other tasks are executing time critical parts, like communication protocols.
+Such protocols control the communication with sensors and actuators.
+Without the help of an \gls{OS}, the programmer is forced to combine all subtasks into one big system that decides if it is safe to sleep for all subtasks.
+
+\Gls{MTASK} offers abstractions for edge layer-specific details such as the heterogeneity of architectures, platforms and frameworks; peripheral access; and multitasking but also for energy consumption and scheduling.
+In \gls{MTASK}, tasks are implemented as a rewrite system, where the work is automatically segmented in small atomic bits and stored as a task tree.
+Each cycle, a single rewrite step is performed on all task trees, during rewriting, tasks do a bit of their work and progress steadily, allowing interleaved and seemingly parallel operation.
+After a loop, the \gls{RTS} knows which task is waiting on which triggers and is thus able to determine the next execution time for each task automatically.
+Utilising this information, the \gls{RTS} can determine when it is possible and safe to sleep and choose the optimal sleep mode according to the sleeping time.
+For example, the \gls{RTS} never attempts to sleep during an \gls{I2C} communication because \gls{IO} is always contained \emph{within} a rewrite step.
+
+An \gls{MTASK} program is dynamically transformed to byte code.
+This byte code and the initial \gls{MTASK} expression are shipped to \gls{MTASK} \gls{IOT} node.
+For the example in \cref{lst:blink} there is byte code representing the \cleaninline{blink} function and \cleaninline{main} determines the initial expression.
+
+The \gls{MTASK} rewrite engine rewrites the current expression just a single rewrite step at a time.
+When subtasks are composed in parallel, all subtasks are rewritten unless the result of the first rewrite step makes the result of the other tasks superfluous.
+The task design ensures such that all time critical communication with peripherals is within a single rewrite step.
+This is very convenient, since the system can inspect the current state of all \gls{MTASK} expressions after a rewrite and decide if sleeping and how long is possible.
+%As a consequence, we cannot have fair multitasking.
+%When a single rewrite step would take forever due to an infinite sequence of function calls, this would block the entire IoT node.
+Even infinite sequences rewrite steps, as in the \cleaninline{blink} example, are perfectly fine.
+The \gls{MTASK} system does proper tail-call optimizations to facilitate this.
+
+\section{Task scheduling}
+Some \gls{MTASK} examples contain one or more explicit \cleaninline{delay} primitives, offering a natural place for the node executing it to pause.
+However, there are many \gls{MTASK} programs that just specify a repeated set of primitives.
+A typical example is the program that reads the temperature for a sensor and sets the system \gls{LED} if the reading is below some given \cleaninline{goal}.
+
+\begin{lstClean}[caption={A basic thermostat task.},label={lst:thermostat}]
+thermostat :: Main (MTask v Bool) | mtask v
+thermostat = DHT I2Caddr \dht->
+ {main = rpeat (
+ temperature dht >>~. \temp.
+ writeD builtInLED (goal <. temp)
+ )}
+\end{lstClean}
+
+This program repeatedly reads the \gls{DHT} sensor and sets the on-board \gls{LED} based on the comparison with the \cleaninline{goal} as fast as possible on the \gls{MTASK} node.
+This is a perfect solution as long as we ignore the power consumption.
+The \gls{MTASK} machinery ensures that if there are other tasks running on the node, they will make progress.
+However, this solution is far from perfect when we take power consumption into account.
+In most applications, it is very unlikely that the temperature will change significantly within one minute, let alone within some milliseconds.
+Hence, it is sufficient to repeat the measurement with an appropriate interval.
+
+There are various ways to improve this program.
+The simplest solution is to add an explicit delay to the body of the repeat loop.
+A slightly more sophisticated option is to add a repetition period to the \cleaninline{rpeat} combinator.
+The combinator implementing this is called \cleaninline{rpeatEvery}.
+Both solutions rely on an explicit action of the programmer.
+
+Fortunately, \gls{MTASK} also contains machinery to do this automatically.
+The key of this solution is to associate dynamically an evaluation interval with each task.
+The interval $\left\langle low, high \right\rangle$ indicates that the evaluation can be safely delayed by any number of milliseconds in that range.
+Such an interval is just a hint for the \gls{RTS}.
+It is not a guarantee that the evaluation takes place in the given interval.
+Other parts of the task expression can force an earlier evaluation of this part of the task.
+When the system is very busy with other work, the task might even be executed after the upper bound of the interval.
+The system calculates the refresh rates from the current task expression.
+This has the advantage that the programmer does not have to deal with them and that they are available in each and every \gls{MTASK} program.
+
+\subsection{Basic Refresh Rates}
+
+We start by assigning default refresh rates to basic tasks.
+These refresh rates reflect the expected change rates of sensors and other inputs.
+Writing to basic \gls{GPIO} pins and actuators has refresh rate $\langle 0, 0 \rangle$, this is never delayed.
+
+\begin{table}
+ \centering
+ \begin{tabular}{ll}
+ \toprule
+ task & default interval \\
+ \midrule
+ reading \pgls{SDS} & $\langle 0, 2000 \rangle$ \\
+ slow sensor, like temperature & $\langle 0, 2000 \rangle$ \\
+ gesture sensor & $\langle 0, 1000 \rangle$ \\
+ fast sensor, like sound or light & $\langle 0, 100 \rangle$ \\
+ reading GPIO pins & $\langle 0, 100 \rangle$ \\
+ \bottomrule
+ \end{tabular}
+ \caption{Default refresh rates of basic tasks.}%
+ \label{tbl:refresh}
+\end{table}
+
+\subsection{Deriving Refresh Rates}
+Based on these refresh rates, the system can automatically derive refresh rates for composed \gls{MTASK} expressions using $\mathcal{R}$.
+We use the operator $\cap_{\textit{safe}}$ to compose refresh ranges.
+When the ranges overlap the result is the overlapping range.
+Otherwise, the result is the range with the lowest numbers.
+The rationale is that subtasks should not be delayed longer than their refresh range.
+Evaluating a task earlier should not change its result but can consume more energy.
+
+\begin{align}
+ \cap_{\textit{safe}} :: \langle \mathit{Int}, \mathit{Int} \rangle \; \langle \mathit{Int}, \mathit{Int} \rangle & \shortrightarrow \langle \mathit{Int}, \mathit{Int} \rangle & \notag \\
+ R_1 \cap_{\textit{safe}} R_2 & = R_1 \cap R_2 & \text{if } R_1 \cap R_2 \neq \emptyset \\
+ \langle l_1, h_1 \rangle \cap_{\textit{safe}} \langle l_2, h_2 \rangle & = \langle l_2, h_2 \rangle & \text{if } h_2 < l_1 \\
+ R_1 \cap_{\textit{safe}} R_2 & = R_1 & \text{otherwise}
+\end{align}
+
+\begin{align}
+ \mathcal{R} :: (\mathit{MTask}~v~a) & \shortrightarrow \langle \mathit{Int}, \mathit{Int} \rangle \notag \\
+ \mathcal{R} (t_1~{.||.}~t_2) & = \mathcal{R}(t_1) \cap_{\textit{safe}} \mathcal{R}(t_2) \label{R:or} \\
+ \mathcal{R}(t_1~{.\&\&.}~t_2) & = \mathcal{R}(t_1) \cap_{\textit{safe}} \mathcal{R}(t_2) \label{R:and}\\
+ \mathcal{R}(t_1~{>\!\!>\!|.}~t_2) & = \mathcal{R}(t_1) \label{R:seq} \\
+ \mathcal{R}(t~{>\!\!>\!=.}~f) & = \mathcal{R}(t) \label{R:bind} \\
+ \mathcal{R}(t~{>\!\!>\!\!*.}~[a_1 \ldots a_n]) & = \mathcal{R}(t) \label{R:step} \\
+ \mathcal{R}(\mathit{rpeat}~t) & = \langle 0, 0 \rangle \label{R:rpeat} \\
+ \mathcal{R}(\mathit{rpeatEvery}~d~t) & = \langle 0, 0 \rangle \label{R:rpeatevery} \\
+ \mathcal{R}(delay~d) & = \langle d, d \rangle \label{R:delay} \\
+ \mathcal{R}(t) & =
+ \left\{%
+ \begin{array}{ll}
+ \langle \infty, \infty \rangle~& \text{if}~t~\text{is Stable} \\
+ \langle r_l, r_u \rangle & \text{otherwise}
+ \end{array}
+ \right.\label{R:other}
+\end{align}
+
+We will briefly discuss the various cases of deriving refresh rates together with the task semantics of the different combinators
+
+\subsubsection{Parallel Combinators} For the parallel composition of tasks we compute the intersection of the refresh intervals of the components as outlined in the definition of $\cap_{\textit{safe}}$.
+The operator \cleaninline{.\|\|.} in \cref{R:or} is the \emph{or}-combinator; the first subtask that produces a stable value determines the result of the composition.
+The operator \cleaninline{.&&.} in \cref{R:and} is the \emph{and}-operator. The result is the tuple containing both results when both subtasks have a stable value.
+The refresh rates of the parallel combinators have no direct relation with their task result.
+
+\subsubsection{Sequential Combinators}
+For the sequential composition of tasks we only have to look at the refresh rate of the current task on the left.
+The sequential composition operator \cleaninline{>>\|.} in \cref{R:seq} is similar to the monadic sequence operator \cleaninline{>>\|}.
+The operator \cleaninline{>>=.} in \cref{R:bind} provides the stable task result to the function on the right-hand side, similar to the monadic bind.
+The operator \cleaninline{>>~.} steps on an unstable value and is otherwise equal to \cleaninline{>>=.}.
+The step combinator \cleaninline{>>*.} in \cref{R:step} has a list of conditional actions that specify a new task.
+
+\subsubsection{Repeat Combinators}
+The repeat combinators repeats their argument indefinitely.
+The combinator \cleaninline{rpeatEvery} guarantees the given delay between repetitions.
+The refresh rate is equal to the refresh rate of the current argument task.
+Only when \cleaninline{rpeatEvery} waits between the iterations of the argument the refresh interval is equal to the remaining delay time.
+
+\subsubsection{Other Combinators}
+The refresh rate of the \cleaninline{delay} in \cref{R:delay} is equal to the remaining delay.
+Refreshing stable tasks can be delayed indefinitely, their value never changes.
+For other basic tasks, the values from \cref{tbl:refresh} apply.
+The values $r_l$ and $r_u$ in \cref{R:other} are the lower and upper bound of the rate.
+
+The refresh intervals associated with various steps of the thermostat program from \cref{lst:thermostat} are given in \cref{tbl:intervals}.
+Those rewrite steps and intervals are circular, after step 2 we continue with step 0 again.
+Only the actual reading of the sensor with \cleaninline{temperature dht} offers the possibility for a non-zero delay.
+
+%%\begin{table}[tb]
+\begin{table}
+ \centering
+ \begin{tabular}{cp{20em}c}
+ \toprule
+ Step & Expression & Interval \\
+ \midrule
+ 0 &
+ \begin{lstClean}[aboveskip=-2ex,belowskip=-2ex,frame=]
+rpeat ( temperature dht >>~. \temp.
+ writeD builtInLED (goal <. temp)
+)\end{lstClean}
+ &
+ $\langle 0, 0 \rangle$ \\
+ %\hline
+ 1 &
+ \begin{lstClean}[aboveskip=-2ex,belowskip=-2ex,frame=]
+temperature dht >>~. \temp.
+writeD builtInLED (goal <. temp) >>|.
+rpeat ( temperature dht >>~. \temp.
+ writeD builtInLED (goal <. temp)
+)\end{lstClean}
+ & $\langle 0, 2000 \rangle$ \\
+ %\hline
+ 2 &
+ \begin{lstClean}[aboveskip=-2ex,belowskip=-2ex,frame=]
+writeD builtInLED false >>|.
+rpeat ( temperature dht >>~. \temp.
+ writeD builtInLED (goal <. temp)
+)\end{lstClean}
+ & $\langle 0, 0 \rangle$ \\
+ \bottomrule
+ \end{tabular}
+ \caption{Rewrite steps of the thermostat from \cref{lst:thermostat} and associated intervals.}%
+ \label{tbl:intervals}
+\end{table}
+
+\subsection{User Defined Refresh Rates}
+In some applications, it is necessary to read sensors at a different rate than the default rate given in \cref{tbl:refresh}, i.e.\ to customise the refresh rate.
+This is achieved by calling the access functions with a custom refresh rate as an additional argument (suffixed with the backtick (\cleaninline{`}))
+
+\begin{lstClean}[caption={Auxiliary definitions to \cref{lst:gpio} for \gls{DHT} sensors and digital \gls{GPIO} with custom timing intervals.},label={lst:dht}]
+class dht v where
+ ...
+ temperature` :: (TimingInterval v) (v DHT) -> MTask v Real
+ temperature :: (v DHT) -> MTask v Real
+ humidity` :: (TimingInterval v) (v DHT) -> MTask v Real
+ humidity :: (v DHT) -> MTask v Real
+
+class dio p v | pin p where
+ ...
+ readD` :: (TimingInterval v) (v p) -> MTask v Bool | pin p
+ readD :: (v p) -> MTask v Bool | pin p
+\end{lstClean}
+
+A tailor-made \gls{ADT} determines the timing intervals.
+
+% doordat texcl aanstaat in listings zijn comments automatisch al in LaTeX
+\begin{lstlisting}[language=Clean,caption={The \gls{ADT} for timing intervals in \gls{MTASK}.},label={lst:interval}]
+:: TimingInterval v = Default
+ | BeforeMs (v Int) // yields $\langle 0, x \rangle $
+ | BeforeS (v Int) // yields $\langle 0, x \times 1000 \rangle $
+ | ExactMs (v Int) // yields $\langle x, x \rangle $
+ | ExactS (v Int) // yields $\langle 0, x \times 1000 \rangle $
+ | RangeMs (v Int) (v Int) // yields $\langle x, y \rangle $
+ | RangeS (v Int) (v Int) // yields $\langle x \times 1000, y \times 1000 \rangle $
+\end{lstlisting}
+
+As example, we define an \gls{MTASK} that updates the \gls{SDS} \cleaninline{tempSds} in \gls{ITASK} in a tight loop.
+The \cleaninline{temperature`} reading requires that this happens at least once per minute.
+Without other tasks on the \gls{IOT} node, the temperature \gls{SDS} is updated once per minute.
+Other tasks can cause a slightly more frequent update.
+
+\begin{lstClean}[caption={Updating \pgls{SDS} in \gls{ITASK} at most once per minute.},label={lst:updatesds2}]
+delayTime = BeforeS (lit 60) // 1 minute in seconds
+
+devTask :: Main (MTask v Real) | mtask, dht, liftsds v
+devTask = DHT (DHT_DHT pin DHT11) \dht =
+ liftsds \localSds = tempSds
+ In {main = rpeat (temperature` delayTime dht >>~. setSds localSds)}
+\end{lstClean}
+
+\subsection{Language}
+\subsection{Device}
+
+\section{Interrupts}
+
+\input{subfilepostamble}
+\end{document}