Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

FatFs, freertos, interrupt

Posted by molnardavid on October 7, 2015

Hi,

I am new at freertos and I need some help. I am using STM32F429 with CubeMx 1.7.0. FreeRTOS and STemWin and fatFs included. I have 2 tasks

blinky task - blinking a led on the board interval = 100ms

main task - read a bmp from sd card and draw it on LCD then clears LCD and start again

until this point everything works fine. Now I would like to detect touch screen from EXTI interrupt. interrupt works fine if I touch the screen almost ~10 interrupts triggered. There is only on thing in the interrupt handler -> print "ISRrn" to serial port. This also works fine. BUT!

After some touch (randomy changes but surely happens) my fatFs file systems responds that there is a timeout with the semaphor at fopen. And after this happened once then no more picture drawed on LCD bacause fopen reports this error.

My drawing function looks like this

~~~~ void guiFiledrawBmp(char* path) { FIL file; /* File object / FRESULT result; / FatFs return code */ result = fopen(&file, path, FAREAD); if (result != FROK) { printf("no file"); return; } GUIDrawStreamedBitmapExAuto(StreamGetData, &file, 0, 0);

f_close(&file);

} ~~~~

Everything works fine until I press the touch screen and generate some interrups.

Interrupt handler:

~~~~ /** * @brief This function handles EXTI Line[15:10] interrupts. / void EXTI1510IRQHandler(void) { / USER CODE BEGIN EXTI1510IRQn 0 / printf("ISR!!rn"); / USER CODE END EXTI1510IRQn 0 */ HALGPIOEXTIIRQHandler(GPIOPIN_13);

/* USER CODE BEGIN EXTI1510IRQn 1 */ //CTPINTCallback();

/* USER CODE END EXTI1510IRQn 1 */ } ~~~~

Any help would be appreciated, thank you in advance Dave


FatFs, freertos, interrupt

Posted by richard_damon on October 7, 2015

Is the printf routine in you system safe to use from interrupts?


FatFs, freertos, interrupt

Posted by molnardavid on October 7, 2015

Thank you for fast answer Good point but!

if I blink my system LED it works

~~~~ void EXTI1510IRQHandler(void) { /* USER CODE BEGIN EXTI1510IRQn 0 / HALGPIOTogglePin(GPIOD,GPIOPIN3); / USER CODE END EXTI1510IRQn 0 */ HALGPIOEXTIIRQHandler(GPIOPIN_13);

/* USER CODE BEGIN EXTI1510IRQn 1 */ //CTPINTCallback();

/* USER CODE END EXTI1510IRQn 1 */ } ~~~~

but if I am doing this

~~~~ void EXTI1510IRQHandler(void) { /* USER CODE BEGIN EXTI1510IRQn 0 */

for (int i=0;i<1000;i++)
{
	HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_3);
}

/* USER CODE END EXTI1510IRQn 0 */ HALGPIOEXTIIRQHandler(GPIOPIN_13);

/* USER CODE BEGIN EXTI1510IRQn 1 */ //CTPINTCallback();

/* USER CODE END EXTI1510IRQn 1 */ } ~~~~

maybe the problem has something to do with timing? If the routine in ISR takes too long then fatFs semaphore corrupted somehow?


FatFs, freertos, interrupt

Posted by molnardavid on October 7, 2015

of course my final goal is to get touch event parameters from screen and add it to a queue than later process them in a task. I have just simlify the problem example where the problem still exists.


FatFs, freertos, interrupt

Posted by molnardavid on October 7, 2015

I made another test. Completely removed the ISR just two tasks.

blinkyTask

~~~~ for(;;) { HALGPIOTogglePin(GPIOD,GPIOPIN3); osDelay(100); } ~~~~

drawBmpTask

~~~~ for(;;) { FIL file; /* File object / FRESULT result; / FatFs return code */ result = fopen(&file, path, FAREAD); if (result != FROK) { printf("no file"); return; } GUIDrawStreamedBitmapExAuto(Stream_GetData, &file, 0, 0);

    f_close(&file);
}

