This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Merging two or more examples

Hello

I am getting started on nRF SDK and I went through all the examples (at least those I'm interested about) successfully. 

Now, I need to merge couple of examples together. For simplicity let's say I'm merging an uart example into the twi_scanner one.

What I did, was

  • to compare "Options" of two projects, and added missing include paths. For this example, I added /libraries/uart and /libraries/uart paths into the twi example
  • Added required #includes, in my case these were #include "app_uart.h" and #include "nrf_uart.h"
  • I've checked sdk_config.h and found that UART was enabled.

And it wasn't enough. For some reason linker fails, and complains it cant find references to any app_uart functions. Funny, since "Go to definitions" finds the file easily. 

So what am I missing? What else should be done?

P.S. I have already searched for help in the DevZone, and found useful threads like this one, but all the links in it are outdated and not working anymore. 

Parents
  • Hello,

    I've checked sdk_config.h and found that UART was enabled.

    I suspect that this is an artifact of the apply_old_config.h file. Are you using the NRFX drivers in your project?
    If so, you need to make sure that no legacy peripheral definitions are defined in your sdk_config.h, as this will cause the apply_old_config to overwrite your nrfx configuration.

    As an example, in the UART case you must make sure that UART_ENABLED is not defined (it is not enough to define it to 0, it must be undefined) so that your NRFX_UART_* configurations are not overwritten.

    Are you using the app uart library, or the nrfx driver directly?

    Best regards,
    Karl

  • Are you using the app uart library, or the nrfx driver directly?

    well uart example has the #include "app_uart.h" so I guess im using the app library.

    As an example, in the UART case you must make sure that UART_ENABLED is not defined (it is not enough to define it to 0, it must be undefined) so that your NRFX_UART_* configurations are not overwritten.

    Unfortunately, it doesn't work this way. Commenting out the statement  #define UART_ENABLED 1, makes even more errors to pop up.

    Additionally, in the perihperal/uart example, the UART_ENABLED is defined, and I want to use it that way. Why is this more complicated than it needs to be?

    The errors I'm facing are with the linker: 

    Building ‘MERS_twi_scanner’ from solution ‘MERS_twi_scanner’ in configuration ‘Debug’
    Linking MERS_twi_scanner.elf
    Output/Debug/Obj/MERS_twi_scanner/main.o: in function `main':
    undefined reference to `app_uart_init'
    D:\Nordic\nRF5_SDK_17.1.0\examples\MERS\MERS_twi_scanner/main.c:185: undefined reference to `app_uart_get'
    D:\Nordic\nRF5_SDK_17.1.0\examples\MERS\MERS_twi_scanner/main.c:186: undefined reference to `app_uart_put'
    Build failed

    So I assume that it is the project settings that needs to be fixed so that linker sees those missing function symbols. How do I set those?

  • Could you share with me your sdk_config.h file?
    I still suspect that this is an sdk_config issue, since the editor is able to find the file - meaning the paths are correct - but not the linker.
    Do you have APP_UART_ENABLED defined to 1 in your sdk_config?

    Best regards,
    Karl

  • Do you have APP_UART_ENABLED defined to 1 in your sdk_config?

    yes, sir!

    Could you share with me your sdk_config.h file?

    Of course, be my guest:

     24036.sdk_config.h

    I still suspect that this is an sdk_config issue, since the editor is able to find the file

    What do you mean by this? I made the last post to show specifically that editor did not, in fact, find the files.

  • Pero Krivic said:
    I still dont see uart lib app_uart.c/.h files in the project explorer:

    Oh, my mistake, I missed this line - you will need to add the source file to your project explicitly. That might very well be the issue here.
    The include paths only points out the headerfiles, the source files must also be added to the project.
    Please right-click on the nRF_Libraries folder and select 'add existing file', and the navigate to SDK_ROOT/components/libraries/uart and select app_uart.c and app_uart_fifo.c (if you are using it with fifo).

    Pero Krivic said:
    yes, sir!

    Thank you for confirming this, and for sharing the sdk_config file as well. I notice that the UART_ENABLED is still defined, which means that any NRFX_UART_* configuration you do will be overwritten by its legacy equivalent - I mention it here yet again since this is known to cause confusion during debugging of UART issues.

    Please try to add the app_uart source files to your project and see if it resolves your issue.

    Best regards,
    Karl

  • you will need to add the source file to your project explicitly. That might very well be the issue here.

    Hello Karl, I am happy to confirm that this advice worked! So I added the .c file and build went on successfully. Thanks!

    I'll try and flash the firmware and close the ticket if everything is all right. 

    I notice that the UART_ENABLED is still defined, which means that any NRFX_UART_* configuration you do will be overwritten by its legacy equivalent - I mention it here yet again since this is known to cause confusion during debugging of UART issues.

    Well I tried it before already, and it comes up with new errors like:

    'NRFX_UARTE0_INST_IDX' undeclared here (not in a function); did you mean 'NRFX_UARTE_INSTANCE'?

    and 

    'NRFX_UART0_INST_IDX' undeclared here (not in a function); did you mean 'NRFX_UARTE_INSTANCE'?

    So, what is the deal here? Should I keep #define UART_ENABLED 1 or not?  Is the NRFX_UART_* recommended supported configuration?

  • I'll try and flash the firmware and close the ticket if everything is all right. 

    Ok, so the flashing didn't go right. The program ends up in the error handler soon after the main routine starts. Here's my main routine, as said, it's a simple merge of two examples, uart and twi_scanner.:

    int main(void)
    {
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    const app_uart_comm_params_t comm_params = {
    RX_PIN_NUMBER,
    TX_PIN_NUMBER,
    0,
    0,
    0,
    false,
    NRF_UART_BAUDRATE_115200
    };

    APP_UART_FIFO_INIT(&comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_error_handle,
    APP_IRQ_PRIORITY_LOWEST,
    err_code);

    APP_ERROR_CHECK(err_code);

    printf("\r\nUART example started.\r\n");

    NRF_LOG_INFO("TWI scanner started.");
    printf("TWI scanner started.");
    NRF_LOG_FLUSH();
    twi_init();

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
    err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
    if (err_code == NRF_SUCCESS)
    {
    detected_device = true;
    NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
    printf("TWI device detected at address 0x%x.", address);

    }
    NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
    NRF_LOG_INFO("No device was found.");
    NRF_LOG_FLUSH();
    }

    while (true) {
    uint8_t cr;
    while (app_uart_get(&cr) != NRF_SUCCESS);
    while (app_uart_put(cr) != NRF_SUCCESS);

    if (cr == 'q' || cr == 'Q')
    {
    printf(" \r\nExit!\r\n");

    while (true)
    {
    // Do nothing.
    }
    }
    }
    }


    The program fails just after the APP_UART_FIFO_INIT() call, and ends up in app_error_fault_handler(). Why is this happening?

