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 again Simon,

    simon1516 said:

    Could you guide me how to use such a timer? I defined "#define TWIM_transmission_time APP_TIMER_TICKS(10) " to get a timer with 10ms delay time. So now, I would like to use this timer in my "twim_handler". Nothing should happen, if the timer isn´t expired. The timer should restart, if it is expired and an twim event was done. Could you give me a small Syntax for this?

    I have already included "app_timer.h", so I think it would make sense to use this.



    Yes, it would be easiest to use the app_timer to create and manage the timer.
    However, could you first try to see what the required delay is, by using nrf_delay?
    It might be that your TWI slave requires some delay between transfer.

    It is slightly more work to implement the solution without wasted CPU cycles. Could you detail for me what transfers you will make - how frequent are they, and how many bytes are in each transfer?
    If you are only doing pairs of two and two bytes ( R/W commands ) then you could perhaps solve this by using the DESC_TXTX and DESC_TXRX, for example. It would mean a lot less work to use the already implemented features of the TWIM driver, so lets look at that first if possible, or depending on your specification we might use the NRFX_TWIM_FLAG_HOLD_XFER feature instead.

    simon1516 said:
    Could you tell me, how to get this Information?

    Yes, please check your sdk_config file, to see if the NRF_LOG_DEFERRED is defined as 1 or 0, and if it is 1, what is then the size of NRF_LOG_BUFSIZE? 

    simon1516 said:
    Here I think I have to debug again (because debugging is working now :-) ). I will try this and give you a short Feedback the next days!

    Great, that sounds like a good plan - I look forward to hearing your findings!

    Best regards,
    Karl

  • Hi Karl,

    here I am again with new findings.

    _______________________________________________________

    However, could you first try to see what the required delay is, by using nrf_delay?
    It might be that your TWI slave requires some delay between transfer.

    It seems so. I measured a few write/read procedures with different timing parameters. The result:

    I have to implement at least the following:

     nrf_delay_us(500);
     
        /* Read */
       err_code = nrfx_twim_xfer(&m_twim, &lm75b_reading, NULL);
       APP_ERROR_CHECK(err_code);
    
     nrf_delay_us(500);

    BEFORE and AFTER my read process a delay of 500us. If I reduce the number of us more, the read process didn´t work correctly (I checked this with printing the values by uart and I could see that the transmission didn´t work with lower timing). Could you maybe give me a syntax for replacing this with app_timer ?

    ___________________________________________________________

    Could you detail for me what transfers you will make - how frequent are they, and how many bytes are in each transfer?

    - I would like to read 14 bytes each transfer (https://invensense.tdk.com/wp-content/uploads/2016/06/DS-000189-ICM-20948-v1.3.pdf chapteer 7.1, register "2D" to "3A"). Accelerometer-Value X, Y, Z (each 2 bytes), Gyroscope-Value X, Y, Z (each 2 bytes) and Temperatur-Value (2 bytes). So in sum 14 bytes.

    - I would like to read the 14 bytes every 10ms. This frequency should be changeable.

    ____________________________________________________________

    Yes, please check your sdk_config file, to see if the NRF_LOG_DEFERRED is defined as 1 or 0, and if it is 1, what is then the size of NRF_LOG_BUFSIZE? 

    NRF_LOG_DEFERRED is "1" and NRF_LOG_BUFSIZE is "1024".

    Do I have the option to deactivate this log-deferring? I am not really sure if I need it.

    _______________________________________________________________

    Where does the application stop after three minutes, is it a particular place in the code?

    In debug terminal I just can see the message "Logs dropped ()" as described above. There is no line number printed out to see where the error happened. Here a screenshot from the error:

    Thank you for helping us with our product development :-)

    Kind regards

    Simon

  • Hello Simon,

    simon1516 said:
    BEFORE and AFTER my read process a delay of 500us. If I reduce the number of us more, the read process didn´t work correctly (I checked this with printing the values by uart and I could see that the transmission didn´t work with lower timing). Could you maybe give me a syntax for replacing this with app_timer ?

    500 us does not sound too bad in this case ( depending on your if you are reading 14 bytes every transfer, or only two, see my question below ).
    You can read about the app timer's usage and syntax in the library documentation, or in the Timer example or see its usage demonstrated in the Timer example from the SDK. Please let me know if anything should be unclear here, so I can provide more detail.
    What will you have your application doing in this time?
    I guess the simplest case for power consumption would be to start the timer, then immediately go to sleep ( for example using sd_app_evt_wait() or similar ).

    simon1516 said:

    - I would like to read 14 bytes each transfer (https://invensense.tdk.com/wp-content/uploads/2016/06/DS-000189-ICM-20948-v1.3.pdf chapteer 7.1, register "2D" to "3A"). Accelerometer-Value X, Y, Z (each 2 bytes), Gyroscope-Value X, Y, Z (each 2 bytes) and Temperatur-Value (2 bytes). So in sum 14 bytes.

    - I would like to read the 14 bytes every 10ms. This frequency should be changeable.

    Thank you for clarifying on this.
    Are you doing the 14 byte read as a single read, or 7 x 2-byte reads?

    simon1516 said:

    NRF_LOG_DEFERRED is "1" and NRF_LOG_BUFSIZE is "1024".

    Do I have the option to deactivate this log-deferring? I am not really sure if I need it.

    Deferred logging means that the logs are put into a buffer when you call NRF_LOG_INFO(), but not actually processed ( since processing it at that particular time in the code might be unwanted ). The logs therefore needs to be processed from the buffer, which you can do using NRF_LOG_PROCESS(). This is ideally done when the processor is free from other tasks. A good implementation of this is shown in many of our examples, for instance the BLE Proximity Peripheral example, in which the NRF_LOG_PROCESS is called when the CPU is idling. If there are no more logs to process, the application goes to sleep.
    You could set NRF_LOG_DEFERRED to 0 to surpress this. It might make some of your functions take longer to complete, since logs are processed as they are called, but I would think it should make no difference for your application here.

    simon1516 said:
    In debug terminal I just can see the message "Logs dropped ()" as described above. There is no line number printed out to see where the error happened. Here a screenshot from the error:

     Yes, attempt to disabled deferred logging as I recommend above, and let me know if this resolves the issue.

    simon1516 said:
    Thank you for helping us with our product development :-)

    Absolutely, it is no problem at all Simon - I am happy to help! :) 

    Best regards,
    Karl

  • Hi Karl,

    _________________________________________________________

    Please let me know if anything should be unclear here, so I can provide more detail.
    What will you have your application doing in this time?

    The Chip should go to sleep, when no transmission is required. So the Syntax should be:

    if Timer is expired

    {

    one TWIM procedure

    restart Timer

    }

    I´ve tried to implement this but unfortunaly I get an error if I try to create a new timer. I do the following:

        APP_TIMER_DEF(my_timer_id); // define new timer
        err_code=app_timer_create(&my_timer_id,APP_TIMER_MODE_REPEATED, NULL); //Create this timer, Time mode repeated because timer should restart every time it is expired. I´m not sure what to insert for "NULL"
        APP_ERROR_CHECK(err_code); // Check if Timer was created successfully

    I debugged this and debug terminal shows me, that the error is here: app_timer2.c:559 --> (ASSERT(timeout_handler);)

    I´m not really sure, what to insert in the "app_timer_create" for timeout_handler. I read that there is a function coming in, which is executed when the timer is expired. Could you please give me an example for this?

    ________________________________________________________________

    Are you doing the 14 byte read as a single read, or 7 x 2-byte reads?

    I´m doing this actually with one read with 14 bytes. This works fine :-)

    _______________________________________________________________

    Yes, attempt to disabled deferred logging as I recommend above, and let me know if this resolves the issue.

    I disabled deferred logging. Now there are no longer errors with this, so this works too :-)

    _______________________________________________________________

    In debug terminal I just can see the message "Logs dropped ()" as described above. There is no line number printed out to see where the error happened. Here a screenshot from the error:

    To this error again: Disabling the deffered logging solves that there are no longer the messages "Logs dropped ()". But the main problem was not solved. I debugged again. And the code stops every time after exactly three minutes, because it is calling "static void sleep_mode_enter(void)"  and "err_code = sd_power_system_off();"

    Exactly three minutes, this is the time, the system is advertising for BLE devices! If I connect with nRF connect Mobile App to the nRF Chip, the TWIM doesn´t stop. The transmission is working until BLE connection is closed. So after advertising, the chip is calling the sleep mode was the explanation here.

    Like it works is okay, because TWIM just has to send data if a BLE connection is established. I just want to give you feedback for this.

    ______________________________________________________________________

    Have a nice weekend, I hope we can solve my Timer issue together.

    Kind regards

    Simon

  • Hello Simon,

    simon1516 said:

    I debugged this and debug terminal shows me, that the error is here: app_timer2.c:559 --> (ASSERT(timeout_handler);)

    I´m not really sure, what to insert in the "app_timer_create" for timeout_handler. I read that there is a function coming in, which is executed when the timer is expired. Could you please give me an example for this?

    You may not provide NULL as the event_handler argument here, this is the reason why it ASSERTS. Are you familiar with using ASSERT?
    If you are unsure what you should provide as arguments to a function, or how to use a function, please see the functions API Refernce.
    In this case, from the app_timer_create API Reference you can see that the third argument is the event_handler, which is the function to be called when the timer expires.
    In your case, you may therefore do a TWIM transfer for each expiration, for example.

    An example for an event_handler function is for instance the saadc_event_handler from the SAADC example.
    This is the function that is called every time the SAADC generates an event - which then is used to handle those events.
    So, when a DONE event is generated, the saadc_event_handler is the function that process the samples that are collected.
    Or, in your case, the timers event handler is the function you would like to call every time the timer expires.

    simon1516 said:
    I´m doing this actually with one read with 14 bytes. This works fine :-)

    Great, I am glad to hear that!
    In that case, adding a 500 us delay before the transfer should not increase your power consumption too much.

    simon1516 said:
    I disabled deferred logging. Now there are no longer errors with this, so this works too :-)

    Great! Just keep in mind that this adds some processing time to each NRF_LOG_* line in your function. So, if you have a function with a lot of debugging write-outs you it will take much longer to complete with DEFERRED LOGGING set to 0.

    simon1516 said:

    To this error again: Disabling the deffered logging solves that there are no longer the messages "Logs dropped ()". But the main problem was not solved. I debugged again. And the code stops every time after exactly three minutes, because it is calling "static void sleep_mode_enter(void)"  and "err_code = sd_power_system_off();"

    Exactly three minutes, this is the time, the system is advertising for BLE devices! If I connect with nRF connect Mobile App to the nRF Chip, the TWIM doesn´t stop. The transmission is working until BLE connection is closed. So after advertising, the chip is calling the sleep mode was the explanation here.

    Like it works is okay, because TWIM just has to send data if a BLE connection is established. I just want to give you feedback for this.

    Good catch, I am happy to hear that you were able to identify the root of the behavior! This is exactly the time that your device is advertising.
    You may disable this feature, but it is a very good power-saving feature. What it does is make the device sleep if it has been without a connection for too long - conserving power by reducing RADIO ON time.
    In your situation, it sounds like you should keep this feature, if you only need to be awake when in a connection.
    Thank you for the feedback on this, I too am curious to hear about the problems resolve.

    simon1516 said:
    Have a nice weekend, I hope we can solve my Timer issue together.

    Thank you Simon, I did indeed have a nice weekend! I hope yours was as well.

    I think we are close to solving the Timer issue. I look forward to hearing if my comments above were helpful in resolving it!

    Best regards,
    Karl

Related