~~~~

if I made a small modification on blinkyTask like this

~~~~ for(;;) { for (int i=0;i<1000;i++) { HALGPIOTogglePin(GPIOD,GPIOPIN3); } osDelay(100); } ~~~~

Then the problem occurs again: fopen gives me FRDISK_ERR

HALSDErrorTypedef HALSDReadBlocks(SDHandleTypeDef *hsd, uint32t *pReadBuffer, uint64t ReadAddr, uint32t BlockSize, uint32t NumberOfBlocks) returns MSDERROR;


FatFs, freertos, interrupt

Posted by heinbali01 on October 7, 2015

Hi Dávid,

of course my final goal is to get touch event parameters from screen and add it to a queue than later process them in a task. I have just simlify the problem example where the problem still exists.

It surprises me that fatFS is suffering from an interrupt that is taking too much time. I would think it is related to the (hardware) disk driver, but I don't know for sure.

What I do know (and you most probably also) is that all hw interrupts are to be kept as short as possible :-)

If your ISR is triggered by a touch event, let it use one of these calls:

~~~~ xTaskNotifyFromISR(); xQueueSendFromISR(); xSemaphoreGiveFromISR(); ~~~~

... in order to wake up a task which will handle the touch event(s).

I wouldn't even bother to fetch the actual touch event data from within the ISR, just let the task do that.

Regards.


FatFs, freertos, interrupt

Posted by molnardavid on October 9, 2015

Hi Hein,

Thank you for your answer. I choosen the solution you suggested. Unfortunately the continous picture update gives me the same result (FRDISKERR). Keep digging ... until that I will turn off that feaure.

Here is what I did

~~~~ /** * @brief This function handles EXTI Line[15:10] interrupts. / void EXTI1510IRQHandler(void) { / USER CODE BEGIN EXTI1510IRQn 0 */ long lHigherPriorityTaskWoken = pdFALSE;

/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);

/* This interrupt does nothing more than demonstrate how to synchronise a
task with an interrupt.  First the handler releases a semaphore.
lHigherPriorityTaskWoken has been initialised to zero. */
xSemaphoreGiveFromISR( touchBinarySemHandle, &lHigherPriorityTaskWoken );

/* If there was a task that was blocked on the semaphore, and giving the
semaphore caused the task to unblock, and the unblocked task has a priority
higher than the currently executing task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE.
Passing pdTRUE into the following macro call will cause this interrupt to
return directly to the unblocked, higher priority, task. */
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );

} ~~~~

~~~~ /* StartTouchTask function / void StartTouchTask(void const * argument) { / USER CODE BEGIN StartTouchTask / I2CInit(); FT5206Init(); FT5206Wake(1); xSemaphoreTake(touchBinarySemHandle,100); HALNVICEnableIRQ(EXTI1510_IRQn); / Infinite loop */ for(;;) {

  if (xSemaphoreTake(touchBinarySemHandle,portMAX_DELAY ) == pdTRUE)
  {
	  CTP_INT_Callback(); 

  }
}
/* USER CODE END StartTouchTask */

} ~~~~

~~~~ /** Interrupt Handlers -------------------------------------------------------*/ void CTPINTCallback() { uint8t reg = prvBaseRegisterForPoint[FT5206Point1 - 1]; I2CTransmit(FT5206ADDRESS, &reg, 1); uint8t storage[4] = {0x00}; I2CReceive(FT5206_ADDRESS, storage, 4);

LCDEventMessage message; message.event = LCDEventTouchEvent; message.data[0] = ((storage[0] & 0x0F) << 8) | storage[1]; message.data[1] = ((storage[2] & 0x0F) << 8) | storage[3]; message.data[2] = (storage[0] & 0xC0) >> 6; message.data[3] = FT5206Point1;

xQueueSendToBack(xLCDEventQueue, &message, NULL); } ~~~~

Main taks

