Dear all,
I’m trying to use FreeRTOS 6.0.4 on an STM32F3 Discovery Board,
but I encounter some problems.
I want to give a mutex by ISR when I receive a CAN bus message, to wake up another task.
I have a second task which permit a LED to blink.
My problem is before the CAN trame is received, the program runs normally, and I see the LED blinks.
But when a CAN trame arrives, the ISR wakes up and the program blocks in it.
Tasks are stop running, and the LED stops to blink.
Sending and receiving CAN trames are working without use of ISR, only problem is when I try to use ISR.
I thought the problem is because of I set wrong priorities but it seems OK for me..
Here’s a part of code in FreeRTOSConfig.h :
~~~~~~
:::C
define configUSE_PREEMPTION 1
define configUSEIDLEHOOK 0
define configUSETICKHOOK 0
define configCPUCLOCKHZ ( ( unsigned long ) 72000000 )
define configTICKRATEHZ ( ( portTickType ) 1000 )
define configMAXPRIORITIES ( ( unsigned portBASETYPE ) 10 )
define configMINIMALSTACKSIZE ( ( unsigned short ) 128 )
define configMAXIMALSTACKSIZE ( ( unsigned short ) 8192)
define configTOTALHEAPSIZE ( 30000 )
define configMAXTASKNAME_LEN ( 16 )
define configUSETRACEFACILITY 0
define configUSE16BIT_TICKS 0
define configIDLESHOULDYIELD 1
…
define configKERNELINTERRUPTPRIORITY 255 // 15
define configMAXSYSCALLINTERRUPT_PRIORITY 191 // 11
~~~~~~
The function below is used to configure ISR parameters :
~~~~~~
:::C
void CAN
initIT(void){
NVIC
PriorityGroupConfig(NVICPriorityGroup
4);
NVICInitTypeDef NVIC
InitStructure;
NVICInitStructure.NVIC
IRQChannel = USBLP
CAN1RX0
IRQn;
NVICInitStructure.NVIC
IRQChannelPreemptionPriority = 13;
NVICInitStructure.NVIC
IRQChannelSubPriority = 0;
NVICInitStructure.NVIC
IRQChannelCmd = ENABLE;
NVICInit(&NVIC
InitStructure);
CANITConfig(CAN1, CAN
ITFMP0, ENABLE);
}
~~~~~~
The ISR and the associated task, and the main function, are here :
~~~~~~
:::C
xSemaphoreHandle ACK
messageCAN;
xSemaphoreHandle message_CAN;
void USB
LPCAN1
RX0IRQHandler(void) {
long yield = 0;
xSemaphoreGiveFromISR(message_CAN, &yield);
// Only use to debug
/*GPIO_SetBits(GPIOE, GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_9 | GPIO_Pin_8);
vTaskDelay(250);
GPIO_ResetBits(GPIOE, GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_9 | GPIO_Pin_8);
vTaskDelay(250);*/
portEND_SWITCHING_ISR(yield);
}
void RX
CAN(void *p)
{
CANinit();
CAN
initIT();
CanRxMsg RxMessage;
RxMessage.Data[0] = 0;
while(1)
{
if(xSemaphoreTake(message_CAN, (portTickType)0 ))
{
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
if(RxMessage.Data[0] == 0x05)
{
...
}
}
}
}
int main()
{
SystemInit();
SystemCoreClockUpdate();
// SysTick end of count event each 1ms
RCC
ClocksTypeDef RCCClocks;
RCC
GetClocksFreq(&RCCClocks);
SysTick
Config(RCCClocks.HCLK_Frequency / 1000);
...
vSemaphoreCreateBinary(message_CAN); // Create the semaphore
xSemaphoreTake(message_CAN, 0); // Take semaphore after creating it.
xTaskCreate(RX_CAN,(signed char *) "receive_CAN_task", 20*configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(Blink, (signed char *) "blink", 20*configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskStartScheduler();
while(1); // the program should never comes here
return -1;
}
~~~~~~
Maybe I forgot something ?
I searched in this forum before to post but I didn’t find anything.
Sorry for this long post and my bad English, I’m a french student.
Thanks for your help.