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

How to configure FREERTOS Tasks for the following description

Hi Everyone

My requirements are as follows

1. I am running 4 tasks using free rtos in which one measures the ADC , 2nd sends the adc data over BLE and 3rd check if the button is pressed or not and 4th sends the ADC data to LORA.

2. All my 4 tasks are running perfectly so far.

But i would like to have this feature in my code.

Whenever i press the button , the controller should come out of sleep mode and run the other 2 tasks of measuring adc and sending data over BLE.

As long as button is in low state(NOT PRESSED) ,the controller should remain in sleep mode and should not do anything.

My questions are

1. How to put the nrf52840 to Sleep mode ?

2. How to achieve the above described theory using FREERTOS Tasks.

3. Can i use mutexes and sempahores for the above theory?

4. What are the available Sleep modes on nrf52840.?

5. What are the functions to call to put nrf52840 to sleep modes?

Parents Reply
  • Hello, Rajat. I tried with timers using ble_app_hrs and my both tasks ble_advertising and saadc reading are working properly. But the concern working with timely basis is I am confused on what values to be set for different tasks. My scenario is when a device is powered on first it will wait maximum for 15 sec for the sensor data to read and then start advertising for 5 sec and then transmit data for 2 sec and go to sleep for rest (4 min 63 sec ) and again do the same thing.

Children
  • yoou can define different timer intervals something like this given below
    #define T1_INTERVAL APP_TIMER_TICKS (15000)

    You can pass this value to your timer start function
    app_timer_start (t1_timer_id, T1_INTERVAL, NULL);

    Depending on the mode you have configured for your timer(repeated or siingle shot)
    The timer will expire after 15 seconds and do its task.

    This  timer can be reconfigured inside the timer handler itself , but you will have to stop and start the timer again with new time and there is no limit on app timer , untill you run out of memory.

    #define APP_ADV_DURATION                18000  
    This parameter comfgures the advertising duration , for 5 seconds you can do your research or read some documentation , its pretty easy.

    app_timer_stop (t1_timer_id);

    app_timer_start (t1_timer_id, APP_TIMER_TICKS (new_sleep_time), NULL);

    This is how you can restart your timer with new time duration(convert 4min 63 sec to miliseconds)

    Thanks

  • Thank you soo much. Will try with the above changes. And yes I have changed APP_ADV_DURATION interval and that gives me 5 sec of BLE advertising.

  • One more question I have, i.e is it necessary to have a while(1) inside the task function that we had called when created a task? Because I have to perform the above tasks using tasks also.

  • I am attaching my code snippet for your reference. I am not able to perform the tasks in sync that is first battery level reading task should be done and then stop and start ble advertising task but

    xSemaphoreHandle task_signal = 0;
    
    
    
    void Battery_Level_Take_Reading(void)
    {
      task_signal = xSemaphoreCreateBinary();
      uint32_t iteration = 0;
      while (1)
      {
         if( task_signal != NULL )
         {
            uint32_t i;
            for(iteration = 0;iteration <10;iteration++)
            {
              nrf_saadc_value_t result;
              uint32_t calc;
    
              if (nrfx_saadc_sample_convert(0, &result) != NRFX_SUCCESS)
              {
                NRF_LOG_INFO("ADC failure\r\n");
              }
              else
              {
               printf("ADC: %d\r\n", result);
          //      NRF_LOG_INFO("ADC: %d\r\n", result);
               }
                vTaskDelay(TASK_DELAY);
            }
         }
         xSemaphoreGive( task_signal );
      }
        
    }
    
    
    
    
    /**@brief Function for starting advertising.
     */
     void advertising_start(void)
    {
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        while(1)
      {
        printf(" ble task 1 \n");
    //    if( task_signal != NULL )
        if(xSemaphoreTake(task_signal, portMAX_DELAY))
    
        {
          uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
          APP_ERROR_CHECK(err_code);
    
          vTaskDelay(15000);
          xSemaphoreGive(task_signal);
        }
       }
    }
    
    
    
    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        
        saadc_init();
        saadc_sampling_event_enable();
    
      
        UNUSED_VARIABLE(xTaskCreate(Battery_Level_Take_Reading, "adc1", configMINIMAL_STACK_SIZE + 200, NULL, 2, &adc1_task_handle));
        UNUSED_VARIABLE(xTaskCreate(advertising_start, "ble", configMINIMAL_STACK_SIZE + 200, NULL, 1, &ble_task_handle));
    
    
        
    // Start FreeRTOS scheduler.
        vTaskStartScheduler();
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    
    
    both the tasks are working together. What wrong am I doing?

  • https://www.freertos.org/a00130.html : To suspend a running task
    https://www.freertos.org/a00131.html : to resume the suspended task

    You can run the battery task and suspend the ble task and then when the measurement is done , you can suspend the battery task and resume the ble task

    Thanks

Related