Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

This page has some ideas and other things I found that could be useful in the future.

--print-memory-usage: Printing memory usage by section from GCC

It turns out that GCC has a flag that works similarly to our pretty_size.sh. If you add -Wl,--print-memory-usage to the stm32f0xx linker flags via adding it to LDFLAGS in platform/stm32f0xx/platform.mk, you get output like this at the end of the make build output:

Building power_distribution.elf for stm32f0xx
Memory region         Used Size  Region Size  %age Used
           FLASH:       28712 B       128 KB     21.91%
             RAM:        7736 B        16 KB     47.22%

It looks like GCC uses the memory sections defined in the linker script (our stm32f0discovery_def.ld) to determine how much of each memory section we used.

See https://embeddedartistry.com/blog/2020/08/17/three-gcc-flags-for-analyzing-memory-usage/, also https://blog.thea.codes/the-most-thoroughly-commented-linker-script/ for some linker script resources.

Generic GPIO

We have a few different kinds of GPIO pins in MSXIV: there are the native GPIO pins on the STM32, accessible via the gpio library, and a few types of I2C IO expanders accessible via their driver (MCP3427 with mcp3427_gpio_expander, PCA9539R with pca9539r_gpio_expander).

All of these drivers/libraries implement the same basic interface for each pin – init_pin, set_state, toggle_state, and get_state – but they’re entirely incompatible at the moment, so you can’t mix and match GPIO types. This leads to awkward situations like in the bts_7200_load_switch and bts_7040_load_switch drivers, where there are two separate init functions and a whole ton of duplication where the only change is whether one pin is a native STM32 GPIO pin or a PCA9539R IO expander pin.

In any remotely object-oriented language, this problem is solved by having each driver’s GpioAddress class inherit from a base AbstractGpioAddress class or implement an IGpioAddress interface; then libraries that need to manipulate GPIO pins but don’t need to care about what they are can pass around AbstractGpioAddress instances and call set_state on them, and dynamic dispatch will be used to route the call to the appropriate driver. Unfortunately, C is not remotely object-oriented, so we have to implement it ourselves.

I don’t have a precise design for this, but we could possibly use a form of virtual method table - have the GpioAddress-type structs contain a pointer to a vtable struct which contains function pointers for each virtual function (init_pin, set_state, etc). The vtable struct would be a global constant for each type. See https://stackoverflow.com/a/8194632.

  • No labels