# FreeRTOS crash caused by CAN task

**URL:** <https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926>\
**Category:** Kernel\
**Created:** [December 18, 2014, 10:03am UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926 "2014-12-18T10:03:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 18, 2014, 10:03am UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/1 "2014-12-18T10:03:25Z")

</div>

**[seb67110](https://sourceforge.net/u/seb67110/)** wrote on [Thursday, December 18, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#538e):

Hello,

I am facing an issue regarding the implementation of a CAN peripheric in FreeRTOS.

Configuration : FreeRTOS V8.1.2  
STM32F407VG (discovery board)

Indeed, i am using a binary semaphore in the reception interrupt of the CAN to trigger a task processing the received data.  
The thing is that it makes my Os crash after a couple of minutes and i can’t figure out how to debug it.  
The interrupts priorities are set correctly (priority of CAN Rx interrupt set to minimum for test) and i for test purposes i activated only the CANRx Task.

Here is my CAN Rx interruption :

```auto
void CAN1_RX0_IRQHandler(void){
	BaseType_t xHigherPriorityTaskWoken=pdFALSE;

	CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

	xSemaphoreGiveFromISR(CANRx_semaphore, &xHigherPriorityTaskWoken);
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); 
	}

```

Here is my CAN Rx Task :

```auto
xTaskCreate( CANRxTask, "CANRx", configMINIMAL_STACK_SIZE, ( void * ) NULL, 3, NULL );
void CANRxTask( void *pvParameters ){
CANRx_semaphore=xSemaphoreCreateBinary();
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
	for(;;){
		if(xSemaphoreTake(CANRx_semaphore, portMAX_DELAY)){

			if(RxMessage.StdId==0x0C0){
				BMS_SOC=RxMessage.Data[0];
				BMS_Mode=RxMessage.Data[1]&0x03;
			}
			else if(RxMessage.StdId==0x0C1){
				BMS_Tension=RxMessage.Data[0];
				BMS_Intensite=RxMessage.Data[1];
			}
}

```

I can post you my CAN\_init function if needed.

I can’t figure out what is going wrong.  
Any help is appreciated.  
Thanks !

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [December 18, 2014, 10:21am UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/2 "2014-12-18T10:21:23Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Thursday, December 18, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#a4d3):

Do you have [configASSERT()](http://www.freertos.org/a00110.html#configASSERT) defined?

As you are using an STM32, are you calling NVIC\_PriorityGroupConfig( NVIC\_PriorityGroup\_4 ); before the RTOS scheduler is started?

How are you protecting the xRxMessage structure from simultaneous access from the interrupt and the task, or a second interrupt overwriting the structure before the task has had time to process the first? If this is a small structure then you may be better off posting a copy of the structure to a queue rather than using a semaphore. That way you will get both buffering and mutual exclusion on the data. However, if the interrupt is fast a queue may be a bit cumbersome and a circular buffer would be better. There is a thread safe circular buffer included in [our TCP/IP stack](http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html) that people are starting to use for this purpose.

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 22, 2014, 2:16am UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/3 "2014-12-22T02:16:17Z")

</div>

**[jradoslav](https://sourceforge.net/u/jradoslav/)** wrote on [Monday, December 22, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#1c33):

RxMessage is global? its probably not good solution.Better is data frames queue.  
Data transmition from ISR via global variable is unsafe. CANRx\_semaphore not solve problem in your code.

Where is code to reenabling or enable/disable CAN\_ISR? CAN\_Receive function probably enables an interrupt handler at the end of subroutine.  
you have to reenable CAN ISR after reading message, other solution will cause problem with rewriting message data.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 22, 2014, 3:27pm UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/4 "2014-12-22T15:27:29Z")

</div>

**[seb67110](https://sourceforge.net/u/seb67110/)** wrote on [Monday, December 22, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#c38f):

First, thank you for your answers. I couldn’t work on it until today.

I called NVIC\_PriorityGroupConfig at the beginning of my main() : i don’t think it is a interrupt priority issue. I had an issue of priorities some weeks ago and nothing worked at the time. Now it is working, it is just unstable because the OS crashes after few minutes or sometimes seconds.

Also i just configured configASSERT(). So it clearly shows me that when the OS crashes an assertion is created because xSemaphoreGiveFromISR returns 0 (errQUEUE\_FULL).  
Why ? Maybe because like you said the interrupt is faster than the task ?  
If an assertion is created at this point, it is not a simultateous access of the memory problem, isn’t it ?  
In all cases it is weird, because for my test, i am using a CAN sniffer by sending a frame each 100ms (250kbps can configuration). So i’m not overloading the bus and it still crashes.

@Radoslav: yes RxMessage is global. Can you enlighten me about why data transmition from ISR via global variables is unsafe please ?

I put my code for enabling the CAN ISR first in the CAN\_Init function, but i moved it at the beginning of the CANRx Task because it made my OS crash if i was receiving a Frame before my CANRx Task was created. (i modified my first post with the code).

Why should i reenable the CAN ISR after reading each message ? I don’t think the CAN\_Receive function does deactivate the ISR, it just resets a flag after reading i guess.

In all cases i am going to try to implement a queue with a structure. I keep you posted.  
Thanks for your imputs !

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 22, 2014, 11:37pm UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/5 "2014-12-22T23:37:37Z")

</div>

**[jradoslav](https://sourceforge.net/u/jradoslav/)** wrote on [Monday, December 22, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#7402):

Sebastien,

In most SW/HW architectures CAN ISR is controled by PeriferialClock, enable-maskbit and status register.  
If interrupt is enabled and ISR was occourred, status bit goes high.  
Interrupt cannot run, while status bit is not cleared. This bit is usually cleared after reading CAN message register automatically or you have to manually enable next transmition/reception by writing control bit.

if CAN\_Receive enables next reception, CANRxTask takes semaphore and reads message from the global variable, but the time interval is as follows(sequence):

from|(isr occurs, read message register to glob variable(\*ISR is active) giving semaphore, taking, reading glob variable ) end|

Problem: \*ISR - from this timepoint can occur CAN\_ISR any time, which writes to same global variable. if time point is “reading glob variable” this variable can be corrupted by several writes from ISR.

this situations can be solved by relocating (\*ISR is active) code after ‘reading glob variable’ in your case at and of if(xSemaphoreTake){ reading, here} block.

You have to study how CAN\_Receive enable next reception, and read STM32F407VG CAN ISR behavior and register documentation.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 22, 2014, 11:53pm UTC](https://forums.freertos.org/t/freertos-crash-caused-by-can-task/926/6 "2014-12-22T23:53:27Z")

</div>

**[jradoslav](https://sourceforge.net/u/jradoslav/)** wrote on [Monday, December 22, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/2d633681/#55e3):

The main idea is the same as Real Time Engineers ltd answered first. According to them TCP/IP stack contains implementation for solutions of similar problems.
