The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
I've been working on extending the GCC support for the firmware (patch for 4.2 RC3 is attached). The following is a comparison of code sizes produced by each of the toolchains I tested.
The following is a comparison of code sizes produced by each of the toolchains I tested.
Well done. Have you tried dumping the output ELF symbols and sort them by size? If I remember it correctly, the most significant difference is in C/C++ RunTime functions, like printf() and probably floating point support.
Pardon my ignorance, but...what the h*ll does the RVDS that GCC is not able to do?
It looks about an half of the overall size, not a small percentage. How it can possible that RVDS is able to squeeze the code so far?
Thank you and good idea posting this kind of comparisons.
Cheers
Biggest fault of Netduino? It runs by electricity.
Hi Mario,
I could be mistaken, since this is absolutely not my area of expertise. But RVDS is made especially for microcontrollers as far as I can find. It's quite possible it can use instruction sets available in those microcontrollers that are a bit hidden for GCC, which is more a generic compiler. Or not?
Just a wild guess :-)
ARM's RVDS is more geared towards higher-end ARM processors, not microcontrollers. ARM's Keil subsidiary sells the MDK tools, which are focused on microcontrollers. Actually I just had to order the MDK, because RVDS (which we already have) doesn't support Cortex-M4 :-(
Ironically, the actual compiler of both tool suites is basically the same. Its far better quality than GCC is probably simply a matter of more and better engineering. After all, it's an absolutely crucial piece of software for ARM. Its processors will be benchmarked and compared to other products based on this compiler's performance. So it makes sense to invest heavily in compiler optimizations.
Pardon my ignorance, but...what the h*ll does the RVDS that GCC is not able to do?
It looks about an half of the overall size, not a small percentage. How it can possible that RVDS is able to squeeze the code so far?
Thank you and good idea posting this kind of comparisons.
Cheers
What Cuno said, and in addition to that keep in mind that there is not as much "manpower" available for gcc for e.g. AVR or ARM targets as for x86.
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"
The following lists show size of symbols (larger than 1000 bytes) from GCC (Sourcery CodeBench 2011.07-60 Trial) and RVCT 4.1 (Trial, but not the latest) outputs, produced by nm tool (nm -C --size-sort -r -t d tinyclr.axf), symbols of the same size are rendered in gray (buffers, tables):
GCC:
00014619 t c_CLR_StringTable_Data
00006222 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*) 00005456 T _svfprintf_r 00003810 T _dtoa_r 00003544 t method_lookup 00002860 T _svfiprintf_r 00002780 B QueueBuffers
00002316 R g_ConfigurationSector 00002152 t c_CLR_StringTable_Lookup
00001786 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration{shortened}
00001646 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration{shortened}
00001284 T _malloc_r
00001178 T FAT_LogicDisk::FormatHelper(char const*, unsigned int) 00001100 T c_CLR_RT_DataTypeLookup 00001092 t c_TypeIndexLookup
00001064 d impure_data 00001036 B g_AT91_GPIO_Driver
00001032 D __malloc_av_ 00001024 t c_CRCTable
00001024 B TxBuffer_Com
00001024 B RxBuffer_Com 00001008 T _realloc_r
RVCT:
00014619 t c_CLR_StringTable_Data 00005970 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*) 00003544 t method_lookup
00002780 B QueueBuffers
00002316 R g_ConfigurationSector 00002152 t c_CLR_StringTable_Lookup 00001100 T c_CLR_RT_DataTypeLookup 00001092 t c_TypeIndexLookup 00001036 B g_AT91_GPIO_Driver 00001024 t c_CRCTable
00001024 B TxBuffer_Com
00001024 B RxBuffer_Com ...
00000946 T FAT_LogicDisk::FormatHelper(char const*, unsigned int) ...
00000692 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration{shortened}
...
00000568 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration{shortened}
Thank you all.
Now I understand that the Netduino firmware is not free, but it costs about US$3000. That's the half of the RVDS price...the other half is free because it can be compiled by GCC.
Okay, I deserve somewhat awful...
Just a point on the comparison: it shows the size of the Netduino *standard* firmware.
Any chance to see what is the expected result for Netduino Plus?
Thanks again guys.
Biggest fault of Netduino? It runs by electricity.
Now I understand that the Netduino firmware is not free, but it costs about US$3000. That's the half of the RVDS price...the other half is free because it can be compiled by GCC.
Well, in case of RVCT (ARM RVDS and Keil) the price includes highly optimized C/C++ RunTime libraries and a better compiler (and if I am not mistaken, some additional optimization like linker data compression is not even enabled when building the firmware). But I still believe we could use GCC, if we had CRT of comparable size (e.g. custom newlib build ?).
Now I understand that the Netduino firmware is not free, but it costs about US$3000. That's the half of the RVDS price...the other half is free because it can be compiled by GCC.
That is not a fair statement. The "free" as it's used in open source doesn't mean free as in "free beer", but as in "not in chains". It's unfortunate that there is no cost-free toolsuite to build it, but that is not because there are things that are "closed" or because you are tied to something, it's just because of not-(yet-)done effort in the cost-free compiler department, not something you can blame Secret Labs for, IMO.
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"
The following lists show size of symbols (larger than 1000 bytes) from GCC (Sourcery CodeBench 2011.07-60 Trial) and RVCT 4.1 (Trial, but not the latest) outputs, produced by nm tool (nm -C --size-sort -r -t d tinyclr.axf), symbols of the same size are rendered in gray (buffers, tables):
GCC:
00014619 t c_CLR_StringTable_Data
00006222 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*) 00005456 T _svfprintf_r 00003810 T _dtoa_r 00003544 t method_lookup 00002860 T _svfiprintf_r 00002780 B QueueBuffers
00002316 R g_ConfigurationSector 00002152 t c_CLR_StringTable_Lookup
00001786 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration{shortened}
00001646 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration{shortened}
00001284 T _malloc_r
00001178 T FAT_LogicDisk::FormatHelper(char const*, unsigned int) 00001100 T c_CLR_RT_DataTypeLookup 00001092 t c_TypeIndexLookup
00001064 d impure_data 00001036 B g_AT91_GPIO_Driver
00001032 D __malloc_av_ 00001024 t c_CRCTable
00001024 B TxBuffer_Com
00001024 B RxBuffer_Com 00001008 T _realloc_r
RVCT:
00014619 t c_CLR_StringTable_Data 00005970 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*) 00003544 t method_lookup
00002780 B QueueBuffers
00002316 R g_ConfigurationSector 00002152 t c_CLR_StringTable_Lookup 00001100 T c_CLR_RT_DataTypeLookup 00001092 t c_TypeIndexLookup 00001036 B g_AT91_GPIO_Driver 00001024 t c_CRCTable
00001024 B TxBuffer_Com
00001024 B RxBuffer_Com ...
00000946 T FAT_LogicDisk::FormatHelper(char const*, unsigned int) ...
00000692 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration{shortened}
...
00000568 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration{shortened}
The firmware builds with YAGARTO are using newlib if I'm not mistaken. What are your thoughts on the custom build of newlib?
Well, in case of RVCT (ARM RVDS and Keil) the price includes highly optimized C/C++ RunTime libraries and a better compiler (and if I am not mistaken, some additional optimization like linker data compression is not even enabled when building the firmware). But I still believe we could use GCC, if we had CRT of comparable size (e.g. custom newlib build ?).
The firmware builds with YAGARTO are using newlib if I'm not mistaken. What are your thoughts on the custom build of newlib?
I was playing with YAGARTO some time ago and if I remember it correctly, there are several 'configuration options' (preprocessor directives) that control various newlib features - perhaps it is possible to reduce the size of newlib by excluding certain features and/or fine-tuning those options. I am not sure what is included in newlib built as a part of YAGARTO. Also, I am not really sure such library is used during firmware build, usually there are several libc (don't rely on the name here, I just mean C/C++ RunTime lib) copies, so a wrong one might be used...
Ok, I custom built a GCC 4.6.1 toolchain with newlib and compiled the firmware; here are the code sizes.
GCC-4.6.1
Firmware: 343,040 bytes
00014619 t c_CLR_StringTable_Data
00005912 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*)
00005124 T _svfprintf_r
00003544 t method_lookup
00003020 T _dtoa_r
00002780 B QueueBuffers
00002332 T _svfiprintf_r
00002316 R g_ConfigurationSector
00002152 t c_CLR_StringTable_Lookup
00001390 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration___MicrosoftSPOTHardwareUsbClientConfiguration(CLR_RT_StackFrame&)
00001312 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration___VOID__MicrosoftSPOTHardwareUsbClientConfiguration(CLR_RT_StackFrame&)
00001100 T c_CLR_RT_DataTypeLookup
00001092 t c_TypeIndexLookup
00001066 T FAT_LogicDisk::FormatHelper(char const*, unsigned int)
00005912 T CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame*)
00005124 T _svfprintf_r
00003544 t method_lookup
00003020 T _dtoa_r
00002780 B QueueBuffers
00002332 T _svfiprintf_r
00002316 R g_ConfigurationSector
00002152 t c_CLR_StringTable_Lookup
00001390 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::get_Configuration___MicrosoftSPOTHardwareUsbClientConfiguration(CLR_RT_StackFrame&)
00001312 T Library_spot_hardware_usb_native_Microsoft_SPOT_Hardware_UsbClient_UsbController::set_Configuration___VOID__MicrosoftSPOTHardwareUsbClientConfiguration(CLR_RT_StackFrame&)
00001100 T c_CLR_RT_DataTypeLookup
00001092 t c_TypeIndexLookup
00001066 T FAT_LogicDisk::FormatHelper(char const*, unsigned int)
Why is it that these from GCC:
00005456 T _svfprintf_r
00003810 T _dtoa_r
00002860 T _svfiprintf_r
are completely absent in RVCT? why are they necessary for GCC, but not RVCT?
Also, is it at all possible to have RVCT precompiled parts mixed with GCC newly compiled parts?
-Valkyrie-MT