Reply
  • I'll try and flash the firmware and close the ticket if everything is all right. 

    Ok, so the flashing didn't go right. The program ends up in the error handler soon after the main routine starts. Here's my main routine, as said, it's a simple merge of two examples, uart and twi_scanner.:

    int main(void)
    {
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    const app_uart_comm_params_t comm_params = {
    RX_PIN_NUMBER,
    TX_PIN_NUMBER,
    0,
    0,
    0,
    false,
    NRF_UART_BAUDRATE_115200
    };

    APP_UART_FIFO_INIT(&comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_error_handle,
    APP_IRQ_PRIORITY_LOWEST,
    err_code);

    APP_ERROR_CHECK(err_code);

    printf("\r\nUART example started.\r\n");

    NRF_LOG_INFO("TWI scanner started.");
    printf("TWI scanner started.");
    NRF_LOG_FLUSH();
    twi_init();

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
    err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
    if (err_code == NRF_SUCCESS)
    {
    detected_device = true;
    NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
    printf("TWI device detected at address 0x%x.", address);

    }
    NRF_LOG_FLUSH();
    }

    if (!detected_device)
    {
    NRF_LOG_INFO("No device was found.");
    NRF_LOG_FLUSH();
    }

    while (true) {
    uint8_t cr;
    while (app_uart_get(&cr) != NRF_SUCCESS);
    while (app_uart_put(cr) != NRF_SUCCESS);

    if (cr == 'q' || cr == 'Q')
    {
    printf(" \r\nExit!\r\n");

    while (true)
    {
    // Do nothing.
    }
    }
    }
    }


    The program fails just after the APP_UART_FIFO_INIT() call, and ends up in app_error_fault_handler(). Why is this happening?

