rt-thread AT元件偶爾當機的問題

一只鱼在水杯里發表於2024-06-01

硬體資訊

微控制器 STM32L431CCT6

4G模組 EC800K-CN

rtt版本:4.1.1

第一個問題

主頻太低不行,比如使用外部晶振8M時會發現at命令的返回收到的資料不完整,是由於處理器太慢和rt-thread 系統處理工作較多導致,測試發現至少16M主頻以上才能良好執行

第二個問題

頻繁透過串列埠傳送資料時經常當機,模擬除錯發現當機在下面等待標誌的地方,主頻越低越容易發生,當主頻高的時候機率很小

 1 static int stm32_putc(struct rt_serial_device *serial, char c)
 2 {
 3     struct stm32_uart *uart;
 4     RT_ASSERT(serial != RT_NULL);
 5 
 6     uart = rt_container_of(serial, struct stm32_uart, serial);
 7     UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
 8 #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \
 9     || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) \
10     || defined(SOC_SERIES_STM32G4)
11     uart->handle.Instance->TDR = c;
12 #else
13     uart->handle.Instance->DR = c;
14 #endif
15     while (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) == RESET);
16     return 1;
17 }

經過查詢資料需要在一下isr中斷處理函式中註釋掉黃底部分,經過測試可以解決問題,

 1 static void uart_isr(struct rt_serial_device *serial)
 2 {
 3     struct stm32_uart *uart;
 4 #ifdef RT_SERIAL_USING_DMA
 5     rt_size_t recv_total_index, recv_len;
 6     rt_base_t level;
 7 #endif
 8 
 9     RT_ASSERT(serial != RT_NULL);
10     uart = rt_container_of(serial, struct stm32_uart, serial);
11 
12     /* UART in mode Receiver -------------------------------------------------*/
13     if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&
14             (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET))
15     {
16         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
17     }
18 #ifdef RT_SERIAL_USING_DMA
19     else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET)
20              && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET))
21     {
22         level = rt_hw_interrupt_disable();
23         recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle));
24         recv_len = recv_total_index - uart->dma_rx.last_index;
25         uart->dma_rx.last_index = recv_total_index;
26         rt_hw_interrupt_enable(level);
27 
28         if (recv_len)
29         {
30             rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
31         }
32         __HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
33     }
34     else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) != RESET)
35     {
36         if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0)
37         {
38             HAL_UART_IRQHandler(&(uart->handle));
39         }
40         else
41         {
42             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
43         }
44     }
45 #endif
46     else
47     {
48         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_ORE) != RESET)
49         {
50             __HAL_UART_CLEAR_OREFLAG(&uart->handle);
51         }
52         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE) != RESET)
53         {
54             __HAL_UART_CLEAR_NEFLAG(&uart->handle);
55         }
56         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE) != RESET)
57         {
58             __HAL_UART_CLEAR_FEFLAG(&uart->handle);
59         }
60         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE) != RESET)
61         {
62             __HAL_UART_CLEAR_PEFLAG(&uart->handle);
63         }
64 #if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) \
65     && !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7) \
66     && !defined(SOC_SERIES_STM32G4)
67         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBD) != RESET)
68         {
69             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBD);
70         }
71 #endif
72         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_CTS) != RESET)
73         {
74             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_CTS);
75         }
76         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE) != RESET)
77         {
78             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TXE);
79         }
80         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) != RESET)
81         {
82             //UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
83         }
84         if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET)
85         {
86             UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_RXNE);
87         }
88     }
89 }

資料連結: https://blog.csdn.net/gmq_syy/article/details/108381854

相關文章