Project settings¶
Important
This documentation is not recommended for new RISC-V projects. New RISC-V projects should reference the newest version of the documentation. Users targeting Arm devices can still use this documentation as their reference.
The newest version of the documentation can be found here: https://mi-v-ecosystem.github.io/SoftConsole-Documentation/
Program image is too large¶
If the program image size is too large, then check the list and map files for details of what application and library code is contributing to the total size. Note that the ELF file size on disk is not indicative of the program image size when running on the embedded hardware target. Some useful common tips for reducing the program image size:
Tell the compiler to optimize:
Level =
Optimize for size -Os
(this will negatively affect debugging capabilities)Use newlib-nano.
Multiple things can be configured in the
Linker
, go into its setting by:Then check to use the
nano.spec
:Uncheck the
nodefaultlibs
:And unchek
nostdlib
:Note the newlib doesn’t have fully ported floating point support for RISC-V and is not utilizing some floating point instructions even if they are supported by the hardware (fmin/fmax/fsqrt…) and some functions might accidentally include soft double support. This can lead to the application footprint growing unexpectedly. If really needed, it’s possible to avoid these newlib functions and replace them with own implementations using inline assembly.
If
printf()
style functions are being used and the program is still too large even when using newlib-nano then it may be possible to use a standalone small printf() implementation instead. Most such implementations may have limitations compared to a “full” standard libraryprintf()
implementation but often these limitations are acceptable in an embedded context. Examples of such “small” printf() implementations include:https://github.com/mpaland/printf (minimalistic
printf()
that supports floats)http://www.xappsoftware.com/wordpress/2011/01/17/a-tiny-printf-for-embedded-systems/
Then disable the use of the compiler standard libraries inside the linker:
Better still consider rewriting the relevant code to avoid the use of
printf()
functions which are generally not recommended on embedded platforms because they are often large and often use the heap.Wrap code that is not always required (e.g. verbose logging code used for debugging/diagnostics only) in blocks such as below:
#ifdef <symbol> // Debuging code, logging feature, auxaliary feature #endif
The blocks can be quickly and conditionally compiled out when not needed (in essence enabled/disabled). Adding addition extra auxiliary features into the ifdef blocks could produce further code shrinking as it’s less frequent that all the features have to be used on the target all the time. Custom (or existing) configurations can be used to have different defines and the
Debug
configuration having different set of features enabled thenRelease
configuration (debugging/troubleshooting log features on a production code will not just make it bigger, but often are considered as a security risk as well).Check if the floating point is using hardware and not software implementation. Not enabling hardware properly and using floating point will emulate every instruction in software and enlarge the codebase significantly. Do not use RVF or RVD floating point without setting the corresponding floating point ABI in :
With RISC-V cores implementing the
F
and/orD
extensions the Floating-point divide/sqrt instructions (-mfdiv
) can also be enabled.Check what function or blocks of project code should be prioritized for optimization. Create a size analysis post build step under:
and put the following in the Command field:
${cross_prefix}nm${cross_suffix} --print-size --size-sort ${BuildArtifactFileName}
Optionally a Description can be given to it, for example:
------- Size analysis -------
.After the build all symbols with their sizes will be displayed and ordered by the size. This can point to functions which will benefit from optimizations the most. It can reveal design/code issues as when a large library could have been linked into a project by mistake or other unnecessary code compiled in.
Enable hardware features if the core is capable – e.g. use the RISC-V M extension fully if present. Under:
Enable/check the Multiply extension (
RVM
) and the Integer divide instructions (-mdiv
) options if appropriate. If the target implements the Compressed extension (RVC
) then enable/check that too.See the
miv-rv32imaf-raytracer-uart-cpp
as an example when making a C++ project. C++ is a large language with an overhead which is very significant from an embedded perspective. Disable as much as is viable in the Optimization tab settings:Do not use exceptions
Do not use RTTI
Do not use _cxa_atexit()
Do not use thread-safe statics
Size optimizations cause trap exception: Load/Store address misaligned (mcause 4/6)¶
Can be caused when using default HAL without any modifications and allowing unaligned accesses in the project settings.
Can be fixed by making the project to use aligned addresses only:
Note
Our HAL is not supporting unaligned accesses. Howerver it’s not recommended for the user to implement the unaligned acesses to the trap handler because it significantly affects the performance.
See: Use strict alignment
Program file does not exist¶
Possibly caused by build finishing successfully and the ELF file existing, but a misconfigured debug launch configuration cannot see it.
Then a likely cause is the use of the wrong slash in the program path name. It is advisable to use the forward slash /
in such paths for Windows and Linux cross OS compatibility. If the backslash \
is used then it will only work on Windows but the forward slash works on both. Unfortunately the debug launch configuration editor on Windows defaults to using the backslash.
Change the slash in launcher configuration from “Debug\blinky.elf” to “Debug/blinky.elf”:
Another cause of this problem is building one configuration (for example Release) and having launcher hard-coded for different configuration (for example Debug). Good and generic launchers (such as launchers bundled in the workspace.examples) always use the macro approach:
${config_name:<YOUR_PROJECT_NAME>}/<YOUR_PROJECT_NAME>.elf
Where <YOUR_PROJECT_NAME>
is replaced with the name of the project, for example:
${config_name:miv-rv32imaf-mandelbrot-uart}/miv-rv32imaf-mandelbrot-uart.elf
Together with build configuration set to Use Active
:
It will allow the launcher to work with any configuration seemingly such as Debug/Release (or many more).
Redirect printf() output to UART¶
To route printf() output to UART:
Set up CoreUART in such way that
UART_polled_tx_string()
output worksAdd the following include file:
#include <stdio.h>
Go to the C/C++ Compiler settings:
And add the define symbol
MSCC_STDIO_THRU_CORE_UART_APB
to the:
Undefined reference to printf
/puts
/write
/strlen
etc.¶
When one of these errors appears:
undefined reference to 'printf'
undefined reference to 'puts'
undefined reference to 'write'
undefined reference to 'strlen'
Then possibly no libraries are present to implement these calls, go to the linker settings:
And uncheck the nodefaultlibs
:
And the nostdlib
:
Build fails when using “Print removed sections (-Xlinker –print-gc-sections)”¶
When the option to print removed unused sections is selected, then CDT may report that the build has failed even though it was completed correctly. This is because of a bug in CDT whereby the --print-gc-sections
option prints removed sections to stderr and CDT incorrectly interprets any output on stderr
as a build error. This bug has been reported to the CDT project and for now it is safe to ignore such build failure false positives.
Alternatively disable the --print-gc-sections
option resolve the issue. First go to the Tool settings
:
For RISC-V targets uncheck the --print-gc-sections
inside the Tool settings
:
For Arm targets uncheck the --print-gc-sections
inside the Tool settings
:
When the –print-gc-sections option is enabled then the following false positive build failure may occur:
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.text.__disable_irq' in file
'./riscv_hal/riscv_hal.o'
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.text.handle_m_ext_interrupt' in
file './riscv_hal/riscv_hal_stubs.o'
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.text.SysTick_Handler' in file
'./riscv_hal/riscv_hal_stubs.o'
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.sbss.__env' in file
'./riscv_hal/syscall.o'
...
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.text.isatty' in file
'lib/rv32im/ilp32\libg_nano.a(lib_a-sysisatty.o)'
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.debug_frame' in file
'lib/rv32im/ilp32\libg_nano.a(lib_a-sysisatty.o)'
riscv64-unknown-elf/bin/ld.exe: Removing unused section '.sdata._global_impure_ptr' in file
'lib/rv32im/ilp32\libg_nano.a(lib_a-impure.o)'
Finished building target: miv-rv32im-systick-blinky.elf
12:35:47 Build Failed. 71 errors, 0 warnings. (took 2s.428ms)
Debugger Console View is not working or GDB is misbehaving¶
SoftConsole v2021.3 debugger version detection can fail and not show Debugger Console
. The Debugger Console
will work when macros are not used in the debug launcher, copy content of the
It should be riscv64-unknown-elf-gdb
or arm-none-eabi-gdb
, if the actual name doesn’t match expected value then workaround the issue, change the Executable
:
To use explicitly riscv64-unknown-elf-gdb
or arm-none-eabi-gdb
instead of the \({cross_prefix}gdb\){cross_suffix} macro.
sprintf() prints empty characters instead of floating point numbers¶
Possible cause is that the support in the libraries is not enabled by default when newlib-nano is used.
Verify if the newlib-nano
is used in the project settings:
If newlib-nano
is used, then the the %f feature can be enabled by checking the following in the project settings:
and/or (when scanf
is used):
Note
Enabling the floating feature of printf will increase the footprint. If that is a problem, see the size shrinking section.
If newlib-nano is not in use but this problem occurs then it may be caused by the GNU or a third party standard library used instead of newlib.
Invalid project path: Duplicate path entries found Warnings¶
Using macros in include files can cause these warnings, use relative paths on all included folders instead. RISC-V projects:
For example replace "${workspace_loc:/${ProjName}/drivers/CoreUARTapb}"
with "../drivers/CoreUARTapb"
undefined reference to `__stack_top’ etc.¶
Or one of the following errors:
undefined reference to `__sdata_start'
undefined reference to `__data_start'
undefined reference to `__sbss_start'
undefined reference to `_heap_end'
undefined reference to `__dso_handle'
hidden symbol `__dso_handle' isn't defined
Possibly caused because of old/wrong/no linker script.
Ensure that the appropriate linker script is configured under: