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.

Parents
  • Hello,

    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.

    Please see the answer by my colleague Susheel in this ticket.

    So what is an application event?

    All events received by my application?

    In essence, yes. Application events are the subset of all the possible events, that is passed to the application - for instance, many of the events are only used by the SoftDevice, and thus not forwarded to the Application layer.
    You may use the NRF_SDH_BLE_OBSERVER macro to forward BLE events to handlers in your application.

    I might be able to use sd_app_evt_wait() to support semaphore-like behavior that I really need.

    Could you elaborate on exactly what this behavior you are looking for is?
    Are you developing with the nRF5 SDK, or nRF Connect SDK? In the case of the latter you should know that Zephyr is an RTOS that already provide this for you.

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

    The explanation here is the same as for the application events - the application interrupts are the subset of interrupts which are passed to and handled by the application.
    An example of this would be a TIMER instance that you setup to periodically trigger an interrupt in your application - this is an application interrupt.
    An example of a 'non-application interrupt' would be the SoftDevice's own timers interrupt, which are never seen by the application.

    Please let me know if anything should still be unclear, or if you encounter any other issues or questions.

    Best regards,
    Karl

  • First I am not using the SDK for any Bluetooth, but only SoftDevice, I have several good reasons for that, but mainly that I am working with the BT SIG Med group to define a single generic health device standard that can be used for all devices. Also I am using the pc-ble-driver for the same purpose. (Here I am writing for the nRF51822 to use on a real device.) Nice to have the two as similar as possible.

    The problem I am trying to solve is the simulation of a semaphore. I have a characteristic value that is several MTUs long, so I indicate, need to wait for the response event, and repeat. The start of the sequence is given when the peer writes a command to do so. I have another posted thread on this site about that. But in that thread and in the documentation there are endless references to 'application event' without ever defining what that was.

    Thus this post to get a straight concrete answer so I can move forward and have a better understand of what my options are. Being able to 'indicate' long characteristic values is central to this standard. Right now when I do a while loop on the sd_ble_gatts_hvx() call and the NRF_ERROR_BUSY it hangs after about three indications. I am calling the method from a timer started in the ble event handler.

Reply
  • First I am not using the SDK for any Bluetooth, but only SoftDevice, I have several good reasons for that, but mainly that I am working with the BT SIG Med group to define a single generic health device standard that can be used for all devices. Also I am using the pc-ble-driver for the same purpose. (Here I am writing for the nRF51822 to use on a real device.) Nice to have the two as similar as possible.

    The problem I am trying to solve is the simulation of a semaphore. I have a characteristic value that is several MTUs long, so I indicate, need to wait for the response event, and repeat. The start of the sequence is given when the peer writes a command to do so. I have another posted thread on this site about that. But in that thread and in the documentation there are endless references to 'application event' without ever defining what that was.

    Thus this post to get a straight concrete answer so I can move forward and have a better understand of what my options are. Being able to 'indicate' long characteristic values is central to this standard. Right now when I do a while loop on the sd_ble_gatts_hvx() call and the NRF_ERROR_BUSY it hangs after about three indications. I am calling the method from a timer started in the ble event handler.

Children
  • brianreinhold said:
    First I am not using the SDK for any Bluetooth, but only SoftDevice

    What do you mean by this exactly, do you mean that you are only using the SoftDevice API from the SDK?

    brianreinhold said:
    but mainly that I am working with the BT SIG Med group to define a single generic health device standard that can be used for all devices.

    Thank you for clarifying.

    brianreinhold said:
    Also I am using the pc-ble-driver for the same purpose.

    Please be advised that the pc-ble-driver only exposes a subset of the available SoftDevice API.

    brianreinhold said:
    I have another posted thread on this site about that. But in that thread and in the documentation there are endless references to 'application event' without ever defining what that was.

    I see. If any part of an answer you receive from us should be unclear, please do not hesitate to let us know and we will do our best to elaborate on it.

    brianreinhold said:
    Right now when I do a while loop on the sd_ble_gatts_hvx() call and the NRF_ERROR_BUSY it hangs after about three indications. I am calling the method from a timer started in the ble event handler.

    Could you elaborate on what you mean when you say that it hangs after three indications? Does it return a different error code after three indications - if so, which?
    Could you also confirm for me that the device is receiving a response to its indications? The device may not proceed from an indication before receiving an ACK.

    An exempt from the sd_ble_gatts_hvx doumentation reads:

    NRF_ERROR_BUSY For BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a BLE_GATTS_EVT_HVC event and retry.

    Please have a look at the excellent answer by my colleague HĂĄkon in this ticket, where he details the difference between notifications and indications.

    Best regards,
    Karl

  • Karl, I am doing the classic 'busy' loop when calling the sd_ble_gatts_hvx(). I am discussing that in another thread. But what you have said contradicts the information I am getting in another thread. If I get an NRF_ERROR_BUSY I need to try again. If I don't it is as if that call was never made.

    Now ideally what I wanted to do  ( and did do in the pc-ble-driver) is make the sd_ble_gatts_hvx()  call and wait on a semaphore. WHen I got the BLE_GATTS_EVT_HVC event, I released the semaphore. Worked great. No such tool here. So all the issues I am having are related to trying to simulate the functionality of a semaphore.

    OH, by the way, when I say I am not using the SDK, I mean I am using sd_* calls for all BLE functionality and anything else that I can do (flash writing for example).

    The other thread is

     https://devzone.nordicsemi.com/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications

    That's how application events came up and I could not get a clear answer on what they were. In the end it appears to be any event that is passed up to my application.

  • Hello,

    Thank you for your patience.

    brianreinhold said:
    But what you have said contradicts the information I am getting in another thread. If I get an NRF_ERROR_BUSY I need to try again. If I don't it is as if that call was never made.

    I am not exactly sure what contradicting information you are referring to, but it is correct that you will need to try again if you get an error - any returned error code != NRF_SUCCESS indicates that the returning function did not succeed for whatever reason, so if you intend to have that packet transferred it will need to be tried again - this is also written in the documentation I referenced. So, your assessment here is correct.
    If this is not the contradicting part, please elaborate on what I have said that contradicts prior information, so we could clear up any possible misunderstandings.

    brianreinhold said:
    Now ideally what I wanted to do  ( and did do in the pc-ble-driver) is make the sd_ble_gatts_hvx()  call and wait on a semaphore. WHen I got the BLE_GATTS_EVT_HVC event, I released the semaphore. Worked great. No such tool here. So all the issues I am having are related to trying to simulate the functionality of a semaphore.

    I see. Are you doing the sd_ble_gatts_hvx call as part of a interrupt handler or from the main context like suggested by my colleague Vidar in your other ticket? - if you are calling it from an interrupt handler, what is the priority of this interrupt configured to?
    My suggestion here would be close to what Vidar already has suggested for you - if you receive a BUSY error, place the indication in a queue and wait for the BLE_GATTS_EVT_HVC after which you try it again. This should work, but you will also have to ensure that there is no pile-up of unsent indications by checking the the rate of new indications vs. the rate of indications going through. Since the indication requires an application level ACK it will at least be 1 full connection interval until this is received.

    brianreinhold said:
    OH, by the way, when I say I am not using the SDK, I mean I am using sd_* calls for all BLE functionality and anything else that I can do (flash writing for example).

     Thank you for clarifying.

    Best regards,
    Karl

  • 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();
    
    

Related