3 ms·
This is something that would be extremely useful on microcontrollers, where you do lots of event-driven programming. Any sane design ends up with a state machin
by jwr 8y ago
This is something that would be extremely useful on microcontrollers, where you do lots of event-driven programming. Any sane design ends up with a state machine (or a hierarchy of state machines) driven by events generated in interrupts.
Coming from Clojure, I wished for something like core.async on microcontrollers for a long time — a way to convert most of my state machine into sequential code, with the complexity hidden, all while keeping everything in C (converted/generated during compile).
- microcolonel 8y ago> a way to convert most of my state machine into sequential code Isn't that the norm for state machines in C? while (cont) { switch (v) { case S_STOP: cont = 0; break; ... } } Or are you talking about inlining sequences of transitions into eachother? I've been avoiding core.async so I don't really know what it does that has to do with this.
- jwr 8y agoWith core.async (or go, for that matter), you can write code like: * do one thing * wait for the result of one thing (for example, an event from an interrupt) * take the result and feed it into another thing * wait for the result of another thing So the code looks sequential. It's easy to write and easy to understand. But the entire 'go' block returns immediately: the whole thing gets converted into a state machine (which you don't normally see). That way you don't have to manage the complexity of the state machine yourself. Note that this is not the same thing as threading. Also, it does not require threading at all, for example core.async works just as well in ClojureScript, even though Javascript has no threads.
- dpwm 8y agoYou may be in for a treat if you haven't already come across protothreads [0]. They provide a form of stack-less, co-operative multi-threading and are aimed at microcontrollers. I came across them by chance, and have used them on an ESP8266 – it's really made everything feel much more clear and far less confusing. You do need to wrap your head around the trick, but that really shouldn't take long. You also need to put any state that you expect to be preserved between calls of the function into something more persistent – just like with state machines. The examples all use static variables, but I am happier using a struct pointer to maintain state. [0] http://dunkels.com/adam/pt/ http://dunkels.com/adam/pt/
- jupp0r 8y agoHave you considered C++ coroutines? Imho they struck a really nice tradeoff in making it a language feature and letting you swap out the underlying infrastructure.
- creatornator 8y agoC++ coroutines, being a feature of C++17/C++20, are not present in most if not all micro-controller toolchains, so I'm not sure if it would be relevant for the parent
- jupp0r 8y agoWhat processors are you referring to? Everything ARM is well supported by LLVM/Clang which implements the coroutines TS.
- creatornator 7y agoAVR and PIC? Maybe things have improved since the last time I've explored compilers alternative to those supplied by manufacturers. But from what I understand avr-gcc is the standard for avr, and PIC is just targeted by the manufacturer's compilers.
- jupp0r 7y agoAVR support is pretty bad in LLVM, PIC32 is MIPS, which is well supported afaik. ARM market share is around 50% in embedded microcontrollers afaik [1], so it's definitely possible to use in embedded projects, but might be impossible for your specific platform. [1] https://www.electronicsweekly.com/news/business/arm-market-share-slipping-2018-05/ https://www.electronicsweekly.com/news/business/arm-market-s...
- Matthias247 8y agoIf you are OK with stackful coroutines (that libmill provides) then an RTOS (like freertos) would mostly be the same thing. Context switching for those isn’t as expensive as for PC Threads and processes. If you can’t afford the memory for a dedicated callstack per thread then there are the other event driven models that had been mentioned here. However one loses out one real-time capabilities and priority handling by using those compared to a preemptive RTOS.
- rixed 8y agoHave you considered gnupth, a venerable, solid light-thread library ? I've never used it on a microcontroller and if you work from interrupts you might need to adapt its event loop, but that's still probably the first lib I would try, having successfully used it in large industrial projects in the past. Actually, there were no release since 2006, when the last bug was fixed I guess :+) https://www.gnu.org/software/pth/ https://www.gnu.org/software/pth/