For PI, there is the C++ bare metal project Circle. All the power of the PI, with much access to the HW, and none of the timing issues.
There's knowing the time, which you can do with something like NTP. That the RPI can manage just fine.
And there's acting with precise timing, eg, if you need to control a mechanism and reliably react on a deadline of a few ms. A RPI doesn't perform well there, which is why 3D printers use microcontrollers instead.
A long time ago, I was playing with Project Nerves on an Orange Pi running some flavor of debian. I was doing some I2C transaction (at 400 kHz, each bit is single-digit microseconds), and I ultimately had to have a re-attempt loop because the transaction would fail so often. I found a failure cutoff of 5 attempts was sufficient to keep going. I don't recall the failure rate, but basically, whenever a transaction failed, I'd have to reattempt 2-3 times before it eventually succeeded.
Meanwhile, on a bog-standard Arduino with an ATMega328P, I send the I2C traffic once, and unless the circuit is physically damaged, the transaction will succeed.
Seriously, stick a scope or logic analyser on e.g. an I2C line and look at the timing consistency. Even on specialised kernels for realtime use, you can have variable timing delays between each transaction on the bus. And this is all in-kernel stuff that's inconsistent--it looks like it's getting pre-empted during a single I2C_RDWR transaction between receipt of one response and sending of the next message. The actual transmission timing under control of the hardware peripheral is really tight, but the inter-transmission delays are all over the place. Compare it with an MCU where the timing is consistent and accurate, and it's night and day.
> control a mechanism and reliably react on a deadline of a few ms
I actually did measure this with an oscilloscope on embedded Linux (not a raspberry pi). A PPS signal was fed into Linux, and in response to the interrupt Linux sent a tune command to a radio. Tuning the radio itself had some unknown latency.
End-to-end, including the unknown latency of tuning the radio, I never observed a latency that would even round to 1 ms. That's unpatched and untuned Linux, no PREEMPT_RT. I didn't dig any further because it met our definition of "reliable" and was well, well within our timing budget.
I'll be the first to admit it wasn't some kind of rigorous test, just a casual characterization. I would not suggest anyone use Linux for a pacemaker, airplane flight controller, etc.
This is making me itch to buy an oscilloscope and run some more thorough tests. I'd like to see how PREEMPT_RT, loading, etc changes things.
What is acceptable does of course depend upon the requirements of your application, and for many applications Linux is perfectly acceptable. However, for stricter requirements Linux can be a completely inappropriate choice, as can A-profile cores. They are not designed or intended for this type of use.
Profiling this stuff is a really interesting challenge, particularly statistical analysis of all of the collected data to compare different systems or scenarios. I've seen some really interesting behaviours on Linux when it comes to the worst-case timings, and they can occasionally be shockingly bad.
Eg, your process can randomly get stuck because something in the background is checking for updates and IO is being much slower than usual, or the system ran out of RAM and everything got bogged down by swap.
On a microcontroller you just don't have anything else running, so those risks don't exist. Eg, a 3D printer controls a MOSFET to enable/disable the heaters. The system can overheat and actually catch on fire if something makes the software get bogged down badly enough. On a Linux system there's a whole bunch of stuff that can go wrong, most of which is completely outside the software you actually wanted to run.
Sure, a single purpose MCU controlling a heater MOSFET has a lot fewer failure modes than a Linux device doing the same.
I don't dispute there are a lot fewer ways it's even possible for that system to misbehave.
The original comment was recommending ESP32s over Raspberry Pis for DIY projects like opening your curtains or flashing LEDs. The ESP IDF runs on FreeRTOS, so we're already moving away from the bulletproof single task MCU. People will almost certainly be adding some custom rolled HTTP webserver on top. They might be leaking memory all over the place, there are probably all kinds of interrupts they have no idea about firing off in the background. I wouldn't trust an ESP32 curtain-bot not to strangle me any more than I'd trust a Raspberry Pi based one.
Your example about running out of RAM seems just as relevant to MCUs. You can leak memory and crash an MCU. You can overload an MCU with tasks and degrade performance. You can use cgroups or ulimit to help prevent a bad process from bringing Linux down.
I agree that Linux is not going to be as reliable as going baremetal, and I'm not recommending you use it as a motor controller. But even the most reliable MCU can fail. An MCU can get hit by cosmic rays or ESD. People might spill water on the 3d printer or physically damage it. It's not even a binary "works right or dies" thing. I've voltage glitched MCUs to get them to skip instructions and get into an unanticipated state.
In any case, the best path to safety is to imagine that the computer might be taken over by Skynet and do everything in its power to kill you. Or worse, ruin your print. If safety is the goal it's probably best to achieve through requiring the computer system to take some positive action to keep the heater on. Or even better, a feedback safety mechanism like a thermal fuse.
Access to most of the hardware and real-time deterministic behavior. It’s a really great project and lets you twiddle those gpio pins at ridiculous speeds with perfect timing (less than a millisecond).
A PI comes with a whole bunch of great hardware baked in, so if you have one laying around, and want to do some microcontroller stuff, I think it’s a great choice.
There are a bunch of clocks that run plenty fast to enable high resolution timing as well.
Low latency can be a good thing, but it's also not related to consistency, particularly when you start looking at what the worst-case scenario can be.
The A-profile cores are for throughput and speed, not for accurate or consistent timing. However, you can disable both the cache and the MMU, if you want to, which will get you much closer to the behaviour of a typical M-profile core, modulo the use of SRAM and XIP. If you're running bare metal with your own interrupt handlers, you should get good results, excepting for the above caveats, but I don't think you'll be able to get as accurate and consistent results as you would be above to achieve with an MCU. But I would love to be proven wrong.
While most of my bare metal experience has been with ST and Nordic parts, I've recently started playing around with a Zynq 7000 FPGA which contains two A9 A-profile cores and GIC. It's a bit more specialised than the MPU since you need to define the AXI buses and peripherals in the FPGA fabric yourself, but it has the same type of interrupt controller and MMU. It will be interesting to profile it and see how comparable it is to the RPi in practice.
Having said that, I think some of the concerns have fairly simple mitigations. Because of the high clock speed, I can’t see that disabling cache and MMU is required. The maximum “stall times” from either of these components should still fall well below what would be needed. It’s bounded non determinism. That’s completely different to running things under Linux.
Secondly, having multiple cores allows for offloading non-deterministic operations. The primary core can be used for real-time, while still allowing non-deterministic operations on others. The only thing to consider is maximum possible time for synchronization (for which there are some helpful tools).
As I said, I’m far from an expert. It was close to 20 years ago when I last did embedded development for a job, and I was a junior back then anyway. Still, I’d be interested to know if you think I’m way off beam.
There are certainly multi-core MPUs and MCUs with a mixture of cores. The i.MX series from NXP have multi-core A7s with an M4 core for realtime use. Some of the ST H7 MCUs have dual M7 and M4 cores for partitioning tasks. There are plenty of others as well, these are the ones I've used in the past and present.
MCU interrupt latency can be extremely deterministic. I ran some measurements for work and found Linux to be adequate for many uses, but it is a valid concern. There are some Linux kernel patches like PREEMPT_RT that attempt to bound Linux latencies, but generally MCUs are a lot better suited if latency is critical. In part because they just have less software running on them to interfere with timing.