\input{subfilepreamble}
\begin{document}
-\ifSubfilesClassLoaded{
- \pagenumbering{arabic}
-}{}
+\input{subfileprefix}
-\chapter{Introduction to \texorpdfstring{\glsxtrshort{IOT}}{IoT} device programming}%
+\chapter{Edge device programming}%
\label{chp:top4iot}
-\todo{betere chapter naam}
\begin{chapterabstract}
- This chapter introduces \gls{MTASK} and puts it into perspective compared to traditional microprocessor programming.
+ This chapter:
+ \begin{itemize}
+ \item shows how to create the \emph{Hello World!} application for microcontrollers using \gls{ARDUINO};
+ \item extends this idea with multithreading, demonstrating the difficulty programming multi-tasking applications;
+ \item describes a comparative variant in \gls{MTASK} and shows that upgrading to a multi-tasking variant is straightforward
+ \item demonstrates that the complexity of running multiple tasks;
+ \item and concludes with the history of \gls{MTASK}'s development.
+ \end{itemize}
\end{chapterabstract}
-The edge layer of \gls{IOT} system mostly consists of microprocessors that require a different method of programming.
-Usually, programming microprocessors requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microprocessor in order to compile and run a program.
+The edge layer of \gls{IOT} system mostly consists of microcontrollers.
+Microcontrollers are tiny computers designed specifically for embedded applications.
+They therefore only have a soup\c{c}on of memory, have a slow processor, come with many energy efficient sleep modes and have a lot of peripheral support such as \gls{GPIO} pins.
+Usually, programming microcontrollers requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to compile and run a program.
The programs are usually cyclic executives instead of tasks running in an operating system, i.e.\ there is only a single task that continuously runs on the bare metal.
-Each type of microprocessors comes with vendor-provided drivers, compilers and \glspl{RTS} but there are many platform that abstract away from this such as \gls{MBED} and \gls{ARDUINO} of which \gls{ARDUINO} is specifically designed for education and prototyping and hence used here.
-The popular \gls{ARDUINO} \gls{C}\slash\gls{CPP} dialect and accompanying libraries provide an abstraction layer for common microprocessor behaviour allowing the programmer to program multiple types of microprocessors using a single language.
+\Cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two very popular microcontrollers.
+
+\begin{table}
+ \caption{Hardware characteristics of typical microcontrollers and laptops.}%
+ \label{tbl:mcu_laptop}
+ \begin{tabular}{llll}
+ \toprule
+ & Laptop & Atmega328P & ESP8266\\
+ \midrule
+ CPU speed & \qtyrange{2}{4}{\giga\hertz} & \qty{16}{\mega\hertz} & \qty{80}{\mega\hertz} or \qty{160}{\mega\hertz}\\
+ \textnumero{} cores & \numrange{4}{8} & 1 & 1\\
+ Storage & \qty{1}{\tebi\byte} & \qty{32}{\kibi\byte} & \qtyrange{0.5}{4}{\mebi\byte}\\
+ \gls{RAM} & \qtyrange{4}{16}{\gibi\byte} & \qty{2}{\kibi\byte} & \qty{160}{\kibi\byte}\\
+ Power & \qtyrange{50}{100}{\watt} & \qtyrange{0.13}{250}{\milli\watt} & \qtyrange{0.1}{350}{\milli\watt}\\
+ Price & \euro{1500} & \euro{3} & \euro{4}\\
+ \bottomrule
+ \end{tabular}
+\end{table}
+
+Each type of microcontrollers comes with vendor-provided drivers, compilers and \glspl{RTS} but there are many platform that abstract away from this such as \gls{MBED} and \gls{ARDUINO} of which \gls{ARDUINO} is specifically designed for education and prototyping and hence used here.
+The popular \gls{ARDUINO} \gls{C}\slash\gls{CPP} dialect and accompanying libraries provide an abstraction layer for common microcontroller behaviour allowing the programmer to program multiple types of microcontrollers using a single language.
Originally it was designed for the in-house developed open-source hardware with the same name but the setup allows porting to many architectures.
It provides an \gls{IDE} and toolchain automation to perform all steps of the toolchain with a single command.
\section{Hello world!}
Traditionally, the first program that one writes when trying a new language is the so called \emph{Hello World!} program.
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.
-On microprocessors, there usually is no screen for displaying text.
-Nevertheless, almost always there is a built-in monochrome $1\times1$ pixel screen, namely an \gls{LED}.
-The \emph{Hello World!} equivalent on microprocessors blinks this \gls{LED}.
+On microcontrollers, there usually is no screen for displaying text.
+Nevertheless, almost always there is a built-in monochrome $1\times1$ pixel screen, namely \pgls{LED}.
+The \emph{Hello World!} equivalent on microcontrollers blinks this \gls{LED}.
\Cref{lst:arduinoBlink} shows how the logic of a blink program might look when using \gls{ARDUINO}'s \gls{C}\slash\gls{CPP} dialect.
Every \gls{ARDUINO} program contains a \arduinoinline{setup} and a \arduinoinline{loop} function.
Listing~\ref{lst:blinkthread} shows how three different blinking patterns might be achieved in \gls{ARDUINO} using the slicing method.
If we want the blink function to be a separate parametrizable function we need to explicitly provide all references to the required state.
Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
-The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microprocessor.
+The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller.
Some devices use very little energy when in \arduinoinline{delay} or sleep state.
Resulting in \arduinoinline{millis} potentially affects power consumption since the processor is basically busy looping all the time.
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.
\section{\texorpdfstring{\Gls{MTASK}}{MTask} history}
\subsection{Generating \texorpdfstring{\gls{C}/\gls{CPP}}{C/C++} code}
-A first throw at a class-based shallowly \gls{EDSL} for microprocessors was made by \citet{plasmeijer_shallow_2016}.
+A first throw at a class-based shallowly \gls{EDSL} for microcontrollers was made by \citet{plasmeijer_shallow_2016}.
The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
A \gls{CPP} code generation backend was available together with an \gls{ITASK} simulation backend.
There was no support for tasks or even functions.
The \gls{MTASK} language as it is now was introduced in 2018 \citep{koopman_task-based_2018}.
This paper updated the language to support functions, tasks and \glspl{SDS} but still compiled to \gls{CPP} \gls{ARDUINO} code.
Later the bytecode compiler and \gls{ITASK} integration was added to the language \citep{lubbers_interpreting_2019}.
-Moreover, it was shown that it is very intuitive to write microprocessor applications in a \gls{TOP} language \citep{lubbers_multitasking_2019}.
+Moreover, it was shown that it is very intuitive to write microcontroller applications in a \gls{TOP} language \citep{lubbers_multitasking_2019}.
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).
In 2019, the \gls{CEFP} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well \citep{lubbers_writing_2019}.
\chapter{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\glsxtrshort{DSL}}{DSL}}%
\label{chp:mtask_dsl}
\begin{chapterabstract}
-This chapter serves as a complete guide to the \gls{MTASK} language, from an \gls{MTASK} programmer's perspective.
+This chapter introduces the \gls{MTASK} language more technically by:
+ \begin{itemize}
+ \item introducing the setup of the \gls{EDSL};
+ \item and showing the language interface and examples for:
+ \begin{itemize}
+ \item data types
+ \item expression
+ \item task and their combinators.
+ \end{itemize}
+ \end{itemize}
\end{chapterabstract}
-The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microprocessors.
+The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microcontrollers.
It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (see \cref{sec:tagless-final_embedding}).
Due to the nature of the embedding technique, it is possible to have multiple views on-programs written in the \gls{MTASK} language.
\item[Byte code compiler]
The compiler compiles the \gls{MTASK} program at runtime to a specialised byte code.
- 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.
+ Using a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks.
Furthermore, with special language constructs, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs.
\end{description}
When using the compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
-I.e.\ some components---e.g.\ the \gls{RTS} on the microprocessor---is largely unaware of the other components in the system, and it is executed on a completely different architecture.
+I.e.\ some components---e.g.\ the \gls{RTS} on the microcontroller---is largely unaware of the other components in the system, and it is executed on a completely different architecture.
The \gls{MTASK} language is an enriched simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definition; and a task language (see \cref{sec:top}).
\section{Types}
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.
-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.
-The most used class constraint is the \cleaninline{type} class collection containing functions for serialization, printing, \gls{ITASK} constraints \etc.
+However, not all types in the host language are suitable for microcontrollers that may only have \qty{2}{\kibi\byte} of \gls{RAM} so class constraints are therefore added to the \gls{DSL} functions.
+The most used class constraint is the \cleaninline{type} class collection containing functions for serialization, printing, \gls{ITASK} constraints, \etc.
Many of these functions can be derived using generic programming.
An even stronger restriction on types is defined for types that have a stack representation.
This \cleaninline{basicType} class has instances for many \gls{CLEAN} basic types such as \cleaninline{Int}, \cleaninline{Real} and \cleaninline{Bool}.
\begin{table}[ht]
\centering
+ \caption{Mapping from \gls{CLEAN}/\gls{MTASK} data types to \gls{CPP} datatypes.}%
+ \label{tbl:mtask-c-datatypes}
\begin{tabular}{lll}
\toprule
\gls{CLEAN}/\gls{MTASK} & \gls{CPP} type & \textnumero{}bits\\
\cleaninline{:: T = A \| B \| C} & \cinline{enum} & 16\\
\bottomrule
\end{tabular}
- \caption{Mapping from \gls{CLEAN}/\gls{MTASK} data types to \gls{CPP} datatypes.}%
- \label{tbl:mtask-c-datatypes}
\end{table}
\Cref{lst:constraints} contains the definitions for the auxiliary types and type constraints (such as \cleaninline{type} an \cleaninline{basicType}) that are used to construct \gls{MTASK} expressions.
\Gls{MTASK}'s task language can be divided into three categories, namely
\begin{enumerate*}
\item Basic tasks, in most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
- 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.
+ In \gls{MTASK}, there are no \emph{editors} in that sense but there is interaction with the outside world through microcontroller peripherals such as sensors and actuators.
\item Task combinators provide a way of describing the workflow.
They combine one or more tasks into a compound task.
\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.
\Gls{GPIO} access is divided into three classes: analog, digital and pin modes.
For all pins and pin modes an \gls{ADT} is available that enumerates the pins.
-The analog \gls{GPIO} pins of a microprocessor are connected to an \gls{ADC} that translates the voltage to an integer.
+The analog \gls{GPIO} pins of a microcontroller are connected to an \gls{ADC} that translates the voltage to an integer.
Analog \gls{GPIO} pins can be either read or written to.
Digital \gls{GPIO} pins only report a high or a low value.
The type class definition is a bit more complex since analog \gls{GPIO} pins can be used as digital \gls{GPIO} pins as well.
Similar to peripherals (see \cref{sssec:peripherals}), they are constructed at the top level and are accessed through interaction tasks.
The \cleaninline{getSds} task yields the current value of the \gls{SDS} as an unstable value.
This behaviour is similar to the \cleaninline{watch} task in \gls{ITASK}.
-Writing a new value to an \gls{SDS} is done using \cleaninline{setSds}.
+Writing a new value to \pgls{SDS} is done using \cleaninline{setSds}.
This task yields the written value as a stable result after it is done writing.
-Getting and immediately after setting an \gls{SDS} is not necessarily an \emph{atomic} operation in \gls{MTASK} because it is possible that another task accesses the \gls{SDS} in between.
+Getting and immediately after setting \pgls{SDS} is not necessarily an \emph{atomic} operation in \gls{MTASK} because it is possible that another task accesses the \gls{SDS} in between.
To circumvent this issue, \cleaninline{updSds} is created, this task atomically updates the value of the \gls{SDS}.
The \cleaninline{updSds} task only guarantees atomicity within \gls{MTASK}.
In {main=count d3 .||. count d5}
\end{lstClean}
-\chapter{Green computing with \texorpdfstring{\gls{MTASK}}{mTask}}%
-\label{chp:green_computing_mtask}
-
-\section{Green \texorpdfstring{\glsxtrshort{IOT}}{IoT} computing}
-
-\section{Task scheduling}
-\subsection{Language}
-\subsection{Device}
-
-\section{Interrupts}
-
\chapter{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}%
\label{chp:integration_with_itask}
+\begin{chapterabstract}
+ This chapter shows the integration of \gls{MTASK} with \gls{ITASK} by showing:
+ \begin{itemize}
+ \item an architectural overview of \gls{MTASK};
+ \item on the interface for connecting devices;
+ \item the interface for lifting \gls{MTASK} tasks to \gls{ITASK} tasks;
+ \item and interface for lifting \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS}.
+ \end{itemize}
+\end{chapterabstract}
+
The \gls{MTASK} language is a multi-view \gls{DSL}, i.e.\ there are multiple interpretations possible for a single \gls{MTASK} term.
-Using the byte code compiler (\cleaninline{BCInterpret}) \gls{DSL} interpretation, \gls{MTASK} tasks are fully integrated in \gls{ITASK} and executed as if they were regular \gls{ITASK} tasks and communicate using \gls{ITASK} \glspl{SDS}.
-\Gls{MTASK} devices contain a domain-specific \gls{OS} (\gls{RTS}) and are little \gls{TOP} servers in their own respect, being able to execute tasks.
+Using the byte code compiler (\cleaninline{BCInterpret}) \gls{DSL} interpretation, \gls{MTASK} tasks can be fully integrated in \gls{ITASK}.
+They are executed as if they are regular \gls{ITASK} tasks and they communicate may access \glspl{SDS} from \gls{ITASK} as well.
+\Gls{MTASK} devices contain a domain-specific \gls{OS} (\gls{RTS}) and are little \gls{TOP} engines in their own respect, being able to execute tasks.
\Cref{fig:mtask_integration} shows the architectural layout of a typical \gls{IOT} system created with \gls{ITASK} and \gls{MTASK}.
The entire system is written as a single \gls{CLEAN} specification where multiple tasks are executed at the same time.
Tasks can access \glspl{SDS} according to many-to-many communication and multiple clients can work on the same task.
-Devices are integrated into the system using the \cleaninline{widthDevice} function (see \cref{sec:withdevice}).
+Devices are integrated into the system using the \cleaninline{withDevice} function (see \cref{sec:withdevice}).
Using \cleaninline{liftmTask}, \gls{MTASK} tasks are lifted to a device (see \cref{sec:liftmtask}).
\Gls{ITASK} \glspl{SDS} are lifted to the \gls{MTASK} device using \cleaninline{liftsds} (see \cref{sec:liftmtask}).
\end{figure}
\section{Devices}\label{sec:withdevice}
-\Gls{MTASK} tasks in the byte code compiler view are always executed on a certain device.
+When interpreted by the byte code compiler view, an \gls{MTASK} task produces a compiler.
+This compiler is exceuted at run time so that the resulting byte code can be sent to an edge device.
All communication with this device happens through a so-called \emph{channels} \gls{SDS}.
The channels contain three fields, a queue of messages that are received, a queue of messages to send and a stop flag.
Every communication method that implements the \cleaninline{channelSync} class can provide the communication with an \gls{MTASK} device.
:: MTDevice //abstract
:: Channels :== ([MTMessageFro], [MTMessageTo], Bool)
-class channelSync a :: a (sds () Channels Channels) -> Task () | RWShared sds
+class channelSync a :: a (Shared sds Channels) -> Task () | RWShared sds
withDevice :: (a (MTDevice -> Task b) -> Task b) | iTask b & channelSync, iTask a
\end{lstClean}
\section{Lifting \texorpdfstring{\glsxtrlongpl{SDS}}{shared data sources}}\label{sec:liftsds}
\begin{lstClean}[label={lst:mtask_itasksds},caption={Lifted \gls{ITASK} \glspl{SDS} in \gls{MTASK}.}]
class liftsds v where
- liftsds :: ((v (Sds t))->In (Shared sds t) (Main (MTask v u)))
+ liftsds :: ((v (Sds t)) -> In (Shared sds t) (Main (MTask v u)))
-> Main (MTask v u) | RWShared sds
\end{lstClean}
\chapter{Implementation}%
\label{chp:implementation}
+\begin{chapterabstract}
+ This chapter shows the implementation of the \gls{MTASK} system.
+ It is threefold: first it shows the implementation of the byte code compiler for \gls{MTASK}'s \gls{TOP} language, then is details of the implementation of \gls{MTASK}'s \gls{TOP} engine that executes the \gls{MTASK} tasks on the microcontroller, and finally it shows how the integration of \gls{MTASK} tasks and \glspl{SDS} is implemented both on the server and on the device.
+\end{chapterabstract}
IFL19 paper, bytecode instructieset~\cref{chp:bytecode_instruction_set}
\section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
IFL18 paper stukken
+\subfile{green}
+
\input{subfilepostamble}
\end{document}