configASSERT xTaskNotifyFromISR

Hi, Using NRF52832 with FreeRTOS v10.0.1 The configASSERT in the callback funtion is asserted and program stops but task has been created successfuly. I don’t know what is the root cause for this problem as I have another similar callback, task and interrupt priority implemented to TWI that runs fine always. Can you please give some advice on how to solve this problem ? Any help is very appreciated. Thanks. ISR callback function: ~~~ /* The callback interrupt service routine for the UARTE interrupt / void uarte_interrupt_handler(nrf_drv_uart_event_t * p_event, void pcontext) { /* Tracealyzer defitions for tracing ISRs */ traceHandle ISRUARTEHandle = xTraceSetISRProperties(“ISRUARTE”, 7);
vTraceStoreISRBegin(ISR_UARTE_Handle); /* Tracelyzer ISR tracing */

BaseType_t xHigherPriorityTaskWoken =  pdFALSE;    

configASSERT(m_uart_task);
/* Notify the task that the p_event occurred in the task's notification value. */
xTaskNotifyFromISR ( m_uart_task, (uint32_t) p_event->type, eSetBits, &xHigherPriorityTaskWoken );   
/* switch context is required */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
vTraceStoreISREnd(xHigherPriorityTaskWoken); /* Stops ISR tracing */
} ~~~ Task function: ~~~ /* This function gets events from the UART and processes them. */ static void uart_task(void * pvParameter) { NRF_LOG_INFO(“Enter uart_task.”); uint8_t rxbuffer; uint32_t err_code; const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 500 ); BaseType_t xResult; uint32_t ulNotifiedValue;
if (m_uart_hook != NULL)
{
    m_uart_hook(pvParameter);
    /* enable receiver */
    err_code = nrf_drv_uart_rx(pvParameter, &rxbuffer, 1);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("UARTE receiver enabled.");
}

while (true)
{
    /* Wait to be notified of an interrupt. */
    xResult = xTaskNotifyWait(pdFALSE,              /* Don't clear bits on entry. */
                              0xFFFFFFFF,           /* Clear all bits on exit. */
                              &ulNotifiedValue,     /* Stores the notified value. */
                              xMaxBlockTime);
    if( xResult == pdPASS )
    {
        /* A notification was received. See which bits were set. */
        if( ( ulNotifiedValue & NRF_DRV_UART_EVT_TX_DONE ) != 0 )
        {
            /* The TX ISR has set a bit. */
            err_code = nrf_drv_uart_tx(pvParameter, &rxbuffer, 1);
            APP_ERROR_CHECK(err_code);
        }
        if( ( ulNotifiedValue & NRF_DRV_UART_EVT_RX_DONE ) != 0 )
        {
            /* The RX ISR has set a bit. */
            if ( nrf_drv_uart_rx_ready(pvParameter) )
            {
                err_code = nrf_drv_uart_rx(pvParameter, &rxbuffer, 1);
                APP_ERROR_CHECK(err_code);
                /* echo data to terminal */
                err_code = nrf_drv_uart_tx(pvParameter, &rxbuffer, 1);
                APP_ERROR_CHECK(err_code);
            }
        }
        if( ( ulNotifiedValue & NRF_DRV_UART_EVT_ERROR ) != 0 )
        {
          NRF_LOG_INFO("Error in uart comm");
        }
    }

    /* ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) allows uart_task to wait in 
       the Blocked state for its notification value to be greater than zero, and either decrements (subtracts one from) 
       or clears the task’s notification value before it returns. */
    (void) ulTaskNotifyTake(pdTRUE,          /* Clear the notification value before exiting (equivalent to the binary semaphore). */
                            xMaxBlockTime ); /* Block */
}
} ~~~ FreeRTOS config: ~~~ configLIBRARYLOWESTINTERRUPTPRIORITY 7 // (ARM highest) 0, 1, 2, 3, 4, 5, 6, 7 (ARM lowest) configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 2
configKERNEL
INTERRUPTPRIORITY configLIBRARYLOWESTINTERRUPTPRIORITY configMAXSYSCALLINTERRUPTPRIORITY configLIBRARYMAXSYSCALLINTERRUPT_PRIORITY ~~~

configASSERT xTaskNotifyFromISR

