Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Timeslot api - timeslots triggered prematurely

Hi, 

Disclaimer - this is definitely a question where one picture worth a 1000 words... ;)

My app use timeslot api to get a free time period to do some hard real-time job (nRF52832, SDK15.2)

The needed timeslot  duration is ~1000us and the interval is ~29000us.

  1. First I open a timeslot session - sd_radio_session_open(TS_RadioCallback)

  2. I request a timeslot using  sd_radio_request(earliest possible) , duration  ~2500us (1000 + 1500us margin) interval ~29000us).
    If request fails, I pump up its priority (NRF_RADIO_PRIORITY_HIGH) and retry

  3. Upon event NRF_RADIO_CALLBACK_SIGNAL_TYPE_START
    1. Initialize T0CC0 to 2000 (500us margin before timeslot expires)
    2. Call app's callback that sets some vars and starts T4
    3. returns with NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE

  4. Some realtime work happens for ~1000us and after 2000us, T0CC0 expires and sets event NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0.
    Upon a global flag value (cleared after 9 timeslots) by the app I decide either to
    1. request another timeslot in ~29000us with NORMAL priority (regardless of the prioirty that was used in stage 2 ) & 
      return NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END

      or

    2. terminate the timeslots burst by returning NRF_RADIO_SIGNAL_CALLBACK_ACTION_END

  5. Occasionally, the next requested timeslot is blocked/cancelled NRF_EVT_RADIO_BLOCKED/NRF_EVT_RADIO_CANCELED.
    In such case I re-request a timeslot (sd_radio_request()) with increasing steps (29100us, 29200us etc)


  6. This is repeated periodically every few seconds

Now, I occasionally observe that the next timeslot, that is supposed to get triggered every 29000us (or longer in 100us steps) actually fires prematurely.

This is often accompanied by a hard-fault (not necessarily immediately)

This long post can be summarized in the attached scope capture (using long persistence time) that depicts several 10 pulses bursts (normal capture and one with the phenomenon described)

The 'nominal' pulses that happen every 29ms are marked with red arrow and are evenly spaced

It can be also seen that there are premature pulses, marked with green arrow, that are triggered prematurely (but seem to retain the 29ms spacing)

Now my question are:

  • What can be the cause for this observation ?
  • If initial timeslot was granted using high priority, do all other timeslots should be requested with high priory as well? Can this explain the hard-faults ?
  • Is it possible that after the  callback returned NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, another single timeslot shall be triggered (as also observed)

Many thanks for any advice.

Normal burst

  • Hi eyalasko,

     

    Now, I occasionally observe that the next timeslot, that is supposed to get triggered every 29000us (or longer in 100us steps) actually fires prematurely.

    This is often accompanied by a hard-fault (not necessarily immediately)

     We have not seen such a behavior with timeslots before. Are you sure that the clock source LFCLK is selected correctly with the right accuracy? If there are differences in the underlying clock accuracies and to which you which configured the softdevice, this could happen as the softdevice measured expected jitter varies to the actual actual clock. This can be fixed by telling the softdevice the right accuracy of the lfclk being used when you enable the softdevice.

    If initial timeslot was granted using high priority, do all other timeslots should be requested with high priory as well?

    No, that should not be needed. You can take each timeslot request on the individual basis. 

     

    Is it possible that after the  callback returned NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, another single timeslot shall be triggered (as also observed)

     That should not happen if you have only opened one session. There seems to be something wrong in the request of the timeslot. Are you sure that your app is not trying to request another timeslot while there is one already in the queue?

  • To whom it may help - 

    It happened to be a flaw in my code.

    I called an RTOS api, xQueueSendFromISR(),  from within the callback.

    The callback runs in the highest priority (smallest number - 0) which is higher than configMAX_SYSCALL_INTERRUPT_PRIORITY (=2) as described here

Related