1.. _module-pw_stm32cube_build: 2 3------------------ 4pw_stm32cube_build 5------------------ 6 7The ``pw_stm32cube_build`` module provides helper utilities for building a 8target with the stm32cube HAL and/or the stm32cube initialization code. 9 10The actual GN build files and headers live in ``third_party/stm32cube`` but 11are documented here. The rationale for keeping the build files in `third_party` 12is that code depending on stm32cube can clearly see that their dependency is on 13third party, not pigweed code. 14 15STM32Cube directory setup 16========================= 17Each stm32 product family (ex. F4, L5, etc.) has its own stm32cube libraries. 18This integration depends on ST's 3 core `MCU Components`_ instead of their 19monolithic `MCU Package`. The components are the hal_driver, cmsis_core, and 20cmsis_device. All of these repos exist on `ST's GitHub page`_. Compatible 21version tags are specified on the ``README.md`` of each MCU component. 22Within a single directory, the following directory/file names are required. 23 24=============== ============================================= 25Dir/File Name Description 26=============== ============================================= 27hal_driver/ checkout of ``stm32{family}xx_hal_driver`` 28cmsis_device/ checkout of ``cmsis_device_{family}`` 29cmsis_core/ checkout of ``cmsis_core`` 30files.txt list of files generated by `gen_file_list`_ 31=============== ============================================= 32 33pw_package 34---------- 35The stm32cube directory can alternatively be setup using ``pw_package``. This 36will automatically download compatible repos into the expected folders and 37generate the ``files.txt``. 38 39.. code-block:: bash 40 41 pw package install stm32cube_{family} 42 43GN build 44======== 45The primary ``pw_source_set`` for this integration is 46``$dir_pw_third_party/stm32cube:stm32cube``. This source set includes all of 47the HAL, init code, and templates, depending on value of the `GN args`_. 48 49Headers 50------- 51``$dir_pw_third_party/stm32cube:stm32cube`` contains the following primary 52headers that external targets / applications would care about. 53 54``{family}.h`` 55^^^^^^^^^^^^^^ 56ex. ``stm32f4xx.h``, ``stm32l5xx.h`` 57 58This is the primary HAL header provided by stm32cube. It includes the entire 59HAL and all product specific defines. 60 61``stm32cube/stm32cube.h`` 62^^^^^^^^^^^^^^^^^^^^^^^^^ 63This is a convenience define provided by this integration. It simply includes 64``{family}.h``. 65 66This is useful because there is a lot of commonality between the HAL's of the 67different stm32 families. Although the API's are not guaranteed to be 68compatible, many basic API's often are (ex. GPIO, UART, etc.). This common 69header allows for stm32 family agnostic modules (ex. ``pw_sys_io_stm32``, which 70could work with most, if not all families). 71 72``stm32cube/init.h`` 73^^^^^^^^^^^^^^^^^^^^ 74As described in the inject_init_ section, if you decide to use the built in 75init functionality, a pre main init function call, ``pw_stm32cube_Init()``, is 76injected into ST's startup scripts. 77 78This header contains the ``pw_stm32cube_Init()`` function declaration. It 79should be included and implemented by target init code. 80 81GN args 82------- 83The stm32cube GN build arguments are defined in 84``$dir_pw_third_party/stm32cube/stm32cube.gni``. 85 86``dir_pw_third_party_stm32cube_xx`` 87^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 88These should be set to point to the stm32cube directory for each family that 89you need to build for. These are optional to set and are only provided for 90convenience if you need to build for multiple families in the same project. 91 92``dir_pw_third_party_stm32cube`` 93^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 94This needs to point to the stm32cube directory for the current build. 95 96For multi target projects, the standard practice to set this for each target: 97 98.. code-block:: text 99 100 dir_pw_third_party_stm32cube = dir_pw_third_party_stm32cube_f4 101 102 103``pw_third_party_stm32cube_PRODUCT`` 104^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 105The product specified in as much detail as possible. 106ex. ``stm32f429zit``, ``stm32l552ze``, ``stm32f207zg``, etc. 107 108``pw_third_party_stm32cube_CONFIG`` 109^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 110The pw_source_set that provides ``stm32{family}xx_hal_conf.h``. The default 111uses the in-tree ``stm32{family}xx_hal_conf_template.h``. 112 113``pw_third_party_stm32cube_TIMEBASE`` 114^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 115The pw_source_set containing the timebase. The default uses the in-tree 116``stm32{family}xx_hal_timebase_tim_template.c``. 117 118``pw_third_party_stm32cube_CMSIS_INIT`` 119^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 120The pw_source_set containing the cmsis init logic. The default uses the in-tree 121``system_stm32{family}xx.c``. 122 123``pw_third_party_stm32cube_CORE_INIT`` 124^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 125pw_source_set containing the core initialization logic. This normally includes 126a ``startup_stm32{...}.s`` + a dependent ``pw_linker_script``. The default 127``core_init_template`` uses the upstream startup and linker script matching 128``pw_third_party_stm32cube_PRODUCT``. If set to "", you must provide your own 129linker/startup logic somewhere else in the build. 130 131stm32cube_builder 132================= 133``stm32cube_builder`` is utility that contains the backend scripts used by 134``pw_package/stm32cube`` and the GN build scripts in ``third_party/stm32cube`` 135to interact with the stm32cube repos. You should only need to interact with 136``stm32cube_builder`` directly if you are doing something custom, like 137using git submodules instead of pw_package, forking the stm32cube libraries, 138interfacing with a different build system, or using your own init. 139 140gen_file_list 141------------- 142Build systems like GN are unable to depend on arbitrary directories. Instead, 143they must have dependencies on specific files. The HAL for each stm32 product 144family has different filenames, so ``files.txt`` was created as a workaround. 145``files.txt`` is a basic list of all the files in the stm32cube directory with 146relavent file extensions. The build system only directly depends on this list, 147which must be updated everytime the underlying repos are updated. 148 149This command will generate ``files.txt`` for correctly structured stm32cube 150directories. 151 152.. code-block:: bash 153 154 stm32cube_builder gen_file_list /path/to/stm32cube_dir 155 156find_files 157---------- 158Within each stm32 family, there are specific products. Although most of the 159HAL is common between products, the init code is almost always different. 160``find_files`` looks for all of the files relevant to a particular product 161within a stm32cube directory. 162 163The product string should be specified in as much detail as possible because 164there are sometimes different defines or init code for submembers of products. 165 166Ex. ``stm32f412cx``, ``stm32f412rx``, ``stm32f412vx``, and ``stm32f412zx`` all 167have different init logic, while all ``stm32f439xx`` have the same init. 168 169``find_files`` only ever looks for init (linker + startup scripts) if the 170``--init`` flag is provided. 171 172The output is currently only provided in the GN 'scope' format to stdout. 173The following variables are output: ``family``, ``product_define``, 174``sources``, ``headers``, ``include_dirs``, and the following three if 175``--init`` is specified: ``startup``, ``gcc_linker``, ``iar_linker``. 176 177.. code-block:: bash 178 179 stm32cube_builder find_files /path/to/stm32cube_dir stm32{family}{product} [--init] 180 181inject_init 182----------- 183ST provides init assembly files for every product in ``cmsis_device``. This is 184helpful for getting up and running quickly, but they directly call into 185``main()`` before initializing the hardware / peripherals. This is because they 186expect to do that initialization in ``main()``, then call into the user 187application. Upstream Pigweed unit tests expect at least ``sys_io`` to be 188initialized before ``main()`` is called. 189 190This command injects a call to ``pw_stm32cube_Init()`` immediately before the 191call to ``main()``. This function should be implemented by the target to do 192whatever init is necessary (hal init, sys_io init, clock configuration, etc.) 193 194``inject_init`` takes in an ST assembly script and outputs the same script with 195the pre main init call. The output is printed to stdout, or to the specified 196``--out-startup-path``. 197 198.. code-block:: bash 199 200 stm32cube_builder inject_init /path/to/startup.s [--out-startup-path /path/to/new_startup.s] 201 202icf_to_ld 203--------- 204Pigweed primarily uses GCC for its Cortex-M builds. However, ST only provides 205IAR linker scripts in ``cmsis_device`` for most product families. This script 206converts from ST's IAR linker script format (.icf) to a basic GCC linker 207script (.ld). This is a very basic converter that only works with exactly how 208ST currently formats their .icf files. 209 210The output .ld files only contain ``RAM`` and ``FLASH`` sections. Anything more 211complicated will require hand customized .ld scripts. Output is printed to 212stdout or the specified ``--ld-path``. 213 214.. code-block:: bash 215 216 stm32cube_builder inject_init /path/to/iar_linker.icf [--ld-path /path/to/gcc_linker.ld] 217 218.. _`MCU Components`: https://github.com/STMicroelectronics/STM32Cube_MCU_Overall_Offer#stm32cube-mcu-components 219.. _`ST's GitHub page`: https://github.com/STMicroelectronics 220