The Case for a firmware platform: Scalability, Degrees of Freedom

In this article we’ll have a look at two of the most important dimensions when designing a firmware platform:

  • Scalability: How do we design for targets with different sets of ressources/compute power?
  • Degrees of freedom: What are degrees of freedom with respect to software?

Disclaimer: I do mention some concrete numbers and productnames in this article. The data quoted will be from official sources (i.e. vendor information!). I do not endorse any of the mentioned products, nor am I in any way sponsored by the vendors to drop their names.

Degrees of freedom

The degrees of freedom that are designed into a software are basically all the extension points that were expected by the architect. This encompasses the hardware as well as the software.

Softwaresize

While we’ll usually want the software to be easily extensible we must bear in mind, that the hardware must be able to support these extensions. An extensible firmware is of little use, if it is constrained to an MCU that has too little flashmemory to allow for extensions. If you’re building a new product, it is probably not feasible to do an exact estimation of how much memory you’ll need, so it’s advisable to choose an MCU where you can have drop in replacements with larger (or smaller) flash sizes.

If you already have a firmware you already have a solid baseline of what the featureset, you require will probably need in terms of flashspace and RAM. Obviously there are some additional variables to be considered here, e.g.:

  • Compiling for a different architecture will yield different codesizes (to some degree).
  • The BSP provided by the silicon vendor might have significant impact (e.g. the ST’s HAL for the STM32 chips consists of a lot of code, and can cause some bloat, depending on how many of the peripherals you actually use).
  • The choice of the operating system will have an impact, e.g. FreeRTOS needs up to 10 KiB of ROM, whereas Segger’s embOS only needs about 1.7 KiB
  • The choice of update mechanism for the device may have an impact on the available flash memory (e.g. if a red-green deployment is used, we might endup only having half the advertised flash size for our application)

A good rule of thumb is, that the first released version of your software should not use more than 70% of the available resources. Depending on the industry your company is active in, your device will have to be supported for a rather long time after the first release (10+ years) – there needs to be enough room for new features to last you through the complete product lifecycle.

Extensionpoints

When we design software systems we should always try to make some guesses as to where the likelihood for an evolution/extension of the software is highest and at least accomodate for extensions. Truth be told, we’ll probably caught with our pants down by the first customer who has some extra wishes that we have not planned for. This is something we can’t realistically plan for. However it is not too far fetched to expect, that a barcode reader might have to support additional barcode types at some point during its lifespan. So, how do we find the most likely areas for extensions?

  • Look at the past: In most companies there will be earlier products, that do something at least similar. Check the development history of these products and make an estimation based on past extensions.
  • Have upcoming trends in mind. Are there any standards or popular protocols in the area you are working in that might gain traction in the future?
  • Look at the constraints that have been put into place in past products. Often we’ll find, that – more or less – arbitrary limitations have been put into place by non-technical people (e.g. product managers) or indee for technical reasons (e.g. available resources). These limitations are subject to change, for a new device.

Price of extensibility

As we’ve previously found out, extensibility and flexibility are some of the core aspects we’ll usually design for, however both of these dimension have pricetags attached. The abstractions involved when we design the system increase complexity and make the design harder to grasp, especially in cases where we can not inspect it while running (e.g. when we only get to stare at the code, because we cannot reproduce an error). Additionally there is usually a price to be paid in terms of required system resources, as a large platform will have a certain minimum footprint, which will increase with the platformsize.

Variants

Depending on your company’s needs the platform will need to run on a variety of targets that do not necessarily provide the same functionality. They may have:

  • Different peripherals
  • Different amounts of resources
  • Different operating systems
  • Different hardware altogether

In practice we should expect all four of these points to hit us at some point, either because the current product lineup already has these characteristics (if not there might not be much of a case for a platform) or because – at some point – parts of the current lineup will be phased out to make room for a new generation of products, at which point we’ll have to face points 2 and 4 at the very least. Since we know this is going to happen at some point we might as well design for it. In the consequence our design should:

  • Not depend on a specific vendor BSP. Indee we should abstract away all hardwarespecific bits.
  • Not make assumptions on the maximum amount of resources/peripherals present (a minimum might be okay).
  • Not depend on a specific operating system, as we might be forced to change (e.g. for smaller devices we might have to use an RTOS while a large, powerful device might have a full-blown OS)

In short: Make assumptions about the evolution of your business logic an build your software to support that evolution, while staying away from concrete hardwaredependencies as much as possible.

..and what about agile?

Since I’m a huge proponent of agile software development I can already hear people shout: “This approach yields a big-design up front, wich will not work yadayadayada”. Listen folks: Agile works best, when the problem domain is completely understood. At this point we’re still trying to figure out what we actually need, and, in true agile fashion we anticipate change and uncertainty. However, at the same time we’re working in a business, where a wrong decision can cost a ton of money down the road, because we cannot fix it with software (i.e. when the hardware was built on wrong expectations), so we’ll at least have to make an educated guess here.

Leave a Reply

Your email address will not be published. Required fields are marked *