Skip to content

jnk0le/simple-crt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple crt

Absolute minimum and optimized startup/newlib-stub/semihosting code for use with e.g. eclipse embedded cdt (mcu on eclipse) /w gcc.

for use with

-fno-exceptions
-nostartfiles
-fno-use-cxa-atexit
--specs=nano.specs
--specs=nosys.specs

-nostdlib/-nodefaultlibs is not required. Bloat will be pulled only when appropriate "standard" function is used. (adding compiler option to use float with newlib printf/scanf will casue bloat even when printf/scanf is not used)

Device headers can be ripped from e.g. vendor generators or CMSIS packs available to download in eclispe iot.

To define different stack/heap limitations

-Wl,--defsym,__min_stack_size__=1024
-Wl,--defsym,__min_heap_size__=4096

note that space "reserved" for stack/heap is counted as used by variables.

To disable c++ static initialization __CRT_NO_STATIC_INITIALIZERS have to be globally (or at last within crt files) defined through compiler flags (project preporties -> preprocessor -> defined symbols (-D)) __CRT_NORETURN_FROM_MAIN will remove deinitialiation only. Those macros will not remove constructors/destructors and init/fini arrays (have to be KEEPt in linker to work at all when used)

To properly print real sizes of each memory segment (e.g. stm32h7)

-Wl,--print-memory-usage

NOTE: currently gcc seems to count preinit/init/fini_array sizes towards .data section

Virgin openocd+gdb doesn't support live variable view and SWO/ITM.

Any change in linker scripts has to be followed by project clean and modifying at least one of the compiled project files (needs to be saved with a recent date)

semihosting

Implemented according to the spec: https://developer.arm.com/documentation/100863/0300/

To use semihosting, it must be enabled in gdb by monitor arm semihosting enable or "enable arm semihosting" option in eclipse debug startup configuration

Newlib implementation of printf("") is caching output until '\n' character (or buffer exahaustion ??? allocates 1kB through malloc) fprintf(stderr,"") is printing out one character at a time which is extremly slow through stlinkv2 clone (and a bit less slow through wchlinkE)

stdio.h assumes hardcoded stdin/stdout/stderr handlers to 0,1,2 but obtaining it through proper way by opening special ":tt" file assigns a bigger numbers. For me both ways work.

Default stderr handle and ":tt" opened with "a" option print in red font (in my eclipse).

In case of reading from stdin (openocd console in eclipse, pops up by default) followig message will appear after entering line: Warn : keep_alive() was not invoked in the 1000 ms timelimit. GDB alive packet not sent! (4688 ms). Workaround: increase "set remotetimeout" in GDB of course setting remotetimeout to a larger value doesn't do anything.

Trying to stop program during waiting for stdin will cause a lot of error windows, those can be ok'd through without affecting further execution though.

to avoid it:

  • pause first
  • write something to console and press enter
  • terminate as usual

To redirect default handlers to ":tt" assignments one of the following macros:

WRITE_REDIRECT_TO_SPECIAL_PATH_TT_STDOUT
WRITE_REDIRECT_TO_SPECIAL_PATH_TT_STDERR
READ_REDIRECT_TO_SPECIAL_PATH_TT_STDIN

have to be globally (or at least within semihosting.h) defined.

WRITE_REDIRECT_TO_SPECIAL_PATH_TT_STDERR will redirect printf stdout to stderr (red font, but faster)