I don’t know which configASSERT() is failing as you didn’t say – but check your definitions in FreeRTOSConfig.h. configKERNELINTERRUPTPRIORITY and configMAXSYSCALLINTERRUPT_PRIORITY should use ARM style priorities, not the ‘library’ versions, which are reversed. grep for similar definitions in the FreeRTOS kernel distribution for examples. Also https://www.freertos.org/RTOS-Cortex-M3-M4.html

configASSERT xTaskNotifyFromISR

Hi Richard, Thanks for your reply. I already read that document in the link and as NRF52 has configPRIOBITS = 3, I used to configure “#define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 2 and also ”#define configLIBRARYLOWESTINTERRUPTPRIORITY 7 the assertion failed is the one in the ISR callback function above ( configASSERT(muarttask); ), as I said before I have implemented similar solution to TWI and works fine and I commented it out and testing with UART but it failing at that point of callback. The task has been successfuly created and muarttask is not NULL or zero whenever asserted in the callback. Any help is greatly appreciated. Thanks, Carlos

configASSERT xTaskNotifyFromISR

Can you place a break point when the assert fails to look at the value of the muarttask? It would be odd that it would assert without it being NULL – assuming configASSERT() is defined in the normal way. Does the interrupt execute a few times before the assert fails? Or does it fail on the first execution. If the first, are you sure the interrupt is not firing earlier than you anticipate – and therefore before the task has been created? Perhaps also post the code where muarttask is set (where the task is created)?

configASSERT xTaskNotifyFromISR

