Hacker News new | past | comments | ask | show | jobs | submit login

Pi Zero will never directly replace something like the arduino. Running linux (or any OS) can be a huge liability when you need to talk to some other bit of hardware that has strict timing requirements. That said, things like the ESP8266 and Arm Cortex M* processors are definitely becoming far more attractive than the AVRs in the lower end Arduino products (Due and others are also using ARM).



> Running linux (or any OS) can be a huge liability when you need to talk to some other bit of hardware that has strict timing requirements.

Not just the timing is critical, also the failure causes (and modes) are far bigger in number when running an OS.

E.g. if you properly code in C or ASM for a microcontroller and avoid things like recursion, it's very hard to crash due to OOM errors.


For what it's worth, you can code bare metal on the Raspberry Pi as well. It just doesn't have the community and support that Arduino currently has. https://github.com/dwelch67/raspberrypi


It also doesn't have the easily available official documentation like you get for a Cortex-M from ST, Atmel, etc.


But you still have a lot less predictability:

- DRAM refresh

- cache hits/misses


There are quite a lot of systems out there with real-time requirements, where the system is not running a real-time predictable operating system - instead the likelihood of a missed deadline are averted simply by over-provisioning. You can get away with murder pretty much this way by just making your processor several times faster than is strictly necessary, provided you don't have any really long pauses in processing (like for instance having to swap in a page from disc). It works well enough most of the time for video playback.

In essence, a job that requires 90% of the CPU time on predictable hardware can often be solved by just throwing faster hardware at it. If the RasPi can do it using 5% CPU, then it's probably fine.

YMMV. Don't do this on medical equipment, space rockets, or self-driving cars.


In the literature, that's often distinguished as soft real-time vs hard real-time requirements. Hard real-time is for when you absolutely cannot miss a deadline without adverse effects (production stalls, equipment crashes, etc), while soft real-time is for situations where missing a deadline is recoverable (like your example, a video renderer would simply skip the current frame and start processing the next frame).


Don't do this on medical equipment

That's funny because I was coming here to say that I built a real-time system running on Windows... for a medical instrument. Windows was fine because speed didn't matter, predictability did, and our latencies were measures in hundreds of milliseconds and Windows has no problem keeping up with that. The only time I saw CPU usage go above 1% was when the instrument was shutting down and had to clean up a lot of objects.


Except that Google's self-driving cars do run Linux (after all, us humans do okay with 250ms latency).

https://www.linux.com/news/linux-leads-self-driving-car-move...


Not in the Pi Zero price range, but the AM335x processor inside the BeagleBone Black has an interesting way to deal with the need for strict timing.

The AM335x has a pair of "PRU" units on the die, that are roughly little microcontrollers that have access to the main ARM's memory.

So, you can write to main memory from Linux, jitter and all, and then let the PRU stream it out to anything that needs high speed, predictable data.

This guy put a BB black inside an old MAC SE, and is driving the CRT with the PRU...very cool: http://www.nycresistor.com/2014/02/02/30th-anniversary-mac/


The AM335x PRU is exactly the Cortex-M core that they were talking about :). It just happens to be on-die with the main core.

Very cool project, thanks for linking!


To be fair, a 8MHz (16MHz?) CPU is also a huge liability when you have strict timing requirements. For almost anything, the Pi will probably give you better guarantees by sheer speed... and you can always compile the kernel with a real-time patch.

Not saying running on the bare metal is worthless, but an Arduino is a really low end board.


Timing requirements don't necessarily translate to _speed_ requirements.

Microcontrollers like the Arduino/Atmel are perfect for situations where you need to guarantee that some signal will be asserted exactly 250 (no more, no less) nanoseconds after some other external event, _no_matter_what_.

Since there's usually no OS running on something like an Arduino, you're basically forced to write very deterministic event driven programs. Also, since most (maybe all) instructions on those Atmel microcontrollers execute in a single clock cycle, you can easily dissect your C functions and know exactly how long they will take to execute.

I wouldn't trust Linux for such an application even with a "real time" scheduler.

Linux as a RTOS certainly has it's place, but it's best left for systems that can actually benefit from the added complexity.

For most typical microcontroller projects, the extra features of a full Linux kernel would just get in the way.

Note: There's nothing stopping someone from using a RPI in such a way as well (bare metal), but they are really geared for more complex applications, so there isn't as much support in that area. Also, the hardware is probably a little more complex. Therefore, my statements assume we're comparing an Arduino to an RPI running Linux.


That's where things like the PRU on the TI chips (Beaglebone being one of them) gets interesting:

http://processors.wiki.ti.com/index.php/PRU-ICSS


>Microcontrollers like the Arduino/Atmel are perfect for situations where you need to guarantee that some signal will be asserted exactly 250 (no more, no less) nanoseconds after some other external event, _no_matter_what_.

What is an example of something like that?


