cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 Uart 921600 System Hangup

Patel.Pritesh
Associate II
Posted on October 20, 2017 at 17:33

I am using STM32F103ZF with Keil RTX RTOS on it. I have a UART configured at 921600 baud. I am sending about 2000 bytes a second and receive about 200 bytes every 5 second. What I am observing is I can transmit fine for days without a problem but if I start receiving 200 bytes every 5 second, some time system locks up after a random period ranging from 5 min to few hours. Using the debugger I can see SysTickTimer not increment, tasks don't switch, no hard faults but ISRs (timers & uarts) triggering. If I do not receive any data on this uart, no lockups ever. I have narrow down issue to receiving any data on this uart.

Is there any issue with running uart at 921600 baud (1Mbit)?

Why would it stop System Tick Timer? and How do I restart without rebooting?

Here is the part of the code:

/**

 *

 */

#ifdef USART2

void USART2_IRQHandler(void)

{

  static uint8_t ChB;

  if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)

  {

    if (CBUF_Getch(&UsartBOutCBuf, &ChB))

    {

      USART_SendData(USART2, ChB);

    }

    else

    {      

      USART_ITConfig(USART2, USART_IT_TXE, DISABLE);

    }

  }

  if((USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) ||

     (USART_GetITStatus(USART2, USART_IT_ORE) != RESET))

  {

    ChB = USART_ReceiveData(USART2);

    CBUF_Putch(&UsartBInCBuf, ChB);

  }

}

#endif

/**

 *

 */

__task void task_smpp(void)

{

    OS_RESULT result;

    uint16_t myTaskId;

    myTaskId = TASKID_SMPP;

    for (;;)

    {

        TASKCNT_SMPP++;

        SMPP_WriteFrame();

        SMPP_ReadFrame();            

        os_dly_msec(1000);

    }

}

I need to resolve this ASAP. I will appreciate any insight on this issue.

3 REPLIES 3
Posted on October 20, 2017 at 17:46

>>Is there any issue with running uart at 921600 baud (1Mbit)?

NO

>>Why would it stop System Tick Timer? and How do I restart without rebooting?

It doesn't preempt other interrupts? Check your grouping and priority settings.

Make sure you clear Parity and Framing Errors.

You'd need to clear all interrupts, and understand where it is stuck and why to unwind the situation.

>>I need to resolve this ASAP.

Then get your colleagues and manager/boss involved in helping you resolve it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Patel.Pritesh
Associate II
Posted on October 20, 2017 at 18:13

Thanks for replying Clive,

I am debugging this for some time and managed to catch this while debugger being active. I catch for all the flags in uart status register since that was my first guess too. But unfortunately I didnt see any other flag triggering and ISR was not looping. I am trying to catch it again with debugger to check one more time.

Below is my interrupt priority and grouping. Let me know if you see any thing unusual.

/**

*

*/

void NVIC_Configuration( void )

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Set the Vector Table base location at 0x08008000 */

/* With Bootloader, update 'Start of ROM' in project options */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00008000);

/* Without Bootloader, update 'Start of ROM' in project options */

//NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00000000);

/* Configure one bit for preemption priority */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

/* Enable the RTC Alarm on EXTI 17 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Enable the RTC Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM2 gloabal Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM4 gloabal Interrupt */

// NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;

// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

// //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

// NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM1 gloabal Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#ifdef USART1

/* Enable the USART1 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

#ifdef USART2

/* Enable the USART2 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

#ifdef USART3

/* Enable the USART3 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

#ifdef UART4

/* Enable the USARTD Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

#ifdef UART5

/* Enable the USARTE Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

// Setup the CAN Rx Interrupts

NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

// Setup the Tx CAN Interrupts

NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

// /* Configure and enable ADC interrupt */

// NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;

// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

// //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

// NVIC_Init(&NVIC_InitStructure);

// /* Enable the USB Interrupt */

// NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

// //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

// NVIC_Init(&NVIC_InitStructure);

return;

}
Posted on October 22, 2017 at 14:51

/* Configure one bit for preemption priority */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

Isn't group 4 defined as 4-bits preemption, 0-bits priority? Not a mapping I'd use.

No settings assigned to SysTick, the one you are complaining about... The default is going to be the lowest priority (set in SysTick_Config), and thus never fire if you are in some other interrupt context.

NVIC_SetPriority(SysTick_IRQn, 0); // Highest Priorities

You'd do better with 

NVIC_PriorityGroup_2, with SysTick at 0,0 if it is critical, ie you have it ticking a count everyone else is depending on.

Try not to do overreaching work in the IRQ Handlers, things that can't get handled in the instance need to be farmed out to worker tasks/threads. Put the biggest sloths at the worst priority/preempt level, and the things that are less frequent and rapidly handled a better levels.

A USART at 921600 baud is going to have an interrupt rate pushing 100KHz, you're going to want to focus on that, and consider using DMA to decimate the interrupt loading, because it is going to eat a lot of your cycle budget.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..