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

undefined reference twi error

Hi,

I hope you can help me. I get an error while compiling. I merge "twi sensor" example from sdk to the "ble app uart" example from sdk. So I customize the sdk_config to enable twi. In addition to that, I add all missing nRF_Drivers to make it work. While compiling, I get the following output:

1> "C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/as" --traditional-format -I../../../config -I../../../../../../components -I../../../../../../components/ble/ble_advertising -I../../../../../../components/ble/ble_dtm -I../../../../../../components/ble/ble_link_ctx_manager -I../../../../../../components/ble/ble_racp -I../../../../../../components/ble/ble_services/ble_ancs_c -I../../../../../../components/ble/ble_services/ble_ans_c -I../../../../../../components/ble/ble_services/ble_bas -I../../../../../../components/ble/ble_services/ble_bas_c -I../../../../../../components/ble/ble_services/ble_cscs -I../../../../../../components/ble/ble_services/ble_cts_c -I../../../../../../components/ble/ble_services/ble_dfu -I../../../../../../components/ble/ble_services/ble_dis -I../../../../../../components/ble/ble_services/ble_gls -I../../../../../../components/ble/ble_services/ble_hids -I../../../../../../components/ble/ble_services/ble_hrs -I../../../../../../components/ble/ble_services/ble_hrs_c -I../../../../../../components/ble/ble_services/ble_hts -I../../../../../../components/ble/ble_services/ble_ias -I../../../../../../components/ble/ble_services/ble_ias_c -I../../../../../../components/ble/ble_services/ble_lbs -I../../../../../../components/ble/ble_services/ble_lbs_c -I../../../../../../components/ble/ble_services/ble_lls -I../../../../../../components/ble/ble_services/ble_nus -I../../../../../../components/ble/ble_services/ble_nus_c -I../../../../../../components/ble/ble_services/ble_rscs -I../../../../../../components/ble/ble_services/ble_rscs_c -I../../../../../../components/ble/ble_services/ble_tps -I../../../../../../components/ble/common -I../../../../../../components/ble/nrf_ble_gatt -I../../../../../../components/ble/nrf_ble_qwr -I../../../../../../components/ble/peer_manager -I../../../../../../components/boards -I../../../../../../components/libraries/atomic -I../../../../../../components/libraries/atomic_fifo -I../../../../../../components/libraries/atomic_flags -I../../../../../../components/libraries/balloc -I../../../../../../components/libraries/bootloader/ble_dfu -I../../../../../../components/libraries/bsp -I../../../../../../components/libraries/button -I../../../../../../components/libraries/cli -I../../../../../../components/libraries/crc16 -I../../../../../../components/libraries/crc32 -I../../../../../../components/libraries/crypto -I../../../../../../components/libraries/csense -I../../../../../../components/libraries/csense_drv -I../../../../../../components/libraries/delay -I../../../../../../components/libraries/ecc -I../../../../../../components/libraries/experimental_section_vars -I../../../../../../components/libraries/experimental_task_manager -I../../../../../../components/libraries/fds -I../../../../../../components/libraries/fifo -I../../../../../../components/libraries/fstorage -I../../../../../../components/libraries/gfx -I../../../../../../components/libraries/gpiote -I../../../../../../components/libraries/hardfault -I../../../../../../components/libraries/hci -I../../../../../../components/libraries/led_softblink -I../../../../../../components/libraries/log -I../../../../../../components/libraries/log/src -I../../../../../../components/libraries/low_power_pwm -I../../../../../../components/libraries/mem_manager -I../../../../../../components/libraries/memobj -I../../../../../../components/libraries/mpu -I../../../../../../components/libraries/mutex -I../../../../../../components/libraries/pwm -I../../../../../../components/libraries/pwr_mgmt -I../../../../../../components/libraries/queue -I../../../../../../components/libraries/ringbuf -I../../../../../../components/libraries/scheduler -I../../../../../../components/libraries/sdcard -I../../../../../../components/libraries/slip -I../../../../../../components/libraries/sortlist -I../../../../../../components/libraries/spi_mngr -I../../../../../../components/libraries/stack_guard -I../../../../../../components/libraries/strerror -I../../../../../../components/libraries/svc -I../../../../../../components/libraries/timer -I../../../../../../components/libraries/twi_mngr -I../../../../../../components/libraries/twi_sensor -I../../../../../../components/libraries/uart -I../../../../../../components/libraries/usbd -I../../../../../../components/libraries/usbd/class/audio -I../../../../../../components/libraries/usbd/class/cdc -I../../../../../../components/libraries/usbd/class/cdc/acm -I../../../../../../components/libraries/usbd/class/hid -I../../../../../../components/libraries/usbd/class/hid/generic -I../../../../../../components/libraries/usbd/class/hid/kbd -I../../../../../../components/libraries/usbd/class/hid/mouse -I../../../../../../components/libraries/usbd/class/msc -I../../../../../../components/libraries/util -I../../../../../../components/nfc/ndef/conn_hand_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/ac_rec_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/le_oob_rec_parser -I../../../../../../components/nfc/ndef/connection_handover/ac_rec -I../../../../../../components/nfc/ndef/connection_handover/ble_oob_advdata -I../../../../../../components/nfc/ndef/connection_handover/ble_pair_lib -I../../../../../../components/nfc/ndef/connection_handover/ble_pair_msg -I../../../../../../components/nfc/ndef/connection_handover/common -I../../../../../../components/nfc/ndef/connection_handover/ep_oob_rec -I../../../../../../components/nfc/ndef/connection_handover/hs_rec -I../../../../../../components/nfc/ndef/connection_handover/le_oob_rec -I../../../../../../components/nfc/ndef/generic/message -I../../../../../../components/nfc/ndef/generic/record -I../../../../../../components/nfc/ndef/launchapp -I../../../../../../components/nfc/ndef/parser/message -I../../../../../../components/nfc/ndef/parser/record -I../../../../../../components/nfc/ndef/text -I../../../../../../components/nfc/ndef/uri -I../../../../../../components/nfc/platform -I../../../../../../components/nfc/t2t_lib -I../../../../../../components/nfc/t2t_parser -I../../../../../../components/nfc/t4t_lib -I../../../../../../components/nfc/t4t_parser/apdu -I../../../../../../components/nfc/t4t_parser/cc_file -I../../../../../../components/nfc/t4t_parser/hl_detection_procedure -I../../../../../../components/nfc/t4t_parser/tlv -I../../../../../../components/softdevice/common -I../../../../../../components/softdevice/s140/headers -I../../../../../../components/softdevice/s140/headers/nrf52 -I../../../../../../components/toolchain/cmsis/include -I../../../../../../external/fprintf -I../../../../../../external/segger_rtt -I../../../../../../external/utf_converter -I../../../../../../integration/nrfx -I../../../../../../integration/nrfx/legacy -I../../../../../../modules/nrfx -I../../../../../../modules/nrfx/drivers/include -I../../../../../../modules/nrfx/hal -I../../../../../../modules/nrfx/mdk -I../config -mcpu=cortex-m4 -mlittle-endian -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb "C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/main.asm" -o "Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o"
1> rm "C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/main.asm"
1> Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o (28.06.2020 20:58:16) is newer than Output/Debug/Exe/ble_app_uart_pca10100_s140.elf (28.06.2020 20:57:32).
1> Linking ble_app_uart_pca10100_s140.elf
1> "C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld" -X --omagic -eReset_Handler --defsym=__vfprintf=__vfprintf_long --defsym=__vfscanf=__vfscanf_long -EL --gc-sections "-TC:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/ble_app_uart_pca10100_s140.ld" -Map Output/Debug/Exe/ble_app_uart_pca10100_s140.map -u_vectors -o Output/Debug/Exe/ble_app_uart_pca10100_s140.elf --emit-relocs --start-group "@C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/ble_app_uart_pca10100_s140.ind" --end-group
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/nrf_drv_twi.o: in function `nrf_drv_twi_init':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\integration\nrfx\legacy/nrf_drv_twi.c:186: undefined reference to `nrfx_twi_init'
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o: in function `nrf_drv_twi_enable':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\examples\ble_peripheral\ble_app_uart\pca10100\s140\ses/../../../../../../integration/nrfx/legacy/nrf_drv_twi.h:513: undefined reference to `nrfx_twim_enable'
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o: in function `nrf_drv_twi_tx':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\examples\ble_peripheral\ble_app_uart\pca10100\s140\ses/../../../../../../integration/nrfx/legacy/nrf_drv_twi.h:544: undefined reference to `nrfx_twim_tx'
Build failed

