3 \frametitle{Current state of mTask
}
5 \item Suits our needs as an EDSL
6 \item It all seems perfect
7 \item \ldots\pause{} but
\ldots
10 \item Compilation requires reprogramming
11 \item Entire system is created and fixed
19 \item New bytecode backend for mTask
20 \item Interpreter on client
21 \item Server in iTasks with integration
22 \item No taskserver generation, onetime programming
23 \item Dynamic task sending
27 \subsection{Extending mTask
}
28 \begin{frame
}[fragile
]
29 \frametitle{Adding a View
}
30 \begin{lstlisting
}[language=Clean
]
31 :: ByteCode a p = BC (RWS ()
[BC
] BCState ())
32 :: BC = BCNop | BCPush BCValue | ...
33 :: BCValue = E.e: BCValue e & mTaskType, TC e
34 :: BCShare =
{ sdsi :: Int, sdsval :: BCValue, sdsname :: String
}
35 :: BCState =
{ freshl :: Int, freshs :: Int, sdss ::
[BCShare
] }
37 instance ByteCode arith, boolExpr, ...
41 \begin{frame
}[fragile
]
42 \frametitle{Implementation
}
44 \item Writing instruction
46 \item Hand-crafted helpers
48 \begin{lstlisting
}[language=Clean
]
49 op2 :: (ByteCode a p1) (ByteCode a p2) BC -> ByteCode b Expr
50 op2 (BC x) (BC y) bc = BC (x >>| y >>| tell
[bc
])
52 tell2 ::
[BC
] -> (ByteCode a p)
55 instance arith ByteCode where
56 lit x = tell2
[BCPush (BCValue x)
]
57 (+.) x y = op2 x y BCAdd
62 \begin{frame
}[fragile
]
63 \frametitle{Control flow
}
66 \item Label are resolved
71 \begin{lstlisting
}[language=Clean
]
72 :: BC = ... | BCLab Int | ...
74 freshlabel = get >>=
\st=:
{freshl
}->put
{st & freshl=freshl+
1} >>| pure freshl
76 instance If ByteCode Stmt Stmt Stmt where If b t e = BCIfStmt b t e
78 BCIfStmt (BC b) (BC t) (BC e) = BC (
79 freshlabel >>=
\else->freshlabel >>=
\endif->
80 b >>| tell
[BCJmpF else
] >>|
81 t >>| tell
[BCJmp endif, BCLab else
] >>|
82 e >>| tell
[BCLab endif
]
87 \begin{frame
}[fragile
]
88 \frametitle{Assignment and SDSs
}
89 \begin{lstlisting
}[language=Clean
]
90 instance sds ByteCode where
91 sds f =
{main = BC (freshshare
92 >>=
\sdsi->pure
{BCShare|sdsname="",sdsi=sdsi,sdsval=BCValue
0}
93 >>=
\sds->pure (f (tell2
[BCSdsFetch sds
]))
94 >>= \(v In bdy)->modify (addSDS sds v)
95 >>| unBC (unMain bdy))
98 instance assign ByteCode where
99 (=.) (BC v) (BC e) = BC (e >>| censor makeStore v)
101 instance sdspub ByteCode where
102 pub (BC x) = BC (censor (\
[BCSdsFetch s
]->
[BCSdsPublish s
]) x)
104 makeStore
[BCSdsFetch i
] =
[BCSdsStore i
]
105 makeStore
[BCDigitalRead i
] =
[BCDigitalWrite i
]
106 makeStore
[...
] =
[...
]
110 \begin{frame
}[fragile
]
111 \frametitle{Bandwidth is scarce
}
112 Publish SDS explicitly
116 pub :: (v t Upd) -> (v () Stmt)
117 instance sdspub ByteCode where
118 pub (BC x) = BC (censor (\
[BCSdsFetch s
]->
[BCSdsPublish s
]) x)
122 \begin{frame
}[fragile
]
123 \frametitle{Task scheduling
}
127 \item Tasks start other tasks
132 \begin{itemize
}[<+->
]
133 \item Old system, taskserver, tasks start tasks
134 \item New system, task+strategy
135 \item \CI{OnShot
},
\CI{OnInterval
},
\CI{OnInterrupt
}
136 \item How to handle termination
139 \begin{lstlisting
}[language=Clean
]
147 \begin{frame
}[fragile
]
149 \begin{itemize
}[<+->
]
150 \item Standard C client software
151 \item Modular implementation
152 \item Specification generated from the macros
155 \begin{lstlisting
}[language=C,caption=
{interface.h
}]
157 #elif defined TARGET_STM32F767ZI
160 #define STACKSIZE
1024
165 #elif defined ARDUINO_ESP8266_NODEMCU
167 bool input_available(void);
168 uint8_t read_byte(void);
169 void write_byte(uint8_t b);
172 void write_dpin(uint8_t i, bool b);
177 \begin{frame
}[fragile
]
179 \begin{itemize
}[<+->
]
180 \item Heap is there, but inefficient
181 \item Allocate space in global data
185 \item Compacting on removal
188 \begin{lstlisting
}[language=C
]
192 unsigned long lastrun;
199 \begin{frame
}[fragile
]
200 \frametitle{Interpreter
}
201 Stack machine, modular
203 \begin{lstlisting
}[language=C
]
204 #define f16(p) program
[pc
]*
265+program
[pc+
1]
206 void run_task(struct task *t)
{
207 uint8_t *program = t->bc;
208 int plen = t->tasklength, pc =
0, sp =
0;
210 switch(program
[pc++
])
{
212 stack
[sp++
] = pc++ //Simplified
215 stack
[sp-
2] = stack
[sp-
2] + stack
[sp-
1];
219 pc = stack
[--sp
] ? program
[pc
]-
1 : pc+
1;
228 \begin{frame
}[fragile
]
229 \frametitle{Device storage
}
230 \begin{lstlisting
}[language=Clean
]
231 :: Channels :== (
[MTaskMSGRecv
],
[MTaskMSGSend
], Bool)
233 = TCPDevice TCPSettings
234 | SerialDevice TTYSettings
237 { deviceTask :: Maybe TaskId , deviceError :: Maybe String
238 , deviceChannels :: String , deviceName :: String
239 , deviceState :: BCState , deviceTasks ::
[MTaskTask
]
240 , deviceResource :: MTaskResource
241 , deviceSpec :: Maybe MTaskDeviceSpec
242 , deviceShares ::
[MTaskShare
]
245 channels :: MTaskDevice -> Shared Channels
247 class MTaskDuplex a where
248 synFun :: a (Shared Channels) -> Task ()
253 \frametitle{SDS storage
}
254 \begin{block
}{Approaches
}
255 \begin{itemize
}[<+->
]
256 \item One SDS per SDS
257 \item One SDS per Device and map
258 \item One SDS in the entire system and map
264 \begin{block
}{Notifications
}
265 \begin{itemize
}[<+->
]
266 \item Tasks monitoring the SDSs
267 \item Parametric lenses!
272 \begin{frame
}[fragile
]
274 \framesubtitle{Parametric Lenses
}
275 \begin{block
}{What is the
\CI{p
} for in
\CI{RWShared p r w
}}
278 \item Parameter fixed when writing
279 \item Used for notifications
280 \item On write the SDS returns
\CI{p -> Bool
}
283 \begin{lstlisting
}[language=Clean
]
284 sdsFocus :: p1 (RWShared p1 r w) -> RWShared p2 r w | iTask p
288 \begin{frame
}[fragile
]
289 \frametitle{Solve the notification problem and how to relay information?
}
291 \item Tailor made share
292 \item The read and write functions have the World
298 \begin{lstlisting
}[language=Clean
]
299 :: P :== Maybe (MTaskDevice, Int)
300 deviceStore :: RWShared P
[MTaskDevice
] [MTaskDevice
]
301 deviceStore = SDSSource
{SDSSource
302 | name="deviceStore", read=realRead, write=realWrite
}
304 realDeviceStore :: Shared
[MTaskDevice
]
305 realDeviceStore = sharedStore "mTaskDevices"
[]
307 realRead :: P *IWorld
308 -> (MaybeError TaskException
[MTaskDevice
], *IWorld)
309 realRead p iw = read realDeviceStore iw
314 \begin{lstlisting
}[language=Clean
]
315 realWrite :: P
[MTaskDevice
] *IWorld
316 -> (MaybeError TaskException (SDSNotifyPred P), *IWorld)
318 # (merr, iw) = write w realDeviceStore iw
319 | isNothing mi = (Ok $ gEq
{|*|
} mi, iw)
320 # (Just (dev, ident)) = mi
321 | ident == -
1 = (Ok $ gEq
{|*|
} mi, iw)
322 = case find ((==)dev) w of
323 Nothing = (Error $ exception "Device lost", iw)
324 Just
{deviceShares
} = case find (
\d->d.identifier == ident) deviceShares of
325 Nothing = (Error $ exception "Share lost", iw)
326 Just s = case sendMessagesIW
[MTUpd ident s.MTaskShare.value
] dev iw of
327 (Error e, iw) = (Error e, iw)
328 (Ok _, iw) = (Ok $ gEq
{|*|
} mi, iw)
333 \begin{frame
}[fragile
]
334 \frametitle{Specific SDS functions
}
336 deviceStoreNP :: Shared
[MTaskDevice
]
337 deviceStoreNP = sdsFocus Nothing deviceStore
339 deviceShare :: MTaskDevice -> Shared MTaskDevice
340 deviceShare d = mapReadWriteError
341 (
\ds->case find ((==)d) ds of
342 Nothing = exception "Device lost"
344 ,
\w ds->case splitWith ((==)d) ds of
345 (
[], _) = Error $ exception "Device lost"
346 (
[_:_
], ds) = Ok $ Just
[w:ds
])
347 $ sdsFocus (Just (d, -
1)) deviceStore
349 shareShare :: MTaskDevice MTaskShare -> Shared BCValue
354 \subsection{Communication
}
356 \frametitle{The glue of the system
}
358 \item Compile, send and interact with Tasks
359 \item Interact with SDSs
360 \item All communication via channels
364 \begin{frame
}[fragile
]
365 \frametitle{Messages
}
366 \begin{lstlisting
}[language=Clean
]
369 :: MTaskFreeBytes :== Int
371 = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
372 | MTSDSAck MSDSId | MTSDSDelAck MSDSId
373 | MTPub MSDSId BCValue | MTMessage String
374 | MTDevSpec MTaskDeviceSpec | MTEmpty
377 = MTTask MTaskInterval String | MTTaskDel MTaskId
378 | MTShutdown | MTSds MSDSId BCValue
379 | MTUpd MSDSId BCValue | MTSpec
383 \begin{frame
}[fragile
]
384 \frametitle{Connecting with a device
}
385 \begin{lstlisting
}[language=Clean
]
386 process :: MTaskDevice (Shared Channels) -> Task ()
389 makeDevice :: String MTaskResource -> MTaskDevice
391 connectDevice :: MTaskDevice -> Task MTaskDevice
392 connectDevice device = set (
[],
[], False) ch
393 >>| appendTopLevelTask newMap True
394 ( process device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
395 >>=
\tid->upd (
\d->
{d&deviceTask=Just tid,deviceError=Nothing
}) (deviceShare device)
396 >>| set (r,
[MTSpec
],ss) ch
399 errHdl e = upd (
\d->
{d & deviceTask=Nothing, deviceError=Just e
}) (deviceShare device) @! ()
405 \frametitle{Compilation
}
406 \begin{itemize
}[<+->
]
407 \item Get device's compiler state
410 \item Instantiate shares
411 \item Convert to messages
413 \item Send the messages
417 \begin{frame
}[fragile
]
418 \frametitle{Interaction with devices
}
419 \begin{block
}{Send task
}
420 \begin{lstlisting
}[language=Clean
]
421 sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval)
422 -> Task (MTaskTask,
[MTaskShare
])
427 \begin{frame
}[fragile
]
428 \frametitle{Example, blink
}
429 \begin{lstlisting
}[language=Clean
]
431 blink = makeDevice "stm32" stm32 >>= connectDevice
432 >>=
\stm-> sendTaskToDevice "blink" blinkTask (stm, OnInterval
1000)
433 >>= \(st,
[t:_
])->forever (
434 updateSharedInformation "Which led to blink"
[] (shareShare stm t)
435 ) >>*
[OnAction (Action "Shutdown") $ always
436 $ deleteDevice stm >>| shutDown
0
439 stm32 = makeDevice "Stm32"
440 (SerialDevice
{devicePath="/dev/ttyUSB0", baudrate=B9600, ...
}
441 blinkTask = sds
\led=LED1 In sds
\x=True In
{main =
442 ledOn LED1 :. ledOn LED2 :. ledOn LED3 :.
443 IF x (ledOff led) (ledOn led) :.