I want to dump a simple Hello World code in a Cortex M4 microcontroller.(Nuvoton M487KM) All the tool, board support files and IDE are provided on the website which are installed with the Eclipse IDE (NuEclipse GCC Windows). After creating a basic Hello world project, I try to build the project but keep getting these errors that wont stop bothering me.
Here is the code: (main.c)
#include <stdio.h>
#include "NuMicro.h"
#define PLL_CLOCK 192000000
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);
/* Enable External XTAL (4~24 MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
/* Waiting for 12MHz clock ready */
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(PLL_CLOCK);
/* Set PCLK0/PCLK1 to HCLK/2 */
CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);
/* Enable UART clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Select UART clock source from HXT */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
SystemCoreClockUpdate();
/* Set GPB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);
/* Lock protected registers */
SYS_LockReg();
}
/*
* This is a template project for M480 series MCU. Users could based on this project to create their
* own application without worry about the IAR/Keil project settings.
*
* This template application uses external crystal as HCLK source and configures UART0 to print out
* "Hello World", users may need to do extra system configuration based on their system design.
*/
int main()
{
SYS_Init();
/* Init UART to 115200-8n1 for print message */
UART_Open(UART0, 115200);
/* Connect UART to PC, and open a terminal tool to receive following message */
printf("Hello World\n");
/* Got no where to go, just loop forever */
while(1);
}
And these are the errors I get:
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-closer.o): in function `_close_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-fstatr.o): in function `_fstat_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-isattyr.o): in function `_isatty_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-lseekr.o): in function `_lseek_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-readr.o): in function `_read_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-sbrkr.o): in function `_sbrk_r': hellowork C/C++ Problem
c:/program files (x86)/gnu arm embedded toolchain/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp\libc_nano.a(lib_a-writer.o): in function `_write_r': hellowork C/C++ Problem
make: *** [hellowork.elf] Error 1 hellowork C/C++ Problem
recipe for target 'hellowork.elf' failed makefile /hellowork/Debug line 56 C/C++
Problem
undefined reference to `_close' hellowork line 0 C/C++ Problem
undefined reference to `_fstat' hellowork line 0 C/C++ Problem
undefined reference to `_isatty' hellowork line 0 C/C++ Problem
undefined reference to `_lseek' hellowork line 0 C/C++ Problem
undefined reference to `_read' hellowork line 0 C/C++ Problem
undefined reference to `_write' hellowork line 0 C/C++ Problem
undefined reference to `errno' hellowork line 0 C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: closer.c C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: fstatr.c C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: isattyr.c C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: lseekr.c C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: readr.c C/C++ Problem
undefined reference to `errno' hellowork line 0, external location: c:\program files (x86)\gnu arm embedded toolchain\10 2021.10\arm-none-eabi\bin\ld.exe: writer.c C/C++ Problem
According to the NuEclipse User Manual, we need to set global Toolchain Settings which I did. The path to Toolchain and Build tools is also mentioned. Still the code keeps giving me these errors. I read online that it might be the "libc_nano.a" files issue but the those solutions have not helped me. Can someone please help me!!
It looks like you are using the Newlib C library for which you need to provide the syscalls stubs to couple the library to your hardware/runtime environment.
Many of the stubs only need dummy implementations. To support printf
you need to implement _write_r()
. To support a heap (malloc()
et al), you need to implement _sbrk_r
.
Details of the syscalls that need implementing can be found at https://sourceware.org/newlib/libc.html#Reentrant-Syscalls, along with "minimal" implementation examples at https://sourceware.org/newlib/libc.html#Stubs. Noting that the re-entrant versions can simply map to (or be implemented in the samr way as) the non-reentrant versions if you are not multi-threading or for very simple implementations. The _r
variants allow for a thread specific errno
for example.
You simply need to create a source file with these functions implemented and link them to your project to resolve the links. It looks like your tool chain already provides for this in these files:
closer.c
fstatr.c
isattyr.c
lseekr.c
readr.c
writer.c
Those are the ones that need modifying, reimplementing or possibly they are ok, but you need to provide the errno
support (a global) indicated by the linker error. In a multi-threaded environment errno
needs "switching" per thread (ideally - or just never rely on errno
), but otherwise a single global is all that is needed most likely (also as described at https://sourceware.org/newlib/libc.html#Stubs).