Quality RTOS & Embedded Software

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




Loading

Interrupt Configuration on STM32F407

Posted by Ronan on April 3, 2013
Dear all,

I'm using a board (Core407V) based on a STM32F407 (Cortex M4) and I 'm having problems. I use FreeRTOS V7.1.0 with Keil uVision 4. My project consist to achieve a data acquisition system.

The system receives :
- data provided by the GPS throught UART3
- data provided by the Inertial Measurement Unit through UART4
- data provided by wind sensor through analog inputs

Then, the system stores these data on Sd card and sends them throught UART1 on a computer. My work is divided is several main tasks (Acquisition Task, Compute Task, Store Task and Send Task) and two others task to recept the GPS and IMU data.

But I think, I have an error in my interrupt initialization because there is crash which often occurs when receiving data throught UART after few minutes or hours running. In the UART ISR, I give a semaphore to unblock an other task (when the frame is completed ). I think I have similary problem describ on the other post (http://sourceforge.net/projects/freertos/forums/forum/382005/topic/4059693) but I don't find my error.

Here is my NVIC configuration :

/*------------------------------------------------------------------------
* PeripheralNVIC - Nested Vectored Interrupt Controller
* -----------------------------------------------------------------------
* functionEnable Interrupt and Configure the Priority
* -----------------------------------------------------------------------*/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* Selectionne la priorite du group */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

/* Enable the DMA2 Stream0 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM1 global Interrupt - FreqMHU*/
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM1 Interrupt - Overflow TIM1*/
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM2 Interrupt - Overflow TIM2 */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the UART4 Interrupt IMU */
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the USART3 Interrupt GPS */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


Here is my NVIC configuration :


/*------------------------------------------------------------------------
* INT.GLOUART3
* -----------------------------------------------------------------------
* Int.USART3 - USART_IT_RXNE
* WhenEach byte come from GPS is received
* -----------------------------------------------------------------------*/

Here is the ISR code for USART3 :

/* Public variables ------------------------------------------------------*/
extern xSemaphoreHandle xBinarySemaphoreGPS;
extern char GPSPacket[MAX_GPS_PACKET_SIZE];// Used in USART3 Interrup (Receipt Frame)
extern unsigned char StateBufGps;;// Used in USART3 Interrup (Receipt State)
extern uint16_t RxCounterGps;// Used in USART3 Interrup (byte counter)

/* Function ------------------------------------------------------------------*/
void USART3_IRQHandler(void)
{
unsigned char RxBufGps;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* Reception GPS - USART3 */
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
/*Lecture de l'octet transmit */
RxBufGps = (USART_ReceiveData(USART3) & 0xFF);

/* Test si il n'y a pas de depassement du compteur du buffer -------------*/
if(RxCounterGps<=(MAX_GPS_PACKET_SIZE-2))
{
/*Lecture de l'octet transmit */
GPSPacket[RxCounterGps++] = RxBufGps;

/* Si il y a plus de 2 caracteres lu */
if(RxCounterGps>2)
{
/* Verifie que l'on a pas le caractere de fin de trame Cr Lf */
if((GPSPacket[RxCounterGps-2]==0x0D) & (GPSPacket[RxCounterGps-1]==0x0A))
{
/* Donne le semaphore */
xSemaphoreGiveFromISR(xBinarySemaphoreGPS,&xHigherPriorityTaskWoken);

/* Force à changer de tache */
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);

/* Reset du compteur */
RxCounterGps = 0;
}
}
}

/* Si il y a depassement du buffer, reinitialise la compteur Buffer GPS --*/
else
{
#ifdef USE_DEBUG_INT_USART
printf("Overflow RxCounterGPS : %d \n",RxCounterGps);
#endif
RxCounterGps = 0;
}
}
}


Here is the code at the task associated to this interrupt:

