Skip to content

Feature Request: Support platform-wide "menu" options #922

Open
@matthijskooijman

Description

@matthijskooijman

Bug Report

Current behavior

Currently, boards.txt allows specifying "menu" options for a board. E.g. for the Arduino Mini, boards.txt contains the following (heavily redacted to just show the bare minimum):

menu.cpu=Processor

mini.name=Arduino Mini
mini.menu.cpu.atmega328=ATmega328P
mini.menu.cpu.atmega328.build.mcu=atmega328p
mini.menu.cpu.atmega168=ATmega168
mini.menu.cpu.atmega168.build.mcu=atmega168

When selecting the Arduino Mini board, this allows specifying the "cpu" option as part of the FQBN, and depending on its value the build.mcu option gets a different value. In the Java IDE, this also causes a menu to be shown that allows the user to select between the two options.

These menu options work fine for such board-specific "subselections" or board-specific options, but often there are also platform-wide options. For example, the Adafruit SAMD core defines a "debug" and "usbstack" menu that is used for pretty much all boards: https://github.com/adafruit/ArduinoCore-samd/blob/1e92424a500a8b3fc5be0701bbbab0da167f2cc6/boards.txt#L17-L22 Currently, this means that the menu options and resulting build properties must be repeated for all board definitions, which is less-than-ideal. The ESP32 and STM32 cores have an even bigger number of options.

This could be greatly simplified if platform-wide menus could be specified. Essentially, these would be menus that are defined outside of any board and are shown for all boards. They can probably also be implemented as such, which should make this rather easy. Specifying/storing the values for these menus can still happen as part of the FQBN, it's just the way the menus are specified that would be simplified.

One open question is where to specify these platform-wide menus? We could put them in platform.txt, which would make sense, or put them at the top of the boards.txt. The latter is probably easier and more consistent with the current menu.cpu=Processor line.

Boards-specific subsets of global options

Sometimes, you might want to have global options that apply to most but not all boards. For example, the Adafruit "usbstack" option is really a platform-wide option, but it only applies to boards with native USB. For this, it would be helpful if you could specify a menu globally, but enable/disable it on a board-by-board basis. Maybe this can be done by setting/clearing the menu title? E.g. (I invented a dummy board here, turns out all of the actual boards in the Adafruit SAMD core have USB):

menu.usbstack=USB Stack
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB

adafruit_feather_m0.name=Adafruit Feather M0
# No menu options here, usbstack is inherit from global

board_without_usb.name=Foo board
# Unset usbstack title to hide it
board_without_usb.menu.usbstack=

Another option would be to do opt-in by not specifying the menu title globally, but specifying it per-board. This requires duplicating the title when a menu is used for multiple boards, though:

# Only specify options, no title
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB

adafruit_feather_m0.name=Adafruit Feather M0
# Set a title to include this menu for this board
board_without_usb.menu.usbstack=USB Stack

board_without_usb.name=Foo board
# No title specified, so usbstack menu not used

A final option could be to make it more explicit by supporting an
"disabled" subproperty (which defaults to "no" for compatibility). A
downside of this approach is that it breaks a menu that wants to use
"enabled" and "disabled" as valid options (maybe we can find a name that is less likely to collide than "disabled"?).

# Only specify options, no title
menu.usbstack=USB Stack
menu.usbstack.arduino=Arduino
menu.usbstack.tinyusb=TinyUSB
menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB
menu.usbstack.disabled=yes

adafruit_feather_m0.name=Adafruit Feather M0
board_without_usb.menu.usbstack=USB Stack
board_without_usb.menu.usbstack.disabled=no

board_without_usb.name=Foo board

We could probably support multiple of these approaches (e.g. both the title based opt-in and opt-out together, or maybe all three of them by hiding options that either have no title, or have "disabled=yes").

The same approaches can also be considered to hide single options from a menu on a board-by-board basis, in addition to hiding complete menus.

Also note that currently, the menu title (e.g. menu.cpu=Processor) must be specified globally (outside of any board definition). Regardless of what we choose here, I would suggest allowing this line to be global or board-specific. If you then have a menu that is only defined for one particular board, it can just be specified for that board, without splitting up the definition of the menu and without cluttering the global definitions. More generally, you could just split the menu definitions arbitrarily between the global and board-specific parts of the file (even allowing something like a global menu with 2 options and then add a third option for just one board).

Implementation-wise, this could mean you just take all global menu options, apply the board-specific ones for the current board on top, and then treat the result just like menus are being treated now, making this fairly easy to implement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: codeRelated to content of the project itselftype: enhancementProposed improvement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions