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
]
32 :: ByteCode a p = BC (RWS ()
[BC
] BCState ())
34 :: RWS r w s a = RWS (r s -> (a, s, w))
35 :: BC = BCNop | BCPush BCValue | ...
36 :: BCValue = E.e: BCValue e & mTaskType, TC e
37 :: BCShare =
{ sdsi :: Int, sdsval :: BCValue, sdsname :: String
}
38 :: BCState =
{ freshl :: Int, freshs :: Int, sdss ::
[BCShare
] }
40 class mTaskType a | toByteCode, fromByteCode, iTask, TC a
41 class toByteCode a :: a -> String
42 class fromByteCode a :: String -> a
44 instance ByteCode arith, boolExpr, ...
48 \begin{frame
}[fragile
]
49 \frametitle{Implementation
}
51 \item Reader Write State Transformer Monad
52 \item Write instruction
54 \item Hand-crafted helpers
56 \begin{lstlisting
}[language=Clean
]
57 op2 :: (ByteCode a p1) (ByteCode a p2) BC -> ByteCode b Expr
58 op2 (BC x) (BC y) bc = BC (x >>| y >>| tell
[bc
])
60 tell2 ::
[BC
] -> (ByteCode a p)
63 instance arith ByteCode where
64 lit x = tell2
[BCPush (BCValue x)
]
65 (+.) x y = op2 x y BCAdd
70 \begin{frame
}[fragile
]
71 \frametitle{Control flow
}
74 \item Label are resolved
79 \begin{lstlisting
}[language=Clean
]
80 :: BC = ... | BCLab Int | ...
82 freshlabel = get >>=
\st=:
{freshl
}->put
{st & freshl=freshl+
1} >>| pure freshl
86 IF b t e = BCIfStmt b t e
87 (?) b t = BCIfStmt b t (tell`
[])
89 BCIfStmt (BC b) (BC t) (BC e) = BC (
90 freshlabel >>=
\else->freshlabel >>=
\endif->
91 b >>| tell
[BCJmpF else
] >>|
92 t >>| tell
[BCJmp endif, BCLab else
] >>|
93 e >>| tell
[BCLab endif
]
98 \begin{frame
}[fragile
]
99 \frametitle{Assignment and SDSs
}
100 \begin{lstlisting
}[language=Clean
]
101 instance sds ByteCode where
102 sds f =
{main = BC (freshshare
103 >>=
\sdsi->pure
{BCShare|sdsname="",sdsi=sdsi,sdsval=BCValue
0}
104 >>=
\sds->pure (f (tell2
[BCSdsFetch sds
]))
105 >>= \(v In bdy)->modify (addSDS sds v)
106 >>| unBC (unMain bdy))
109 instance assign ByteCode where
110 (=.) (BC v) (BC e) = BC (e >>| censor makeStore v)
112 addSDS sds v s =
{s & sdss=
[{sds & sdsval=BCValue v
}:s.sdss
]}
114 makeStore
[BCSdsFetch i
] =
[BCSdsStore i
]
115 makeStore
[BCDigitalRead i
] =
[BCDigitalWrite i
]
116 makeStore
[...
] =
[...
]
120 \begin{frame
}[fragile
]
121 \frametitle{Bandwidth is scarce
}
122 Publish SDS explicitly
126 pub :: (v t Upd) -> (v () Stmt)
128 instance sdspub ByteCode where
130 = BC (censor (\
[BCSdsFetch s
]->
[BCSdsPublish s
]) x)
134 \begin{frame
}[fragile
]
135 \frametitle{Task scheduling
}
136 \begin{block
}{Arduino C++ system
}
139 \item Tasks start other tasks
143 \begin{block
}{Interpreted Bytecode system
}
144 \begin{itemize
}[<+->
]
145 \item Task accompanied with strategy
146 \item \CI{OnShot
},
\CI{OnInterval
},
\CI{OnInterrupt
}
147 \item How to handle termination?
150 \begin{lstlisting
}[language=Clean
]
158 \begin{frame
}[fragile
]
160 \begin{itemize
}[<+->
]
161 \item Standard C client software
162 \item Modular implementation
163 \item Specification generated from the macros
166 \begin{lstlisting
}[language=C,caption=
{interface.h
}]
168 #elif defined TARGET_STM32F767ZI
174 #elif defined ARDUINO_ESP8266_NODEMCU
176 bool input_available(void);
177 uint8_t read_byte(void);
178 void write_byte(uint8_t b);
181 void write_dpin(uint8_t i, bool b);
186 \begin{frame
}[fragile
]
188 \begin{itemize
}[<+->
]
189 \item Heap is there, but inefficient
190 \item Allocate space in global data
194 \item Compacting on removal
197 \begin{lstlisting
}[language=C
]
201 unsigned long lastrun;
208 \begin{frame
}[fragile
]
209 \frametitle{Interpreter
}
210 Stack machine, modular
212 \begin{lstlisting
}[language=C
]
213 #define f16(p) program
[pc
]*
265+program
[pc+
1]
215 void run_task(struct task *t)
{
216 uint8_t *program = t->bc;
217 int plen = t->tasklength, pc =
0, sp =
0;
219 switch(program
[pc++
])
{
221 stack
[sp++
] = pc++ //Simplified
224 stack
[sp-
2] = stack
[sp-
2] + stack
[sp-
1];
228 pc = stack
[--sp
] ? program
[pc
]-
1 : pc+
1;
237 \begin{frame
}[fragile
]
238 \frametitle{Device storage
}
239 \begin{lstlisting
}[language=Clean
]
240 :: Channels :== (
[MTaskMSGRecv
],
[MTaskMSGSend
], Bool)
242 = TCPDevice TCPSettings
243 | SerialDevice TTYSettings
246 { deviceTask :: Maybe TaskId , deviceError :: Maybe String
247 , deviceChannels :: String , deviceName :: String
248 , deviceState :: BCState , deviceTasks ::
[MTaskTask
]
249 , deviceResource :: MTaskResource
250 , deviceSpec :: Maybe MTaskDeviceSpec
251 , deviceShares ::
[MTaskShare
]
254 channels :: MTaskDevice -> Shared Channels
256 class MTaskDuplex a where
257 synFun :: a (Shared Channels) -> Task ()
262 \frametitle{SDS storage
}
263 \begin{block
}{Approaches
}
264 \begin{itemize
}[<+->
]
265 \item One SDS per SDS
266 \item One SDS per Device and map
267 \item One SDS in the entire system and map
273 \begin{block
}{Notifications
}
274 \begin{itemize
}[<+->
]
275 \item Tasks monitoring the SDSs
276 \item Parametric lenses!
281 \begin{frame
}[fragile
]
283 \framesubtitle{Parametric Lenses
}
284 \begin{block
}{What is the
\CI{p
} for in
\CI{RWShared p r w
}}
287 \item Parameter fixed when writing
288 \item Used for notifications
289 \item On write the SDS returns
\CI{p -> Bool
}
293 \begin{lstlisting
}[language=Clean
]
294 sdsFocus :: p1 (RWShared p1 r w) -> RWShared p2 r w | iTask p
298 \begin{frame
}[fragile
]
299 \frametitle{Solve the notification problem and how to relay information?
}
301 \item Tailor made share
302 \item The read and write functions have the World
308 \begin{lstlisting
}[language=Clean
]
309 :: P :== Maybe (MTaskDevice, Int)
310 deviceStore :: RWShared P
[MTaskDevice
] [MTaskDevice
]
311 deviceStore = SDSSource
{SDSSource
312 | name="deviceStore", read=realRead, write=realWrite
}
314 realDeviceStore :: Shared
[MTaskDevice
]
315 realDeviceStore = sharedStore "mTaskDevices"
[]
317 realRead :: P *IWorld -> (MaybeError TaskException
[MTaskDevice
], *IWorld)
318 realRead p iw = read realDeviceStore iw
323 \begin{lstlisting
}[language=Clean
]
324 realWrite :: P
[MTaskDevice
] *IWorld
325 -> (MaybeError TaskException (SDSNotifyPred P), *IWorld)
327 # (merr, iw) = write w realDeviceStore iw
328 | isNothing mi = (Ok $ gEq
{|*|
} mi, iw)
329 # (Just (dev, ident)) = mi
330 | ident == -
1 = (Ok $ gEq
{|*|
} mi, iw)
331 = case find ((==)dev) w of
332 Nothing = (Error $ exception "Device lost", iw)
333 Just
{deviceShares
} = case find (
\d->d.identifier == ident) deviceShares of
334 Nothing = (Error $ exception "Share lost", iw)
335 Just s = case sendMessagesIW
[MTUpd ident s.MTaskShare.value
] dev iw of
336 (Error e, iw) = (Error e, iw)
337 (Ok _, iw) = (Ok $ gEq
{|*|
} mi, iw)
342 \begin{frame
}[fragile
]
343 \frametitle{Specific SDS functions
}
345 deviceStoreNP :: Shared
[MTaskDevice
]
346 deviceStoreNP = sdsFocus Nothing deviceStore
348 deviceShare :: MTaskDevice -> Shared MTaskDevice
349 deviceShare d = mapReadWriteError
350 (
\ds->case find ((==)d) ds of
351 Nothing = exception "Device lost"
353 ,
\w ds->case splitWith ((==)d) ds of
354 (
[], _) = Error $ exception "Device lost"
355 (
[_
], ds) = Ok $ Just
[w:ds
])
356 $ sdsFocus (Just (d, -
1)) deviceStore
358 shareShare :: MTaskDevice MTaskShare -> Shared BCValue
363 \subsection{Communication
}
365 \frametitle{The glue of the system
}
367 \begin{block
}{Communication
}
369 \item Compile, send and interact with Tasks
370 \item Interact with SDSs
371 \item All communication via channels
376 \begin{frame
}[fragile
]
377 \frametitle{Messages
}
378 \begin{lstlisting
}[language=Clean
]
381 :: MTaskFreeBytes :== Int
383 = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
384 | MTSDSAck MSDSId | MTSDSDelAck MSDSId
385 | MTPub MSDSId BCValue | MTMessage String
386 | MTDevSpec MTaskDeviceSpec | MTEmpty
389 = MTTask MTaskInterval String | MTTaskDel MTaskId
390 | MTShutdown | MTSds MSDSId BCValue
391 | MTUpd MSDSId BCValue | MTSpec
395 \begin{frame
}[fragile
]
396 \frametitle{Connecting with a device
}
397 \begin{lstlisting
}[language=Clean
]
398 process :: MTaskDevice (Shared Channels) -> Task ()
401 makeDevice :: String MTaskResource -> MTaskDevice
403 connectDevice :: MTaskDevice -> Task MTaskDevice
404 connectDevice device = set (
[],
[], False) ch
405 >>| appendTopLevelTask newMap True
406 ( process device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
407 >>=
\tid->upd (
\d->
{d&deviceTask=Just tid,deviceError=Nothing
}) (deviceShare device)
408 >>| set (r,
[MTSpec
],ss) ch
411 errHdl e = upd (
\d->
{d & deviceTask=Nothing, deviceError=Just e
}) (deviceShare device) @! ()
417 \frametitle{Compilation
}
418 \begin{itemize
}[<+->
]
419 \item Get device's compiler state
422 \item Instantiate shares
423 \item Convert to messages
425 \item Send the messages
429 \begin{frame
}[fragile
]
430 \frametitle{Interaction with devices
}
431 \begin{block
}{Send task
}
432 \begin{lstlisting
}[language=Clean
]
433 sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval)
434 -> Task (MTaskTask,
[MTaskShare
])
439 \begin{frame
}[fragile
]
440 \frametitle{Example, blink
}
441 \begin{lstlisting
}[language=Clean
]
445 >>=
\stm->sendTaskToDevice "blink" blinkTask (stm, OnInterval
1000)
446 >>= \(st,
[_,t
])->forever (
447 updateSharedInformation "Which led to blink"
[] (shareShare stm t)
448 ) >>*
[OnAction (Action "Shutdown") $ always
449 $ deleteDevice stm >>| shutDown
0
452 blinkTask = sds
\led=LED1 In sds
\x=True In
{main =
453 ledOff led1 :. ledOff led2 :. ledOff led3 :.
454 IF x (ledOff led) (ledOn led) :.