/*------------------------------------------------------------------------
* TaskGPS
* -----------------------------------------------------------------------
* DescrParse GPS Frame
* PrioritytskIDLE_PRIORITY + 5
* SizeconfigMINIMAL_STACK_SIZE*2
* -----------------------------------------------------------------------*/
void TaskGps(void * pvParameters)
{
/* The parameters are not used. */
( void ) pvParameters;

/* If Use Log Tick Counter, enable TIM2 counter */
#ifdef USE_CNT_TASKGPS
TIM_Cmd(TIM2,ENABLE);
#endif

/* Prend le semaphoreGPS 1 fois au depart */
xSemaphoreTake(xBinarySemaphoreGPS, portMAX_DELAY);

for(;;)
{
/* Prend le semaphoreGPS */
xSemaphoreTake(xBinarySemaphoreGPS, portMAX_DELAY);

/* Disable Interrupts */
#ifdef USE_NOPREMP
DisableInterrupts();
taskDISABLE_INTERRUPTS();
#endif

/* Debug Task GPS*/
#ifdef USE_DEBUG_TASK
//printf("\nTASK GPS\t");
strcpy(SecondLastDebugTask,LastDebugTask);
sprintf(LastDebugTask,"TASK GPS");
#endif

/* Get Cnt Tm2 */
#ifdef USE_CNT_TASKGPS
CntStart = TIM_GetCounter(TIM2);
#endif

/* Analyse la trame GPS */
parseGPSPacket(GPSPacket,&GPSData);

/* Mise à jour de l'horloge temps reel avec l'heure GPS (une fois au depart) */
if((GPSData.UTC_time != 0)&&(FirstUpdateTime == 1))
{
/* Mise à jour de l'heure */
UpdateTime(GPSData.UTC_time);

/* Reset FirstUpdateTime*/
FirstUpdateTime=0;

}
if((GPSData.date != 0)&&(FirstUpdateDate == 1))
{
/* Mise à jour de la date */
UpdateDate(GPSData.date);

/* Reset FirstUpdateTime*/
FirstUpdateDate=0;
}

/* Get Cnt Tm2 and computime task tick execute */
#ifdef USE_CNT_TASKGPS
CntStop = TIM_GetCounter(TIM2);
if(CntStop>CntStart) TickTask = CntStop - CntStart;
else TickTask = (65535-CntStart) + CntStop ;
#endif

/* Enable Interrupts */
#ifdef USE_NOPREMP
EnableInterrupts();
taskENABLE_INTERRUPTS();// Reactive les interruptions
#endif

/* Enable the USART3 Receive interrupt */
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
}


Many thanks in advance for your assistance.



RE: Interrupt Configuration on STM32F407

Posted by Ronan on April 3, 2013
Sorry for the bad layout

Here is the ISR code for USART3 :


/*------------------------------------------------------------------------
* INT.GLOUART3
* -----------------------------------------------------------------------
* Int.USART3 - USART_IT_RXNE
* WhenEach byte come from GPS is received
* -----------------------------------------------------------------------*/

/* Public variables ------------------------------------------------------*/
extern xSemaphoreHandle xBinarySemaphoreGPS;
extern char GPSPacket[MAX_GPS_PACKET_SIZE];// Used in USART3 Interrup (Receipt Frame)
extern unsigned char StateBufGps;;// Used in USART3 Interrup (Receipt State)
extern uint16_t RxCounterGps;// Used in USART3 Interrup (byte counter)

/* Function ------------------------------------------------------------------*/
void USART3_IRQHandler(void)
{
unsigned char RxBufGps;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* Reception GPS - USART3 */
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
/*Lecture de l'octet transmit */
RxBufGps = (USART_ReceiveData(USART3) & 0xFF);

/* Test si il n'y a pas de depassement du compteur du buffer ---------*/
if(RxCounterGps<=(MAX_GPS_PACKET_SIZE-2))
{
/*Lecture de l'octet transmit */
GPSPacket[RxCounterGps++] = RxBufGps;

/* Si il y a plus de 2 caracteres lu */
if(RxCounterGps>2)
{
/* Verifie que l'on a pas le caractere de fin de trame Cr Lf */
if((GPSPacket[RxCounterGps-2]==0x0D) & (GPSPacket[RxCounterGps-1]==0x0A))
{
/* Donne le semaphore */
xSemaphoreGiveFromISR(xBinarySemaphoreGPS,&xHigherPriorityTaskWoken);

/* Force à changer de tache */
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);

/* Reset du compteur */
RxCounterGps = 0;
}
}
}

/* Si il y a depassement du buffer, reinitialise la compteur Buffer GPS --*/
else
{
#ifdef USE_DEBUG_INT_USART
printf("Overflow RxCounterGPS : %d \n",RxCounterGps);
#endif
RxCounterGps = 0;
}
}
}


Here is the code at the task associated to this interrupt:

/*------------------------------------------------------------------------
* TaskGPS
* -----------------------------------------------------------------------
* DescrParse GPS Frame
* PrioritytskIDLE_PRIORITY + 5
* SizeconfigMINIMAL_STACK_SIZE*2
* -----------------------------------------------------------------------*/
void TaskGps(void * pvParameters)
{
/* The parameters are not used. */
( void ) pvParameters;

/* If Use Log Tick Counter, enable TIM2 counter */
#ifdef USE_CNT_TASKGPS
TIM_Cmd(TIM2,ENABLE);
#endif

/* Prend le semaphoreGPS 1 fois au depart */
xSemaphoreTake(xBinarySemaphoreGPS, portMAX_DELAY);

for(;;)
{
/* Prend le semaphoreGPS */
xSemaphoreTake(xBinarySemaphoreGPS, portMAX_DELAY);

/* Disable Interrupts */
#ifdef USE_NOPREMP
DisableInterrupts();
taskDISABLE_INTERRUPTS();
#endif

/* Debug Task GPS*/
#ifdef USE_DEBUG_TASK
//printf("\nTASK GPS\t");
strcpy(SecondLastDebugTask,LastDebugTask);
sprintf(LastDebugTask,"TASK GPS");
#endif

/* Get Cnt Tm2 */
#ifdef USE_CNT_TASKGPS
CntStart = TIM_GetCounter(TIM2);
#endif

/* Analyse la trame GPS */
parseGPSPacket(GPSPacket,&GPSData);

/* Mise à jour de l'horloge temps reel avec l'heure GPS (une fois au depart) */
if((GPSData.UTC_time != 0)&&(FirstUpdateTime == 1))
{
/* Mise à jour de l'heure */
UpdateTime(GPSData.UTC_time);

/* Reset FirstUpdateTime*/
FirstUpdateTime=0;

}
if((GPSData.date != 0)&&(FirstUpdateDate == 1))
{
/* Mise à jour de la date */
UpdateDate(GPSData.date);

/* Reset FirstUpdateTime*/
FirstUpdateDate=0;
}

/* Get Cnt Tm2 and computime task tick execute */
#ifdef USE_CNT_TASKGPS
CntStop = TIM_GetCounter(TIM2);
if(CntStop>CntStart) TickTask = CntStop - CntStart;
else TickTask = (65535-CntStart) + CntStop ;
#endif

/* Enable Interrupts */
#ifdef USE_NOPREMP
EnableInterrupts();
taskENABLE_INTERRUPTS();// Reactive les interruptions
#endif

/* Enable the USART3 Receive interrupt */
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
}


Many thanks in advance for your assistance.



RE: Interrupt Configuration on STM32F407

Posted by Richard on April 3, 2013
“ /* Enable the USART3 Interrupt GPS */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);”


This interrupt priority is being set to 5 - is configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY also set to 5? So something like this in FreeRTOSConfig.h:

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

#define configKERNEL_INTERRUPT_PRIORITY \
( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )





Is USE_DEBUG_INT_USART defined? printf'ing from an interrupt could cause you problems.

Do you have stack overflow detection turned on?

Is the interrupt stack large enough? Stack overflow detection will only detect stack overflows in the tasks. The stack used by interrupts is the same stack used by main() - so the stack set up by the linker script/project configuration.

Regards.

RE: Interrupt Configuration on STM32F407

Posted by Ronan on April 3, 2013
Thank for your response.

In my projet, The configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY set to 15


#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY15

#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


Otherwise for the moment, the stack overflown detection is turn off (for the tasks).

I think the interrupt stack is large enough because I increased the stack size and heap size in the "startup_stm32f4xx.s" file.

I 'll configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY set to 5 and try if it works. If it doen't work I add stack overflow detection.


RE: Interrupt Configuration on STM32F407

Posted by Richard on April 3, 2013
“configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY set to 15”


That is definitely an error then, and will lead to intermittent crashes if you have an interrupt that uses the interrupt safe FreeRTOS API (those functions that end in FromISR) from an interrupt of priority 5. Remember that on a Cortex-M priority 5 will preempt priority 15.

http://www.freertos.org/RTOS-Cortex-M3-M4.html

Regards.

RE: Interrupt Configuration on STM32F407

Posted by Ronan on April 3, 2013
Thank you Richard,

But I have one more questions because I still have crashes with this configuration :


#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY15

#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


NVIC configuration :


/*------------------------------------------------------------------------
* PeripheralNVIC - Nested Vectored Interrupt Controller
* -----------------------------------------------------------------------
* functionEnable Interrupt and Configure the Priority
* -----------------------------------------------------------------------*/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* Selectionne la priorite du group */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

/* Enable the DMA2 Stream0 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM1 global Interrupt - FreqMHU */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM1 Interrupt - Overflow TIM1 */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM2 Interrupt - Overflow TIM2 */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the UART4 Interrupt IMU */
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY - 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the USART3 Interrupt GPS */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


So what are the interrupts used by FreeRTOS and what are their priority level ? because I don't see where they are configured.

Thank you very much for your help.

Regards,

Ronan.

RE: Interrupt Configuration on STM32F407

Posted by Richard on April 3, 2013
The handlers used by FreeRTOS are listed as part of the answer to FAQ item 1 on this page: http://www.freertos.org/FAQHelp.html - they run at the priority set by configKERNEL_INTERRUPT_PRIORITY, which should always be the lowest priority available.

Regards.


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




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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

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

OpenRTOS and SafeRTOS