zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.43k stars 6.39k forks source link

build: Allow board discovery on nested folders #30612

Open jaronkelleher opened 3 years ago

jaronkelleher commented 3 years ago

Is your enhancement proposal related to a problem? Please describe. cmake/boards.cmake supports nested folders in the list_boards() function. However, the board discovery step in boilerplate.cmake (line 349) does not support nest board definitions. This can lead to one set of boards being listed when listing all possible boards, and the inability of the user to select those that are nested.

Another limitation of this is that developers working on large complex boards with multiple MCUs that will spin different revisions are forced to put all board definitions in a single layer, rather than organizing by folder structure. For example, a board called foo with 3 microcontrollers all using x86 architecture and having 6 different revisions across development would have a folder structure that looks like: boards

-- x86/
   -- foo_rev_0_mcu_0
   -- foo_rev_0_mcu_1
   -- foo_rev_0_mcu_2
   -- foo_rev_1_mcu_0
   -- foo_rev_1_mcu_1
   -- foo_rev_1_mcu_2
   -- foo_rev_2_mcu_0
   -- foo_rev_2_mcu_1
   -- foo_rev_2_mcu_2
   -- foo_rev_3_mcu_0
   -- foo_rev_3_mcu_1
   -- foo_rev_3_mcu_2

While this works, the number of folders contained within boards/ will continue to grow as a product is being worked on. Then moving onto the next product will further expand the size of the folder, making it slightly harder to navigate.

Describe the solution you'd like I'm proposing we add the ability for board discovery to search nested folders inside of board. This achieves two things:

  1. It matches the behavior of the list_boards() function in boards.cmake
  2. It allows developers to organize their boards in a folder hierarchy to enable easier navigation to the board folder being searched for. The folder structure then for the previous example could look like:
    -- x86/
    -- foo/
      -- rev0/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/
      -- rev1/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/
      -- rev2/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/

The benefit of this approach is that is allows more flexibility for the developer/organization in organizing their boards folder as more and more boards are made and put here. To be clear, this approach isn't necessarily target at the zephyr root folder, but could be very useful for out-of-tree zephyr directories and modules that define boards in them.

