undefined reference to `_sbrk' when using atof() function

Asked by Maskari

Hi,

I am trying to cast a string as a float in a function, I was successfully able to cast a string as an integer in the same function and I can compile the code without any errors as long as I comment out the atof() part.

my code is:

 void cmd_color(BaseSequentialStream *chp, int argc, char *argv[]) {

  (void)argv;

  float fx, fy;
  char test[20];
   strcpy(test, "123.456");
 //test = 123.456;
 // fx = atof(argv[0]);
  fy = atof(test);
  fx = 4.8;
// fy = 2.4;
 chprintf(chp, "String values = %s , %s . Float values = %f , %f\r\n", argv[0], argv[1], fx, fy);

 // Color(atof(x), atof(y));

   //Color(atof(argv[0]), atof(argv[1]));

  FindValues();
  //printing ratios of the 3 primary LEDs
  chprintf(chp, "Ratio of Red LED is %f \r\n", Ratior());
  chprintf(chp, "Ratio of Green LED is %f \r\n", Ratiog());
  chprintf(chp, "Ratio of Blue LED is %f \r\n", Ratiob());

 }

the above code has been modified from its original context in order to try and debug it, my final aim/goal is to read two variable length strings argv[0] and argv[1] and use them as inputs for the function Color which takes two floats.

the compiler outputs this:

Compiling console.c
console.c:18:30: warning: 'chp' defined but not used [-Wunused-variable]
Linking build/ch.elf
/Users/maskari/Projects/arm/Toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
make: *** [build/ch.elf] Error 1

I am using a make file provided to me by ChibiOS which is an embedded RTOS and has worked without any problems until now.

my version of arm gcc is 4.7.4 which has been downloaded from this website.

any suggestions would be massively appreciated as this error is driving me nuts!

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Joey Ye (jinyun-ye) said :
#1

Add -specs=nosys.specs in linker options
2014-4-12 上午3:26于 "Maskari" <email address hidden>写道:

> New question #246883 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/246883
>
> Hi,
>
> I am trying to cast a string as a float in a function, I was successfully
> able to cast a string as an integer in the same function and I can compile
> the code without any errors as long as I comment out the atof() part.
>
> my code is:
>
> void cmd_color(BaseSequentialStream *chp, int argc, char *argv[]) {
>
> (void)argv;
>
> float fx, fy;
> char test[20];
> strcpy(test, "123.456");
> //test = 123.456;
> // fx = atof(argv[0]);
> fy = atof(test);
> fx = 4.8;
> // fy = 2.4;
> chprintf(chp, "String values = %s , %s . Float values = %f , %f\r\n",
> argv[0], argv[1], fx, fy);
>
> // Color(atof(x), atof(y));
>
> //Color(atof(argv[0]), atof(argv[1]));
>
>
> FindValues();
> //printing ratios of the 3 primary LEDs
> chprintf(chp, "Ratio of Red LED is %f \r\n", Ratior());
> chprintf(chp, "Ratio of Green LED is %f \r\n", Ratiog());
> chprintf(chp, "Ratio of Blue LED is %f \r\n", Ratiob());
>
> }
>
>
>
> the above code has been modified from its original context in order to try
> and debug it, my final aim/goal is to read two variable length strings
> argv[0] and argv[1] and use them as inputs for the function Color which
> takes two floats.
>
>
>
> the compiler outputs this:
>
> Compiling console.c
> console.c:18:30: warning: 'chp' defined but not used [-Wunused-variable]
> Linking build/ch.elf
> /Users/maskari/Projects/arm/Toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc.a(lib_a-sbrkr.o):
> In function `_sbrk_r':
> sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
> collect2: error: ld returned 1 exit status
> make: *** [build/ch.elf] Error 1
>
>
> I am using a make file provided to me by ChibiOS which is an embedded RTOS
> and has worked without any problems until now.
>
> my version of arm gcc is 4.7.4 which has been downloaded from this website.
>
> any suggestions would be massively appreciated as this error is driving me
> nuts!
>
>
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Maskari (al-maskari) said :
#2

Hi,
Thank you for your answer but I'm afraid I still get the same error.

I added this line to my make file:
LDFLAGS= -specs=nosys.specs

and the linker gave me this error:
Compiling console.c
console.c:18:30: warning: 'chp' defined but not used [-Wunused-variable]
Linking build/ch.elf
/Users/maskari/Projects/arm/Toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
make: *** [build/ch.elf] Error 1

