\begin{itemize}
\item giving an overview of general green computing measures for edge devices;
\item explaining task scheduling in \gls{MTASK}, and how to tweak it so suit the applications and energy needs;
\begin{itemize}
\item giving an overview of general green computing measures for edge devices;
\item explaining task scheduling in \gls{MTASK}, and how to tweak it so suit the applications and energy needs;
-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{nizetic_internet_2020}.
+Furthermore, many of these 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{nizetic_internet_2020}.
It is therefore crucial to lower their energy consumption.
To reduce the power consumption of an \gls{IOT} edge device, the specialised low-power sleep modes of the microprocessors can be leveraged.
Different sleep mode achieve different power reductions because of their run time characteristics.
These specifics range from disabling or suspending the \gls{WIFI} radio; stop powering (parts) of the \gls{RAM}; disabling peripherals; or even turning off the processor completely, requiring an external signal to wake up again.
Determining exactly when, and for how long it is safe to sleep is expensive in the general case.
It is therefore crucial to lower their energy consumption.
To reduce the power consumption of an \gls{IOT} edge device, the specialised low-power sleep modes of the microprocessors can be leveraged.
Different sleep mode achieve different power reductions because of their run time characteristics.
These specifics range from disabling or suspending the \gls{WIFI} radio; stop powering (parts) of the \gls{RAM}; disabling peripherals; or even turning off the processor completely, requiring an external signal to wake up again.
Determining exactly when, and for how long it is safe to sleep is expensive in the general case.
-In practise it means that either annotations in the source code, a \gls{RTOS}, or a scheduler is required.
+In practise, it means that either annotations in the source code, a \gls{RTOS}, or a scheduler is required.
\Cref{tbl:top_sleep} shows the properties and current consumption of two commonly used microcontrollers in their various sleep modes.
It uncovers that switching the \gls{WIFI} radio off yields the biggest energy saving.
\Cref{tbl:top_sleep} shows the properties and current consumption of two commonly used microcontrollers in their various sleep modes.
It uncovers that switching the \gls{WIFI} radio off yields the biggest energy saving.
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.
After each loop, the \gls{RTS} knows which task is waiting on which triggers and is thus determines when it is possible and safe to sleep and choose the optimal sleep mode according to the sleeping time.
%As a consequence, we cannot have fair multitasking.
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.
After each loop, the \gls{RTS} knows which task is waiting on which triggers and is thus determines when it is possible and safe to sleep and choose the optimal sleep mode according to the sleeping time.
%As a consequence, we cannot have fair multitasking.
\section{Rewrite interval}
Some \gls{MTASK} programs contain one or more explicit \cleaninline{delay} primitives, offering a natural place a pause.
\section{Rewrite interval}
Some \gls{MTASK} programs contain one or more explicit \cleaninline{delay} primitives, offering a natural place a pause.
Only after stepping, the combinator rewrites to the result of evaluating the right-hand side expression.
\subsubsection{Repeating combinators}
Only after stepping, the combinator rewrites to the result of evaluating the right-hand side expression.
\subsubsection{Repeating combinators}
\subsection{Tweaking rewrite rates}
A tailor-made \gls{ADT} (see \cref{lst:interval}) is used to tweak the timing intervals.
\subsection{Tweaking rewrite rates}
A tailor-made \gls{ADT} (see \cref{lst:interval}) is used to tweak the timing intervals.
During compilation, the constructor of the \gls{ADT} is checked and code is generated accordingly.
If it is \cleaninline{Default}, no extra code is generated.
In the other cases, code is generated to wrap the task tree node in a \emph{tune rate} node.
During compilation, the constructor of the \gls{ADT} is checked and code is generated accordingly.
If it is \cleaninline{Default}, no extra code is generated.
In the other cases, code is generated to wrap the task tree node in a \emph{tune rate} node.
The rewrite rates from the previous section only tell us how much the next evaluation of the task can be delayed.
In the \gls{MTASK} system, an \gls{IOT} edge devices can run multiple tasks.
In addition, it has to communicate with a server to collect new tasks and updates of \glspl{SDS}.
The rewrite rates from the previous section only tell us how much the next evaluation of the task can be delayed.
In the \gls{MTASK} system, an \gls{IOT} edge devices can run multiple tasks.
In addition, it has to communicate with a server to collect new tasks and updates of \glspl{SDS}.
The \gls{MTASK} tasks are ordered at their absolute latest start time in this queue; earliest deadline first.
We use the earliest deadline to order tasks with equal latest deadline.
The \gls{MTASK} tasks are ordered at their absolute latest start time in this queue; earliest deadline first.
We use the earliest deadline to order tasks with equal latest deadline.
We use a simple heuristic to evaluate tasks and determine sleep time rather than wasting energy on a fancy evaluation algorithm.
\Cref{lst:evalutionRound} gives this algorithm in pseudo code.
First the edge device checks for new tasks and updates of \glspl{SDS}.
This communication adds the new task to the queue, if there where any.
The \cleaninline{stepped} set contains all tasks evaluated in this evaluation round.
Next, we evaluate tasks from the queue until we encounter a task that has an evaluation interval that has not started.
We use a simple heuristic to evaluate tasks and determine sleep time rather than wasting energy on a fancy evaluation algorithm.
\Cref{lst:evalutionRound} gives this algorithm in pseudo code.
First the edge device checks for new tasks and updates of \glspl{SDS}.
This communication adds the new task to the queue, if there where any.
The \cleaninline{stepped} set contains all tasks evaluated in this evaluation round.
Next, we evaluate tasks from the queue until we encounter a task that has an evaluation interval that has not started.
%Using the \prog{stepped} set ensures that we evaluate each task at most once during an evaluation round.
Executed tasks are temporarily stored in the \cleaninline{stepped} set instead of inserted directly into the queue to ensure that they are evaluated at most once in a evaluation round to ensure that there is frequent communication with the server.
A task that produces a stable value is completed and is not queued again.
%Using the \prog{stepped} set ensures that we evaluate each task at most once during an evaluation round.
Executed tasks are temporarily stored in the \cleaninline{stepped} set instead of inserted directly into the queue to ensure that they are evaluated at most once in a evaluation round to ensure that there is frequent communication with the server.
A task that produces a stable value is completed and is not queued again.
While interrupt tasks have their own node type in the task tree, they differ slightly from other node types because they require a more elaborate setup and teardown.
Enabling and disabling interrupts is done in a general way in which tasks register themselves after creation and deregister after deletion.
While interrupt tasks have their own node type in the task tree, they differ slightly from other node types because they require a more elaborate setup and teardown.
Enabling and disabling interrupts is done in a general way in which tasks register themselves after creation and deregister after deletion.
-Interrupts should be disabled when there are no tasks waiting for that kind of interrupt because unused interrupts can lead to unwanted wake ups, and only one kind of interrupt can be attached to a pin at the time..
+Interrupts should be disabled when there are no tasks waiting for that kind of interrupt because unused interrupts can lead to unwanted wake-ups, and only one kind of interrupt can be attached to a pin at the time.
\subsubsection{Event registration}
The \gls{MTASK} \gls{RTS} contains an event administration to register which task is waiting on which event.
\subsubsection{Event registration}
The \gls{MTASK} \gls{RTS} contains an event administration to register which task is waiting on which event.
This event registration is stored as a linked list of task tree nodes so that the garbage collector cleans them up when they become unused.
Registering and deregistering interrupts is a device-specific procedure, although most supported devices use the \gls{ARDUINO} \gls{API} for this.
This event registration is stored as a linked list of task tree nodes so that the garbage collector cleans them up when they become unused.
Registering and deregistering interrupts is a device-specific procedure, although most supported devices use the \gls{ARDUINO} \gls{API} for this.
At the time of registration, the \gls{RTS} checks whether the interrupt is valid and throws an \gls{MTASK} exception if it is not.
Moreover, an exception is thrown if multiple types of interrupts are registered on the same pin.
At the time of registration, the \gls{RTS} checks whether the interrupt is valid and throws an \gls{MTASK} exception if it is not.
Moreover, an exception is thrown if multiple types of interrupts are registered on the same pin.
The interrupt can be disabled as all tasks waiting for the interrupt become stable after firing.
More occurrences of the interrupts do not change the value of the task as stable tasks keep the same value forever.
Therefore, it is no longer necessary to keep the interrupt enabled, and it is relatively cheap to enable it again if needed in the future.
The interrupt can be disabled as all tasks waiting for the interrupt become stable after firing.
More occurrences of the interrupts do not change the value of the task as stable tasks keep the same value forever.
Therefore, it is no longer necessary to keep the interrupt enabled, and it is relatively cheap to enable it again if needed in the future.
The task emits the status of the pin as a stable value if the information in the task shows that it was triggered.
Otherwise, no value is emitted.
The task emits the status of the pin as a stable value if the information in the task shows that it was triggered.
Otherwise, no value is emitted.
This chapter show how we can automatically associate execution intervals to tasks.
Based on these intervals, we can delay the executions of those tasks.
When all task executions can be delayed, the microprocessor executing those tasks can go to sleep mode to reduce its energy consumption.
This chapter show how we can automatically associate execution intervals to tasks.
Based on these intervals, we can delay the executions of those tasks.
When all task executions can be delayed, the microprocessor executing those tasks can go to sleep mode to reduce its energy consumption.
Furthermore, the execution intervals offer an elegant and efficient way to add interrupts to the language.
Those interrupts offer a more elegant and energy efficient implementation of watching an input than polling this input.
The actual reduction of the energy is of course highly dependent on the number and nature of the task shipped to the edge device.
Our examples show a reduction in energy consumption of two orders of magnitude.
Those reductions are a necessity for edge devices running of battery power.
Furthermore, the execution intervals offer an elegant and efficient way to add interrupts to the language.
Those interrupts offer a more elegant and energy efficient implementation of watching an input than polling this input.
The actual reduction of the energy is of course highly dependent on the number and nature of the task shipped to the edge device.
Our examples show a reduction in energy consumption of two orders of magnitude.
Those reductions are a necessity for edge devices running of battery power.