AnsweredAssumed Answered

Sometimes a crash in the main-loop occurs: STM32F407 with CAN, USART1 and TIMER2

Question asked by bruns.torsten on Jan 19, 2015
Latest reply on Jan 20, 2015 by bruns.torsten

Dear All,

I am working on a project where I want to control a couple of motors via CAN (CANopen).

The STM32F407 is connected via an USB-Serial converter (FT232RL, FTDI) to a PC.

(USART1 with USART_InitStructure.USART_BaudRate = 3072000;)

On the PC a GUI application is running (configuration, demand value propagation for the STM32, monitoring of demand and actual values etc.).

TIMER2 is configured with a cycle time of 1 millisecond: Every millisecond a flag is set to trigger an action in the main-loop.

The following 3 interrupts are active overall:


1. Receive commands from PC

void USART1_IRQHandler(void)


     if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)


          rxBuf[p_rxBuf] = USART_ReceiveData(USART1);


2. Receive CAN messages (three each millisecond from three motor controller overall)

void CAN1_RX0_IRQHandler(void)


CAN_Receive(CAN1, CAN_FIFO0, &CAN1_RxMessage);



3. Trigger flag. If the flag is set some jobs (calculations, message processing etc.) will be done in the main-loop.

void UB_TIMER2_ISR_CallBack(void)


All interrupts are set up with

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

So they shouldn't interrupt each other.


The information flow from STM32 to PC is done according to the following:

void UART1_SendByte(uint16_t val)


     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

     USART_SendData(USART1, val);


This happens in the main-loop during the trigger flag is set.

Every millisecond up to 80 Bytes are transferred from the STM32 to the PC (monitoring data).


Every millisecond up to 3 CAN messages are sent to the motor controllers:


     timeout = 0;

     while (!(CAN1->TSR & CAN_TSR_TME0 || CAN1->TSR & CAN_TSR_TME1 ||

               CAN1->TSR & CAN_TSR_TME2))



          if (timeout > CAN1_TX_TIMEOUT)



     CAN_Transmit(CAN1, &CAN1_TxMessage);



This also happens in the main-loop during the trigger flag is set.


If I don't send data from the GUI to the STM32, everything is fine.

The motor-control-loop with cycle time of 1 millisecond (3 Tx-CAN-Msg, 3 Rx-CAN-Msg) works fine.

Also the information flow from STM32 to PC via USART1 is fine.

The blocking implementation of Tx-USART1 consumes CPU time, but even if I sent 80 bytes per millisecondm, the calculations and jobs in the main-loop according to the TIMER2 trigger signal consume only roundabout 40% of the available CPU time.


The Problem occurs if I send data from the PC to the STM32.

At first everything is fine, but somewhere along the line the crash happens.

In the main-loop nothing happens any longer, but the TIMER2 ISR still works, even sending data via USART1 works in the TIMER2 ISR.


Variables which are accessed in the main-loop and by interrupts are secured by bit-banding flags like the following:

#define UART_RX_ISR_FLAG     *((volatile unsigned long *) (0x22000000))

#define UART_RX_MAIN_FLAG     *((volatile unsigned long *) (0x22000004))


For data transfer from variables to CAN or USART1 Tx-buffers and vice versa I use “memcpy”:

txBuf2[0] = 10;

txBuf2[1] = 76;

memcpy(&txBuf2[2], &t, 4);

memcpy(&txBuf2[6], &curDem[0], 12);

memcpy(&txBuf2[18], &curAct[0], 12);


It would be really great if somebody has an idea what is the reason for that crashes

I seems so as if the USART1 Rx Interrupt causes the problem, but I have no idea how to work around.

Perhaps USART in DMA mode could be a workaround!???


Thanks in advance,