it compiled fine with the new flag specified but with atof() commented out and failed when i tried to compile it with one atof() function in use.

Revision history for this message
Maskari (al-maskari) said :
#3

this is the make file I am using, please note that I have no experience with making makefiles!

Makefile:

##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#

# Compiler options here.
ifeq ($(USE_OPT),)
  USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif

# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
  USE_COPT =
endif

# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
  USE_CPPOPT = -fno-rtti
endif

# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
  USE_LINK_GC = yes
endif

# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
  USE_THUMB = yes
endif

# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
  USE_VERBOSE_COMPILE = no
endif

#
# Build global options
##############################################################################

##############################################################################
# Architecture or project specific options
#

# Enables the use of FPU on Cortex-M4.
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FPU),)
  USE_FPU = no
endif

# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FWLIB),)
  USE_FWLIB = no
endif

#
# Architecture or project specific options
##############################################################################

##############################################################################
# Project, sources and paths
#

# Define project name here
PROJECT = ch

# Imported source files and paths
CHIBIOS = ../..
include $(CHIBIOS)/boards/ST_STM32F4_DISCOVERY/board.mk
include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
include $(CHIBIOS)/test/test.mk

#Define linker flags here (added by me to enable the use of atof() function for coverting strings to floats)

LDFLAGS= -specs=nosys.specs

# Define linker script file here
LDSCRIPT= $(PORTLD)/STM32F407xG.ld
#LDSCRIPT= $(PORTLD)/STM32F407xG_CCM.ld

# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(PORTSRC) \
       $(KERNSRC) \
       $(TESTSRC) \
       $(HALSRC) \
       $(PLATFORMSRC) \
       $(BOARDSRC) \
       $(CHIBIOS)/os/various/devices_lib/accel/lis302dl.c \
       $(CHIBIOS)/os/various/chprintf.c \
       main.c \
       console.c \
       shell.c

# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC =

# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =

# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =

# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =

# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =

# List ASM source files here
ASMSRC = $(PORTASM)

INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
         $(HALINC) $(PLATFORMINC) $(BOARDINC) \
         $(CHIBIOS)/os/various/devices_lib/accel \
         $(CHIBIOS)/os/various

#
# Project, sources and paths
##############################################################################

##############################################################################
# Compiler settings
#

MCU = cortex-m4

#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
OD = $(TRGT)objdump
HEX = $(CP) -O ihex
BIN = $(CP) -O binary

# ARM-specific options here
AOPT =

# THUMB-specific options here
TOPT = -mthumb -DTHUMB

# Define C warning options here
CWARN = -Wall -Wextra -Wstrict-prototypes

# Define C++ warning options here
CPPWARN = -Wall -Wextra

#
# Compiler settings
##############################################################################

##############################################################################
# Start of default section
#

# List all default C defines here, like -D_DEBUG=1
DDEFS =

# List all default ASM defines here, like -D_DEBUG=1
DADEFS =

# List all default directories to look for include files here
DINCDIR =

# List the default directory to look for the libraries here
DLIBDIR =

# List all default libraries here
DLIBS =

#
# End of default section
##############################################################################

##############################################################################
# Start of user section
#

# List all user C define here, like -D_DEBUG=1
UDEFS =

# Define ASM defines here
UADEFS =

# List all user directories here
UINCDIR =

# List the user directory to look for the libraries here
ULIBDIR =

# List all user libraries here
ULIBS =

#
# End of user defines
##############################################################################

ifeq ($(USE_FPU),yes)
  USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
  DDEFS += -DCORTEX_USE_FPU=TRUE
else
  DDEFS += -DCORTEX_USE_FPU=FALSE
endif

ifeq ($(USE_FWLIB),yes)
  include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
  CSRC += $(STM32SRC)
  INCDIR += $(STM32INC)
  USE_OPT += -DUSE_STDPERIPH_DRIVER
endif

include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk

Revision history for this message
Joey Ye (jinyun-ye) said :
#4

Maskari,

This error message means that linker cann't find the libgloss that defines _sbrk. There are two approaches to solve it:

1. Appending -lnosys.specs to end of your linker command line (This works for 4.7 and 4.8)
2. Add -specs=nosys.specs in any place of your linker command line (This works for 4.8)

Since you are using 4.7, place try the first option. If it is still not solved, place attach your complete linker command line.

Thanks,
Joey

Can you help with this problem?

Provide an answer of your own, or ask Maskari for more information if necessary.

To post a message you must log in.