1.. _optimization_tools: 2 3Optimization Tools 4################## 5 6The available optimization tools let you analyse :ref:`footprint_tools` 7and :ref:`data_structure_tools` using different build system targets. 8 9.. _footprint_tools: 10 11Footprint and Memory Usage 12************************** 13 14The build system offers 3 targets to view and analyse RAM, ROM and stack usage 15in generated images. The tools run on the final image and give information 16about size of symbols and code being used in both RAM and ROM. Additionally, 17with features available through the compiler, we can also generate worst-case 18stack usage analysis. 19 20Some of the tools mentioned in this section are organizing their output based 21on the physical organization of the symbols. As some symbols might be external 22to the project's tree structure, or might lack metadata needed to display them 23by name, the following top-level containers are used to group such symbols: 24 25* Hidden - The RAM and ROM reports list all processing symbols with no matching 26 mapped files in the Hidden category. 27 28 This means that the file for the listed symbol was not added to the metadata file, 29 was empty, or was undefined. The tool was unable to get the name 30 of the function for the given symbol nor identify where it comes from. 31 32* No paths - The RAM and ROM reports list all processing symbols with relative paths 33 in the No paths category. 34 35 This means that the listed symbols cannot be placed in the tree structure 36 of the report at an absolute path under one specific file. The tool was able 37 to get the name of the function, but it was unable to identify where it comes from. 38 39 .. note:: 40 41 You can have multiple cases of the same function, and the No paths category 42 will list the sum of these in one entry. 43 44 45Build Target: ram_report 46======================== 47 48List all compiled objects and their RAM usage in a tabular form with bytes 49per symbol and the percentage it uses. The data is grouped based on the file 50system location of the object in the tree and the file containing the symbol. 51 52Use the ``ram_report`` target with your board, as in the following example. 53If you are using :ref:`sysbuild`, see :ref:`sysbuild_dedicated_image_build_targets` instead. 54 55.. zephyr-app-commands:: 56 :tool: all 57 :zephyr-app: samples/hello_world 58 :board: reel_board 59 :goals: ram_report 60 61These commands will generate something similar to the output below:: 62 63 Path Size % Address 64 ======================================================================================== 65 Root 4637 100.00% - 66 ├── (hidden) 4 0.09% - 67 ├── (no paths) 2748 59.26% - 68 │ ├── _cpus_active 4 0.09% 0x20000314 69 │ ├── _kernel 32 0.69% 0x20000318 70 │ ├── _sw_isr_table 384 8.28% 0x00006474 71 │ ├── cli.1 16 0.35% 0x20000254 72 │ ├── on.2 4 0.09% 0x20000264 73 │ ├── poll_out_lock.0 4 0.09% 0x200002d4 74 │ ├── z_idle_threads 128 2.76% 0x20000120 75 │ ├── z_interrupt_stacks 2048 44.17% 0x20000360 76 │ └── z_main_thread 128 2.76% 0x200001a0 77 ├── WORKSPACE 184 3.97% - 78 │ └── modules 184 3.97% - 79 │ └── hal 184 3.97% - 80 │ └── nordic 184 3.97% - 81 │ └── nrfx 184 3.97% - 82 │ └── drivers 184 3.97% - 83 │ └── src 184 3.97% - 84 │ ├── nrfx_clock.c 8 0.17% - 85 │ │ └── m_clock_cb 8 0.17% 0x200002e4 86 │ ├── nrfx_gpiote.c 132 2.85% - 87 │ │ └── m_cb 132 2.85% 0x20000060 88 │ ├── nrfx_ppi.c 4 0.09% - 89 │ │ └── m_channels_allocated 4 0.09% 0x200000e4 90 │ └── nrfx_twim.c 40 0.86% - 91 │ └── m_cb 40 0.86% 0x200002ec 92 └── ZEPHYR_BASE 1701 36.68% - 93 ├── arch 5 0.11% - 94 │ └── arm 5 0.11% - 95 │ └── core 5 0.11% - 96 │ ├── mpu 1 0.02% - 97 │ │ └── arm_mpu.c 1 0.02% - 98 │ │ └── static_regions_num 1 0.02% 0x20000348 99 │ └── tls.c 4 0.09% - 100 │ └── z_arm_tls_ptr 4 0.09% 0x20000240 101 ├── drivers 258 5.56% - 102 │ ├── ... ... ...% 103 ======================================================================================== 104 4637 105 106 107Build Target: rom_report 108======================== 109 110List all compiled objects and their ROM usage in a tabular form with bytes 111per symbol and the percentage it uses. The data is grouped based on the file 112system location of the object in the tree and the file containing the symbol. 113 114Use the ``rom_report`` target with your board, as in the following example. 115If you are using :ref:`sysbuild`, see :ref:`sysbuild_dedicated_image_build_targets` instead. 116 117.. zephyr-app-commands:: 118 :tool: all 119 :zephyr-app: samples/hello_world 120 :board: reel_board 121 :goals: rom_report 122 123These commands will generate something similar to the output below:: 124 125 Path Size % Address 126 ======================================================================================== 127 Root 27828 100.00% - 128 ├── ... ... ...% 129 └── ZEPHYR_BASE 13558 48.72% - 130 ├── arch 1766 6.35% - 131 │ └── arm 1766 6.35% - 132 │ └── core 1766 6.35% - 133 │ ├── cortex_m 1020 3.67% - 134 │ │ ├── fault.c 620 2.23% - 135 │ │ │ ├── bus_fault.constprop.0 108 0.39% 0x00000749 136 │ │ │ ├── mem_manage_fault.constprop.0 120 0.43% 0x000007b5 137 │ │ │ ├── usage_fault.constprop.0 84 0.30% 0x000006f5 138 │ │ │ ├── z_arm_fault 292 1.05% 0x0000082d 139 │ │ │ └── z_arm_fault_init 16 0.06% 0x00000951 140 │ │ ├── ... ... ...% 141 ├── boards 32 0.11% - 142 │ └── arm 32 0.11% - 143 │ └── reel_board 32 0.11% - 144 │ └── board.c 32 0.11% - 145 │ ├── __init_board_reel_board_init 8 0.03% 0x000063e4 146 │ └── board_reel_board_init 24 0.09% 0x00000ed5 147 ├── build 194 0.70% - 148 │ └── zephyr 194 0.70% - 149 │ ├── isr_tables.c 192 0.69% - 150 │ │ └── _irq_vector_table 192 0.69% 0x00000040 151 │ └── misc 2 0.01% - 152 │ └── generated 2 0.01% - 153 │ └── configs.c 2 0.01% - 154 │ └── _ConfigAbsSyms 2 0.01% 0x00005945 155 ├── drivers 6282 22.57% - 156 │ ├── ... ... ...% 157 ======================================================================================== 158 21652 159 160.. _footprint_tools_plot: 161 162Build Targets: ram_plot/rom_plot 163================================ 164 165Similar to the ``ram_report`` and ``rom_report`` build targets, these targets generate memory usage 166reports in a sunburst chart as a visual representation. 167A user can click on segments to navigate through the directory structures, and hover over segments 168to get more details. 169 170Running the targets will first generate the CLI report and then open a browser window. 171 172.. zephyr-app-commands:: 173 :tool: all 174 :zephyr-app: samples/hello_world 175 :board: reel_board 176 :goals: ram_plot 177 178.. image:: ram_plot.png 179 :align: center 180 :alt: RAM usage sunburst chart 181 182And similarly for the ROM usage. 183 184.. zephyr-app-commands:: 185 :tool: all 186 :zephyr-app: samples/hello_world 187 :board: reel_board 188 :goals: rom_plot 189 190.. image:: rom_plot.png 191 :align: center 192 :alt: ROM usage sunburst chart 193 194 195Build Target: puncover 196====================== 197 198This target uses a third-party tool called puncover which can be found at 199https://github.com/HBehrens/puncover. When this target is built, it will 200launch a local web server which will allow you to open a web client and browse 201the files and view their ROM, RAM, and stack usage. 202 203Before you can use this 204target, install the puncover Python module:: 205 206 pip3 install --user puncover 207 208.. warning:: 209 210 This is a third-party tool that might or might not be working at any given 211 time. Please check the GitHub issues, and report new problems to the 212 project maintainer. 213 214After you installed the Python module, use ``puncover`` target with your board, 215as in the following example. 216If you are using :ref:`sysbuild`, see :ref:`sysbuild_dedicated_image_build_targets` instead. 217 218.. zephyr-app-commands:: 219 :tool: all 220 :zephyr-app: samples/hello_world 221 :board: reel_board 222 :goals: puncover 223 224The ``puncover`` target will start a local web server on ``localhost:5000`` by default. 225The host IP and port the HTTP server runs on can be changed by setting the environment 226variables ``PUNCOVER_HOST`` and ``PUNCOVER_PORT``. 227 228To view worst-case stack usage analysis, build this with the 229:kconfig:option:`CONFIG_STACK_USAGE` enabled. 230 231.. zephyr-app-commands:: 232 :tool: all 233 :zephyr-app: samples/hello_world 234 :board: reel_board 235 :goals: puncover 236 :gen-args: -DCONFIG_STACK_USAGE=y 237 238 239.. _data_structure_tools: 240 241Data Structures 242**************** 243 244 245Build Target: pahole 246===================== 247 248Poke-a-hole (pahole) is an object-file analysis tool to find the size of 249the data structures, and the holes caused due to aligning the data 250elements to the word-size of the CPU by the compiler. 251 252Poke-a-hole (pahole) must be installed prior to using this target. It can be 253obtained from https://git.kernel.org/pub/scm/devel/pahole/pahole.git and is 254available in the dwarves package in both fedora and ubuntu:: 255 256 sudo apt-get install dwarves 257 258Alternatively, you can get it from fedora:: 259 260 sudo dnf install dwarves 261 262After you installed the package, use ``pahole`` target with your board, 263as in the following example. 264If you are using :ref:`sysbuild`, see :ref:`sysbuild_dedicated_image_build_targets` instead. 265 266.. zephyr-app-commands:: 267 :tool: all 268 :zephyr-app: samples/hello_world 269 :board: reel_board 270 :goals: pahole 271 272Pahole will generate something similar to the output below in the console:: 273 274 /* Used at: [...]/build/zephyr/kobject_hash.c */ 275 /* <375> [...]/zephyr/include/zephyr/sys/dlist.h:37 */ 276 union { 277 struct _dnode * head; /* 0 4 */ 278 struct _dnode * next; /* 0 4 */ 279 }; 280 /* Used at: [...]/build/zephyr/kobject_hash.c */ 281 /* <397> [...]/zephyr/include/zephyr/sys/dlist.h:36 */ 282 struct _dnode { 283 union { 284 struct _dnode * head; /* 0 4 */ 285 struct _dnode * next; /* 0 4 */ 286 }; /* 0 4 */ 287 union { 288 struct _dnode * tail; /* 4 4 */ 289 struct _dnode * prev; /* 4 4 */ 290 }; /* 4 4 */ 291 292 /* size: 8, cachelines: 1, members: 2 */ 293 /* last cacheline: 8 bytes */ 294 }; 295 /* Used at: [...]/build/zephyr/kobject_hash.c */ 296 /* <3b7> [...]/zephyr/include/zephyr/sys/dlist.h:41 */ 297 union { 298 struct _dnode * tail; /* 0 4 */ 299 struct _dnode * prev; /* 0 4 */ 300 }; 301 ... 302 ... 303