This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

FREERTOS timer on NRF52833 doesn't work.

Hello Everyone,

                     I am using NRF52833 in my project. My code is FREERTOS based. I am also using 2 UART, one is normal uart and other is LIBUARTE. I have also initialised timers in my tasks to perform some operations at regular intervals. My timers are not working.

The code for timers is as follows:- 

#define QUEUE_LENGTH    10
#define ITEM_SIZE       sizeof( let_btn_task_evt_t )

/* The variable used to hold the queue's data structure. */
static StaticQueue_t xStaticQueue;

/* The array to use as the queue's storage area.  This must be at least
uxQueueLength * uxItemSize bytes. */
uint8_t led_queue_storage_area[ QUEUE_LENGTH * ITEM_SIZE ];


volatile TaskHandle_t led_task_handle = NULL;


static TimerHandle_t button_timer_handle;
static StaticTimer_t button_timer;

static TimerHandle_t red_led_timer_handle;
static StaticTimer_t red_led_timer;

static TimerHandle_t grn_led_timer_handle;
static StaticTimer_t grn_led_timer;


err_rc_t init_led_button_task(void)
{
    err_rc_t rc = RESULT_SUCCESS;

    do {
        /* Start the two tasks as described in the comments at the top of this
        file. */
        led_task_handle = xTaskCreateStatic(
                              led_button_task,       /* Function that implements the task. */
                              "LEDBTN",          /* Text name for the task. */
                              LED_BUTTON_TASK_STACK_SIZE,      /* Number of indexes in the led_button_stack array. */
                              ( void * ) 1,    /* Parameter passed into the task. */
                              LED_TASK_PRIORITY,/* Priority at which the task is created. */
                              led_button_stack,          /* Array to use as the task's stack. */
                              &task_led_button_tcb );  /* Variable to hold the task's data structure. */

        if(led_task_handle == NULL) {
            rc = RESULT_ERROR_FAILURE;
            break;
        }

        /* Create a queue capable of containing 10 uint64_t values. */
        led_button_queue_handle = xQueueCreateStatic( QUEUE_LENGTH,
                                  ITEM_SIZE,
                                  led_queue_storage_area,
                                  &xStaticQueue );

        if(led_button_queue_handle == NULL) {
            rc = RESULT_ERROR_FAILURE;
            break;
        }

        button_timer_handle = xTimerCreateStatic("ButtonTimer",
                              100,
                              pdTRUE,
                              ( void * ) 0,
                              button_timer_callback,
                              &button_timer);

        if( button_timer_handle == NULL ) {
            /* The timer was not created */
            rc = RESULT_ERROR_FAILURE;
            break;
        }


        red_led_timer_handle = xTimerCreateStatic("RedTmr",
                               1000,
                               pdFALSE,
                               ( void * ) 0,
                               red_timer_callback, //**
                               &red_led_timer);

        if( red_led_timer_handle == NULL ) {
            /* The timer was not created */
            rc = RESULT_ERROR_FAILURE;
            break;
        }

        grn_led_timer_handle = xTimerCreateStatic("GrnTmr",
                               1000,
                               pdFALSE,
                               ( void * ) 0,
                               grn_timer_callback,
                               &grn_led_timer);

        if( grn_led_timer_handle == NULL ) {
            /* The timer was not created */
            rc = RESULT_ERROR_FAILURE;
            break;
        }


    } while(0);

    return rc;
}



void grn_timer_callback( TimerHandle_t xTimer )
{
    let_btn_task_evt_t evt;
    evt.id = LED_TASK_EVT_PROCESS_LED_RC1;

    led_btn_task_queue_event(evt);
}
void red_timer_callback( TimerHandle_t xTimer )
{
    let_btn_task_evt_t evt;
    evt.id = LED_TASK_EVT_PROCESS_LED_RC2;

    led_btn_task_queue_event(evt);
}
void button_timer_callback( TimerHandle_t xTimer )
{
    button_manager_timer_handle();
}

My doubt is that LIBUARTE settings is causing some issue. I am not sure about it. Just guessing. I have also attached sdk_config.h. 

Please help me solve this issue.

6355.sdk_config.h

  • There are HW timers (TIMERS using HFCLK) used by libuarte and there are low accuracy timer (RTC) used by the freertos.

    Which timers are not working? 
    What do you mean by not working, you mean to say that they do no expire at all? how did you initialize UART and LibUARTE drivers? It would be useful to see what priorities they are initialized with.

  • Hi Susheel,

                     When I try to run few tasks through the callback functions, I tried to check in debug mode, it never goes in the callback functions to execute the tasks. 

    The code of LIBUARTE is as follows:- 

        static uint8_t data_array2[50];
    char *string2;
    
    //https://devzone.nordicsemi.com/f/nordic-q-a/80192/general-info-of-the-correct-usage-of-libuarte-error-libuarte_async-evt-failed-to-allocate-buffer-for-rx
    void libuart_event_handler(void *context, nrf_libuarte_async_evt_t *p_evt) {
        static uint8_t index;
        char *str;
      nrf_libuarte_async_t *p_libuarte = (nrf_libuarte_async_t *)context;
      ret_code_t ret;
    
      switch (p_evt->type) {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR: {
          NRF_LOG_ERROR("LIBUARTE ERROR");
          break;
        }
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA: {
         // Receive complete
         memset(buffer,'0',sizeof(buffer));
          memcpy(buffer, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
          int data_length = p_evt->data.rxtx.length;
          str = malloc(strlen(buffer) + 1);
          strcpy(str,buffer); 
          NRF_LOG_INFO("%s",str);     
          nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
          break;
        }
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE: {
          // Transmit complete
    
          break;
        }
      }
    }
    
    
    //https://devzone.nordicsemi.com/f/nordic-q-a/65109/possible-bug-in-libuarte-nrf_libuarte_async-c
    void sys_uart2_init(void)
    {
      
      ret_code_t err_code;
      
        nrf_libuarte_async_config_t nrf_libuarte_async_config = {
                .tx_pin     = UART_TX_2_PIN_NUMBER,
                .rx_pin     = UART_RX_2_PIN_NUMBER,
                .baudrate   = NRF_UARTE_BAUDRATE_9600,
                .parity     = NRF_UARTE_PARITY_EXCLUDED,
                .hwfc       = NRF_UARTE_HWFC_DISABLED,
                .timeout_us = 100,
                .int_prio   = APP_IRQ_PRIORITY_LOW
        };
    
        err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, libuart_event_handler, (void *)&libuarte);
    
        APP_ERROR_CHECK(err_code);
    
        nrf_libuarte_async_enable(&libuarte);
    
    }
    
    

    I am able to transmit and receive data via UART. There is no problem with LIBUARTE, but the freertos timers dont get executed. The functions in the callback functions never seem to run.

    Libuarte is initialised in UART task. 

    and led code which I shared above is initialised in LED task.

    #define UART_TASK_STACK_SIZE 1024

    #define LED_TASK_STACK_SIZE 1024

    #define UART_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )

    #define LED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )

    Thanks & Regards,

    Snehal.

  • sne_333 said:
    The functions in the callback functions never seem to run.

    Try increasing the timer priority a bit more than the UART and LED task. (configTIMER_TASK_PRIORITY set to 3). It seems to me that some other context with higher priority than timer thread is not allowing  timer thread to execute. I would recommend you to start the debugger, run your code in debugger for sometime and hit the halt button. Check after the code execution halts which context the MCU is executing just to get an idea to see if the code is looping or stuck in a deadlock.

  • Hi Susheel,

               The #define configTIMER_TASK_PRIORITY ( 2 ) is set to 2 in the firmware. What value to set to increase the priority?

    When I put breakpoint and halt it , it is seen in rtos fucntions & other i2c functions. It is not stuck in deadlock. I added the below lines in led_button_task function. I was able to start timer. I can see the print which i had kept in the handler. But now the issue is it is executed only once. It is not running in continuous loop.

    if(xTimerStart(red_led_timer_handle, 0 ) != pdPASS ) {
    /* The timer could not be set into the Active
    state. */
    }

    Thanks & Regards,

    Snehal Bundele.

  • sne_333 said:
     The #define configTIMER_TASK_PRIORITY ( 2 ) is set to 2 in the firmware. What value to set to increase the priority?

    You can set it to, for example 3, to increase the priority than other tasks.

    Good that you verified that there are no deadlocks, that means then it most likely could be the issue with tasks priority calibration. Make sure that your application architect knows all the tasks and their priorities so that correct priorities are given to all tasks.

    sne_333 said:
    I was able to start timer. I can see the print which i had kept in the handler. But now the issue is it is executed only once. It is not running in continuous loop.

    That is because you have created with timer as one-shot . To be able to have a continuous timer you need to have uxAutoReload set to True.

    Change the below in your code

            red_led_timer_handle = xTimerCreateStatic("RedTmr",
                                   1000,
                                   pdFALSE,
                                   ( void * ) 0,
                                   red_timer_callback, //**
                                   &red_led_timer);

    to

            red_led_timer_handle = xTimerCreateStatic("RedTmr",
                                   1000,
                                   pdTRUE,
                                   ( void * ) 0,
                                   red_timer_callback, //**
                                   &red_led_timer);

Related