tools/boardgen.py: Make per-pin content output extensible. by agatti · Pull Request #19130 · micropython/micropython · GitHub
Skip to content

tools/boardgen.py: Make per-pin content output extensible.#19130

Open
agatti wants to merge 1 commit intomicropython:masterfrom
agatti:boardgen-afio-extension-point
Open

tools/boardgen.py: Make per-pin content output extensible.#19130
agatti wants to merge 1 commit intomicropython:masterfrom
agatti:boardgen-afio-extension-point

Conversation

@agatti
Copy link
Copy Markdown
Contributor

@agatti agatti commented Apr 20, 2026

Summary

This PR lets classes extending the base PinGenerator class to override the process of generating extra per-pin content when creating the pins' information source file.

There are cases in which one may want to have more control on the part of the source generation process that dumps additional per-pin information to the source file. The current approach works fine if each pin generates self-contained additional data to be placed in the source file, but there is no clean way to provide a prologue or an epilogue to that content.

For example, if one wants to emit a single consolidated additional pin data table it is not that convenient to be able to consistently emit the table start definition and the table end markers. With these changes all one has to do to achieve this is to override
PinGenerator.print_pin_source in their PinGenerator-derived class to either wrap the output or to replace what is being output altogether.

Testing

The stm32/PYBV10 board firmware was rebuilt from scratch without errors to make sure the changes still output the additional pin data as expected.

Trade-offs and Alternatives

This can probably be achieved by overriding PinGenerator.load_inputs to add the per-pin additional data header at the end of the function and overriding PinGenerator.print_source to add the data trailer before the rest of the function executes. It is not really that intuitive or clean.

Generative AI

I did not use generative AI tools when creating this PR.


In my CH32V port I'm trying a couple of different approaches to reduce the pin tables' size [1], and the most promising involves consolidating the AFIO pin tables into one single entity, which right now it is not possible with the board generator in a clean way (unless the workaround mentioned in the trade-offs section is used).

Right now the default tools/boardgen.py output structure for the pins/AFIO .c file is as such:

struct AFIO pin1_AF[] = { { .. } };
struct AFIO pin2_AF[] = { { .. } };
...
struct AFIO pinN_AF[] = { { .. } };

struct PIN pin1 = { .. };
struct PIN pin2 = { .. };
..
struct PIN pinN = { .. };

assuming that PIN has a pointer to a relevant AFIO structure and a byte counting how many entries the AFIO structure contains, for a total of up to 8 bytes (if the count is the last entry in the struct).

With a consolidated AFIO table, in my pin structures I only need to reference the starting index inside the table and the count, with each PIN using an uint8_t for each value (count = 0 indicates no AFIOs). With proper structure packing that'd provide some substantial savings in the ROM-ed structures without complicating the machine.Pin code too much. Hence the reason for an AFIO prologue/epilogue extension point.

[1] Although the CH32V's main inspiration for peripheral design is the STM32, they don't provide automatic AFIO pin tracking unlike the STM32 does. Nothing stops you from having the same pins shared among several peripherals and then change the pins' values via the GPIO registers - making a mess out of the board state if you're not careful. This means that I have to keep everything in sync myself and do the peripheral pin management in code to make sure pins are claimed/released and used only on one peripheral at a time.

I'm not sure if there's any other port doing all of this, but since some peripherals can have their pins reconfigured at runtime (eg. SPI) this is necessary otherwise pins would retain a stale state (both in the interpreter and in the GPIO registers) and all sort of fun will happen in that case...

This commit lets classes extending the base `PinGenerator` class to
override the process of generating extra per-pin content when creating
the pins' information source file.

There are cases in which one may want to have more control on the part
of the source generation process that dumps additional per-pin
information to the source file.  The current approach works fine if each
pin generates self-contained additional data to be placed in the source
file, but there is no clean way to provide a prologue or an epilogue to
that content.

For example, if one wants to emit a single consolidated additional pin
data table it is not that convenient to be able to consistently emit the
table start definition and the table end markers.  With these changes
all one has to do to achieve this is to override
`PinGenerator.print_pin_source` in their PinGenerator-derived class
to either wrap the output or to replace what is being output altogether.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
@agatti agatti added the tools Relates to tools/ directory in source, or other tooling label Apr 20, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 20, 2026

@github-actions
Copy link
Copy Markdown

Copy link
Copy Markdown
Member

@dpgeorge dpgeorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools Relates to tools/ directory in source, or other tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants