Dealing with an ESP-IDF project that needs to support many PCB revisions?

squirtle321
Posts: 11
Joined: Tue Jan 11, 2022 9:26 pm

Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby squirtle321 » Tue Sep 13, 2022 5:34 pm

I have an project which has several different PCB revisions, each with different peripheral ICs that the ESP32 communicates with. Each revision has a variety of changes like for example using a different sensor IC, and so I need different functions to communicate with the specific sensor. The application code otherwise remains identical. Until now there were just two PCB revisions, and so I used pre-processor directives to conditionally compile with relevant blocks code.

We are now approaching a third hardware version, and so I want to create a sort of hardware abstraction layer that includes only code relating to that specific PCB revision. That way the code can remain clear, and it will be simple in the future to add changes for new hardware revisions. What I am envisioning is that when I build the project, I could specify the PCB revision I am building for, and the relevant component would be included. When changes are made to the application code, automated CI processes could build for each of the revisions.

For example there could be a component for each PCB revision. Then there would be a header file with interface definitions, for example "uint32_t read_sensor_api()". Each board component would then have the actual implementation for their specific sensor.

What is the best practice with the ESP-IDF build system to accomplish this? Would I need to write CMake instructions? Any help on the direction to go with this would be greatly appreciated.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby ESP_igrr » Thu Sep 15, 2022 6:26 am

Hi squirtle321,
One way to add such "board revision" choice in an IDF based project would be by adding a Kconfig option.
You can get the idea from Kconfig.projbuild and CMakeLists.txt files in this example: https://github.com/espressif/esp-idf/tr ... onfig/main
Hope that helps.

sukeshak
Posts: 50
Joined: Sat Aug 19, 2017 10:20 am
Contact:

Re: Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby sukeshak » Thu Sep 22, 2022 10:50 am

You can check this example to see how I had done it. In my case using same project with ESP32 & ESP32-S3
https://github.com/sukesh-ak/ESP32-LVGL8x-SDSPI

Main issue is that sdconfig file gets overwritten in the project root when you run menuconfig.
This means when you rebuild, it goes through full compile.

I have modified the CMakeList.txt to store the sdconfig inside the build folder. Check readme for details.
https://github.com/sukesh-ak/ESP32-LVGL ... sts.txt#L8

squirtle321
Posts: 11
Joined: Tue Jan 11, 2022 9:26 pm

Re: Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby squirtle321 » Fri Sep 23, 2022 7:10 pm

ESP_igrr wrote:
Thu Sep 15, 2022 6:26 am
Hi squirtle321,
One way to add such "board revision" choice in an IDF based project would be by adding a Kconfig option.
You can get the idea from Kconfig.projbuild and CMakeLists.txt files in this example: https://github.com/espressif/esp-idf/tr ... onfig/main
Hope that helps.

Hi ESP_igrr,

Thank you for the tip, it's been very helpful. I've been working through adapting your linked example and I'm wondering if you have any feedback about my attempt to achieve this board revision choice feature?

This is my project structure:

Code: Select all

application:
    CMakeLists.txt
    sdkconfig
    main:
        CMakeLists.txt
        kconfig.projbuild
        main.c
components:
    hardware_interface:
    	CMakeLists.txt
        foo_interface.h
        bar_interface.h
        version_1:
            foo_implementation.c
            bar_implementation.c
        version_2:
            foo_implementation.c
            bar_implementation.c
    application_code:
    	CMakeLists.txt
        func.h
        func.c
In reality there's several more interfaces and source code files.

The component application_code has "REQUIRES hardware_interface" in its CMakeLists.txt, and the header file func.h has:

Code: Select all

#include "foo_interface.h"
#include "bar_interface.h"
I've made a similar kconfig.projbuild as the example you mentioned, which sets BUILD_VERSION_1 or BUILD_VERSION_2 to true or false:

Code: Select all

menu "Example Product Configuration"
    choice EXAMPLE_FUNC_IMPL
        prompt "Choose the implementation of interfaces defined in the hardware_interface component"
        help
            This setting is used in component CMakeLists.txt.

        config BUILD_VERSION_1
            bool "Hardware version 1"
        config BUILD_VERSION_2
            bool "Hardware version 2"
    endchoice
endmenu

