Now that the constants are all set up, the next step is to add some detection code.

There are several ways that PlatformDetect is able to figure out which board and chip you are running and we will go over some of those methods. We start with adding detection for the chip since that will narrow down the number of boards to check. For detecting the chip, there are a number of available functions built-in that make it much easier.

Chip Detection

First we'll start with exploring the various chip detection methods.

Environment Variables

The first thing that PlatformDetect does is look for environment variables. This is used for boards that are more OS independent such as the FT232H and MCP2221, which are meant to be connected directly to a desktop. If none of the variables that it is expecting are found, it goes onto the next method.

Checking Linux

The next thing it does is check if Linux is the environment that it is currently running in and if so, it checks a number of locations that are Linux specific.

Using /proc/cpuinfo

One of the main ways of detecting the processor is by using the information available in /proc/cpuinfo. There is a built-in function called get_cpuinfo_field() that will return the value for a specific field from /proc/cpuinfo.

Using /proc/device-tree/compatible

Another location that is used is /proc/device-tree/compatible. This will return a string that can be matched against a specific value to check for specific chips. The built-in function check_dt_compatible_value() is used checking for specific values easier.

Using /etc/armbian-release

If you are running a release of Armbian, then /etc/armbian-release should be available that will check which board and processor that the specific version of armbian was released for. You will want to use the built-in function get_armbian_release_field().

Using /proc/device-tree/model

If none of those places are an option, another is to get the information from /proc/device-tree/model to get the device model. For this, you will want to use the get_device_model() function.

Using /proc/device-tree/compatible

Finally, another option is to use information available from /proc/device-tree/compatible. To check this, use the built-in get_device_compatible() function.

Adding the Chip Detection

Now that you are more familiar with the detection methods, the next step is to start modifying the code so that your chip is correctly detected. It's easiest to start from the top as the adafruit_platformdetect/chip.py file will try different things and return the chip once it has been correctly identified. Placing your detection code as close to the top means not needing to do any unnecessary processing.

Here's a little gotcha with the chip in hardware. The sun50iw1p1 value that appears in /proc/cpuinfo looks like it should be a unique value, but is a common among several AllWinner chips. The unique value is inside of /proc/device-tree/compatible. We recently ran into this trap and after attempting to add other chips with the same ID, we switched detection methods. The place that worked best for the Pine64 was inside the _linux_id() function where we end up adding the following lines:

if compatible and "sun50i-a64" in compatible:
    linux_id = chips.A64

Board Detection

Once you have the chip being correctly detected, it's time to move onto the board. For board detection, we start with taking the result of the chip detection and run it through a giant if/else if statement. If there are multiple boards using the same chip, we will narrow it down further. If there's only one board, which is often the case, then it's easy and we will just return that board.

Adding Multiple Board Detection

If there are multiple boards we want to create a new function in adafruit_platformdetect/board.py down near the bottom. It should be called something that starts with an underscore, represents the board or chip manufacturer that they have in common, and ends in _id(). In the case of the Pine64, we will go with _pine64_id and since this is part of a class, we need to pass the self parameter, so it ends up being:

def _pine64_id(self):

After that, the function should employ some sort of detection to narrow down which board it is and should return the board constant that you defined earlier. Take a look at some of the other functions for detection ideas. The functions used in chip detection are also available for board detection and we will use get_device_model() for checking which board we have. For the Pine64, here is the full function:

def _pine64_id(self):
    """Try to detect the id for Pine64 board or device."""
    board_value = self.detector.get_device_model()
    board = None
    if 'pine64' in board_value.lower():
        board = boards.PINE64
    elif 'pinebook' in board_value.lower():
        board = boards.PINEBOOK
    elif 'pinephone' in board_value.lower():
        board = boards.PINEPHONE
    return board

In the giant if/else if statement, we want to add the following lines near the bottom right before the return statement:

elif chip_id == chips.A64:
    board_id = self._pine64_id()

The bottom of the statement then becomes:

elif chip_id == chips.A64:
    board_id = self._pine64_id()
return board_id

Additionally, since there are multiple boards that use the same processor, we want to add a convenience property that we can use to check if it is any Pine64 board. This makes things much easier in Blinka. All we need to do is check if the identified board id matches any of our Pine64 board IDs. Here's the code for that function:

@property
def any_pine64_board(self):
    """Check whether the current board is any Pine64 device."""
    return self.id in boards._PINE64_DEV_IDS

This guide was first published on Mar 17, 2020. It was last updated on Mar 17, 2020.

This page (Adding Detection Code) was last updated on Oct 08, 2021.

Text editor powered by tinymce.