2 Techniques to Version Embedded Hardware

When it comes to embedded systems version control, I often immediately jump to thinking about the software. Software changes often and carefully managing those changes are crucial, but so is versioning the hardware. A small hardware change could obsolesce every version of software up to that hardware change. In todays’ post, we are going to examine two techniques to version hardware that are also software readable so that the software can ensure that it is paired with a compatible hardware version.

Technique #1 – Using GPIO to Hard Code PCB Versions

The first technique that we are going to discuss is how to use GPIO lines on the microcontroller to provide a readable PCB version number. Nearly every PCB I have ever seen puts the hardware version number on the PCB silkscreen, but the system software can’t read the silkscreen like a human can (at least not yet). Hardware can change considerably between versions and it can be critical to ensure that a certain software version runs on specific hardware. To accomplish this, the software needs to be able to read the hardware version number directly from the PCB to make sure that it is running on compatible hardware.

A common way to version the hardware is to use a few spare GPIO lines as a dedicated hardware version number. Each GPIO line can be either pulled to VCC (represents a 1) or ground (represents a 0). If a binary representation is used, two GPIO would provide up to four versions while three GPIO would provide eight versions as shown below:

Version GPIO 0 GPIO 1 GPIO 2
Version 1 0 0 0
Version 2 0 0 1
Version 3 0 1 0
Version 4 0 1 1
Version 5 1 0 0
Version 6 1 0 1
Version 7 1 1 0
Version 8 1 1 1

When the software starts, it can initialize the GPIO lines and then read the PCB version number and determine if the software supports the hardware. If everything is good, then the software runs the application.

There are a few gotchas with using GPIO lines though. First, there has to be free GPIO lines on the microcontroller. If the design is dense or using a low-pin count microcontroller, there may not be two or three GPIO lines to use for versioning. Second, we need to make sure that the resistors that are used to pull the GPIO line high or low are approximately sized so that we do not end up with a large leakage current. Third, when the boards are manufactured, we need to verify that the version number was properly updated so that we don’t end up with boards with the wrong version number due to a manufacturing error.

Technique #2 – Using an Analog-To-Digital Converter to Hard Code Versions

Not all systems will have two or three free GPIO lines available. An alternative solution to versioning the PCB is to leverage a free analog to digital (ADC) channel. An ADC channel will often have a range from 0 to 3.3 volts (although some may have 0 – 1.7 or 0 – 5.0) that we can breakup into different voltage ranges to represent different board versions. For example, a standard 12-bit ADC channel will have a range from 0 – 4095 that we could breakup into eight different versions as shown below:

Version ADC Low ADC High
Version 1 0 512
Version 2 513 1024
Version 3 1025 1536
Version 4 1537 2048
Version 5 2049 2560
Version 6 2561 3072
Version 7 3073 3584
Version 8 3584 4095

The goal is to create a resistive ladder circuit where the mid-point of the ladder is connected to the ADC pin. The values for the resistors should be selected so that they fall within the midpoint for our range. For example, version one should select resistors that product a voltage of ~0.206 which corresponds to ~256 counts. When a version 2 of the board is ready, the resistor ladder is updated to produce a voltage of ~0.618 which corresponds to ~768 counts. When the system boots, the software would read the analog voltage and then determine which version the PCB is at and whether the software is compatible with that hardware version.

Now there are a few points to consider when using the ADC versioning scheme. First, you could easily scale this system to more than eight versions by simply adjusting the range. This is better than having to add additional GPIO pins to reach higher version numbers. Second, just like with the GPIO technique, resistor values need to be appropriately selected in order to minimize leakage current. One way to minimize this current is to have a GPIO line supply the VCC so that the version circuit can be turned off when it is not needed. This does require the use of one additional pin though, but for a low power system can save on precious leakage current. Third, you need to select components whose value are high precision, 1% or better, and won’t de-rate by too much over the products lifetime. This will prevent a version 1 hardware from suddenly becoming a version 2 or version 3 over the course of 5 or 10 years.


As we have seen in today’s post, there are several different ways that developers can version their hardware such that the software can verify that they are running on a known hardware version. This can prevent hardware / software mismatches and ensure that the system itself can verify that it is configured appropriately. We’ve seen that there are at least two techniques to make our PCB version number readable. The technique that you choose will depend on your end goals and the application that you are targeting.

Share >

6 thoughts on “2 Techniques to Version Embedded Hardware

  1. You could use 1,0,hiZ as three possibilities instead of 2 per pin, then 2 pins would get you more combinations than 3 pins with only 1 and 0. The Z is detected by driving the line low, then input, then drive high, and finally input. Pin & board capacitance hold the last drive level for a little while and the hiZ condition is detected when the 2 input stages see different values.

  2. Another useful technique if the CPU doesn’t have enough available GPIOs but has a SPI bus is using a 74HC165 to send rev info serially. This can also be useful for option modules, as there are enough bits to encode both a module ID and a hardware rev.

  3. Thanks! Remember that option 2 requires care in making the correct BOM change (as well as ensuring the correct resistor value is installed). Also, the version voltages do not need to be linear (in case someone wants to use common or available resistor values) as long as the levels are documented.

  4. We have used Technique #2 for years, with an official document specify the resistors to use for each version level.
    Because you only need to check this once at power up, we usually then switch the A/D channel to some other analogue device like a thermistor.

  5. We are using here a somewhat different scheme for hardware version control. The controllers are ATxmega, which allow a hardware fingerprinting by some unique information programmed during chip manufacturing. You then have to ‘only’ keep a data base, which relates the fingerprints to the hardware revisions. As we ensure a tracking of all assembled components, this is for us no additional effort. The read-out of the fingerprint is done during assembled board testing. We are using the fingerprints instead of serial numbers throughout our QM system.
    There are other contollers on the market with similar features.
    You can do the same by using one of those single-wire hw id chips.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.