responsive

Embedded Firmware Development for Hardware Products

Hardware is the skeleton of a product, but it does not do anything on its own. A board can be designed, fabricated and assembled correctly and still fail to perform because the code that is supposed to drive it was written late, written by someone who never saw the schematic, or written around a hardware problem that nobody diagnosed. Keeping the hardware and the firmware development inside one team removes that gap, and it is the reason an embedded firmware group works beside the layout team rather than after it.

The Platforms Covered

Work is carried out on the mainstream microcontroller families, including the STM32 and GD32 ranges, the NXP families, the PIC and SAM devices and the MSP430 and C2000 parts, together with a number of domestic Chinese alternatives. The choice of platform follows the function the product needs, the cost target and what can actually be bought in the quantities required, and not the preference of the engineer.

Wireless and internet of things products add a communication module, and the modules in use cover wireless networking, Bluetooth, ZigBee, narrowband cellular, LoRa and full cellular data. Working with a module means working with its command set and its development environment, and the usual functions built on top are the connection to a network, the uploading of data and the remote control of the device.

Where the product is more than a simple control loop, the code is built on a real time operating system so that the response time and the stability of the system can be reasoned about. FreeRTOS, RT-Thread and uC/OS are all in use. Products that need a graphical interface or a complex network stack are supported on an embedded Linux platform instead.

The interfaces that have to be driven are the ordinary ones, including the serial port, SPI, I2C, USB, CAN, analog to digital conversion and pulse width modulation. Most of the work is written in C, with C++ where the structure of the product suits it and assembly only where a low level optimisation actually requires it.

firmware engineer working on embedded code

What the Work Consists Of

A device driver is the level that connects the hardware to everything above it, and it is where an error becomes expensive. The internal peripherals of the microcontroller are the first layer: the ports, the serial ports, SPI and I2C buses, the converters, the timers and the pulse width modulators. The second layer covers the parts outside the chip, such as a display, a touch panel, a sensor, a memory device or a motor driver. The third covers the communication interfaces, including USB, CAN, Ethernet and RS485, with the protocol stack above them.

Power consumption is treated as a design requirement rather than as an afterthought. For a product that runs on a battery, the difference between a board that lasts a week and one that lasts a month is decided by how the code uses the sleep modes, the wake sources and the peripherals, and that decision is made while the hardware is still being chosen.

Above the drivers sits the application. Data acquisition and processing, the interface presented to the user through keys, a display or indicators, control algorithms for a motor, a power stage or a temperature loop, communication protocols such as Modbus, MQTT, HTTP or a customer specific format, data storage and logging, and the remote update mechanism all belong to this level.

A remote OTA update mechanism is normally part of the application work, because a product that has to be returned to a service centre to change a line of code has a very expensive support model. The update has to be fail safe: the new image is verified before it is applied, the old one is kept until the new one has run, and a loss of supply in the middle of the transfer does not leave a device that cannot start. Where a customer already has a hardware design and a first version of the code that suffers from faults, poor performance or instability, the work becomes diagnosis and improvement: correcting logic errors, tuning performance, reducing memory use and restructuring the code so that the next change is less risky than the last one.

How the Quality Is Held

Every project follows the same sequence from requirements through architecture, coding, unit test, integration test and system test, which is what makes progress visible rather than a matter of opinion. The code is held in version control, so every change is recorded against a date and a reason and can be restored when a change turns out to be wrong.

A common coding standard is applied, with naming that says what a value is and comments that say why a decision was taken. Critical sections are reviewed by a second engineer, which is the cheapest way to find the faults that a single author cannot see. At the end of the project the customer receives the full source tree, including its history, together with the documentation needed to build it.

embedded board connected to a debug probe

Hardware and Software in One Team

The strongest argument for keeping both disciplines with one group is that the boundary between them is where most schedule overruns live. When a symptom appears on a prototype, the first question is whether it is a hardware problem or a software problem, and a single team answers that question internally in an hour rather than exchanging messages for a week.

Cooperation also works forwards. During hardware selection, the firmware engineer comments on the microcontroller chosen, the memory available, the pins allocated and the interfaces exposed, so that a design is not completed and then found to be difficult to program. During debugging, the hardware and the code can be changed in the same conversation, and at handover the customer receives one set of documents covering the schematic, the board, the bill of materials, the firmware source and the test report.

Further iterations are easier for the same reason. When the product is upgraded, the hardware and the software can move together in one plan rather than in two that have to be reconciled.

Deliverables and the Commercial Side

The deliverables are the source code, the build environment description and the technical documentation, and the intellectual property in custom developed code belongs to the customer once the project is accepted. Where an open source component is used, its licence is identified in the documentation and the obligation it carries is stated rather than discovered later.

Cost is estimated from the work content, which is the number of engineer days the requirement is expected to take, and it is broken down so that the customer can see where the effort sits. Payment is normally staged, with the source released on acceptance, and additional functions requested later are quoted against the additional work.

A customer who has hardware and no firmware can hand over the schematic or a working sample together with the functional requirement, and the hardware is assessed before the work begins to confirm that it can support what is being asked of it. Where the assessment identifies a change that the hardware needs, that change is reported rather than worked around in the code.

Our PCB design and layout group works with the same firmware team, and the resulting design goes into PCB manufacturing and prototype assembly as a single order.

Working With a Customer Who Has No Code Yet

`r`n

The starting point is a requirement rather than a specification of the implementation. The customer describes what the product does, how a user operates it, what it connects to and what has to happen when something goes wrong, and the engineer turns that into a structure. Disagreements are almost always about something that was assumed rather than stated, which is why the requirement is written down and agreed before the coding begins.

`r`n

A prototype is normally delivered in stages so that the customer can see the behaviour early, when a change is still inexpensive. Reporting progress only at the end is the pattern that produces a product nobody asked for, delivered on time to nobody’s benefit.

`r`n

FAQ

How long does firmware take? A simple acquisition and display task may take one to two weeks. A product with communication and a control algorithm usually takes three to six weeks, and a complex product takes two to three months or more.

Who owns the code? The customer, for custom developed work, with the source and the documentation handed over on acceptance.

Can you start from hardware that already exists? Yes, provided the schematic or sample and the functional requirement are available so that the hardware can be assessed first.

Leave A Comment