I make two products [1] that both use AVR microprocessors (though not Arduino), and both rely on sub-microsecond accuracy. One is a high-speed LED camera flash. The pulse width needs to be exactly the same every time, and so does the latency, otherwise the shot will be missed. The other is a sound trigger for flahes and cameras. That has to both be as fast as possible, but also exactly the same every time. If you're lining up a photo of a bullet passing through a cherry, you need to know that the bullet will be in the same position every time.

Incidentally, I've written a post[2] about high-resolution timers with Arduino. The normal timing functions are not accurate enough for my sort of work, but the nice thing about Arduino is that you can easily drop down to the native AVR code, or even assembly if you need.

[1] https://www.vela.io/

[2] https://www.vela.io/posts/how-fast-is-your-flash


This post made my day! High speed photography prompted my true diving into the guts of computers. It introduced me to C, in very raw way, by my use of the AVR Butterfly demo board. Prior to that I had only tinkered around with Perl/PHP/Java.

I was able to get pictures like this [1] with a $25 microcontroller board (even cheaper now), about $150 in camera equipment, and a $40 pellet rifle. The setup was simple [2], with just a regular camera flash under a plastic bag (cheap diffuser!) and a configurable delay. The firing of the timer was controlled by the AVR's ADC readout of an electret mic. I ended up delaying about 20 milliseconds for the shots I took. [3] The AVR triggered the flash via an optoisolator relay. Pretty simple, I was glad to find out that even just placing a coin across the contacts will trigger the flash.

Now I'm excited to measure how fast that standard flash really was, with your article's advice. And then, for the cherry on top, compare it to my General Radio 1531-AB stroboscope. [4] It was the cheapest externally triggerable stroboscope that I could find on eBay at the time. I got that flash because it can produce strobes as short as 0.8 microseconds! I really want to recreate an old high speed shot and see the difference between the flashes first hand. But college happened and I haven't touched photography in about a decade. I haven't even taken a darn photo with the stroboscope, I've just turned it on and soothed myself with the rapid and loud clicking. :P I hope your post motivates me!

Your Vela One... so tempting...

[1]: https://www.flickr.com/photos/jevinskie/115619170/

[2]: https://www.flickr.com/photos/jevinskie/112758047/

[3]: https://www.flickr.com/photos/jevinskie/albums/7205759408438...

[4]: http://www.ietlabs.com/1531.html


Nice shots! If you do it again, you might find the AVR's analog comparator is a better route than the ADC. I use an external comparator on an interrupt pin in my sound trigger, which gives more flexibility.

Perhaps I can tempt you further with a discount. Use the code HACKERNEWS for 10% off. That's open to anyone else reading this too, and is valid until next week.


Music, for example. If you're doing audio processing for music, it's much more preferable to have something that takes 20ms consistently to transform an input than something that takes 5ms 90% of the time and 50ms 10% of the time (due to, e.g. interrupts). That 50ms gap will show up as a note that's audibly behind the beat, while the improvement from 20ms to 5ms isn't really that beneficial.

EDIT: another example is controlling a UAV. You can design around a system that consistently takes 20ms to process an input (e.g. by limiting the max speed). It's a lot more difficult to design around a component that takes 5ms most of the time, but will randomly take 50ms here and there, because you don't get to control when those lag spikes happen.


For music, it seems like the rt-linux patch ought to be enough. They claim sub-100 microsecond timing jitter for process wakeup (https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO#Benchm...). That ought to be tiny, if you're talking about audio latency in the range of milliseconds.

For UAVs, you're typically talking to ESCs that want PWM signals in 1-2ms ranges, so 10s of microseconds of jitter would certainly matter for PWM generation, but that's why you'd probably offload that to an external PWM chip, and handle the code that will tolerate 20ms processing times with 100us jitter (like the flight-control loop) on the CPU.

Bare-metal can't be beat for tiny (easily-auditable) code size, and general lack of "what if the timing goes wrong somehow" situations, of course. Plus, who knows if the rt-linux patches would actually perform to that level on a Pi-zero.


My last experience with rt-linux teached me that the kernel is not the only thing that needs to support real-time. As soon as you have any drivers (DMA!) or e.g. Service Management Interrupts (SMIs) that circumvent any smart preemptive scheduler of the kernel you're still screwed. So, what was said is correct, hard real-time is hard, and an OS on top of a "general purpose" hardware platform makes it harder.

That being said, there is stuff like VxWorks, which kind of proves that it is possible, if you have full control over the hardware and the OS.


100μs of jitter is enough to cause major problems if you're bit-banging or doing high-speed closed-loop control. Something like the Bus Pirate is almost trivial to implement on bare metal, but a complete nightmare if there's an OS involved.

RTOSes can be extremely useful, but they're not a perfect substitute for bare metal.

http://dangerousprototypes.com/docs/Bus_Pirate


Well, right, that needs to be a multi-purpose serial interface device, and who knows what crazy timing requirements some sensor or interface chip will need. An example: There are some cheap little radios around. They literally just output a carrier with a binary value encoded on it in a super-simple modulation. Even with an RT device, you've got to keep transmissions very short and include a clock-synch section at the beginning.

You can still transmit and receive if your devices have a lot of jitter, but you'll have to kill your transmission rate to keep things working reliably.


engine management units, camera flashes, LED lights, servo motors and brushless motors to name a few.

Whilst the raspberry pi has the ability generate PWM, you can't guarantee when they run because something else might be scheduled to be on the CPU at the time.

The fancy RGB lights require a precise, complex signal running at ~800KHZ* you can't miss a signal slot because it'll change colour. Its the same for servo motors, although thats more simple as it only needs a static PWM to hold position.

*might be less


I had an temperature and humidity sensor that uses one wire to read and write data from and to it. It has libraries in both Arduino and raspberry pi. The raspberry pi one does much worse and reads data wrong all the times - and given the library was written by ladyada, which is generally high quality code. It is none to her fault - Linux doesn't guarantee the timings - the best that someone could do is to crank the priority to max to get the timings right but even then it is still iffy. Interesting to see, given the raspberry pi has a way higher clock compared to the Arduino.

Note the comment:

https://github.com/adafruit/Adafruit_Python_DHT/blob/master/...

# Note that sometimes you won't get a reading and # the results will be null (because Linux can't # guarantee the timing of calls to read the sensor). # If this happens try again!


Sampling from external sensors for example. If you're measuring something changing over time, you may need very precise timing.


Another specific example would be something like an IRIG-B (DC) timecode decoder where you need to provide a PPS signal that's phase locked to the P0 rising edge or maybe even just display the time. This would be accomplished by implementing a state machine to lock on to the IRIG frame and essentially run a PLL to synchronize one of the local timers. Decoding the IRIG frame would require you to be able to catch every transition of the signal. With a good implementation, you can achieve PPS accuracies to within a few clock cycles (with it being deterministic too).


Yes, but even with rt-linux, you've got a jitter of potentially several dozen microseconds, and each interrupt routine will vary. With an AVR, your delay is 4 clock cycles every time, which comes out to .2 microseconds at 20 Mhz. This is the kind of guarantee you can get with being on an intimate level with the chip which you can't get with any OS.


At least not any OS that's not geared for realtime from the ground up.


It's not just about the OS, it's about the platform (hardware). Even with a fully-optimized RTOS on a standard PC platform, you might run into millisecond-latency due to non-maskable interrupts, cache misses or bus contention (DMA bus-mastering kills any real-time guarantees). That's not even considering the stalls introduced by SMM or TPM instructions.


I would think it would be difficult to achieve the low jitter of a simple, fixed # of cycles / instruction, architecture like AVR in a superscalar, cached, speculative architecture like modern X86 CPUs. A hard RTOS is necessary, but perhaps not sufficient with most X86 microarchs. Maybe you can disable some of that dynamic behavior via MSRs but probably not all.


I think that's confusing liability with speed. Running interrupt-free code on an ARM or AVR is incredibly reliable. I would argue much more reliable than going to the length of patching the kernel.

Just because it's slow doesn't mean you can't predict what's going to happen, they're two separate issues.


Couldn't you write a really simple kernel[1] or bootstrapping program, and effectively run your program without an OS?

Does an architecture (ARM / AVR / x86) limit the possibility of writing real-time code if the code is the OS, and just runs on the bare metal?

Your program would run in ring 0, be the only "process" and have full access to RAM. You decide whether you want to handle interrupts or not. (I assume there's a way to select what interrupts you want to handle.)

[1] For e.g., this tutorial explains how to write a basic x86 kernel: http://www.jamesmolloy.co.uk/tutorial_html/


There's no such thing as bare metal any more. https://en.wikipedia.org/wiki/System_Management_Mode - the CPU itself may at times spend some time doing "other things" such as changing the spin speed of the cooling fans, or interpreting the signals from the USB keyboard. The OS (running in ring 0) has no control over this - the CPU effectively just pauses for a little bit every now and again.


I'm not aware of any ARM systems that have this yet.


TrustZone. It is "one level deeper" just like any other hypervisor or monitor. As far as I know, it is quite common in Android phones for HSM and DRM purposes. Yay? =\

http://www.arm.com/products/processors/technologies/trustzon...

Edit: And, of course, it is probably exploitable in some way. See http://bits-please.blogspot.com/2015/08/exploring-qualcomms-...


Generally there is a trade-off between latency and throughput. Embedded Linux is generally geared towards more throughput than latency. Microcontrollers have less throughput-oriented features (threads, for instance), which makes them very well suited for latency-critical real time stuff.


Can you bit-bang a 640x480 VGA on a Pi? No. Not even in bare metal, no OS. But a lowly attony85 can do it easily.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: