This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK 14.2.0, app_uart not finding its own function?

Hello,

We've been developing nRF52 software for about two years. We develop on Linux desktop machines, and build with GCC from the command line interface.

I'm starting to bring our software into compliance with SDK 14.2.0. I've encountered a strange compiler error in a very simple UART program. I am simply trying to print "Hello world" over the USB to a terminal. Here is the code, mostly copied verbatim from Nordic example code:

#include <stdio.h>
#include "app_uart.h"
#include "boards.h"

static void uart_error_handler(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        APP_ERROR_HANDLER(p_event->data.error_communication);
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        APP_ERROR_HANDLER(p_event->data.error_code);
}


ret_code_t uart_init(void)
{
    ret_code_t err_code;
    
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_ENABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud115200
    };

    // Not using the FIFO.
    APP_UART_INIT(&comm_params,
                  uart_error_handler,
                  APP_IRQ_PRIORITY_LOW,
                  err_code);
    
    return err_code;
}

int main(void)
{
    ret_code_t err_code;

    err_code = uart_init();
    if (err_code == NRF_SUCCESS)
        puts("Hello world!\n");
    return 0;
}

Here's what happens when I try to invoke GCC:

john@L:~/Documents/accel$ make
Compiling file: main.c
Linking target: _build/nrf52832_xxaa.out
_build/nrf52832_xxaa/main.c.o: In function `uart_init':
/home/john/Documents/accel/./main.c:41: undefined reference to `app_uart_init'
collect2: error: ld returned 1 exit status
/home/john/src/nRF5_SDK_14.2.0/components/toolchain/gcc/Makefile.common:292: recipe for target '_build/nrf52832_xxaa.out' failed
make: *** [_build/nrf52832_xxaa.out] Error 1

My code uses the APP_UART_INIT macro from app_uart.h. The macro decodes to a string which includes a call to app_uart_init, which is also defined in app_uart.h. I am clearly including the header correctly. If I had not, the macro itself would cause the error, rather than the function call inside it.

I don't show the Makefile, but I am compiling app_uart.c as well.

So why do I have an undefined reference? Any advice is greatly appreciated, thanks!

  • my guess would be that you don't have app_uart_c.o on the link line. Can you get a verbose make output?

  • Hello RK, thanks for your reply. I have modified Makefiles, but I haven't had to debug a make command at this level of detail before. For your information, I'm modifying the Makefile from the UART demo in the SDK 14.2 examples folder. I am not attempting to re-use an SDK 12.3 Makefile, as I can see that quite a bit has changed. For example, I've noticed that the _build folder that SDK 14.2 makes is organized a little differently, now there's a subfolder, nrf52832_xxaa. I directed the output of a make -d command into a log file, which ended up being 250K long. I found 50 references in that log file to app_uart.c.o. I'm not sure what error I might be looking for. The last referenced line reads: No need to remake target '_build/nrf52832_xxaa/app_uart.c.o'. .

  • Message 2: I looked through the make log for the terms "link" and "must remake". They only appear once each, at the very end, right before the failure:

    Finished prerequisites of target file '_build/nrf52832_xxaa.out'.
        Must remake target '_build/nrf52832_xxaa.out'.
    Linking target: _build/nrf52832_xxaa.out
    Putting child 0x55797f87e710 (_build/nrf52832_xxaa.out) PID 3537 on the chain.
    Live child 0x55797f87e710 (_build/nrf52832_xxaa.out) PID 3537 
    Reaping winning child 0x55797f87e710 PID 3537 
    Live child 0x55797f87e710 (_build/nrf52832_xxaa.out) PID 3539 
    Reaping losing child 0x55797f87e710 PID 3539 
    /home/john/src/nRF5_SDK_14.2.0/components/toolchain/gcc/Makefile.common:292: recipe for target '_build/nrf52832_xxaa.out' failed
    Removing child 0x55797f87e710 PID 3539 from chain.
    
  • make -n will print out what make is going to do without doing it make VERBOSE=1 should print as it goes

    all else fails put a shell script called 'ld' in your path which just prints its arguments and exits then make and see what it prints.

    you need the link line so you can run it by hand and figure out what's missing.

  • Following up to myself: whatever the problem was, it was my fault.  I started over again from scratch with the SDK 14.2 UART example, modifying both its main.c and the Makefile, and I was able to complete the build.

    The strange thing is that simply including and building app_uart doesn't seem to be enough to define the reference to app_uart_init(), even though I can see quite clearly that it is in fact defined there.  Perhaps there are some flags in other files which override what I expected.

Related