add stuff about assignments, class implementation etc
[msc-thesis1617.git] / results.arch.tex
1 \section{Devices}
2 The client code for the devices is compiled from one codebase. For a device to
3 be eligible for \glspl{mTask}, it must be able to compile the shared codebase
4 and implement (part of) the device specific interface. The shared codebase only
5 uses standard \gls{C} and no special libraries or tricks are used. Therefore
6 the code is compilable for almost any device or system. Note that it is not
7 needed to implement a full interface. The full interface --- excluding the
8 device specific settings --- is listed in Appendix~\ref{app:device-interface}.
9 The interface works in a similar fashion as the \gls{EDSL}. Devices do not have
10 to implement all functionality, this is analogous to the fact that views do not
11 have to implement all type classes in the \gls{EDSL}. When the device connects
12 for the first time with a server the specifications of what is implemented is
13 communicated.
14
15 At the time of writing the following device families are supported and can run
16 the device software.
17 \begin{itemize}
18 \item \texttt{POSIX} compatible systems
19
20 This includes systems running \emph{Linux} and \emph{MacOS}.
21 \item \texttt{STM32} family microcontrollers supported by \texttt{ChibiOS}.
22
23 This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
24 development board.
25 \item Microcontrollers programmable by the \gls{Arduino} \gls{IDE}.\\
26
27 This does not only include \gls{Arduino} compatible boards but also
28 other boards capable of running \gls{Arduino} code. The code
29 has been found working on the \texttt{ESP8266} powered \emph{NodeMCU}.
30 It is tested on devices as small as the regular \gls{Arduino}
31 \emph{UNO} board that only boasts a meager \emph{2K} of \emph{RAM}.
32 \end{itemize}
33
34 \section{Specification}
35 Devices are stored in a record type and all devices in the system are stored in
36 a \gls{SDS} containing all devices. From the macro settings in the interface
37 file a profile is created for the device that describes the specification. When
38 a connection between the server and a client is established the server will
39 send a request for specification. The client will serialize his specification
40 and send it to the server so that the server knows what the client is capable
41 of. The exact specification is listed in Listing~\ref{lst:devicespec}
42
43 \begin{lstlisting}[label={lst:devicespec},
44 caption={Device specification for \glspl{mTask}}]
45 :: MTaskDeviceSpec =
46 {haveLed :: Bool
47 ,haveAio :: Bool
48 ,haveDio :: Bool
49 ,bytesMemory :: Int
50 }
51 \end{lstlisting}
52
53 \section{Device Storage}
54 All devices available in the system are stored in a big \gls{SDS} that contains
55 a list of \CI{MTaskDevice}s. The exact specification is listed in
56 Listing~\ref{lst:mtaskdevice} with the accompanying classes and types.
57
58 The \CI{deviceResource} component of the record must implement the
59 \CI{MTaskDuplex} interface that provides a function that launches a task used
60 for synchronizing the channels. The \CI{deviceTask} stores the \gls{Task}-id
61 for this \gls{Task} when active so that it can be checked upon. This top-level
62 task has the duty to report set the \CI{deviceError} field whenever an error
63 occurs. All communication goes via these channels. If the system wants to send
64 a message to the device it just puts it in the channels. Messages sent from the
65 client to the server are also placed in there. In the case of the \gls{TCP}
66 device type the \gls{Task} is just a simple wrapper around the existing
67 \CI{tcpconnect} function in \gls{iTasks}. In case of the serial device type it
68 uses the newly developed serial port library of \gls{Clean}\footnote{\url{%
69 https://gitlab.science.ru.nl/mlubbers/CleanSerial}}.
70
71 Besides all the communication information the record also keeps track of the
72 \glspl{Task} currently on the device and the according \glspl{SDS}. Finally it
73 stores the specification of the device that is received when connecting.
74 All of this is listed in Listing~\ref{lst:mtaskdevice}. The definitions of the
75 message format are explained in the following section.
76
77 \begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}]
78 deviceStore :: Shared [MTaskDevice]
79
80 :: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
81 :: MTaskResource
82 = TCPDevice TCPSettings
83 | SerialDevice TTYSettings
84 :: MTaskDevice =
85 { deviceTask :: Maybe TaskId
86 , deviceError :: Maybe String
87 , deviceChannels :: String
88 , deviceName :: String
89 , deviceTasks :: [MTaskTask]
90 , deviceData :: MTaskResource
91 , deviceSpec :: Maybe MTaskDeviceSpec
92 , deviceShares :: [MTaskShare]
93 }
94
95 channels :: MTaskDevice -> Shared Channels
96
97 class MTaskDuplex a where
98 synFun :: a (Shared Channels) -> Task ()
99 \end{lstlisting}
100
101 \section{Communication}
102 All \gls{mTask} messages are encoded following the specification given in
103 Appendix~\ref{app:communication-protocol}. Available messages are:
104 \begin{lstlisting}[caption={Available messages}]
105 :: MTaskMSGRecv
106 = MTTaskAck Int Int | MTTaskDelAck Int
107 | MTSDSAck Int | MTSDSDelAck Int
108 | MTPub Int BCValue | MTMessage String
109 | MTDevSpec MTaskDeviceSpec | MTEmpty
110
111 :: MTaskMSGSend
112 = MTTask MTaskInterval String | MTTaskDel Int
113 | MTShutdown | MTSds Int BCValue
114 | MTUpd Int BCValue | MTSpec
115
116 :: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int
117 \end{lstlisting}
118
119 \subsection{Add a device}
120 A device can be added by filling in the \CI{MTaskDevice} record as much as
121 possible and running the \CI{connectDevice} function. This function grabs the
122 channels, starts the synchronization \gls{Task}, makes sure the errors are
123 handled when needed and runs a processing function in parallel to react on the
124 incoming messages. Moreover, it sends a specification request to the device in
125 question to determine the details of the device and updates the record to
126 contain the top-level \gls{Task}-id. All the device functionality heavily
127 depends on the \CI{withDevices} function that applies a function a device in
128 the \gls{SDS} when they are equal. Device equality is defined as equality on
129 their channels. This allows you to give an old device record to the function
130 and still update the latest instance. Listing~\ref{lst:connectDevice} shows the
131 connection function.
132
133 \begin{lstlisting}[label={lst:connectDevice},%
134 caption={Connect a device}]
135 withDevices :: MTaskDevice (MTaskDevice -> MTaskDevice) -> Task [MTaskDevice]
136
137 connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels
138 connectDevice procFun device = let ch = channels device
139 in appendTopLevelTask 'DM'.newMap True
140 (procFun device ch -||- catchAll (getSynFun d.deviceData ch) errHdl)
141 >>= \tid->withDevices device (\d->{d&deviceTask=Just tid,deviceError=Nothing})
142 >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch
143 where
144 errHdl e = withDevices device (\d->{d & deviceTask=Nothing, deviceError=Just e}) @! ()
145 \end{lstlisting}
146
147 Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
148 the server with their device specification. This is detected by the processing
149 function and the record is updated accordingly.
150
151 \begin{figure}[H]
152 \begin{sequencediagram}
153 \newthread{s}{Server}
154 \newinst[4]{c}{Client}
155 \begin{call}{s}{MTSpec}{c}{MTDevSpec}
156 \end{call}
157 \end{sequencediagram}
158 \caption{Connect a device}\label{fig:handshake}
159 \end{figure}
160
161 \subsection{\glspl{Task}}
162 \subsection{\glspl{SDS}}
163 \todo{Connectie, hoe gaat dat in zijn werk}