Skip to content

Commit 19e36be

Browse files
committed
Update code size tools post with Zephyr puncover steps
1 parent f60806b commit 19e36be

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

_posts/2019-06-06-best-firmware-size-tools.md

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ author: francois
55
tags: [fw-code-size, toolchain]
66
---
77

8-
<!-- excerpt start -->
9-
108
Every firmware engineer has run out of code space at some point or another.
119
Whether they are trying to cram in another feature, or to make enough space for
1210
[A/B firmware
1311
updates](https://sbabic.github.io/swupdate/overview.html#double-copy-with-fall-back)
1412
more code space is always better.
1513

14+
<!-- excerpt start -->
15+
1616
In this [series of posts]({% tag_url fw-code-size %}), we'll explore ways to save code space and ways not to
1717
do it. We will cover compiler options, coding style, logging, as well as
1818
desperate hacks when all you need is another 24 bytes.
@@ -21,6 +21,10 @@ But first, let's talk about measuring code size.
2121

2222
<!-- excerpt end -->
2323

24+
{% include newsletter.html %}
25+
26+
{% include toc.html %}
27+
2428
## Why measure?
2529

2630
Optimization is often counter intuitive. Don't take my word for it: this is one
@@ -47,9 +51,10 @@ $ arm-none-eabi-size build/with-libc.elf
4751
```
4852

4953
So in this program we have:
50-
* 10800 bytes of `text`, which is code
51-
* 104 bytes of `data`, which is statically initalized memory
52-
* 8272 bytes of `bss`, which is zero-initialized memory
54+
55+
- 10800 bytes of `text`, which is code
56+
- 104 bytes of `data`, which is statically initalized memory
57+
- 8272 bytes of `bss`, which is zero-initialized memory
5358

5459
Unfortunately, the output of this tool is a little misleading. You may think
5560
that your program will occupy `10800` bytes of flash, but this is not the case.
@@ -134,6 +139,7 @@ print_region $ram $max_ram "RAM"
134139
```
135140

136141
which gives us:
142+
137143
```terminal
138144
$ ./get-fw-size build/with-libc.elf 0x40000
139145
0x8000
@@ -159,7 +165,7 @@ and `bss`.
159165

160166
## Digging into functions
161167

162-
The above tells us *how much* code space we are using, but not *why*. To answer
168+
The above tells us _how much_ code space we are using, but not _why_. To answer
163169
the latter, we need to go deeper.
164170

165171
This is where another tool bundled with the GNU ARM toolchain comes in handy:
@@ -233,22 +239,22 @@ Truly, it is a firmware analysis swiss army knife!
233239
Using puncover is relatively straightforward. You'll need to lightly prepare
234240
your codebase, setup the tool itself, and run it.
235241

236-
## Preparing our codebase
242+
### Preparing our codebase
237243

238244
In order to for puncover to work, our elf file needs to contain the requisite
239245
information. As such, you'll need to make sure you've got the following CFLAGS
240246
set:
241247

242-
* `-g`: this generates debug information which puncover requires for analysis
243-
* `-fdebug-prefix-map=/=`: this flag forces gcc to collect full paths for
248+
- `-g`: this generates debug information which puncover requires for analysis
249+
- `-fdebug-prefix-map=/=`: this flag forces gcc to collect full paths for
244250
filenames. This allows puncover to create the hierarchical view of the code.
245-
Even better would be to use your repository's root (usually found by running
246-
`git rev-parse --show-toplevel`).
251+
Even better would be to use your repository's root (usually found by running
252+
`git rev-parse --show-toplevel`).
247253

248254
I typically add those two to my CFLAGS for every project directly in my
249255
Makefile.
250256

251-
## Setting up puncover
257+
### Setting up puncover
252258

253259
Puncover is relatively straightforward to setup: you simply need to clone it,
254260
setup a virtualenv, and install the dependencies.
@@ -282,7 +288,7 @@ mock-1.3.0 nose-1.3.7 nose-cov-1.6 pbr-5.2.0 requests-2.21.0 six-1.12.0
282288
urllib3-1.24.3
283289
```
284290

285-
## Running puncover
291+
### Running puncover
286292

287293
While you can install puncover as an executable, I typically just run the
288294
`runner.py` script directly. All it requires is the path to your GNU ARM
@@ -323,6 +329,20 @@ symbols do not come with file information as newlib is not compiled with `-g` in
323329
most distributions. If you built your own newlib from source, you could fix
324330
that!
325331

332+
### Puncover in Zephyr
333+
334+
The Zephyr RTOS project has the ability to [run puncover directly within West](https://docs.zephyrproject.org/latest/develop/optimizations/tools.html#build-target-puncover). It's slick!
335+
336+
You can do so by running the following:
337+
338+
```
339+
# Build as normal
340+
west build ...
341+
342+
# After installing puncover with 'pip install puncover'
343+
west build -t puncover
344+
```
345+
326346
## Epilogue
327347

328348
Upon reviewing this blog post, a friend suggested I look at Bloaty by Google.
@@ -333,8 +353,8 @@ Bloaty is a nifty tool that wraps all the objdump analysis into a nice CLI
333353
client, and can even tell you what sections, symbols, and files grew or shrunk
334354
between two ELFs which would be very useful for a CI system.
335355

336-
What tools and technique do you use to debug code size? Let us know in the
356+
What tools and techniques do you use to debug code size? Let us know in the
337357
comments!
338358

339-
Next in the series, we'll talk about compiler settings you can use to optimize
340-
for code size.
359+
Next in the series, we'll talk about [compiler settings you can use to optimize
360+
for code size]({% post_url 2019-08-20-code-size-optimization-gcc-flags %}).

0 commit comments

Comments
 (0)