Qmk_firmware: Using malloc on ARM causes build failure

Created on 17 Oct 2019  路  4Comments  路  Source: qmk/qmk_firmware

I've seen a few queries on the Discord server about using malloc for various purposes, such as using snprintf to dynamically convert arbitrary value types (double or uint32_t) into a send_string-friendly char * string, or declaring a memory allocation to allow injecting Rust code into QMK.

Because Atmel ARM GNU toolchain does not have syscalls enabled, attempting to make a keymap with any reference to malloc will invariably fail with a linker error similar to the following:

| | /usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/thumb/v7e-m/libg.a(lib_a-sbrkr.o): In function `_sbrk_r': | /build/newlib-jo3xW1/newlib-2.4.0.20160527/build/arm-none-eabi/thumb/v7e-m/newlib/libc/reent/../../../../../../../newlib/libc/reent/sbrkr.c:58: undefined reference to `_sbrk' | collect2: error: ld returned 1 exit status
A workaround I've found involves adding the CFLAGs "-lc -specs=nosys.specs" to the make invocation -- make CFLAGs+="-lc -specs=nosys.specs" <keyboard>:<keymap>. More about this workaround can be read here

Caveat emptor as if you aren't freeing up your memory ASAP after malloc I could see the board getting into a super sad state. Be careful!

Opening an issue on this as @yanfali suggested adding this to the documentation. I would like to open a PR to get this added to documentation but just wanted to get this semi-documented for now.

bug discussion help wanted

All 4 comments

There may be many reasons for your problem.

  1. It does not look like malloc is doing any checks at all. The fault that you get comes from hardware detecting a write to an invalid address, which is probably coming from malloc itself.
    or,
  2. Your program most likely crashes because of illegal memory access, which is almost always an indirect (subsequent) result of legal memory access, but one that you did not intend to perform.

I have searched a little bit in this, the following link may help you -
https://stackoverflow.com/questions/22422733/malloc-behaviour-on-an-embedded-system

@Ratna04priya I think you are misunderstanding my write-up here.

The issue you linked regards unexpected results returned by malloc(), e.g. returning something other than NULL when the heap is full, and presupposes that the code successfully builds in the first place. The stackoverflow link you have posted regards run-time issues, and how to predict when malloc() will fail due lack of memory available to be allocated, which is at least one step ahead of what I am talking about here.

The issue I have filed concerns compile-time build failures due to system calls like malloc() being entirely absent from arm-none-eabi-gcc. I linked to the explanation in my initial post, which you can review here (#6 and #9, specifically): http://ww1.microchip.com/downloads/en/DeviceDoc/Frequently-Asked-Questions-4.9.3.26.txt

Looks like you can also add SRC += $(CHIBIOS)/os/various/syscalls.c to your rules.mk to work round the issue.

This file is added in a few other scenarios, so we could make it the default behaviour?

Ah that鈥檚 interesting (and way cleaner).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jetpacktuxedo picture jetpacktuxedo  路  3Comments

fredizzimo picture fredizzimo  路  4Comments

helluvamatt picture helluvamatt  路  4Comments

Frefreak picture Frefreak  路  4Comments

drashna picture drashna  路  3Comments