cancel
Showing results for 
Search instead for 
Did you mean: 

Using timer to save files in SD card with interrupt

FPicc.1
Senior

Hi all,

I'm trying to use Timer16 to create a 50Hz timer to save files in the SD card. I managed to make the timer work blinking a LED, but when I put the code to save it only saves one line. Here's the logic:

First I create a file  and initiate the timer in the USER CODE BEGIN 2 (I want to state that if I start the timer after the SD has been created, it doesn't work (don't know why)).

//Timer
HAL_TIM_Base_Start_IT(&htim16);

//Mount SD
fresult = f_mount(&fs, "", 0);
f_getfree("", &fre_clust, &pfs);
total = (uint32_t)((pfs->n_fatent - 2) * pfs->csize * 0.5);
bufclear();
free_space = (uint32_t)(fre_clust * pfs->csize * 0.5);
//Open file to read / create it if it doesn't exist
//fresult = f_open(&fil, file_name, FA_OPEN_ALWAYS | FA_WRITE);
fresult = f_open(&fil, "testeTimer2.csv", FA_OPEN_ALWAYS | FA_WRITE);
f_gets(buffer, f_size(&fil), &fil);
fresult = f_lseek(&fil, f_size(&fil));
fresult = f_puts("cabecalho,numero,tempo,ticks,ano,mes,dia,hora,minuto,segundo\n", &fil);
//Close file
fresult = f_close(&fil);

 

After, in the USER CODE BEGIN 4, I have the callback function as follow:

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM16)
{
  //Start of the File ****Update new file every test day****
  fresult = f_open(&fil, "testeTimer2.csv", FA_OPEN_ALWAYS | FA_WRITE);
  f_gets(buffer, f_size(&fil), &fil);
  fresult = f_lseek(&fil, f_size(&fil));
 
  //Data Input
  fresult = f_printf(&fil, "%d,%d,%d,%d,%04d,%02d,%02d,%02d,%02d,%02d\n", count, file_number, ret, msTicks, year, month, day, hour, minute, second);
 
  fresult = f_close(&fil);
  //Open to read
   fresult = f_open(&fil, "testeTimer2.csv", FA_READ);
  //Read string from the file
   f_read(&fil, buffer, f_size(&fil), &br);
   f_close(&fil);
  bufclear();
  HAL_GPIO_TogglePin(GPIOB, LED2_Pin);
}
}
 
It only calls one time the function and stops working, anyone knows what it's about? Attached is the ioc configuration
1 ACCEPTED SOLUTION

Accepted Solutions
FPicc.1
Senior

Managed to get it working, it really doesn't work using the interruption to this application, so I use it in normal mode. This link has some insights about it: https://www.digikey.com/en/maker/projects/getting-started-with-stm32-timers-and-timer-interrupts/d08e6493cefa486fb1e79c43c0b08cc6

 

View solution in original post

4 REPLIES 4

Doing this kind of work under interrupt / callback context is NOT recommended. Watch that the SYSTICK and SDIO/SDMMC/DMA can preempt the TIM16 IRQ

Suggest writing time constrained content to a ring-buffer, flush periodically to the file itself in the main loop.

The file system and SDIO/SDMMC are basically single threaded.

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Is using another timer a solution or it will be the same thing?

Also, will this method save the file at 50Hz? Or is there another solution?

FPicc.1
Senior

Managed to get it working, it really doesn't work using the interruption to this application, so I use it in normal mode. This link has some insights about it: https://www.digikey.com/en/maker/projects/getting-started-with-stm32-timers-and-timer-interrupts/d08e6493cefa486fb1e79c43c0b08cc6

 

You cannot do other heavy actions called inside an INT handler, e.g. writing a file to SD Card!

The functions to write to SD Card need also INTs. But calling from inside an INT handler means: all other INTs are still blocked - SD Card INTs will never be handled.

You have to use an RTOS, or some means, where you run your "user code" (here as writing to SD Card) which sits outside of all INT handlers. An INT handler triggers just a task/thread (outside INT context), doing the stuff now, so that all INTs remain "active", needed for SD Card.