~~~~ /* USER CODE BEGIN 5 / / Infinite loop */ for(;;) { //graphicsTest_RGB565BMPStreamed();

	  if( xLCDEventQueue != 0 )
	  {
		  LCDEventMessage receivedMessage;
		  // Peek a message on the created queue.  Block for 10 ticks if a
		  // message is not immediately available.

		  if( xQueueReceive( xLCDEventQueue, & (receivedMessage), ( TickType_t ) 10 ) )
		  {

	          if (receivedMessage.data[3] == FT5206Point_1 )
	          {
	        	  printf("%lu: %lu %lu\r\n",receivedMessage.data[2],receivedMessage.data[0],receivedMessage.data[1]);
	        	  if (receivedMessage.data[2] ==1)
	        	  {
		        	  uint32_t result;
		        	  HAL_RNG_GenerateRandomNumber(&hrng,&result);
		        	  uint32_t color = result &0xFFFFFF;
		        	  GUI_SetColor(color);

	        	  }
	        	  else if (receivedMessage.data[2]==2)
	        	  {
	        		  GUI_FillCircle(480-receivedMessage.data[1],receivedMessage.data[0],10);
	        	  }
	          }
			  // pcRxedMessage now points to the struct AMessage variable posted
			  // by vATask, but the item still remains on the queue.
		  }
	  }
}

~~~~

Thank you for your help. If I will find the error I will post again.

Regards, Dave


FatFs, freertos, interrupt

Posted by molnardavid on October 9, 2015

solution on the way...

if I am doing this the problem solved

there is a function which continously draws bmp onto the picture. If I disable interrupt before f_read and then reenable file system stays consistent

~~~~ static int Stream_GetData(void * p, U8 ** ppData, unsigned NumBytesReq, U32 Off) {

FRESULT result;    /* FatFs return code */
static int FileAddress = 0;
UINT NumBytesRead;
FIL *PicFile;
PicFile = (FIL *)p;
/*
* Check buffer size
*/

/*
* Set file pointer to the required position
*/
if(Off == 1) FileAddress = 0;
else FileAddress = Off;
result = f_lseek(PicFile, FileAddress);
if (result != FR_OK) return -1;
/*
* Read data into buffer (directly to gui buffer)
*/
__disable_irq();
result = f_read(PicFile, *ppData, NumBytesReq, &NumBytesRead);
__enable_irq();
//printf("f_read: %d read:%d\r\n ",result,NumBytesRead);
/*
* Return number of available bytes
*/

return NumBytesRead;

} ~~~~


FatFs, freertos, interrupt

Posted by molnardavid on October 9, 2015

I am getting closer

~~~~ /** * @brief Reads block(s) from a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read
* @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ uint8t BSPSDReadBlocks(uint32t *pData, uint64t ReadAddr, uint32t BlockSize, uint32t NumOfBlocks) { HALSDErrorTypedef status=HALSDReadBlocks(&hsd, pData, ReadAddr, BlockSize, NumOfBlocks); if( status != SDOK) { return MSDERROR; } else { return MSDOK; } } ~~~~

gives me SDRXOVERRUN


FatFs, freertos, interrupt

Posted by molnardavid on October 15, 2015

Hi

My final solution is in bspdriversd.c. Need to disable OS during readblocks. It is somehow correlated with a timeout. Until I had short tasks for example led blink the problem not occurs.

regards, Dave

~~~~ /** * @brief Reads block(s) from a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read
* @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ uint8t BSPSDReadBlocks(uint32t *pData, uint64t ReadAddr, uint32t BlockSize, uint32t NumOfBlocks) { vPortEnterCritical(); //context switch cause SDRXOVERRUN (maybe takes too much time) HALSDErrorTypedef status=HALSDReadBlocks(&hsd, pData, ReadAddr, BlockSize, NumOfBlocks); vPortExitCritical(); if( status != SDOK) { return MSDERROR; } else { return MSDOK; } } ~~~~


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists