Programming on bare metal
I am surprised by how often I am asked about how one might go about programming on “bare metal” – i.e. without the support of an OS of any kind. Historically, this was a common approach – maybe no other option was available. However, modern engineers, faced with the idea of filling a completely empty memory with their own code, are often somewhat flummoxed …
In the early days of embedded systems development, software was rather minimal and often something of an afterthought. Commonly, it was developed by the same engineer(s) who had designed the hardware and, naturally, their code interacted very closely with the electronics. They understood all the nuances of the hardware’s behavior, so it was not seen as a particular challenge.
As systems became somewhat more sophisticated, software specialists began to be involved, but they tended to be engineers with a significant knowledge and understanding of hardware, so they too were quite happy programming close to the hardware.
As complexity increased, the single software engineer became a team. Different team members would have different types of expertise. Those with good hardware knowledge would encapsulate that expertise in software modules that provided a clean interface and concealed the complexity of hardware interaction; these modules were termed drivers.
With increasingly powerful microprocessors/microcontrollers and larger memories, the need for a rational program structure drove the adoption of real-time operating systems (RTOSes) that enabled the use of a multi-tasking model. It was a natural progression for the drivers to become part of the RTOS.
But, what about programming on bare metal today?
Although the largest proportion of modern embedded software designs are implemented utilizing an OS of some kind, there are a couple of circumstances when doing without – programming on bare metal – may be a reasonable decision:
- If the application is extremely simple and is implemented, perhaps, on a low-end processor.
- If there is a need to extract every last cycle of CPU power for the application and the overhead introduced by an OS is unacceptable.
(1) is a real possibility and makes sense. (2) is much less likely, as powerful CPUs are very readily available and cheap; a careful choice of OS, focusing on high-efficiency RTOS products, would make most sense. In both cases, thought must be given to possible future enhancements to the software. If further development is likely, starting out with a scalable program structure is a worthwhile investment.
A third argument for bare metal programming: hard real time control.
Robotics is an applications that needs hard real time control. Robotics is about motion, of the platform, arms and grippers, as well as sensing the environment. The control loops are updated periodically, at typical rates of 1-10 KHz to insure that the loops do not go unstable.
Major programming languages (C, C++, etc.) are state based have no abstraction for time.
Real time programming happens at the bare metal, where each instruction takes a known execution time. A common approach is to separate the real time programming from the rest of the software. In factory automation, real time control is typically implemented using a Programmable Logic Controller (PLC). The PLC periodically scans its inputs and generates its outputs using bare metal code. Bare metal coding allows the execution time of the code block for the scan is fixed and calculated to be less than the scan interval. Some robot architectures use the same approach, separating real time code from state oriented code.
@David: very good points