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

Unexpected warning

I am receiving an unexpected warning from nrf_atfifo_item_get that reports "Get failed - no item in the FIFO." This occurs when I start advertising using

void advertising_start(bool erase_bonds)

This calls bsp_led_indication which calls app_timer_start which triggers drv_rtc_irq_trigger

I am assuming this is to catch short timer periods, but can this warning be avoided so that there is no call to the rtc trigger?

Parents
  • I cannot follow this code:

    app_timer_start places a request on the atfifo stack to start a timer. It then requests the timer to do an interrupt that then enacts the request that has been placed on the atfifo stack. So far so good, even if I do not follow the reasoning.

    However in the code for timer_req_process I see the line req = nrf_atfifo_item_check(m_req_fifo, &fifo_ctx);, which calls the routine with the address of a variable on the stack that is so far not initialised.

    /**
     * @brief Function for processing user requests.
     *
     * Function is called only in the context of RTC interrupt.
     */
    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req;
        bool                                    req = nrf_atfifo_item_check(m_req_fifo, &fifo_ctx);

    And then in nrf_atfifo_item_check the address of an element in fifo_ctx is passed to another routine. As fifo_ctx is uninitialised it will pass rubbish to the nrf_atfifo_rspace_req routine as the address of last_head.

    void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
    {
        if (nrf_atfifo_rspace_req(p_fifo, &(p_context->last_head)))
        {
     

  • Apologies It appears there is something else going on.

    nrf_atfifo_item_check calls nrf_atfifo_rspace_req the first time and reports there is something in the fifo, but in the second call it reports there is nothing in the fifo.

  • Got it. This version of app_timer2 uses nrf_atfifo_item_check to control the loop, but by using nrf_atfifo_rspace_req it removes the item so preventing getting an item from the fifo.

    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req;
            bool                                    req = nrf_atfifo_item_check(m_req_fifo, &fifo_ctx);

        while (req)
        {
                    p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
            switch (p_req->type)
            {

    Other versions of timer_req_process do not check and use the call to nrf_atfifo_item_get and its return to control the loop, but this generates a warning on any check.

    /**
     * @brief Function for processing user requests.
     *
     * Function is called only in the context of RTC interrupt.
     */
    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);

        while (p_req)
        {
            switch (p_req->type)

    It appears nrf_atfifo_item_check needs to be corrected so that it does not remove the item from the fifo

Reply
  • Got it. This version of app_timer2 uses nrf_atfifo_item_check to control the loop, but by using nrf_atfifo_rspace_req it removes the item so preventing getting an item from the fifo.

    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req;
            bool                                    req = nrf_atfifo_item_check(m_req_fifo, &fifo_ctx);

        while (req)
        {
                    p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
            switch (p_req->type)
            {

    Other versions of timer_req_process do not check and use the call to nrf_atfifo_item_get and its return to control the loop, but this generates a warning on any check.

    /**
     * @brief Function for processing user requests.
     *
     * Function is called only in the context of RTC interrupt.
     */
    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);

        while (p_req)
        {
            switch (p_req->type)

    It appears nrf_atfifo_item_check needs to be corrected so that it does not remove the item from the fifo

Children
  • I have not tested but this problem with nrf_atfifo_item_check could affect other routines such as in nrf_fstorage_sd.c in the following:

    /* Load a new operation from the queue. */
    static bool queue_load_next(void)
    {
        if (nrf_atfifo_item_check(m_fifo, &m_iget_ctx)) {
        m_p_cur_op = nrf_atfifo_item_get(m_fifo, &m_iget_ctx);

        return (true);
        } else {
            return (false);
        }
    }

  • The following is a workaround that resets the head of the FIFO queue to its original value after the check so that it correctly returns the next item and avoids the call that would return an empty queue message.

    /**
     * @brief Function for processing user requests.
     *
     * Function is called only in the context of RTC interrupt.
     */
    static void timer_req_process(drv_rtc_t const * const  p_instance)
    {
        nrf_atfifo_item_get_t fifo_ctx;
        timer_req_t *         p_req;
            bool                                    req = nrf_atfifo_item_check(m_req_fifo, &fifo_ctx);

        while (req)
        {
                    m_req_fifo->head.tag = fifo_ctx.last_head.tag;
                    m_req_fifo->head.pos.wr = fifo_ctx.last_head.pos.wr;
                    m_req_fifo->head.pos.rd = fifo_ctx.last_head.pos.rd;
                    p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
            switch (p_req->type)
            {

Related