簡體   English   中英

STM32 USB 不可靠編譯與 GCC '-Os'

[英]STM32 USB Unreliable compilation with GCC '-Os'

我注意到我的軟件中有一些非常奇怪的行為。 實際上花了幾個月的時間來追蹤。

我使用 ST 的 USB 虛擬 COM 端口示例代碼作為我項目的一部分,偶爾生成的二進制文件在使用-Os編譯時完全無法工作。 如果我改變了一些不相關的東西,那么它會突然恢復生機——並且在沒有-Os情況下-Os一切總是完美的。

我將其追溯到導致重復調用中斷處理程序的 USB 初始化代碼。 代碼是這樣的:

#define     __IO    volatile  
#define RegBase  (0x40005C00L)  /* USB_IP Peripheral Registers base address */
#define CNTR    ((__IO unsigned *)(RegBase + 0x40))
#define ISTR    ((__IO unsigned *)(RegBase + 0x44))
#define _SetCNTR(wRegValue)  (*CNTR   = (uint16_t)wRegValue)
#define _SetISTR(wRegValue)  (*ISTR   = (uint16_t)wRegValue)

  _SetISTR(0); // Clear all pending interrupts
  wInterrupt_Mask = IMR_MSK; // 7168
  _SetCNTR(wInterrupt_Mask); // enable interrupts for WKUP/RESET/SUSP

這很好,但是 GCC(通過許多不同的版本,雖然目前是 4.8.4)產生了這個代碼:

r1 = 7168
r2 = 0x40005c44 (USB_ISTR)
r3 = 0x40005c40 (USB_CNTR)
r4 = 0
   14b42:   6019        str r1, [r3, #0]    ; USB_CNTR = 7168
   14b44:   490b        ldr r1, [pc, #44]   ; r1 = &wInterrupt_Mask
   14b46:   6014        str r4, [r2, #0]    <--------------- hangs here - USB_ISTR = 0 (USB_ISTR)

所以這些陳述的順序完全錯誤,把一切都搞砸了。 兩個寄存器甚至都被標記為易失性!

即使我這樣做:

  _SetISTR(0); // Clear all pending interrupts
  _SetISTR(0);
  _SetISTR(0);
  _SetISTR(0);
  _SetISTR(0); // I really mean it GCC
  wInterrupt_Mask = IMR_MSK; // 7168
  _SetCNTR(wInterrupt_Mask); // enable interrupts for WKUP/RESET/SUSP

我明白了:

   12d60:   601c        str r4, [r3, #0]
   12d62:   6011        str r1, [r2, #0] ; CNTR
   12d64:   601c        str r4, [r3, #0]
   12d66:   601c        str r4, [r3, #0]
   12d68:   601c        str r4, [r3, #0]
   12d6a:   601c        str r4, [r3, #0]

因此,雖然它解決了問題,但 GCC 仍然以一種完全奇怪的方式(沒有收益)重新排序寫入,而且我不完全確定它不會決定在將來的某個時候首先設置 CNTR。

那么 - 為什么 GCC 這樣做了,我該怎么做才能避免它呢? 顯然,在嵌入式系統上任意重新排序寄存器寫入是非常糟糕的消息。 在這種情況下,有沒有一種很好的方法可以解決它,有沒有辦法確保它不會在其他任何地方重新排序寫入?

謝謝!

我知道這是一篇舊帖子,但我想知道 wInterrupt_Mask 是如何聲明的? 它也被宣布為 volatile 嗎? 如果沒有,那是否會允許 GCC 任意重新排序?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM