Working with the Freescale S08 and S12 build tools, there is something I really appreciated: that the linker reports on the console the code size of the application:
This is especially handy as it allows you to see the impact on code size immediately e.g. if I change a compiler option or do a source code change. Simple and easy. Yes, I could get that kind of information from the linker map file too. But this means I need to open that file, scroll down/etc: many steps just to find out the code size.
As with all good things: you learn to appreciate it even more if you do not have it any more. And this happens to me when I moved to ColdFire, PowerPC and Kinetis applications using CodeWarrior build tools. I would expect that this kind of simple thing would be there, but…. nada. I need to open the map file.
GNU gcc for Kinetis: arm-none-eabi-size
With the advent of gcc for Kinetis in CodeWarrior for MCU10.3 (see the Freedom board posts), there is finally some relief. GNU gcc is here the default compiler for the Kinetis L family. The KL25Z which is on the FRDM-KL25Z Freedom board has decent RAM and Flash, but the L series really is targeting the small and tiny microcontrollers. And here code and data size information right at link time is important, as it is e.g. for the S08. And with the move of Freescale to gcc, the arm-none-eabi-size is part of the tools: it is part of the GNU tools for ARM Cortex M0+. I can find that tool inside
<installationPath>\Cross_Tools\arm-none-eabi-gcc-4_6_2\bin\arm-none-eabi-size.exe
Command Line Interface
Executing that tool from the command prompt/DOS Shell with the option -help provides pretty much everything needed:
C:\Freescale\CW MCU v10.3\Cross_Tools\arm-none-eabi-gcc-4_6_2\bin>arm-none-eabi-size.exe -help Usage: arm-none-eabi-size.exe [option(s)] [file(s)] Displays the sizes of sections inside binary files If no input file(s) are specified, a.out is assumed The options are: -A|-B --format={sysv|berkeley} Select output style (default is berkeley) -o|-d|-x --radix={8|10|16} Display numbers in octal, decimal or hex -t --totals Display the total sizes (Berkeley only) --common Display total size for *COM* syms --target=<bfdname> Set the binary file format @<file> Read options from <file> -h --help Display this information -v --version Display the program's version arm-none-eabi-size.exe: supported targets: elf32-littlearm elf32-bigarm elf32-little elf32-big srec symbolsrec verilog tekhex binary ihex
Executing the utility with
arm-none-eabi-size.exe c:\wsp_Freedom\Freedom_Accel\FLASH\Freedom_Accel.elf
gives
text data bss dec hex filename 6036 40 1120 7196 1c1c c:\wsp_Freedom\Freedom_Accel\FLASH\Freedom_Accel.elf
Here I have the code size (text), constant data (data) and global variables or statically allocated variables (bss), all in decimal. The sum of text+data+bss is shown in dec(imal) and hex(adecimal).
Printing Code Size for gcc in Eclipse/CodeWarrior
Now while using the command line tool is nice, I want it be part of the build in Eclipse/CodeWarrior. The good news is: as shown in “S-Record Generation with gcc for ARM/Kinetis” it can be done.
In the build tool settings, I enable the ‘Print Size’ option and press the Apply button:
This enables a ‘GNU Print Size’ option group:
Now if I build my application, I get code and data size information:
Happy Sizing 🙂
Any new “intel” on when CW 10.3 will be released?
LikeLike
Just checked the page on http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=CW-MCU10&tid=vanCWMCU10, and it is there on the right side 🙂 http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=CW-MCU-10-3-BETA
LikeLike
Pingback: Tutorial: Freedom with FreeRTOS and Kinetis-L | MCU on Eclipse
Pingback: Optimizing the Kinetis gcc Startup | MCU on Eclipse
This didnt work for me, when I build its like its not executing the _size command. I also dont see the .s19 record appear.
LikeLike
Did you press the ‘Apply’ button? then additional panels should show up. Keep in mind that the default extension for the S19 file is .hex.
LikeLike
Pingback: Reducing Code Size with gcc and EWL | MCU on Eclipse
Hi Erich,
Your post is very useful. I’m using CodeWarrior 10.2 for Kinetis K60N512. How can I print code size with Codewarrior ARM toolchain?
LikeLike
Hello, this is only possible with gcc and MCU10.3.
LikeLike
Thank you 🙂 Hope next version of CW will support it
LikeLike
I need to disappoint you: according to Freescale, the non-gcc ARM compiler is in maintenance mode. It is still present in MCU10.3, but I would not expect any new features or enhancements for it. ARM gcc is the future. I already switched over all my Kintetis project to gcc, and the code is not only faster, it is smaller too, and the compiler/build tools have more features. No reasons for me to stay with the non gcc compiler.
LikeLike
Hi,
The “Additional Tools” settings seem to be removed in CW 10.3 official version. Is there any way to enable the “Print Size” option in CW 10.3 official release?
Thank you for your help.
LikeLike
Hi Joey,
it is still there for me in my offical MCU10.3. Keep in mind that the setting is for gcc, and *not* for the other ARM compiler (from Freescale) in MCU10.3. Maybe this is the disconnect?
LikeLike
Hi Erich:
Mmm… I can find it with projects that I created (and gcc was selected as compiler), but I can’t find “Additional Tools” in a MQX example project (created by selecting New MQX 3.8 project, and selected “hello” project from the example list). It seems MQX projects are still using ARM compiler, even we create it under CW 10.3.
Thank you for your response. I will inform my customers to check code size from xMap file.
PS: I am Freescale disty FAE and your blog does help me a lot. I would like to present my appreciation for your contributions on this blog.
LikeLike
Hi Joey,
thanks :-). For MQX-Lite (Kinetis-L) projects, gcc is used. I think the next MQX version will finally support gcc as well for the other Kinetis parts.
LikeLike
Hello:
First of all thank you for your hard work on your blog, I really liked it and it has helped me a lot to learn about ARMs.
I wanted to ask you about the data, bss and Text information. At the end, which one of them can tell me about FLASH and RAM usage? When I download a program to the board, what it downloads is the sum of text + data, so what is bss? I made a new barebones project and I have a huge bss data (2076).
Also, how can I know the RAM the program will use?
Thank you very much for your time,
Ed.
LikeLike
Hi Ed,
thank you :-).
You ask a good question. Let me see what I could write up on this subject over the week-end.
LikeLike
The NetBeans based tools for Microchip PIC32 show you two little fuel gauges for Flash and RAM usage. Very cool feature. The rest of the thing is nearly unusable, though. 🙂
LikeLike
Yes, mbed (https://mcuoneclipse.com/2013/03/10/mbed-for-the-freedom-board/) has something similar: it shows with bar graphs the RAM/Flash usuage.
LikeLike
Hi Ed,
have a look here: https://mcuoneclipse.com/2013/04/14/text-data-and-bss-code-and-data-size-explained/
I hope this helps.
LikeLike
Pingback: text, data and bss: Code and Data Size Explained | MCU on Eclipse
in case you want to reduce bss consumption, you can modify the linker script in the heap and stack area. Afaik heap can be chosen to zero, when no malloc is used.
LikeLike
Hi Michael,
yes, this is indeed true. I have not optimized the linker file for things like this yet.
Thanks for pointing to this!
LikeLike
I had myself scratching my head and pawing my HP42S when you said “Here I have the code size (text), constant data (data) and global variables or statically allocated variables (bss), all in hexadecimal. The sum of text+data+bss is shown in dec(imal) and hex(adecimal).”
Until I realized you meant *all in decimal*, when you said “all in hexadecimal”
LikeLike
Hi Tim,
thanks for spotting this bug! Indeed, it should read *decimal*. I have fixed it now.
Thanks again!
LikeLike
No worries Erich.
Your blog is so good, and this was such a minor thing.
I’m just happy you are shedding so much light on the Freedom boards. At least for me, there is no other source of this information. I’m trying out the Freescale ARM Cortex chips after having been a Mot/Freescale person for decades, and more lately taken a few years out for other things. Just an observation about Freedom stuff, at least the K20D50 version: For a product that tries to be like Arduino….it is far from the ease of use of Arduino, and could use a lot more sample programs and drag and drop kind of applications for the un-itiated. I know this is a blog thread about finding the memory left in Codewarrior, but I wanted to get that off my chest!
Tim
Offgrid
LikeLike
Hi Tim,
yeah, I know what you mean, and I felt the same, so I published my findings as much as possible. I think many companies (especially silicon companies) have not realized (yet?) that the best microcontrollers are nothing without good tools and software. I mean the Arduino and Raspberry Pi are not the best microcontrollers, but having an excellent software and tools environment. And especially an open source driven environment. I belive only vendors will survive which can adopt to that change. Will see.
LikeLike
Erich, You are really keen on Processor Expert, and I need some help, so I thought I would write.
I’ve never used the tool, electing instead to handcraft code to get exactly what I want. Now with lots of RAM and Flash, and with the ability to use different variants easily, I find myself more interested in PE, and using it at least for startup code on different peripherals.
My dillema is that I have spent far too much time on getting a real time timer running and I could use a hand; I literally cannot get the timer to start and run. I’m using the RealTime_LDD and it’s configured to use GetTimeSec function. The help window on this component gives me this Typical Usage:
void main(void) { unsigned int i, time; float one_loop_us;
RT1_Reset(); /* reset the counter */ for (i = 0; i < 60000; ++i); /* for-cycle */
/* get measured time of whole for-cycle */ if(RT1_GetTimeUS(RT1_DeviceData,&time) == ERR_OK) { /* average time of one loop */ one_loop_us = time / 60000.0; } }
1. First off, I cannot use the RT1_Reset() function as the gcc compiler gives me "undefined reference to `RT1_Reset'" in clock.c , which seem weird since this is defined in the PE modules, and referenced in my ProcessorExpert.c file. 2. Here is my clock routine (clock.c), when single stepping in debug mode, I see that it does actually go into the RT1_GetTimeUS() function.
unsigned int seconds, minutes, hours, i; unsigned int msecTimer, time, RT1_DeviceData; //typedef uint32_t TU2_TValueType ; // Type for data parameters of methods. 32bit is maximum //long TU2_TValueType ; // Type for data parameters of methods. 32bit is maximum //int LDD_TDeviceData;
int Clock(void) { #define TICKS1SEC 100 // there are 100 – 10msec ticks in one second
if(RT1_GetTimeUS(RT1_DeviceData,&time) == 0){ msecTimer = time ; } else i = 0; //RT1_Reset(); //for (i = 0; i = TICKS1SEC){ msecTimer = 0; seconds ++; //RT1_Reset(); /* reset the real time counter */ } if (seconds >= 60) { seconds = 0; minutes ++; if (minutes >= 60) { minutes = 0; hours ++; if (hours >= 24) hours = 0; // hours go to 0 every day, 24 hours } } return (seconds); }
I do see the RT1_GetTimeUS() routine wants to return ERR_OVERFLOW when called. I’ve got both the linked timer, TimerUnit_LDD (TU2) and this RealTime_LDD resultion set to 16 bits, and resultion set to 10msecs. Initialization for RealTime is yes in init code and yes for Auto initialization, and yes in init code for the TU2 timer.
Anything you can do to get me moving again…would be most appreciated!!!
LikeLike
I apologize for my late response (to many things going on right now). I would need to try out the same thing you describe, but here are a few thoughts (blindly without trying it myself):
– If RT1_Reset() is not defined, it could be that it is not enabled? Check if the method has a X on it in the Components view. If yes, it is disabled. Enable it with right mouse click.
– If you are interested just in a realtime clock functionality (without the need for the RTC on the chip), you easily could use the GenericTimeDate component I have created. See https://mcuoneclipse.com/2012/07/26/there-is-a-time-and-date-for-both-worlds/. Simply import that component (see https://mcuoneclipse.com/2013/05/09/processor-expert-component-peupd-files-on-github/), then add a timer (e.g. 10 ms) and call the TmDt1_AddTick() from the timer interrupt. Then you have a realtime clock 🙂
I hope this helps get moving.
LikeLike
Thanks Erich, your tip about enabling the Reset was right on, it was disabled, and I learned a new way to talk to PE. Unfortunately, that did not fix my problem. Moving the routine to main did solve the problem, so I need to see why the routines are not working in my clock file. I’ll take a look at your clock code, but since this part has it’s own RTC, it seems smart to use the on-chip resource.
Thanks again,
Tim
LikeLike
Hi Tim, yes, I agree using the onboard RTC is a good thing. In my projects I used the software RTC (GenericTimeDate) or an external RTC like a Maxim DS3232.
LikeLike
Hi Erich,
First of all, thanks for this post, it was helpful.
After doing what you teach here, and enjoying it, I wonder if you ever had this issue:
Sometimes, I do a Build All, and because it sometimes takes 1 or 2 minutes, I start to do other things: checking my mail, going to the bathroom, … sometimes I came back to the computer 15 minutes later, and then… Do I did the Build All ???? or not ??? I don’t remember !
So, I need to go to the file .elf to check the hour/date.
Do you think there might be an easy way to have the Date and Time in the console, in the last line ?
Or, is there other place were this information is available ?
Best Regards,
Christian
LikeLike
Hi Christian,
Not in CodeWarrior, but in the new Eclipse Kepler with the GNU ARM Eclipse plugins (https://mcuoneclipse.com/2013/12/23/diy-free-toolchain-for-kinetis-part-7-gnu-arm-eclipse-plugins/).
See the screenshot ‘Building the Project (Console Output)’ which reports date/time when the build was made.
LikeLike
Thanks Erich.
LikeLike
Hi Erich, a question that i think is in topic with the article:
If i notice that the size of the used RAM is increasing more than expected,how can i check in detail the RAM size allocate by my globals and static allocated variables?
Say that, somewhere ,i erroneously declared an array with [1000] elements instead of[100] as needed,is it possible to put it in evidence in some ordered list?
Thanks for your useful work.
Diego
LikeLike
Hi Diego,
I suggest that you enable the linker map file (under the linker options). This creates a text file with that information.
Unfortunately at least for GNU linker that map file is not that easy to read, but I’m sure you get to it 🙂
LikeLike
Erich thanks for the datailed answer on the same
question(added by more data) on Freescale forum
freescale community thread/321919
,unselecting the Print Link Map option everything works fine
Diego
LikeLike
Hi Diego,
you are welcome! Good to hear that this solves your problem 🙂
LikeLike
Pingback: Printing Code Size Information in Eclipse | MCU on Eclipse
Hi,
Please let me know the option to enable the memory map summary like the one in the starting of this thread. I want to know what is the total size of the .text, total size of .bss and the total size of .data. Currently I use the option -Xlinker -Map=$(basename $(1)).map to generate the map file..with Arm gcc compiler.
Best Regards
Hari
LikeLike
See the last screenshot of this post (“Kinetis ARM GNU gcc Code and Data Size Information with CodeWarrior”) which shows the options. You do not get that from the linker, you need to call the size program.
LikeLike
Hi Erich
Had to deal with memory questions and noted, that the option to put the size information to the console has not worked for me. I don’t even see a call to the size program in the console. However, using Post-build steps in Project Properties > C/C++ Build > Settings > Build Steps has helped me out. I placed
“${ARM_GNU_TOOLS_HOME}/bin/arm-none-eabi-size.exe” –format=sysv ${BuildLocation}/${BuildArtifactFileName} >> ${BuildLocation}/${BuildArtifactFileBaseName}.map
in there and from now on I get a neat memory usage table at the end of my map file.
Thought this might help some other people around here. Thank you and keep on going with this great blog!
Adrian
LikeLike
Hi Adrian,
thanks, I’ll do my best :-).
About your problem, it might be related to this issue
https://mcuoneclipse.com/2013/06/12/traps-and-pitfalls-no-hexbins19-file-created-with-gnu/
?
LikeLike
Took me a while to find the size option on KDS. It is in C/C++ Build -> Settings -> Toolchains instead of Tool Settings.
LikeLike
Yes, the most recent plugin from GNU ARM Eclipse have that option moved there.
LikeLike
hi Eric,
I am genrating srecord file in my project and i have print size option selected in Kenetis Design Studio.
I am trying to find the End of the Program Code.
the End of program code address calculated by looking into console screen in KDS, from below is addr(33808)+ size(234296) = 268104
section size addr
.interrupts 1024 32768
.flash_config 16 1024
.text 234296 33808
.ARM 8 268104
.init_array 4 268112
.data 5452 536806400
.m_data_1FFF0000 53792 536811852
.m_interrupts_ram 1024 536805376
.bss 129660 536865792
.stack 1024 537001984
.ARM.attributes 55 0
.debug_info 980501 0
.debug_abbrev 79454 0
.debug_aranges 17552 0
.debug_ranges 14576 0
.debug_macro 490179 0
.debug_line 611590 0
.debug_str 1977333 0
.comment 112 0
.debug_frame 56792 0
.stab 156 0
.stabstr 335 0
Total 4654935
LikeLike
but when I check in srec file (below shown end of file)generated by KDS. I see end address diffreent which is higher than above print
which is 0x4FEB0 -> in decimal 327344
S21404FE900000000000000000000000000000000059
S21404FEA00000000000000000000000000000000049
S21404FEB00000000000000000000000000000000039
is this generated srec is adding any dummy data in to Flash area
LikeLike
Hi Niranjan,
this all depends on your linker file, maybe you are using some filling with zero bytes?
Regardless, if you want to know the end of your code, then you can define a symbol in the linker file.
For example
___ROM_AT = .;
} > m_text
the ___ROM_AT symbol is what you can use in your code to find out the end of the m_text segment.
LikeLike
Thanks Eric
LikeLiked by 1 person