The drawback of this is that developers searching for a board may need to navigate deeper into the folder heirarchy to find the one they are looking for. A recommended approach to help mitigate this would be to name the board in the nested folders by the path to get to it (e.g foo/rev_0/mcu0/foo_rev0_mcu0_defconfig. This also would help mitigate the drawback of a higher potential in unintended duplicate board names.

Describe alternatives you've considered Another alternative for this would be to keep it the way it currently is, and update the list_boards() function to behave in the same manner. I think this is a reductive approach, and more flexibility is better.

Additional context Demonstration of list_boards() finding nested board files.

[zephyr]$ tree boards/x86/ -ifF | grep _defconfig boards/x86/acrn/acrn_defconfig boards/x86/minnowboard/minnowboard_defconfig boards/x86/qemu_x86/qemu_x86_64_defconfig boards/x86/qemu_x86/qemu_x86_coverage_defconfig boards/x86/qemu_x86/qemu_x86_defconfig boards/x86/qemu_x86/qemu_x86_nommu_defconfig boards/x86/qemu_x86/qemu_x86_nopae_defconfig boards/x86/qemu_x86/qemu_x86_xip_defconfig boards/x86/tmp1/tmp2/foo/foo_defconfig boards/x86/tmp1/tmp3/minnowboard/minnowboard_defconfig boards/x86/up_squared/up_squared_32_defconfig boards/x86/up_squared/up_squared_defconfig

[zephyr]$ cmake -P cmake/boards.cmake // only showing the x86 portion x86: acrn minnowboard qemu_x86_64 qemu_x86_coverage qemu_x86 qemu_x86_nommu qemu_x86_nopae qemu_x86_xip foo minnowboard up_squared_32 up_squared

tejlmand commented 3 years ago

@jaronkelleher Thanks for this. I wonder if the board revision feature will be helpful / solve your use-case ? https://github.com/zephyrproject-rtos/zephyr/pull/29990

jaronkelleher commented 3 years ago

@jaronkelleher Thanks for this. I wonder if the board revision feature will be helpful / solve your use-case ?

29990

I'll take a look at this and bring it up to the team. Thanks for pointing it out.

mbolivar-nordic commented 3 years ago

I wonder if the board revision feature will be helpful / solve your use-case ?

29990

Note that this helps address revisions at the board level, but not the MCU level. For that we would need to rework the concept of 'board', I think.

jaronkelleher commented 3 years ago

I wonder if the board revision feature will be helpful / solve your use-case ?

29990

Note that this helps address revisions at the board level, but not the MCU level. For that we would need to rework the concept of 'board', I think.

This was the sentiment I received from the team as well. While that is a nice solution for board revisions, there is still a preference to be able to organize MCU subfolders by a board name as was suggested initially. I'd also like to emphasize that this is targeted for out-of-tree zephyr folders, not the in-tree board folder here.

tejlmand commented 3 years ago

I wonder if the board revision feature will be helpful / solve your use-case ?

29990

Note that this helps address revisions at the board level, but not the MCU level. For that we would need to rework the concept of 'board', I think.

Not completely sure what you refer to here.

It is possible for another board revision to select another MCU / MCU revision, if that is what you mean. The soc selection is normally done in the _defconfig file, but that is just a Kconfig fragment.

So as example, the https://github.com/zephyrproject-rtos/zephyr/blob/1c493b4a7706e9934949f8d23f8d8eddc7256200/boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig#L4

could just as easily have made

CONFIG_SOC_PART_NUMBER_SAME70Q21B=y

in a sam_e70_xplained_B revision of same board, instead of creating a new board.

That would have given two files. First file: sam_e70_xplained_A.conf

# sam_e70_xplained_A
CONFIG_SOC_PART_NUMBER_SAME70Q21=y

and second file: sam_e70_xplained_B.conf

# sam_e70_xplained_B
CONFIG_SOC_PART_NUMBER_SAME70Q21B=y

https://github.com/zephyrproject-rtos/zephyr/tree/master/boards/arm/sam_e70_xplained

@mbolivar-nordic please let me know if this is not what you were refering to.

tejlmand commented 3 years ago

While that is a nice solution for board revisions, there is still a preference to be able to organize MCU subfolders by a board name as was suggested initially.

While i'm not opposing the idea, it really needs to be ensured such feature is not colliding with existing infrastructure. And the behaviour should be identical for boards in Zephyr repo, and other BOARD_ROOTs.

If looking at your initial problem statement, you would like this structure:

-- x86/
   -- foo/
      -- rev0/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/
      -- rev1/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/
      -- rev2/
         -- mcu_0/
         -- mcu_1/
         -- mcu_2/

which will give you this list of files in EACH sub-directory to maintain, that is in this example 9 times.

boards/x86/foo/revX/mcu_N
├── board.cmake
├── CMakeLists.txt
├── doc
│   ├── plank.png
│   └── index.rst
├── Kconfig.board
├── Kconfig.defconfig
├── plank_defconfig
├── plank.dts
└── plank.yaml

https://docs.zephyrproject.org/latest/guides/porting/board_porting.html#create-your-board-directory.

Using the board revision feature, this can be reduced to:

-- x86/
   -- foo_mcu0/
      -- <standard board files>
      -- foo_mcu0_rev1.conf
      -- foo_mcu0_rev1.overlay
      -- foo_mcu0_rev2.conf
      -- foo_mcu0_rev2.overlay
      -- foo_mcu0_rev3.conf
      -- foo_mcu0_rev3.overlay
   -- foo_mcu1/
      -- <standard board files>
      -- foo_mcu1_rev1.conf
      -- foo_mcu1_rev1.overlay
      -- foo_mcu1_rev2.conf
      -- foo_mcu1_rev2.overlay
      -- foo_mcu1_rev3.conf
      -- foo_mcu1_rev3.overlay
   -- foo_mcu2/
      -- <standard board files>
      -- foo_mcu2_rev1.conf
      -- foo_mcu2_rev1.overlay
      -- foo_mcu2_rev2.conf
      -- foo_mcu2_rev2.overlay
      -- foo_mcu2_rev3.conf
      -- foo_mcu2_rev3.overlay

thus reducing the number of times you need to duplicate the standard board files significantly and simply add the differences in <revN>.conf and/or <revN>.overlay files. You can then refer to the board/mcu using. -DBOARD=foo_mcu1@rev2.

The foo_mcuX is similar to other boards with multiple socs/ As example the nrf9160dk, which is a board with two socs, an nrf9160 and a nrf52840: https://github.com/zephyrproject-rtos/zephyr/tree/master/boards/arm/nrf9160dk_nrf9160 https://github.com/zephyrproject-rtos/zephyr/tree/master/boards/arm/nrf9160dk_nrf52840

mbolivar-nordic commented 3 years ago

It is possible for another board revision to select another MCU / MCU revision, if that is what you mean.

... as long as it has the same architecture, yes. But if not, you're out of luck if you want to keep a bunch of related hardware in a single folder.

tejlmand commented 3 years ago

It is possible for another board revision to select another MCU / MCU revision, if that is what you mean.

... as long as it has the same architecture, yes. But if not, you're out of luck if you want to keep a bunch of related hardware in a single folder.

but if that was the case, then I don't think this issue would have started out with an x86 level in its initial suggestion:

 -- x86/
   -- foo/
      -- rev0/
       ....
mbolivar-nordic commented 3 years ago

Fair point.

zephyrbot commented 6 months ago

Hi @tejlmand,

This issue, marked as an Enhancement, was opened a while ago and did not get any traction. It was just assigned to you based on the labels. If you don't consider yourself the right person to address this issue, please re-assing it to the right person.

Please take a moment to review if the issue is still relevant to the project. If it is, please provide feedback and direction on how to move forward. If it is not, has already been addressed, is a duplicate, or is no longer relevant, please close it with a short comment explaining the reason.

@jaronkelleher you are also encouraged to help moving this issue forward by providing additional information and confirming this request/issue is still relevant to you.

Thanks!