1
\$\begingroup\$

I am new freeRTOS and i am using stm32F4 . Requirement is to create a task it should the sd card every after 15min what is the best possible solution ??

osThreadDef(taksSDWrite, task_SDWrite, osPriorityNormal, 0, 256);
taksSDWriteHandle = osThreadCreate(osThread(taksSDWrite), NULL);

void task_sdWrite(void const * argument)
{
  /* USER CODE BEGIN task_sdWrite */

  uint8_t tickcount = 0;
  const TickType_t xPeriod = pdMS_TO_TICKS( 1000 ); //1000 ms

  /* Infinite loop */
  for(;;)
  {
     if(xSemaphoreTake(semsdHandle, xPeriod ))
     {
      count++;

      if(count%900 == 0) //15 min
      {

       // write the data into sd card
          xSemaphoreGive(semsdHandle);
      }

    }
    osDelay(1);
  }

}

above is the code which i tried but i could not achieve the requirement

\$\endgroup\$
1
\$\begingroup\$

The xSemaphoreTake() does not necessarily block the thread so it's NOT the right way to implement a delay. As long as you have no other thread using the same mutex, the semaphore will always be free when the task_sdWrite tries to take it. The tick argument only defines the maximum time the thread tries to lock the semaphore before it would return False.

To achieve a 15min delay, take a look at the FreeRTOS software timers

TimerHandle_t xTimerCreate
                 ( const char * const pcTimerName,
                   const TickType_t xTimerPeriod,
                   const UBaseType_t uxAutoReload,
                   void * const pvTimerID,
                   TimerCallbackFunction_t pxCallbackFunction );

Create a flag that is set True in your timer callback function (e.g. bool write_SD_now). In the write task you can check if the flag is set, if so, take the semaphore that protects the SD card, do the writing, give the semaphore and set the write_SD_now back to False

\$\endgroup\$
  • \$\begingroup\$ thanks for the reply . so i need to create timer of 15min and in timer callback i can release the semaphore .will it work?? \$\endgroup\$ – Ethane Das Mar 13 at 7:18
  • \$\begingroup\$ The 15 minute timer and the semaphore have no direct relation. A semaphore is used to protect critical code from concurrent access. I updated my answer... \$\endgroup\$ – po.pe Mar 13 at 7:40
  • \$\begingroup\$ hi it works but it execute only two time and then stop \$\endgroup\$ – Ethane Das Mar 13 at 9:44
  • 1
    \$\begingroup\$ Please update the question with the current code implementation \$\endgroup\$ – po.pe Mar 13 at 10:45
  • 1
    \$\begingroup\$ Could you add it to your question and format it accordingly? \$\endgroup\$ – po.pe Mar 14 at 5:39
0
\$\begingroup\$

If you use a software timer then you can't do anything that blocks in the timer callback (https://www.freertos.org/RTOS-software-timer.html ) but it has the benefit of not needing to create an additional task (which requires an additional stack to be allocated). If you can run an additional task and what it to execute every 15 minutes then the simplest thing to do is just use a vTaskDelay() (https://www.freertos.org/a00127.html ). If you want it to be a maximum of 15 seconds, but also respond to other events, then those other events can either abort the delay or you could wait on a semaphore with a timeout of 15 minutes and have the other events give the semaphore.

\$\endgroup\$
  • \$\begingroup\$ hi richard , thanks for the reply first time i tried same i.e first i created a separate task and have given a normal priority and in the task it put it as vTaskDelay(5000) so it enter into the task for 5 second but on next execution it goes to 6sec then 7 sec .so i was unable to achieve the exact time \$\endgroup\$ – Ethane Das Mar 14 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.