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

"Undefined Reference" on the linker level

Hi. I am a beginner with nrf52832. Trying to get Bluetooth and UART and a I2C peripheral working at the same time. I had a working version of the I2C peripheral and UART working together and tried to merge Bluetooth in, referencing the ble_app_uart example provided in nRF5_SDK_12.3.0. Currently when I try to do make flash I do not get any compiling errors, but I am getting linker errors that say that I have "undefined reference":

Linking target: _build/nrf52832_xxaa.out
_build/nrf52832_xxaa_twi.c.o: In function `twi_master_init':
/home/yilunsheng/src/accelerometer, SDK12.3, app_uart_merge/./twi.c:43: undefined reference to `nrf_drv_twi_init'
/home/yilunsheng/src/accelerometer, SDK12.3, app_uart_merge/./twi.c:46: undefined reference to `nrf_drv_twi_enable'
_build/nrf52832_xxaa_lis3dh.c.o: In function `lis3dh_read_data':
/home/yilunsheng/src/accelerometer, SDK12.3, app_uart_merge/./lis3dh.c:171: undefined reference to `nrf_drv_twi_tx'
/home/yilunsheng/src/accelerometer, SDK12.3, app_uart_merge/./lis3dh.c:180: undefined reference to `nrf_drv_twi_rx'
_build/nrf52832_xxaa_lis3dh.c.o: In function `lis3dh_init':
/home/yilunsheng/src/accelerometer, SDK12.3, app_uart_merge/./lis3dh.c:232: undefined reference to `nrf_drv_twi_tx'
collect2: error: ld returned 1 exit status
../nRF5_SDK_12.3.0/components/toolchain/gcc/Makefile.common:153: recipe for target '_build/nrf52832_xxaa.out' failed
make: *** [_build/nrf52832_xxaa.out] Error 1

Very confused about where the problem is.

  • Hi,

    This is caused by one of (or both) the following things:

    1. You have not included the source file that implements the functions in your project. In SDK 12.3.0, these functions are implemented in the source file 'nRF5_SDK_12.3.0_d7731ad\components\drivers_nrf\twi_master\nrf_drv_twi.c'
    2. You have not enabled the module in your project's sdk_config.h file. Check if you can find TWI_ENABLED in the file, and set it to 1. If you cannot find this section in the sdk_config.h file in the BLE project, you need to copy the entire section related to the TWI master driver from one of the TWI master projects and add it to the sdk_config.h file of your BLE project.

    // <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver
    //==========================================================
    #ifndef TWI_ENABLED
    #define TWI_ENABLED 1
    #endif
    #if  TWI_ENABLED
    // <o> TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency
     
    // <26738688=> 100k 
    // <67108864=> 250k 
    // <104857600=> 400k 
    
    #ifndef TWI_DEFAULT_CONFIG_FREQUENCY
    #define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
    #endif
    
    // <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT  - Enables bus clearing procedure during init
     
    
    #ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
    #define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
    #endif
    
    // <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit
     
    
    #ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
    #define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
    #endif
    
    // <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
     
    
    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    
    #ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
    #define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 7
    #endif
    
    // <e> TWI0_ENABLED - Enable TWI0 instance
    //==========================================================
    #ifndef TWI0_ENABLED
    #define TWI0_ENABLED 1
    #endif
    #if  TWI0_ENABLED
    // <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
     
    
    #ifndef TWI0_USE_EASY_DMA
    #define TWI0_USE_EASY_DMA 1
    #endif
    
    #endif //TWI0_ENABLED
    // </e>
    
    // <e> TWI1_ENABLED - Enable TWI1 instance
    //==========================================================
    #ifndef TWI1_ENABLED
    #define TWI1_ENABLED 0
    #endif
    #if  TWI1_ENABLED
    // <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)
     
    
    #ifndef TWI1_USE_EASY_DMA
    #define TWI1_USE_EASY_DMA 0
    #endif
    
    #endif //TWI1_ENABLED
    // </e>
    
    // <e> TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
    //==========================================================
    #ifndef TWI_CONFIG_LOG_ENABLED
    #define TWI_CONFIG_LOG_ENABLED 0
    #endif
    #if  TWI_CONFIG_LOG_ENABLED
    // <o> TWI_CONFIG_LOG_LEVEL  - Default Severity level
     
    // <0=> Off 
    // <1=> Error 
    // <2=> Warning 
    // <3=> Info 
    // <4=> Debug 
    
    #ifndef TWI_CONFIG_LOG_LEVEL
    #define TWI_CONFIG_LOG_LEVEL 3
    #endif
    
    // <o> TWI_CONFIG_INFO_COLOR  - ANSI escape code prefix.
     
    // <0=> Default 
    // <1=> Black 
    // <2=> Red 
    // <3=> Green 
    // <4=> Yellow 
    // <5=> Blue 
    // <6=> Magenta 
    // <7=> Cyan 
    // <8=> White 
    
    #ifndef TWI_CONFIG_INFO_COLOR
    #define TWI_CONFIG_INFO_COLOR 0
    #endif
    
    // <o> TWI_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
     
    // <0=> Default 
    // <1=> Black 
    // <2=> Red 
    // <3=> Green 
    // <4=> Yellow 
    // <5=> Blue 
    // <6=> Magenta 
    // <7=> Cyan 
    // <8=> White 
    
    #ifndef TWI_CONFIG_DEBUG_COLOR
    #define TWI_CONFIG_DEBUG_COLOR 0
    #endif
    
    #endif //TWI_CONFIG_LOG_ENABLED
    // </e>
    
    #endif //TWI_ENABLED
    // </e>

    If you had spent 1 minute searching DevZone for the errors you are experiencing, you would have found countless other questions answering how to solve this issue.

    Best regards,
    Jørgen

  • You have not included the source file that implements the functions in your project

    This is a standard 'C' issue - nothing specifically to do with Nordic.

    However, in this case, I would have thought you would have got compile errors?

    ou have not enabled the module in your project's sdk_config.h file.

    This one is specific to the way Nordic configure their SDKs.

    As   said, this one is a frequent cause of confusion - so maybe there's a clue for Nordic there, that it needs to be better explained...?

  • However, in this case, I would have thought you would have got compile errors?

    As long as the header file where the function is declared is included, you will not get compilation error. If header file is included but source file is not included in project, you will get this linker error.

    this one is a frequent cause of confusion - so maybe there's a clue for Nordic there, that it needs to be better explained...?

    I think it is explained well in the documentation:

    "Every module in SDK contains at least one configuration option that enables this module. If the module is disabled, then even if source code is added to the project, it is not compiled because the module implementation is conditionally included."

    I will say that is should be expected of customers to read through the Getting Started section of the SDK documentation to get familiar with the SDK before starting to develop applications.

  • I think it is explained well in the documentation:

    "Every module in SDK contains at least one configuration option that enables this module

    I didn't find that it was always easy to identify what configuration option(s) is/are required by a particular module.

    Especially as some (many? most?) modules have dependencies on other modules.

    Plus the added confusion of there often being NRFX and "legacy" versions of the same thing ...

    eg, see: https://devzone.nordicsemi.com/f/nordic-q-a/39469/linking-mpu6050-sensor-with-ble-uart/152957#152957

    See also: https://devzone.nordicsemi.com/f/nordic-q-a/34739/how-to-add-simple-timer-to-a-project/133302#133302

  • and why does the forum quote feature keep going wrong like that - ie, the quoted text is outside the quote marker!

Related