And finally in the CMakeLists.txt in the hardware_interface component, I want to conditionally include the source code in either version_1 or version_2 subdirectories.

Code: Select all

if (BUILD_VERSION_1)
    set(srcs "./version_1/foo_implementation.c" "./version_1/bar_implementation.c")
elseif(BUILD_VERSION_2)
    set(srcs "./version_2/foo_implementation.c" "./version_2/bar_implementation.c")
endif()

idf_component_register(SRCS "${srcs}"
    INCLUDE_DIRS "."
    )
I borrowed the above from https://docs.espressif.com/projects/esp ... figuration.

I am a beginner at working with CMake and ESP-IDF and am wondering if there is a better way to be conditionally compiling with different source code? It feels a little verbose to specify the relative path and name of each file. Any help or a point in the right direction is appreciated.

Thank you!

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby ESP_igrr » Mon Sep 26, 2022 7:39 pm

The project structure you have posted does make sense to me!

Regarding verbosity in CMake, one way to handle it could be to introduce another variable for version name. This will work if every hardware version has the same set of source files. For example:

Code: Select all

menu "Example Product Configuration"
    choice BUILD_VERSION
        prompt "Choose the implementation of interfaces defined in the hardware_interface component"
        help
            This setting is used in component CMakeLists.txt.

        config BUILD_VERSION_1
            bool "Hardware version 1"
        config BUILD_VERSION_2
            bool "Hardware version 2"
    endchoice
    
    # Hidden Kconfig option which gets set to the name of the hardware version
    config BUILD_VERSION
    string
        default "version_1" if BUILD_VERSION_1
        default "version_2" if BUILD_VERSION_2
endmenu

Code: Select all

set(srcs ${CONFIG_BUILD_VERSION}/foo_implementation.c
            ${CONFIG_BUILD_VERSION}/bar_implementation.c)

idf_component_register(SRCS ${srcs}
    INCLUDE_DIRS "."
    )
If you are using CMake 3.15 or later, you can simplify the CMake part this even further, using list(TRANSFORM ... PREPEND) command:

Code: Select all

set(srcs foo_implementation.c bar_implementation.c)

list(TRANSFORM srcs PREPEND "${CONFIG_BUILD_VERSION}/")

idf_component_register(SRCS ${srcs}
    INCLUDE_DIRS "."
    )

squirtle321
Posts: 11
Joined: Tue Jan 11, 2022 9:26 pm

Re: Dealing with an ESP-IDF project that needs to support many PCB revisions?

Postby squirtle321 » Fri Oct 14, 2022 5:16 pm

ESP_igrr wrote:
Mon Sep 26, 2022 7:39 pm
The project structure you have posted does make sense to me!

Regarding verbosity in CMake, one way to handle it could be to introduce another variable for version name. This will work if every hardware version has the same set of source files. For example:

Code: Select all

menu "Example Product Configuration"
    choice BUILD_VERSION
        prompt "Choose the implementation of interfaces defined in the hardware_interface component"
        help
            This setting is used in component CMakeLists.txt.

        config BUILD_VERSION_1
            bool "Hardware version 1"
        config BUILD_VERSION_2
            bool "Hardware version 2"
    endchoice
    
    # Hidden Kconfig option which gets set to the name of the hardware version
    config BUILD_VERSION
    string
        default "version_1" if BUILD_VERSION_1
        default "version_2" if BUILD_VERSION_2
endmenu

Code: Select all

set(srcs ${CONFIG_BUILD_VERSION}/foo_implementation.c
            ${CONFIG_BUILD_VERSION}/bar_implementation.c)

idf_component_register(SRCS ${srcs}
    INCLUDE_DIRS "."
    )
If you are using CMake 3.15 or later, you can simplify the CMake part this even further, using list(TRANSFORM ... PREPEND) command:

Code: Select all

set(srcs foo_implementation.c bar_implementation.c)

list(TRANSFORM srcs PREPEND "${CONFIG_BUILD_VERSION}/")

idf_component_register(SRCS ${srcs}
    INCLUDE_DIRS "."
    )
Thank you, ESP_igrr! My project structure is a lot cleaner now and those CMake tips also saved a lot of characters and lines.

Appreciate it!

Who is online

Users browsing this forum: markkuk and 334 guests