blob: 632149536c3f3894f60f4f11fb44c9945203fc5e [file] [log] [blame]
Varun Sharma708d38c2021-04-29 09:03:12 -07001.. _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