I am trying to compile FreeRTOS project for stm32f4 using cmake. Everything goes smooth except for linking syscalls.c.
Project structure looks like this:
Everyting that is not in src
folder is compiled as a static library i.e. SPL, startup files, FreeRTOS and etc.
My last compilation step:
[100%] Linking C executable bin/stm32f4_template.elf
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -march=armv7e-m -fsingle-precision-constant
-finline-functions -Wdouble-promotion -std=gnu99 -Os -g -Wall -ffunction-sections
-fdata-sections -specs=nano.specs -u _scanf_float -u printf_float -fno-exceptions
-Wl,--gc-sections,-T/home/kript0n/Documents/projects/STM32F4-FreeRTOS/Utilities/stm32_flash.ld,
-Map,/home/kript0n/Documents/projects/STM32F4-FreeRTOS/build/bin/stm32f4_template.elf.map
CMakeFiles/stm32f4_template.elf.dir/src/main.c.obj CMakeFiles/stm32f4_template.elf.dir/src/controller.c.obj -o bin/stm32f4_template.elf
Libraries/STM32F4xx_StdPeriph_Driver/libdriverlib.a FreeRTOS/libFreeRTOS.a hardware/libhardware.a -lm Libraries/TM/libtm.a Libraries/syscall/libsyscalls.a
And output:
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg_nano.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
CMakeFiles/stm32f4_template.elf.dir/build.make:126: recipe for target 'bin/stm32f4_template.elf' failed
make[2]: *** [bin/stm32f4_template.elf] Error 1
As you can see syscalls.c is linked however system calls are still not found. Here is contents of syscalls.c and all the missing functions are presented inside:
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "stdio.h"
#include "stm32f4xx_usart.h"
/***************************************************************************/
int _open(const char *name, int flags, int mode){
return -1;
}
int _read(int file, char * ptr, int len) {
ptr = ptr;
len = len;
errno = EINVAL;
return -1;
}
/***************************************************************************/
int _lseek(int file, int ptr, int dir) {
file = file;
ptr = ptr;
dir = dir;
return 0;
}
/***************************************************************************/
int _write(int file, char * ptr, int len) {
int index;
if (!ptr) {
return 0;
}
for (index = 0; index < len; index++) {
while (!(USART3->SR & 0x00000040));
USART_SendData(USART3, ptr[index]);
}
return len;
}
/***************************************************************************/
int _close(int file) {
return 0;
}
/***************************************************************************/
/* Register name faking - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
caddr_t _sbrk(int incr) {
extern char end asm ("end"); // Defined by the linker.
static char * heap_end;
char * prev_heap_end;
if (heap_end == NULL)
heap_end = & end;
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr) {
// Some of the libstdc++-v3 tests rely upon detecting
// out of memory errors, so do not abort here.
#if 0
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
errno = ENOMEM;
return (caddr_t) -1;
#endif
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
/***************************************************************************/
int _fstat(int file, struct stat * st) {
file = file;
memset (st, 0, sizeof (* st));
st->st_mode = S_IFCHR;
return 0;
}
/***************************************************************************/
int _isatty(int fd) {
fd = fd;
return 1;
}
int _kill(int pid, int sig) {
errno=EINVAL;
return(-1);
}
int _getpid(void) {
return 1;
}
And its' building step:
[ 85%] Building C object Libraries/syscall/CMakeFiles/syscalls.dir/syscalls.c.obj
cd /home/kript0n/Documents/projects/STM32F4-FreeRTOS/build/Libraries/syscall && /home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc -DARM_MATH_CM4 -DHSE_VALUE=8000000 -DSTM32F40_41xxx -DSTM32F4XX -DUSESTD_PERIPH_DRIVER -D__FPU_PRESENT=1 -D__FPU_USED=1 -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/Libraries/CMSIS/Include -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/Libraries/STM32F4xx_StdPeriph_Driver/inc -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/Libraries/TM/TM_SPL -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/FreeRTOS/include -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/FreeRTOS/portable/GCC/ARM_CM4F -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/config -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/hardware -I/home/kript0n/Documents/projects/STM32F4-FreeRTOS/include -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -march=armv7e-m -fsingle-precision-constant -finline-functions -Wdouble-promotion -std=gnu99 -Os -g -Wall -ffunction-sections -fdata-sections -specs=nano.specs -o CMakeFiles/syscalls.dir/syscalls.c.obj -c /home/kript0n/Documents/projects/STM32F4-FreeRTOS/Libraries/syscall/syscalls.c
[ 89%] Linking C static library libsyscalls.a
cd /home/kript0n/Documents/projects/STM32F4-FreeRTOS/build/Libraries/syscall && /usr/bin/cmake -P CMakeFiles/syscalls.dir/cmake_clean_target.cmake
cd /home/kript0n/Documents/projects/STM32F4-FreeRTOS/build/Libraries/syscall && /usr/bin/cmake -E cmake_link_script CMakeFiles/syscalls.dir/link.txt --verbose=1
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-ar qc libsyscalls.a CMakeFiles/syscalls.dir/syscalls.c.obj
/home/kript0n/Applications/EmbeddedArm/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-ranlib libsyscalls.a
make[2]: Leaving directory '/home/kript0n/Documents/projects/STM32F4-FreeRTOS/build'
[ 89%] Built target syscalls
It seems that file is compiled into a library, functions are presented and it is linked. So what's wrong with it?
Thanks!
The rules that determine which symbol will be linked in, and when do they get marked as used, and not dropped by the linker, are somewhat different for standalone object files and libraries. Your problem might be correted by carefully rearranging the linker command line.
I have stopped caring about it, and just force marking the dropped functions as 'used'.
#define USED __attribute__ ((used))
#define UU __attribute__((unused))
int USED _close(int x UU) {
return -1;
}
int USED _fstat(int file UU, struct stat *st) {
st->st_mode = S_IFCHR;
return 0;
}
User contributions licensed under CC BY-SA 3.0