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

What is an Application Event?

I am searching for a straight answer to this question. 'Application event' is used frequently in the documentation but never defined. I write the application but I clearly do not define these events. Initially I assumed they were events I defined and I could use them with sd_app_evt_wait(). Alas that is not the case.

So what is an application event?

All events received by my application?

If I know what an application event actually is, then I might be able to use sd_app_evt_wait(). If SoftDevice events (such as all the Bluetooth GAP and GATT events) are 'application events', I might be able to use sd_app_evt_wait() to support semaphore-like behavior that I really need.

Someone please tell me what 'application events' are and give some examples! It would also be helpful to tell me what events received by my application from SoftDevice are NOT 'application events'.

I guess while your at it, can you tell me what application interrupts are? These sound more like interrupts I define unlike application events.

  • I am calling from the main context (as suggested).

    THe contradiction I am talking about is that the message sequence does NOT do any retries. It simply calls the ble get event and then the wait. That's not what the docs say. They say I need to re-call the ble get event method if I get an event. That is not present in the message sequence - it is not mentioned.

    So what you are saying is that I must do the loop on the get event until I get no more events before calling the wait (regardless of what the message sequence diagrams).

    So lets take a look at what you are suggesting:

    First I have an array of 200 bytes to indicate using an MTU of 23 so I get 20 bytes per indication.

    I call the sd method to send the indication

    now what I would like to is wait for the event indicating it was acked.

    If I get a busy, call again with no wait.

    If I get a success, wait for the ack event using the sd_wait and sd_ble get event methods in a loop unitl I get what I want, jump back to the outer loop where I send the next 20 bytes.

    Is this correct?

  • Second reply.

    This is getting very frustrating as none of these approaches are working. They all hang, and due to the NRF LOG restrictions I cannot find what is hanging. The furthest I have been able to get was before I did all this 'main thread' things and was just using the classic ble dispatch handler as used in the health device examples. I did a while loop on the sd_indicate method until not busy. I got as far as three indication sequences before hanging.

    So I am clearly missing a critical piece of information - I just don't know what. I went and looked at the void intern_softdevice_events_execute(void) handler in the softdevice_handler.c file to see if I could find some hints. This method dispatches events to my app if I register in the normal way. I see the void intern_softdevice_events_execute(void) method is called by void SOFTDEVICE_EVT_IRQHandler(void). However, the intern_softdevice_events_execute(void) enters an infinite loop and only exits if the user suspends the handler.

    I find this confusing as it seems like SOFTDEVICE_EVT_IRQHandler(void) would be called several times and invoke the intern_softdevice_events_execute(void) which is already in an infinite loop. I do not see any use of the sd_app_evt_wait() method.

    There must be an easier way to do this; it's such a basic need! Clearly one must face this need all the time; indicate a sequence of data! Is it best to go back to the standard approach used in the health device examples and figure out why the wait on busy loop freezes? I got further using that approach than doing anything else, and all just using sd_ calls.

    What happens if I invoke sd_app_evt_wait() in more than one place? For example in the standard for(;;) loop all the examples use and after doing something like 

        error_code = sd_ble_gatts_hvx(m_connection_handle, &hvx_params);
        sd_app_evt_wait();
    
    

  • I have to reply here as this site is once again messing up and there is no reply button to the reply I need to reply to. One of these days this site will get fixed!

    Just wanted to say all my problems were due to NRF_LOG_DEBUG. Printing a string that was too long I guess. Don't know. But removing it solved all my issues. That aside, at least I know what an application event is.

  • Hello again brianreinhold,

    brianreinhold said:
    I have to reply here as this site is once again messing up and there is no reply button to the reply I need to reply to. One of these days this site will get fixed!

    I am sorry to hear that your experience with the site is not up to par - we're continuously working on making the forum better, and I will submit this as an issue internally to be looked into.

    brianreinhold said:
    Just wanted to say all my problems were due to NRF_LOG_DEBUG. Printing a string that was too long I guess. Don't know. But removing it solved all my issues. That aside, at least I know what an application event is.

    Thank you for the update - I am happy to hear that you were able to identify and resolve all your issues!
    To limit the effects that the logger module has on your program you may want to use the deferred_logging option of the logger. This will allow you to process loggings only when you have the time, and not where the call to NRF_LOG_DEBUG is actually made. You can see how this is implemented as part of most example's idle_state_handler. 

    Regarding your previous comment on the contradiction I am unfortunately still not seeing where my answer contradicts the documentation - you're interpretation of my suggestion regarding the sending loop - retry if != NRF_SUCCESS is returned, wait for application layer ack before sending next - is correct.

    Please do not hesitate to open a new ticket if you should encounter any issues or questions in the future.

    Good luck with your development!

    Best regards,
    Karl

  • The main problem I have with the site is the 'reply' button not being displayed. It is shown after some posts but not all them. Someone figured out a clever way to make it display, but it does not always get all of the missing ones.

    In any case the contradiction I was mentioning is the between the message diagram and the text description for the sd_ble_evt_get(). The message diagram shows no repeat of the sd_ble_evt_get(), the sd_ble_evt_get() is done once and then one is back to the sd_app_evt_wait().

    If I had ONLY looked at the diagram, I would not have looped over the sd_ble_evt_get() until I got no more events. Given the issues I was having I tried all kinds of combinations (many made no sense but one got desperate)!

    As far as the logging goes I do use the deferred approach and process the log in that final for(;;) loop used in all the examples. So It has something to do with the size of the string. If the string is short, no problem. But when it is not, it freezes. I do use the nrf_log_push() to contain the string.

    In any case, I cannot use the log when I deploy it on the actual device (I assume). All I have connecting the actual device to Keil is the SWD interface on the DK.

    Here is my final loop

    static void main_loop(void)
    {
        uint8_t enabled;
        uint16_t len;
        uint32_t result;
        for (;;)
        {
            indicate_data();        // when flag is set, a set of data is indicated. Flag reset in method
            main_wait();            // Contains the sd_app_evt_wait()
            while(true)
            {
                sd_softdevice_is_enabled(&enabled); // Don't do this if disabled, for example when writing flash at the end
                if (enabled != 1)
                {
                    break;
                }
                result = sd_ble_evt_get(NULL, &len);    // Get sixe of event
                if (result == NRF_ERROR_NOT_FOUND)      // If there aren't any, go back to wait
                {
                    break;
                }
                evt_buf = (uint8_t *)calloc(1, len);                // Make space for event
                result = sd_ble_evt_get((uint8_t *)evt_buf, &len);  // get the event
                if (result == NRF_SUCCESS)
                {
                    ble_evt_t *evt = (ble_evt_t *)evt_buf;
                    ble_evt_dispatch(evt);                          // dispatch event to handler
                    NRF_LOG_PROCESS();                              // SHould I do this here to get a tighter display of log?
                }
                else                                                // Hopefully no error but just in case log it.
                {        
                    #if (USE_DK == 1)
                    NRF_LOG_DEBUG("PENDING BLE Event return error: %u\r\n", result);
                    #endif
                    free(evt_buf);  // Clean up
                    break;          // back to wait
                }
                free(evt_buf);      // clean up and get the next event
            }
        }
    }

    I get an APP:ERROR:FATAL when I write to flash (pairing and bonding data) but the write succeeds. On a reconnect all the data is present and valid. This is the only scar remaining though it odes not affect performance. After the data is sent, the nrf51822 disconnects, disables SofDevice, writes to flash (only on a first time connect) and then has no more do. 

    What is the proper way to shut down? Exit from the above loop?

Related