X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=results.arch.tex;h=30fbc7a6511116c0d1c6d79b27a602c137f1c70d;hb=7ca87066ed1f3a962d993a9ac32ab761cfdc05a9;hp=fde75c0cae261424f38ed47594e836858210bea5;hpb=d118ff9d857683084065145df45135ef6fa06711;p=msc-thesis1617.git diff --git a/results.arch.tex b/results.arch.tex index fde75c0..30fbc7a 100644 --- a/results.arch.tex +++ b/results.arch.tex @@ -1,13 +1,13 @@ \section{Devices} The client code for the devices is compiled from one codebase. For a device to -be eligible for \glspl{mTask} it must be able to compile the shared codebase +be eligible for \glspl{mTask}, it must be able to compile the shared codebase and implement (part of) the device specific interface. The shared codebase only uses standard \gls{C} and no special libraries or tricks are used. Therefore the code is compilable for almost any device or system. Note that it is not -needed to implement a full interface. The full interface excluding the device -specific settings is listed in Appendix~\ref{app:device-interface}. The -interface works in a similar fashion as the \gls{EDSL}. Devices do not have to -implement all functionality, this is analogous to the fact that views do not +needed to implement a full interface. The full interface --- excluding the +device specific settings --- is listed in Appendix~\ref{app:device-interface}. +The interface works in a similar fashion as the \gls{EDSL}. Devices do not have +to implement all functionality, this is analogous to the fact that views do not have to implement all type classes in the \gls{EDSL}. When the device connects for the first time with a server the specifications of what is implemented is communicated. @@ -22,13 +22,13 @@ the device software. This is tested in particular on the \texttt{STM32f7x} series \gls{ARM} development board. - \item Microcontrollers programmable by the \emph{Arduino} \gls{IDE}.\\ + \item Microcontrollers programmable by the \gls{Arduino} \gls{IDE}.\\ - This does not only include \emph{Arduino} compatible boards but also - other boards capable of running \emph{Arduino} code. The code + This does not only include \gls{Arduino} compatible boards but also + other boards capable of running \gls{Arduino} code. The code has been found working on the \texttt{ESP8266} powered \emph{NodeMCU}. - It is tested on devices as small as the regular \emph{Arduino UNO} - board that only boasts a meager \emph{2K} of \emph{RAM}. + It is tested on devices as small as the regular \gls{Arduino} + \emph{UNO} board that only boasts a meager \emph{2K} of \emph{RAM}. \end{itemize} \section{Specification} @@ -50,20 +50,33 @@ of. The exact specification is listed in Listing~\ref{lst:devicespec} } \end{lstlisting} -\section{Communication} -The communication to and fro a device runs via a single \gls{SDS}. Every -device has a specific resource that is used to connect to the device. The -current system supports connecting devices via a serial connection and via a -\gls{TCP} connection. Every device has the type \CI{MTaskDevice} and which -is listed in Listing~\ref{lst:mtaskdevice}. When a device is added a background -task is started that runs the \CI{synFun}. The \CI{synFun} is the task that -synchronizes the channel \gls{SDS} with the actual device. For the \gls{TCP} -device this is a simple \CI{tcpconnect}. The \CI{TaskId} of the background task -is saved to be able to stop the task in the future. When the task is unable to -connect it will set the \CI{deviceError} field to notify the user. -\todo{netter maken} +\section{Device Storage} +All devices available in the system are stored in a big \gls{SDS} that contains +a list of \CI{MTaskDevice}s. The exact specification is listed in +Listing~\ref{lst:mtaskdevice} with the accompanying classes and types. + +The \CI{deviceResource} component of the record must implement the +\CI{MTaskDuplex} interface that provides a function that launches a task used +for synchronizing the channels. The \CI{deviceTask} stores the \gls{Task}-id +for this \gls{Task} when active so that it can be checked upon. This top-level +task has the duty to report set the \CI{deviceError} field whenever an error +occurs. All communication goes via these channels. If the system wants to send +a message to the device it just puts it in the channels. Messages sent from the +client to the server are also placed in there. In the case of the \gls{TCP} +device type the \gls{Task} is just a simple wrapper around the existing +\CI{tcpconnect} function in \gls{iTasks}. In case of the serial device type it +uses the newly developed serial port library of \gls{Clean}\footnote{\url{% +https://gitlab.science.ru.nl/mlubbers/CleanSerial}}. + +Besides all the communication information the record also keeps track of the +\glspl{Task} currently on the device and the according \glspl{SDS}. Finally it +stores the specification of the device that is received when connecting. +All of this is listed in Listing~\ref{lst:mtaskdevice}. The definitions of the +message format are explained in the following section. \begin{lstlisting}[language=Clean,caption={Device type},label={lst:mtaskdevice}] +deviceStore :: Shared [MTaskDevice] + :: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool) :: MTaskResource = TCPDevice TCPSettings @@ -76,8 +89,75 @@ connect it will set the \CI{deviceError} field to notify the user. , deviceTasks :: [MTaskTask] , deviceData :: MTaskResource , deviceSpec :: Maybe MTaskDeviceSpec + , deviceShares :: [MTaskShare] } +channels :: MTaskDevice -> Shared Channels + class MTaskDuplex a where synFun :: a (Shared Channels) -> Task () \end{lstlisting} + +\section{Communication} +All \gls{mTask} messages are encoded following the specification given in +Appendix~\ref{app:communication-protocol}. Available messages are: +\begin{lstlisting}[language=Clean,caption={Available messages}] +:: MTaskMSGRecv + = MTTaskAck Int Int | MTTaskDelAck Int + | MTSDSAck Int | MTSDSDelAck Int + | MTPub Int BCValue | MTMessage String + | MTDevSpec MTaskDeviceSpec | MTEmpty + +:: MTaskMSGSend + = MTTask MTaskInterval String | MTTaskDel Int + | MTShutdown | MTSds Int BCValue + | MTUpd Int BCValue | MTSpec + +:: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int +\end{lstlisting} + +\subsection{Add a device} +A device can be added by filling in the \CI{MTaskDevice} record as much as +possible and running the \CI{connectDevice} function. This function grabs the +channels, starts the synchronization \gls{Task}, makes sure the errors are +handled when needed and runs a processing function in parallel to react on the +incoming messages. Moreover, it sends a specification request to the device in +question to determine the details of the device and updates the record to +contain the top-level \gls{Task}-id. All the device functionality heavily +depends on the \CI{withDevices} function that applies a function a device in +the \gls{SDS} when they are equal. Device equality is defined as equality on +their channels. This allows you to give an old device record to the function +and still update the latest instance. Listing~\ref{lst:connectDevice} shows the +connection function. + +\begin{lstlisting}[language=Clean,label={lst:connectDevice},% + caption={Connect a device}] +withDevices :: MTaskDevice (MTaskDevice -> MTaskDevice) -> Task [MTaskDevice] + +connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels +connectDevice procFun device = let ch = channels device + in appendTopLevelTask 'DM'.newMap True + (procFun device ch -||- catchAll (getSynFun d.deviceData ch) errHdl) + >>= \tid->withDevices device (\d->{d&deviceTask=Just tid,deviceError=Nothing}) + >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch + where + errHdl e = withDevices device (\d->{d & deviceTask=Nothing, deviceError=Just e}) @! () +\end{lstlisting} + +Figure~\ref{fig:handshake} shows the connection diagram. The client responds to +the server with their device specification. This is detected by the processing +function and the record is updated accordingly. + +\begin{figure}[H] + \begin{sequencediagram} + \newthread{c}{Server} + \newinst[4]{s}{Client} + \mess{c}{MTSpec}{s} + \mess{s}{MTDevSpec d}{c} + \end{sequencediagram} + \caption{Connect a device}\label{fig:handshake} +\end{figure} + +\subsection{\glspl{Task}} +\subsection{\glspl{SDS}} +\todo{Connectie, hoe gaat dat in zijn werk}