Every firmware engineer has run out of code space at some point or another.
Whether they are trying to cram in another feature, or to make enough space for
A/B firmware
updates
more code space is always better.
First of all, thanks a lot for this article, it’s very helpful!
My question is - does the pacover tool works also on axf files? if yes, how do I need to prepare my codebase?
The puncover tool works on any file that was built with debug information and stored in the ELF file format.
.axf (and .out) files usually use the ELF format so you should just be able to follow the instructions as is.
You can easily check to see if the file is in the ELF format by checking to see if the file starts with the EI_MAG header which is 0x7F followed by ‘E’, ‘L’, ‘F’. For example, here’s an axf file I generated recently using the NXP MCUXpressoIDE:
You can use a tool like readelf to check and see if the ELF was compiled with debug information. If it was there will be debug_* sections in the file, i.e
I’m using the same configuration that you described at the post.
well, look the error bellow:
(venv) C:\sources\git\tools\puncover>python runner.py --arm_tools_dir=c:\arm\8-2019-q3-update --elf_file c:\sources\git\fw\imetos\iMetos3_RTX\iMetosEcoD3_Full_Debug\iMetos3_RTX.elf
DEPRECATED: argument --arm_tools_dir will be removed, use --gcc_tools_base instead.
parsing ELF at c:\sources\git\fw\imetos\iMetos3_RTX\iMetosEcoD3_Full_Debug\iMetos3_RTX.elf
Traceback (most recent call last):
File “runner.py”, line 11, in
main()
File “C:\sources\git\tools\puncover\puncover\puncover.py”, line 58, in main
builder.build_if_needed()
File “C:\sources\git\tools\puncover\puncover\builders.py”, line 32, in build_if_needed
self.build()
File “C:\sources\git\tools\puncover\puncover\builders.py”, line 22, in build
self.collector.parse_elf(self.get_elf_path())
File “C:\sources\git\tools\puncover\puncover\collector.py”, line 306, in parse_elf
self.parse_assembly_text(“”.join(self.gcc_tools.get_assembly_lines(elf_file)))
File “C:\sources\git\tools\puncover\puncover\gcc_tools.py”, line 27, in get_assembly_lines
return self.gcc_tool_lines(‘objdump’, [‘-dslw’, os.path.basename(elf_file)], os.path.dirname(elf_file))
File “C:\sources\git\tools\puncover\puncover\gcc_tools.py”, line 23, in gcc_tool_lines
proc = subprocess.Popen([self.gcc_tool_path(name)] + args, stdout=subprocess.PIPE, cwd=cwd)
File “C:\sources\git\tools\puncover\puncover\gcc_tools.py”, line 18, in gcc_tool_path
raise Exception(“Could not find %s” % path)
Exception: Could not find c:\arm\8-2019-q3-update\bin/arm-none-eabi-objdump
hey there. I wanted to use puncover for a msp430 gcc toolchain. Is this specifically made for arm controllers? because i get the following error message:
raise Exception("Could not find %s" % path)
Exception: Could not find C:…\msp430-gcc-8.3.0.16_win32\bin/arm-none-eabi-objdump
@donar I believe it’s only ever been tested with ARM, but you may be able to get it to work by setting the --gcc_tools_base path rather than the --arm_tools_dir flag. Something like --gcc_tools_base=C:\...msp430-gcc-8.3.0.16_win32\bin\msp430-none-eabi-
@francois Thanks for the answer. I get the following output, and after jumping over the python code I think it will not work without changes
C:\repos\python\puncoverTest\venv\Scripts>puncover.exe --gcc_tools_base=C:/ti/ccs920/ccs/tools/compiler/msp430-gcc-8.3.0.16_win32/bin/ --elf_file C:\Users\baerch\workspace_v9_2\testCCode\Debug\testCCode.out
parsing ELF at C:\Users\baerch\workspace_v9_2\testCCode\Debug\testCCode.out
Traceback (most recent call last):
File “C:\repos\python\puncoverTest\venv\Scripts\puncover-script.py”, line 11, in
load_entry_point(‘puncover==0.0.1’, ‘console_scripts’, ‘puncover’)()
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\puncover.py”, line 58, in main
builder.build_if_needed()
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\builders.py”, line 32, in build_if_needed
self.build()
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\builders.py”, line 22, in build
self.collector.parse_elf(self.get_elf_path())
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\collector.py”, line 306, in parse_elf
self.parse_assembly_text("".join(self.gcc_tools.get_assembly_lines(elf_file)))
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\gcc_tools.py”, line 27, in get_assembly_lines
return self.gcc_tool_lines(‘objdump’, [’-dslw’, os.path.basename(elf_file)], os.path.dirname(elf_file))
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\gcc_tools.py”, line 23, in gcc_tool_lines
proc = subprocess.Popen([self.gcc_tool_path(name)] + args, stdout=subprocess.PIPE, cwd=cwd)
File “C:\repos\python\puncoverTest\venv\lib\site-packages\puncover\gcc_tools.py”, line 18, in gcc_tool_path raise Exception(“Could not find %s” % path)
Exception: Could not find C:/ti/ccs920/ccs/tools/compiler/msp430-gcc-8.3.0.16_win32/bin/objdump
Main problem is that all the gcc stuff is named with the prefix : msp430-elf-…exe.
After I renamed all the needed files I got the error message: AttributeError: ‘Collector’ object has no attribute ‘parse_size_line_re’
Since this is the best documentation on how to use puncover, I’d like to add some corrections that were necessary to get things working (ran through the article yesterday).
Please use upstream https://github.com/HBehrens/puncover version instead of the memfault fork (not clear why one should use the memfault version, other than tox support).
To install, after checkout: python3 ./setup.py install --user . This will handle all of the requirements and install puncover to user controlled directory (/home/user/.local/bin/puncover over here, on Ubuntu). puncover should then be executable just by the program name (~/.local/bin/ should be already in your PATH). Using python2.7 will not work. Running setup like this replaces the Setting up for puncover section in the article.
I’m not sure whether -fdebug-prefix-map is required anymore. Things seem to work here without it with build_dir option to puncover.
Since the article came out, puncover learned to also collate the build time generated stack usage information. Add -fstack-usage option to your GCC runs to get the *.su files that puncover will collect.
I use the following command line for a project that is built in the source directory (yes I know it’s bad, but it’s just a sandbox for playing): puncover --gcc_tools_base /home/user/local/gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi- --elf_file ${PWD}/generic-test.elf --build_dir ${PWD}
Important bit here being that the expected format for the new gcc_tools_base is a prefix, not just a path (compared to the old arm_tools_dir). The paths to the puncover options also need to be absolute.
After this, you should have nice interactively navigatable view into stack, static SRAM and code space usage.
I got puncover from HBehrens’ repository and installed it successfully. But I cannot get the output in a webpage. How could I figure out what’s wrong here?
Hi, I tried out puncover and really like the interface, however the code size reporting is not accurate for me. Some symbols are reported with a lower code size (compared to the size reported by nm), resulting in around 10% lower than the actual total size. I don’t understand the cause yet, but someone else in GitHub has a similar issue: use map files instead of output from nm as a source of symbols and sizes · Issue #41 · HBehrens/puncover · GitHub. If someone has an idea, I would be interested.
Bloaty reports the sizes accurately, however I found the usage a bit confusing and not as powerful as the GUI of puncover. Nevertheless it could be strong basis for a visual tool.