But I don´t know what I´m making wrong.

Could you help me with that?

Thanks in advance

  • Hello Simon,

    You can see the necessary steps for using the application timer library in its documentation. It seems to me that you are close to making it work, you will just need to move your APP_TIMER_DEF, and possibly also enable the timers in the sdk_config file.

    simon1516 said:
    But when I try to start the timer in my main function, then I get an error because "my_timer_id" is not declared in here:

    You should move your APP_TIMER_DEF to the top of your file - right next to your #define's.
    Could you also verify for me that APP_TIMER_ENABLED, TIMER_ENABLED, and NRFX_TIMER_ENABLED is defined to 1 in the sdk_config? You will also need to have the particular timer instance ENABLE set to 1 ( seem to me like you are using timer instance 3 ).

    Hope this helps! :) 

    Best regards,
    Karl

  • Hi Karl,

    I am here again with new findings:

    __________________________________

    you will just need to move your APP_TIMER_DEF, and possibly also enable the timers in the sdk_config file

    Thats it. After moving "APP_TIMER_DEF(my_timer_id);" to the top of main.c the compilation works fine. But how can there be an ID (Integer Value) for my timer? I just give it the name my_timer_id. Do I have to give an ID at all? If I trying to do that, I get an error:

    __________________________________

    Could you also verify for me that APP_TIMER_ENABLED, TIMER_ENABLED, and NRFX_TIMER_ENABLED is defined to 1 in the sdk_config? You will also need to have the particular timer instance ENABLE set to 1 ( seem to me like you are using timer instance 3 ).

    Everything is set to "1".

    NRFX_TIMER0_ENABLED to NRFX_TIMER4_ENABLED is set to 1.

    __________________________________

    If I don´t define the "#define my_timer_id 3" the compiling works fine. Then the main loop is running. But after the expiration of the timer (#define TWIM_transmission_time          APP_TIMER_TICKS(10000)) the code stucks with NRF_BUSY error. It´s the same error like posted on 24. August 2020 7:54 p.m. (although I didn´t change anything on this function since then). So the behaviour is confusing a little bit.

    In my main loop is not much code.

    This works:

            nrf_delay_ms(20);
           // ret_code_t err_code = app_timer_start(my_timer_id, TWIM_transmission_time, NULL);
           // APP_ERROR_CHECK(err_code);
            read_sensor_data();

    This doesn´t work:

            nrf_delay_ms(20);
            ret_code_t err_code = app_timer_start(my_timer_id, TWIM_transmission_time, NULL);
            APP_ERROR_CHECK(err_code);
          //  read_sensor_data();

    Where is the difference? The only difference is, that in first example the function "read _sensor_data()"  is called automatically and in the second example the function "read _sensor_data()"  is called by expiration of the timer. Because of that, I don´t think there is someting wrong with my function rather someting with the timer procedure...

    __________________________________

    So, I hope you see something that I don´t see, which I can fix :-)

    Kind regards

    Simon

  • Hello Simon, 

    simon1516 said:
    Thats it. After moving "APP_TIMER_DEF(my_timer_id);" to the top of main.c the compilation works fine.
    simon1516 said:
    But how can there be an ID (Integer Value) for my timer? I just give it the name my_timer_id. Do I have to give an ID at all? If I trying to do that, I get an error:

    You do not need to give your timer an integer ID, no. The APP_TIMER_DEF creates an instance with that name. So, what you would do is basically:

    APP_TIMER_DEF(m_twi_timer);
    ..
    err_code = app_timer_init();
    ..
    err_code = app_timer_create(&m_twi_timer, APP_TIMER_MODE_SINGLE_SHOT, twi_timer_handler);
    APP_ERROR_CHECK(err_code);
    ..
    err_code = app_timer_start(m_twi_timer, TWI_TRANSMISSION_DELAY, NULL);
    APP_ERROR_CHECK(err_code);
    ..
    

    If you would like to see the source of the compiler error you are getting here, go to the definition of APP_TIMER_DEF and see what argument it expects, vs. the integer "3" you provided.

    simon1516 said:

    Everything is set to "1".

    NRFX_TIMER0_ENABLED to NRFX_TIMER4_ENABLED is set to 1.

    Thank you for confirming this.

    simon1516 said:
    APP_TIMER_TICKS(10000)

     This is a 10,000 ms delay, i.e 10 s. Is this the intended delay?

    simon1516 said:
    the code stucks with NRF_BUSY error

    Which function is returning this error code, nrfx_twim_xfer? And, what do you mean by "stuck", does the device reset?

    simon1516 said:
    Where is the difference? The only difference is, that in first example the function "read _sensor_data()"  is called automatically and in the second example the function "read _sensor_data()"  is called by expiration of the timer.

    The difference is that the CPU is free to continue with other tasks in the meantime, while the timer is running. In your current setup, this means that the CPU will run for 10 seconds while the timer is still running. The question then becomes, what are you doing in these 10 seconds? If the code above is your entire main loop then the CPU will immediately enter the loop again, and try to start the timer again in the next loop iteration. From the 

    app_timer_start

    documentation we see that this function call is ignored if the timer is already started.
    What you should instead do is therefore to either go to sleep, or perform some other task.
    Could you show the entire contents of your current main function?

    Best regards,
    Karl

  • If you would like a more fully-fledged tutorial on the app_timer, then I highly recommend taking a look at this one written by my colleague.
    The tutorial is a bit old, but the general approach and theory still holds true for the app_timer in the newest SDK.

    Best regards,
    Karl

  • Hi Karl,

    thanks for your support!

    So, what you would do is basically:

    I´m doing it like this, so I think setting up the timer is correct.

     This is a 10,000 ms delay, i.e 10 s. Is this the intended delay?

    No, it was just for testing the procedure while watching the timer expiration. In normal mode, we would like to process a TWIM with BLE transfer each 10ms, maybe 20ms. In your opinion, does it make sense to set the chip into sleep modus for this small time? If we expect, a data transfer needs about 2ms...then the chip could sleep for 8ms until the next transfer - a long time?

    What could be a good way to handle this? After each transfer, I can call "sleep_mode_enter()". And then the system is off? Is it possible, to wake up with timer expiration as interrupt? Is there an easy example for this?

    documentation we see that this function call is ignored if the timer is already started.

    Okay, but ignoration should be okay for me or not? But someting aborts in my application. But I´m with you, that the timer should just start at one time. Because of that, I moved this from my main loop to the initialization of my main application. So there the timer starts just one time. I´ve added the actual project file for you which includes main.c for analyzing this.

    Which function is returning this error code, nrfx_twim_xfer? And, what do you mean by "stuck", does the device reset?

    Correct. It´s the function "nrfx_twim_xfer" again. The complete error message is:

    <error> app: ERROR 17 [NRF_ERROR_BUSY] at C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\examples\ble_peripheral\ble_app_uart_with_twim v0.2\main.c:826
    PC at: 0x0003137B

    Karl, thanks for you help! I think it´s time to add an actual project file (attached) for analyzing.

    ble_app_uart_with_twim v0.6.zip

    Simon

Related