More on peripheral_lbs sample program.

Greetings. 

This a follow-on to my prior question about the sample app "peripheral_lbs."

The program obtains a value for variable "led_state" in response to a user keystroke on the "nRF Blinky" mobile app:

static void app_led_cb(bool led_state)
{
    dk_set_led(USER_LED, led_state);
}
.
.
.
static struct bt_lbs_cb lbs_callbacs = {
    .led_cb    = app_led_cb,
    .button_cb = app_button_cb,
};
At the end of the program is an infinite loop which continually blinks another LED:
for (;;) {
        dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
        k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
    }
My questions are:  What causes execution to abort the infinite loop in response to a user keystroke on the mobile app?  Where specifically is the user keystroke detected which in turn switches the state of "led_state"?
My goal is to execute a while loop as follows:
while(led_state)
do calculation
printk...
do calculation
etc.
If phone keystroke detected, abort while loop, invert "led_state", continue program execution.
}
... however I do not know how to abort the while loop when a keystroke occurs.  Placing "static void app_led_cb(bool led_state)" inside the loop does not work.    
Help is appreciated.  Thank you.  
  • Hi,

    The nRF Connect SDK is based on Zephyr, which is an  RTOS. And the main function is a thread in itself, so which it is good to keep in mind.

    What causes execution to abort the infinite loop in response to a user keystroke on the mobile app?

    This is an eternal loop that is never aborted. It consists of two statements, one calling a dk_set_led() that sets the LED state, and a k_sleep() which is a kernel API call that causes the main thread (as that is where it is called from) to sleep for the specified amount of time. During that time, oter threads can run, and if no threads, are running the device is automatically put in system ON idle (sleep) until it is time to wake up.

    Where specifically is the user keystroke detected which in turn switches the state of "led_state"?

    That is handled by the DK buttons library - notice the call to dk_buttons_init(). In that call the sample provides a function pointer to button_changed(), so whenever there is a GPIO interrupt on the bin used by the button, the button_changed function is called. This all then happens in the interrupts (and not in thred context).

    Placing "static void app_led_cb(bool led_state)" inside the loop does not work.    

    Yes, that is expected. This function is used for teh Led button BLE Service so that the peer can control the LED. When writing to the LED characteristic, that calls this callback to contorll the LED.

    My goal is to execute a while loop as follows:
    while(led_state)
    do calculation
    printk...
    do calculation
    etc.
    If phone keystroke detected, abort while loop, invert "led_state", continue program execution.

    Then you can implement all the logic for that exactly as you want inside the main function. The only input you need here is the button state, and if you don't need that immediately, you could simply  make a global volatile variable tha thas the button state, and theck that in your loop to be able to act on button presses. For instance, make a global variable "volatile uint32_t button_state" and assign the value in button_changed(). And read it in your main function/thread.

    You can also do this in a more robust but complex way, using a semaphore or similar. You may be inetersted in the nRF Connect SDK fundamentals course as well as the intermediate course (particularily  Lesson 1 – Zephyr RTOS: Beyond the basics). You can find thos eon the Nordic Developer Academy.

Related