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
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)
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.
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);
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)
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 = 10;
txBuf2 = 76;
memcpy(&txBuf2, &t, 4);
memcpy(&txBuf2, &curDem, 12);
memcpy(&txBuf2, &curAct, 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,