Hi Richard, sure I did what you suggested. In fact, I see muarttask is not NULL breaking at configASSERT in the callback function and no interrupt execution prior to send any char to uart. Please see detailed information below. The code behaves as following steps: 0- clock and gpio initialization; 1- UART Task is created successfuly; 2- Scheduler is started successfuly; 3- UART task is executed, calling hook function and Rx UARTE initialized successfuly; 4- While not sending any char thru terminal to PC comm port, there is no trigger at IRQ handler in the debugger and callback function is not called/triggered. That is all right. 5- Now, I remove the breakpoint at IRQ Handler to avoid stop here when I send the first char in the terminal. 6- Now, I have only a break at configASSERT in ISR callback function and send only one char; 7- Break it, where muarttask contains the value (0x20007900), looking the memory dump in details: muarttask is stored statically at address 0x2000A070 and contains 0x20007900 that points to address 0x20007874 that points to address 0x200078E4 that contains 0x00000000. Is it clear ? Hope this can help to understand what is the fault. As per your request, here goes code to: UARTE initialization: static void uarte0init(void * pcontext) { uint32t errcode; const nrfdrvuartconfigt uartconfig = { .pseltxd = TXPINNUMBER, ///< TXD pin number. .pselrxd = RXPINNUMBER, ///< RXD pin number. .pselcts = CTSPINNUMBER, ///< CTS pin number. .pselrts = RTSPINNUMBER, ///< RTS pin number. .pcontext = pcontext, ///< Context of UARTE instance passed to interrupt handler. .hwfc = (nrfuarthwfct) NRFUARTEHWFCDISABLED, ///< Flow control configuration. .parity = (nrfuartparityt) NRFUARTEPARITYEXCLUDED, ///< Parity configuration. .baudrate = (nrfuartbaudratet) NRFUARTEBAUDRATE115200, ///< Baudrate. .interruptpriority = UARTDEFAULTCONFIGIRQPRIORITY, ///< Interrupt priority. ” #ifdef UARTEPRESENT .useeasy_dma = true, ” #endif };
err_code = nrf_drv_uart_init(p_context,
                             &uart_config,
                             uarte_interrupt_handler);                                          /* using callback for UARTE IRQ */
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("UARTE initialized");
} Task creation: /**@brief Function for creating a task to retrieve UART events. * @param[in] hookfn Function to run in the UART FreeRTOS task, * before entering the task loop. * @param[in] pcontext Parameter for the function @p hook. */ void nrf_uart_freertos_init(nrf_uart_freertos_task_hook_t hook_fn, void * p_context) { NRF_LOG_INFO(“Creating a UART task.”);
m_uart_hook = hook_fn;

BaseType_t xReturned = xTaskCreate(uart_task,
                                   "UART",
                                   NRF_BLE_FREERTOS_UART_TASK_STACK,
                                   p_context,               
                                   NRF_BLE_FREERTOS_UART_TASK_PRIO,
                                   &m_uart_task);
if (xReturned != pdPASS)
{
    NRF_LOG_ERROR("UART task not created.");
    APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
} functions calling ISR callback: __STATICINLINE void rxdoneevent(uartcontrolblockt * puartcb, uint8t bytes, uint8t * pdata) { nrfdrvuartevent_t event;
event.type             = NRF_DRV_UART_EVT_RX_DONE;
event.data.rxtx.bytes  = bytes;
event.data.rxtx.p_data = p_data;
/* is non-blocking mode, callback function */
configASSERT(p_uart_cb->handler != NULL)
p_uart_cb->handler(&event, p_uart_cb->p_context); /* ISR callback function is called here */
} __STATICINLINE void txdoneevent(uartcontrolblockt * puartcb, uint8t bytes) { nrfdrvuartevent_t event;
event.type             = NRF_DRV_UART_EVT_TX_DONE;
event.data.rxtx.bytes  = bytes;
event.data.rxtx.p_data = (uint8_t *)p_uart_cb->p_tx_buffer;

p_uart_cb->tx_buffer_length = 0;

NRF_LOG_INFO("TX done len:%d", bytes);
/* non-blocking mode, callback function */
configASSERT(p_uart_cb->handler != NULL)
p_uart_cb->handler(&event, p_uart_cb->p_context); /* ISR callback function is called here */
} IRQ Handler: __STATICINLINE void uarteirqhandler(NRFUARTEType * puarte, uartcontrolblockt * puartcb) { /* Tracealyzer defitions for tracing ISRs */ traceHandle UARTEIRQHandle = xTraceSetISRProperties(“IRQUARTE”, UARTDEFAULTCONFIGIRQPRIORITY);
vTraceStoreISRBegin(UARTE_IRQ_Handle); /* Tracelyzer ISR tracing */ 
BaseType_t yield_req = pdFALSE;

/* End of transmition */
if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
{
    nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
    if (p_uart_cb->tx_buffer_length)
    {
        tx_done_event(p_uart_cb, nrf_uarte_tx_amount_get(p_uarte));
    }
}
/* End of reception ? */
else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
{
    nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
    uint8_t amount = nrf_uarte_rx_amount_get(p_uarte);
    // If the transfer was stopped before completion, amount of transfered bytes
    // will not be equal to the buffer length. Interrupted transfer is ignored.
    if (amount == p_uart_cb->rx_buffer_length)
    {
        if (p_uart_cb->rx_secondary_buffer_length)
        {
            nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
            p_uart_cb->rx_buffer_length     = p_uart_cb->rx_secondary_buffer_length;
            p_uart_cb->p_rx_buffer          = p_uart_cb->p_rx_secondary_buffer;
            p_uart_cb->rx_secondary_buffer_length = 0;
            rx_done_event(p_uart_cb, amount, p_uart_cb->p_rx_buffer);
        }
        else
        {   /* reset rx buffer length due to trunked transfer */
            p_uart_cb->rx_buffer_length = 0;
            rx_done_event(p_uart_cb, amount, p_uart_cb->p_rx_buffer);
        }
    }

    /* verify error event has occurred in the reception */
    if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
    {
        nrf_drv_uart_event_t event;

        nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);

        event.type                   = NRF_DRV_UART_EVT_ERROR;
        event.data.error.error_mask  = nrf_uarte_errorsrc_get_and_clear(p_uarte);
        event.data.error.rxtx.bytes  = nrf_uarte_rx_amount_get(p_uarte);
        event.data.error.rxtx.p_data = p_uart_cb->p_rx_buffer;

        //abort transfer
        p_uart_cb->rx_buffer_length           = 0;
        p_uart_cb->rx_secondary_buffer_length = 0;
        /* non-blocking mode, callback function */
        configASSERT(p_uart_cb->handler != NULL)
        p_uart_cb->handler(&event, p_uart_cb->p_context);
    } 
    /* Timeout event has occurred in the reception? */
    else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
    {
        nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
        if (p_uart_cb->rx_buffer_length)
        {   /* reset rx buffer length */
            p_uart_cb->rx_buffer_length = 0;
            rx_done_event(p_uart_cb, nrf_uarte_rx_amount_get(p_uarte), p_uart_cb->p_rx_buffer);
        }
    }   
} // end-of-reception
/* Switch the task if required. */
portYIELD_FROM_ISR(yield_req);
vTraceStoreISREnd(yield_req); /* Stops ISR tracing */
} Thanks for your attention to this issue. Have a nice day.

configASSERT xTaskNotifyFromISR

In fact, I see muarttask is not NULL breaking at configASSERT
That is very weird, how have you defined configASSERT()? Is anything interfering with execution – for example are you using semihosting?
muarttask is stored statically at address 0x2000A070
So that is the address of the variable that holds themuarttask value….
and contains 0x20007900
…and that is the value held in muarttask – which as you said – is not NULL. This is in effect a pointer to the task TCB.
that points to address 0x20007874
Which is presumably the address of the TCB. I would probably expect that to be 8-byte aligned. The code you posted doesn’t show how muarttask is declared. Is it just as follows: TaskHandlet muart_task; ? Is this a file scope or static variable – basically make sure it is not defined on the stack, not even the stack of main(), as none of that memory will be valid. Regards.

configASSERT xTaskNotifyFromISR

Hi Richard, following more information. Regards. These definitions are held in nrfuartfreertos.h : “#define NRFBLEFREERTOSUARTTASKSTACK 256 “#define NRFBLEFREERTOSUARTTASKPRIO configMAXPRIORITIES – 3 /* prio 1, configMAXPRIORITIES = 4 */ typedef void (*nrf_uart_freertos_task_hook_t)(void * p_context); static TaskHandlet muarttask; //!< Reference to UART FreeRTOS task. static nrfuartfreertostaskhookt muarthook; //!< A hook function run by the UART task before entering its loop. From the .map file: muart0 0x00025b4c 0x8 Data Lc main.o [1] muartcb 0x20009f8c 0x20 Data Lc nrfdrvuartfreertos.o [1] muarthook 0x2000a06c 0x4 Data Lc nrfuartfreertos.o [1] muarttask 0x2000a070 0x4 Data Lc nrfuart_freertos.o [1] uarttask 0x00029049 0x96 Code Lc nrfuartfreertos.o [1] uarte0init 0x000255cb 0x42 Code Lc main.o [1] uarteinterrupthandler 0x00025579 0x52 Code Gb main.o [1] uarteirqhandler 0x0002898b 0x118 Code Lc nrfdrvuartfreertos.o [1] ucHeap 0x20006a28 0x2000 Data Lc heap1.o [1] The memory model is heap_1. definition in FreeRTOSConfig.h: /* Define to trap errors during development. */ “#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) “#define configASSERT( x ) ASSERT(x) “#endif // defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) from nrfassert.h : “#if (defined(DEBUGNRF) || defined(DEBUGNRFUSER)) “#define NRFASSERTPRESENT 1 “#else “#define NRFASSERTPRESENT 0 “#endif //#if defined(DEBUGNRF) || defined(DEBUGNRF_USER) /lint -emacro(506, ASSERT) */ / Suppress “Constant value Boolean / /lint -emacro(774, ASSERT) / / Suppress “Boolean within ‘if’ always evaluates to True” */ /** @brief Function for checking intended for production code. * * Check passes if “expr” evaluates to true. */ “#ifdef lint “#define ASSERT(expr) if (expr) { } else { while (1); } “#else //lint “#define ASSERT(expr) if (NRFASSERTPRESENT) { if (expr) { } else { assertnrfcallback((uint16t)LINE, (uint8t *)FILE); } } “#endif

configASSERT xTaskNotifyFromISR

The definitions of ASSERT() would seem to show they won’t be triggered when the task handle is non-null – I think you are going to have to step through the code as the assert is triggered to figure out why this is happening.

configASSERT xTaskNotifyFromISR

Hi Richard, I managed that issue moving callback function from main.c to the file that contains task handler. That solved, even that weird situation, I will investigate further to understand what happened. Thank you for your support. Regards.