Children
  • Pero Krivic said:
    I am happy to confirm that this advice worked! So I added the .c file and build went on successfully. Thanks!

    Great, I am happy to hear that it resolved the initial issue!

    Pero Krivic said:
    So, what is the deal here? Should I keep #define UART_ENABLED 1 or not?  Is the NRFX_UART_* recommended supported configuration?

    You should remove the legacy UART_ENABLED, and make sure that the NRFX_UART instance you are trying to use is enabled. It looks to me like it is UART0 that you are using in this case, so you need to make sure that it is enabled in the sdk_config.
    This is where having the legacy UART_ENABLED becomes an issue, because if the legacy UART0 define is 0, and the NRFX UART0 is enabled, the legacy configuration will overwrite the NRFX configuration if the UART_ENABLED is defined in the sdk_config.h.

    Pero Krivic said:
    Ok, so the flashing didn't go right. The program ends up in the error handler soon after the main routine starts. Here's my main routine, as said, it's a simple merge of two examples, uart and twi_scanner.:

    Please make sure to have DEBUG defined in your preprocessor defines like shown in the included image:

    This will make your logger output a detailed error message whenever a non-NRF_SUCCESS error code is passed to an APP_ERROR_CHECK.

    Best regards,
    Karl

  • Please make sure to have DEBUG defined in your preprocessor defines like shown in the included image

    This is the output:

    <error> app: ERROR 8 [NRF_ERROR_INVALID_STATE] at D:\Nordic\nRF5_SDK_17.1.0\examples\MERS\MERS_twi_scanner\main.c:160
    PC at: 0x00006281
    <error> app: End of error report

    I think there seems be a conflict with NRF_LOG and uart. The error is gone if  I  set

    #define NRF_LOG_BACKEND_UART_ENABLED 0

    But gets funny now, since the printf() prints into the JLINK console in Segger IDE instead to my UART console (what is a completely different USB port). Is this a topic for another ticket, or you think it can be resolved quickly?

  • Pero Krivic said:
    <error> app: ERROR 8 [NRF_ERROR_INVALID_STATE] at D:\Nordic\nRF5_SDK_17.1.0\examples\MERS\MERS_twi_scanner\main.c:160
    PC at: 0x00006281
    <error> app: End of error report

    Which function is being called on line 160 of main.c?

    Pero Krivic said:

    I think there seems be a conflict with NRF_LOG and uart. The error is gone if  I  set

    #define NRF_LOG_BACKEND_UART_ENABLED 0

    But gets funny now, since the printf() prints into the JLINK console in Segger IDE instead to my UART console (what is a completely different USB port). Is this a topic for another ticket, or you think it can be resolved quickly?

    Do you have NRF_LOG_BACKEND_RTT_ENABLED defined to 1?
    If so, the logger will route its loggings to the RTT backend, outputting it on either the SES Debug Terminal or a standalone RTT terminal like Segger RTT viewer.
    You are correct that there may only exist a single UART instance in your application, since the nRF52832 only has 1 UART instance - so if it is used by the logger, you can not use it in your application and visa versa.
    In that case, you can switch the logger to use RTT instead.

    Best regards,
    Karl

Related