{"id":113,"date":"2014-11-11T11:26:14","date_gmt":"2014-11-11T11:26:14","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=113"},"modified":"2018-05-14T10:40:26","modified_gmt":"2018-05-14T17:40:26","slug":"arm-newlib-nano","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/newlib-nano\/","title":{"rendered":"Building ARM Projects with Newlib-Nano"},"content":{"rendered":"<p>This tutorial demonstrates how to use newlib-nano, a lightweight version of the standard C\/C++ library that is included with our ARM toolchain. We will show the main differences compared to the full library and demonstrate some efficient debugging techniques. We will first create a very basic C++ project with the full-size library and then reduce its size by using newlib-nano. We will target the STM32F4Discovery board, however the techniques demonstrated here will work with any other ARM device as well.<\/p>\n<p>To use all features described in this tutorial please update to GCC 4.9.2 and VisualGDB 4.3.<\/p>\n<ol>\n<li>Begin with creating a normal Embedded project with VisualGDB project wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/01-newprj.png\" alt=\"01-newprj\" width=\"700\" height=\"394\" \/><\/a><\/li>\n<li>Proceed with the default settings on the first page of the wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/02-binprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/02-binprj.png\" alt=\"02-binprj\" width=\"702\" height=\"571\" \/><\/a><\/li>\n<li>On the device selection page select the default C library type and disable the C++ binary size reduction:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/03-toolchain.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/03-toolchain.png\" alt=\"03-toolchain\" width=\"702\" height=\"571\" \/><\/a><\/li>\n<li>Proceed with the default sample settings:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/04-sample.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/04-sample.png\" alt=\"04-sample\" width=\"702\" height=\"571\" \/><\/a><\/li>\n<li>Select a debugging method that matches your hardware:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/05-jtag.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/05-jtag.png\" alt=\"05-jtag\" width=\"702\" height=\"571\" \/><\/a><\/li>\n<li>Press Finish to create the project. Replace the contents of the main source file with a very basic main() function:\n<pre>#include&lt;stm32f4xx_hal.h&gt;\r\n\r\nint main(void)\r\n{\r\n    HAL_Init();\r\n\r\n   return 0;\r\n}<\/pre>\n<p>Then build the project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/06-basicprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-6\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/06-basicprj.png\" alt=\"06-basicprj\" width=\"699\" height=\"606\" \/><\/a>Note the memory utilization shown in the build output. Most likely you will use less than 2 kilobytes of FLASH.<\/li>\n<li>Now add some basic C++ code to the project:\n<pre class=\"\">#include &lt;stm32f4xx_hal.h&gt;\r\n#include &lt;stdio.h&gt;\r\n\r\nclass BaseClass\r\n{\r\npublic:\r\n   virtualvoid SomeMethod() = 0;\r\n};\r\n\r\nclass ChildClass : public BaseClass\r\n{\r\npublic:\r\n    virtual void SomeMethod()\r\n    {\r\n    }\r\n};\r\n\r\nint main(void)\r\n{\r\n    HAL_Init();\r\n\r\n    ChildClass inst;\r\n    inst.SomeMethod();\r\n\r\n   return 0;\r\n}<\/pre>\n<p>Build the project again. You will see that the amount of used memory increased by more than 70K:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/07-morecode.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/07-morecode.png\" alt=\"07-morecode\" width=\"699\" height=\"685\" \/><\/a><\/li>\n<li>We will now track down the source of the high memory consumption and show how to reduce it. Open the Embedded Memory Explorer pane:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/08-memexp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/08-memexp.png\" alt=\"08-memexp\" width=\"699\" height=\"685\" \/><\/a><\/li>\n<li>Then click &#8220;Explore details&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/09-memstat.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/09-memstat.png\" alt=\"09-memstat\" width=\"699\" height=\"685\" \/><\/a>As you can see, most of the memory is used by various library functions that we don&#8217;t call directly. Those functions come from the default C++ exception handling mechanism. The default implementation for the pure virtual SomeMethod() actually throws an exception and this automatically involves lots of heavy code that deals with name demangling and information formatting.<\/li>\n<li>While using 70K of code to get user-friendly printing of unhandled exceptions could be a good tradeoff for desktop programs, it is certainly not for embedded targets. We can disable it by linking with a special library that provides an alternate implementation for the pure virtual method that simply activates a hardware breakpoint. Enable the corresponding checkbox in the VisualGDB Project Properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/10-compactcpp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/10-compactcpp.png\" alt=\"10-compactcpp\" width=\"700\" height=\"620\" \/><\/a><\/li>\n<li>If you now rebuild your project, you will notice that it requires about a hundred bytes of memory more than the original main() function:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/11-compactbuild.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/11-compactbuild.png\" alt=\"11-compactbuild\" width=\"699\" height=\"685\" \/><\/a><\/li>\n<li>Another scenario that may involve the heavy exception-related code is using C++ allocation operators. Add the following code to your main() function:\n<pre>char *p = newchar[128];\r\ndelete[] p;<\/pre>\n<p>Then build your project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/12-newdel.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/12-newdel.png\" alt=\"12-newdel\" width=\"699\" height=\"662\" \/><\/a>You will see that the exception-related functions have been linked again driving the image size to 70K+.<\/li>\n<li>In this case you can reduce the binary size by switching from the classical C\/C++ library to a reduced-size version, newlib-nano. It provides many trade-offs that reduce the size of your binaries, e.g. contains a C++ library built without exception support. You can select newlib-nano via VisualGDB project properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/13-nano.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-13\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/13-nano.png\" alt=\"13-nano\" width=\"700\" height=\"620\" \/><\/a><\/li>\n<li>However, if you build your project now, you will get several &#8216;undefined symbol&#8217; errors:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/14-sbrk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-14\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/14-sbrk.png\" alt=\"14-sbrk\" width=\"699\" height=\"662\" \/><\/a><\/li>\n<li>This happens because newlib-nano comes without default implementations for the system calls required by the memory allocation code. This can be fixed by linking with a library that provides default versions of those system calls:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/15-nosys.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-15\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/15-nosys.png\" alt=\"15-nosys\" width=\"700\" height=\"620\" \/><\/a><\/li>\n<li>Now the build will succeed resulting in a small binary again:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/16-nosysnewdel.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-16\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/16-nosysnewdel.png\" alt=\"16-nosysnewdel\" width=\"700\" height=\"626\" \/><\/a><\/li>\n<li>The problem now is that the default syscall stubs provided by the toolchain are not smart enough to detect the out-of-memory condition. Hence the memory allocation will always succeed leading to memory damage in case the memory runs out:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/17-outofmem.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-17\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/17-outofmem.png\" alt=\"17-outofmem\" width=\"699\" height=\"644\" \/><\/a><\/li>\n<li>We can fix that by copying the implementation of _sbrk(), a function responsible for memory allocation from the full version of newlib. First switch back to full newlib without syscall stubs in the VisualGDB Project Properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/18-defaultlib.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-18\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/18-defaultlib.png\" alt=\"18-defaultlib\" width=\"700\" height=\"620\" \/><\/a><\/li>\n<li>Then set a breakpoint on the _sbrk() function (Ctrl-B):<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/19-sbrk-bp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-19\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/19-sbrk-bp.png\" alt=\"19-sbrk-bp\" width=\"594\" height=\"269\" \/><\/a><\/li>\n<li>Start debugging. Once the breakpoint is triggered, VisualGDB will suggest downloading the newlib source code:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/20-getlib.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-20\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/20-getlib.png\" alt=\"20-getlib\" width=\"699\" height=\"643\" \/><\/a><\/li>\n<li>Proceed with the download:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/21-instlib.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-21\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/21-instlib.png\" alt=\"21-instlib\" width=\"484\" height=\"182\" \/><\/a><\/li>\n<li>Once the source is downloaded, you will see that the current _sbrk() implementation does check for the out-of-memory condition:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/22-sbrk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-22\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/22-sbrk.png\" alt=\"22-sbrk\" width=\"699\" height=\"817\" \/><\/a><\/li>\n<li>Now switch back to newlib-nano + syscall stubs and copy the &#8220;smart&#8221; _sbrk() implementation to your main source file:\n<pre class=\"\">#include &lt;errno.h&gt;\r\n\r\nextern \"C\" caddr_t _sbrk (int incr)\r\n{\r\n   register char * stack_ptr asm (\"sp\");\r\n   extern char end asm (\"end\");\r\n   static char *heap_end;\r\n   char *prev_heap_end;\r\n\r\n   if (heap_end == NULL)\r\n        heap_end = &amp;end;\r\n\r\n    prev_heap_end = heap_end;\r\n\r\n    if(heap_end + incr &gt; stack_ptr)\r\n    {\r\n        errno = ENOMEM;\r\n        return (caddr_t) -1;\r\n    }\r\n\r\n    heap_end += incr;\r\n\r\n   return (caddr_t) prev_heap_end;\r\n}<\/pre>\n<\/li>\n<li>If you build your project now, your binary will be slim again:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/23-sbrk-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-23\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/23-sbrk-build.png\" alt=\"23-sbrk-build\" width=\"699\" height=\"707\" \/><\/a><\/li>\n<li>And trying to allocate too much memory will now result in a call to _abort() (as we are using libc++ without exception support) that by default generates a division-by-zero exception:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/24-exit.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-24\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/24-exit.png\" alt=\"24-exit\" width=\"699\" height=\"707\" \/><\/a><\/li>\n<li>One last thing: by default newlib-nano does not support float\/double types in printf()\/scanf() functions. stepping through the following code (requires &lt;math.h&gt;):\n<pre>char *p = newchar[1024];\r\nsprintf(p, \"pi = %f\", acosf(-1));\r\ndelete[] p;<\/pre>\n<p>You will notice that the %f specifier was simply ignored:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/25-format.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-25\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/25-format.png\" alt=\"25-format\" width=\"699\" height=\"643\" \/><\/a><\/li>\n<li>This can be fixed by enabling the corresponding version of newlib-nano via VisualGDB Project Properties:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/26-float-printf.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-26\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/26-float-printf.png\" alt=\"26-float-printf\" width=\"700\" height=\"580\" \/><\/a><\/li>\n<li>This costs ~10K of FLASH memory more, so only use it when you really need that functionality:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/27-printf-pi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-27\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/tutorials\/arm\/newlib-nano\/27-printf-pi.png\" alt=\"27-printf-pi\" width=\"699\" height=\"643\" \/><\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial demonstrates how to use newlib-nano, a lightweight version of the standard C\/C++ library that is included with our<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[53],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/113"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=113"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/113\/revisions"}],"predecessor-version":[{"id":3987,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/113\/revisions\/3987"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}