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

What is the reason of making nRF APIs that complicated?

As an example, let's see this function from app_hrm (heart rate monitor):

static void conn_params_init(void)
{
    uint32_t               err_code;
    ble_conn_params_init_t cp_init;

    memset(&cp_init, 0, sizeof(cp_init));

    cp_init.p_conn_params                  = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle    = m_hrs.hrm_handles.cccd_handle;
    cp_init.disconnect_on_fail             = true;
    cp_init.evt_handler                    = NULL;
    cp_init.error_handler                  = conn_params_error_handler;

    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}

Quickly looking, it seems that there's a lot of code doing lots of things. However, after reading out the lines it turns out that the information is mostly redundant (like "cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY"), and the function just bypasses parameters forward to another function. I used to see this type of coding at the beginning of 1990's, but it was quite soon replaced with much more comfortable way, using function parameters. With that style, the above code would shrink as follows:

ble_conn_params_init(
    NULL, FIRST_CONN_PARAMS_UPDATE_DELAY, NEXT_CONN_PARAMS_UPDATE_DELAY,
    MAX_CONN_PARAMS_UPDATE_COUNT, m_hrs.hrm_handles.cccd_handle, true, NULL,
    conn_params_error_handler);

And actually, the extra function definition conn_params_init() would no more be needed at all. This type of coding would make application much much more readable, yet it would save code lines and probably even flash space.

I have to say that your code looks much more complicated that it would need to be. I know this is a kind of "school of thought" issue, and maybe related to "linux-style" -coding. But still, your coding style doesn't make the APIs too easy for customers. Sorry to say, but it has been a horrendous experience to get familiar with nRF51822 SDK (and the DFU OTA is still not working, but that's another story).

  • In my Nokia days, the Symbian OS and it's complicated coding patterns were also argued to be powerfull from the perspective of microprocessor. However, programming was just pain from the perspective of developer. And what finally happened?

  • Totally agree that no program or piece of code is worth endless flame war;) However you posted the question so you deserve full feedback:

    • I've worked with several big SDKs for ARM Cortex-M or 8051 processors and haven't seen anything which would be way simpler or better organized then nRF5x SDKs. Actually it was usually worse (and most importantly more buggy - e.g. STM32 CUBE SDK is pretty awful when it comes to their "drivers").
    • I have now ~10 different FWs running on nRF51x22 chip, all compiled with nRF51 SDK (different versions since 6.1.0 up to latest 10.0.0) and I was never victim of pasting hundreds of lines on and on.
  • (continue)

    • You very much nailed it in your last remark. BLE chipset is not meant (and won't be until more advanced architectures such as ARM Cortex-Ax will achieve similar power budget, which will take another 5+ years) to host OS comparable with anything you quote (Symbian/Android/other embedded Linux or Windows clones). You might get closer with "embedded" systems such as Brillo but look at their requirements for hosting platform and try to ask Google if it will ever run on ARM Cortex-M processors (expect "U nuts?!" answer;).

    Cheers Jan

  • Yes, I agree that the sdk is pretty consistent and probably not very buggy. What I meant with those "hundreads of code lines" is the main file of the examples, having roughly 900 lines or so: For me, it looks like 90% of the code lines are exactly the same, such as functions advertising_init(), device_manager_Init(), ble_stack_init() etc. I don't see the point of using this much copy-paste code instead of providing simple basic functions that just set the default values. Most of applications would do well with the defaults. This would not harm the developers who still need the more advanced settings.

  • My mention of Symbian was not meant to be taken that way. After starting my career with 6502 processor, I do know what is a resource limited system. And I also do know the absolutely most resource limited system is our own brain. That's too often forgotten, and strange arguments to save microprocessor power instead of our brain power start to fly. I would even bet there's more final binary code in that structure-filling system than with argument passing.

Related