gcc重新排序我的易变量吗?

时间:2017-08-15 05:48:42

标签: gcc optimization arm volatile cortex-m

我正在使用FreeRTOS在GNU ARM工具链(gcc 5.4.1)上开发STM32F746(ARM Cortex-M7)。我使用以下CFLAGS集:

-g -Werror -Wextra -O2  -fno-common -ffunction-sections -fmessage-length=0 -g -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -fno-common -ffunction-sections -fmessage-length=0 -g -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16

以下代码在控制台中显示“0”,就像DMA控制器未启动一样。通常,在AHB1ENR寄存器中写入RCC_AHB1ENR_DMA1EN会为DMA控制器供电。

/* *** Other peripheral configurations *** */
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;                                     
DMA1_Stream3->CR = DMA_SxCR_PL | DMA_SxCR_MINC |                        
        DMA_SxCR_TCIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE;
DEBUG_PRINTF("%x\r\n", DMA1_Stream3->CR);

但以下代码正在打印DMA1_Stream3-> CR的良好值。

/* *** Other peripheral configurations *** */
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
__asm__ __volatile__ ("" ::: "memory");                                     
DMA1_Stream3->CR = DMA_SxCR_PL | DMA_SxCR_MINC |                        
        DMA_SxCR_TCIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE;
DEBUG_PRINTF("%x\r\n", DMA1_Stream3->CR);

我从来没有为任何其他控制器添加这些内存屏障,为什么我必须为此执行此操作呢?我正在考虑GCC重新排序的加载/存储指令要么是计时问题。我检查了勘误表(STM32F746)或数据表的勘误表,但没有找到任何东西。

以下是RCC结构的定义:

typedef struct
{
    /* ... */
    __IO uint32_t AHB1ENR;
    /* ... */
} RCC_TypeDef;

这是DMA1_Stream3结构类型的定义:

typedef struct                                                                  
{                                                                               
  __IO uint32_t CR;     /*!< DMA stream x configuration register      */        
  __IO uint32_t NDTR;   /*!< DMA stream x number of data register     */        
  __IO uint32_t PAR;    /*!< DMA stream x peripheral address register */        
  __IO uint32_t M0AR;   /*!< DMA stream x memory 0 address register   */        
  __IO uint32_t M1AR;   /*!< DMA stream x memory 1 address register   */        
  __IO uint32_t FCR;    /*!< DMA stream x FIFO control register       */        
} DMA_Stream_TypeDef;

__ IO被定义为volatile。

以下是为函数生成的汇编代码:

08003f4c <bsp_initSPIADIS>:
 8003f4c:       4956            ldr     r1, [pc, #344]  ; (80040a8 <bsp_initSPIADIS+0x15c>)
 8003f4e:       4a57            ldr     r2, [pc, #348]  ; (80040ac <bsp_initSPIADIS+0x160>)
 8003f50:       6b08            ldr     r0, [r1, #48]   ; 0x30
 8003f52:       f440 7080       orr.w   r0, r0, #256    ; 0x100
 8003f56:       b5f8            push    {r3, r4, r5, r6, r7, lr}
 8003f58:       6308            str     r0, [r1, #48]   ; 0x30
 8003f5a:       2500            movs    r5, #0
 8003f5c:       6810            ldr     r0, [r2, #0]
 8003f5e:       f240 3607       movw    r6, #775        ; 0x307
 8003f62:       4b53            ldr     r3, [pc, #332]  ; (80040b0 <bsp_initSPIADIS+0x164>)
 8003f64:       f44f 5eb8       mov.w   lr, #5888       ; 0x1700
 8003f68:       f020 000c       bic.w   r0, r0, #12
 8003f6c:       4c51            ldr     r4, [pc, #324]  ; (80040b4 <bsp_initSPIADIS+0x168>)
 8003f6e:       4f52            ldr     r7, [pc, #328]  ; (80040b8 <bsp_initSPIADIS+0x16c>)
 8003f70:       6010            str     r0, [r2, #0]
 8003f72:       6810            ldr     r0, [r2, #0]
 8003f74:       f040 0008       orr.w   r0, r0, #8
 8003f78:       6010            str     r0, [r2, #0]
 8003f7a:       6890            ldr     r0, [r2, #8]
 8003f7c:       f020 000c       bic.w   r0, r0, #12
 8003f80:       6090            str     r0, [r2, #8]
 8003f82:       6890            ldr     r0, [r2, #8]
 8003f84:       f040 0004       orr.w   r0, r0, #4
 8003f88:       6090            str     r0, [r2, #8]
 8003f8a:       6890            ldr     r0, [r2, #8]
 8003f8c:       f040 0008       orr.w   r0, r0, #8
 8003f90:       6090            str     r0, [r2, #8]
 8003f92:       6a10            ldr     r0, [r2, #32]
 8003f94:       f020 00f0       bic.w   r0, r0, #240    ; 0xf0
 8003f98:       6210            str     r0, [r2, #32]
 8003f9a:       6a10            ldr     r0, [r2, #32]
 8003f9c:       f040 0010       orr.w   r0, r0, #16
 8003fa0:       6210            str     r0, [r2, #32]
 8003fa2:       6a10            ldr     r0, [r2, #32]
 8003fa4:       f040 0040       orr.w   r0, r0, #64     ; 0x40
 8003fa8:       6210            str     r0, [r2, #32]
 8003faa:       6b08            ldr     r0, [r1, #48]   ; 0x30
 8003fac:       4a43            ldr     r2, [pc, #268]  ; (80040bc <bsp_initSPIADIS+0x170>)
 8003fae:       f040 0002       orr.w   r0, r0, #2
 8003fb2:       6308            str     r0, [r1, #48]   ; 0x30
 8003fb4:       6818            ldr     r0, [r3, #0]
 8003fb6:       f020 5040       bic.w   r0, r0, #805306368      ; 0x30000000
 8003fba:       6018            str     r0, [r3, #0]
 8003fbc:       6818            ldr     r0, [r3, #0]
 8003fbe:       f040 5000       orr.w   r0, r0, #536870912      ; 0x20000000
 8003fc2:       6018            str     r0, [r3, #0]
 8003fc4:       6898            ldr     r0, [r3, #8]
 8003fc6:       f020 5040       bic.w   r0, r0, #805306368      ; 0x30000000
 8003fca:       6098            str     r0, [r3, #8]
 8003fcc:       6898            ldr     r0, [r3, #8]
 8003fce:       f040 5080       orr.w   r0, r0, #268435456      ; 0x10000000
 8003fd2:       6098            str     r0, [r3, #8]
 8003fd4:       6898            ldr     r0, [r3, #8]
 8003fd6:       f040 5000       orr.w   r0, r0, #536870912      ; 0x20000000
 8003fda:       6098            str     r0, [r3, #8]
 8003fdc:       6a58            ldr     r0, [r3, #36]   ; 0x24
 8003fde:       f020 6070       bic.w   r0, r0, #251658240      ; 0xf000000
 8003fe2:       6258            str     r0, [r3, #36]   ; 0x24
 8003fe4:       6a58            ldr     r0, [r3, #36]   ; 0x24
 8003fe6:       f040 7080       orr.w   r0, r0, #16777216       ; 0x1000000
 8003fea:       6258            str     r0, [r3, #36]   ; 0x24
 8003fec:       6a58            ldr     r0, [r3, #36]   ; 0x24
 8003fee:       f040 6080       orr.w   r0, r0, #67108864       ; 0x4000000
 8003ff2:       6258            str     r0, [r3, #36]   ; 0x24
 8003ff4:       6b08            ldr     r0, [r1, #48]   ; 0x30
 8003ff6:       f040 0002       orr.w   r0, r0, #2
 8003ffa:       6308            str     r0, [r1, #48]   ; 0x30
 8003ffc:       6818            ldr     r0, [r3, #0]
 8003ffe:       f020 4040       bic.w   r0, r0, #3221225472     ; 0xc0000000
 8004002:       6018            str     r0, [r3, #0]
 8004004:       6818            ldr     r0, [r3, #0]
 8004006:       f040 4000       orr.w   r0, r0, #2147483648     ; 0x80000000
 800400a:       6018            str     r0, [r3, #0]
 800400c:       6898            ldr     r0, [r3, #8]
 800400e:       f020 4040       bic.w   r0, r0, #3221225472     ; 0xc0000000
 8004012:       6098            str     r0, [r3, #8]
 8004014:       6898            ldr     r0, [r3, #8]
 8004016:       f040 4080       orr.w   r0, r0, #1073741824     ; 0x40000000
 800401a:       6098            str     r0, [r3, #8]
 800401c:       6898            ldr     r0, [r3, #8]
 800401e:       f040 4000       orr.w   r0, r0, #2147483648     ; 0x80000000
 8004022:       6098            str     r0, [r3, #8]
 8004024:       6a58            ldr     r0, [r3, #36]   ; 0x24
 8004026:       f020 4070       bic.w   r0, r0, #4026531840     ; 0xf0000000
 800402a:       6258            str     r0, [r3, #36]   ; 0x24
 800402c:       6a58            ldr     r0, [r3, #36]   ; 0x24
 800402e:       f040 5080       orr.w   r0, r0, #268435456      ; 0x10000000
 8004032:       6258            str     r0, [r3, #36]   ; 0x24
 8004034:       6a58            ldr     r0, [r3, #36]   ; 0x24
 8004036:       f040 4080       orr.w   r0, r0, #1073741824     ; 0x40000000
 800403a:       6258            str     r0, [r3, #36]   ; 0x24
 800403c:       6c0b            ldr     r3, [r1, #64]   ; 0x40
 800403e:       4820            ldr     r0, [pc, #128]  ; (80040c0 <bsp_initSPIADIS+0x174>)
 8004040:       f443 4380       orr.w   r3, r3, #16384  ; 0x4000
 8004044:       640b            str     r3, [r1, #64]   ; 0x40
 8004046:       61e5            str     r5, [r4, #28]
 8004048:       6026            str     r6, [r4, #0]
 800404a:       6823            ldr     r3, [r4, #0]
 800404c:       4e1d            ldr     r6, [pc, #116]  ; (80040c4 <bsp_initSPIADIS+0x178>)
 800404e:       f023 0338       bic.w   r3, r3, #56     ; 0x38
 8004052:       6023            str     r3, [r4, #0]
 8004054:       6823            ldr     r3, [r4, #0]
 8004056:       f043 0338       orr.w   r3, r3, #56     ; 0x38
 800405a:       6023            str     r3, [r4, #0]
 800405c:       f8c4 e004       str.w   lr, [r4, #4]
 8004060:       6b0b            ldr     r3, [r1, #48]   ; 0x30
 8004062:       4c19            ldr     r4, [pc, #100]  ; (80040c8 <bsp_initSPIADIS+0x17c>)
 8004064:       f443 1300       orr.w   r3, r3, #2097152        ; 0x200000
 8004068:       630b            str     r3, [r1, #48]   ; 0x30
 800406a:       603a            str     r2, [r7, #0]
 800406c:       6839            ldr     r1, [r7, #0]
 800406e:       f000 faab       bl      80045c8 <printf>
 8004072:       4b16            ldr     r3, [pc, #88]   ; (80040cc <bsp_initSPIADIS+0x180>)
 8004074:       4629            mov     r1, r5
 8004076:       2203            movs    r2, #3
 8004078:       601c            str     r4, [r3, #0]
 800407a:       2001            movs    r0, #1
 800407c:       f7fe f90e       bl      800229c <xQueueGenericCreate>
 8004080:       4629            mov     r1, r5
 8004082:       6170            str     r0, [r6, #20]
 8004084:       2203            movs    r2, #3
 8004086:       2001            movs    r0, #1
 8004088:       f44f 4480       mov.w   r4, #16384      ; 0x4000
 800408c:       f7fe f906       bl      800229c <xQueueGenericCreate>
 8004090:       4b0f            ldr     r3, [pc, #60]   ; (80040d0 <bsp_initSPIADIS+0x184>)
 8004092:       2240            movs    r2, #64 ; 0x40
 8004094:       f44f 4100       mov.w   r1, #32768      ; 0x8000
 8004098:       6130            str     r0, [r6, #16]
 800409a:       601c            str     r4, [r3, #0]
 800409c:       6019            str     r1, [r3, #0]
 800409e:       f883 230e       strb.w  r2, [r3, #782]  ; 0x30e
 80040a2:       f883 230f       strb.w  r2, [r3, #783]  ; 0x30f
 80040a6:       bdf8            pop     {r3, r4, r5, r6, r7, pc}
 80040a8:       40023800        andmi   r3, r2, r0, lsl #16
 80040ac:       40022000        andmi   r2, r2, r0
 80040b0:       40020400        andmi   r0, r2, r0, lsl #8
 80040b4:       40003800        andmi   r3, r0, r0, lsl #16
 80040b8:       40026058        andmi   r6, r2, r8, asr r0
 80040bc:       00030416        andeq   r0, r3, r6, lsl r4
 80040c0:       08008ec8        stmdaeq r0, {r3, r6, r7, r9, sl, fp, pc}
 80040c4:       2000c2d0        ldrdcs  ip, [r0], -r0
 80040c8:       00030456        andeq   r0, r3, r6, asr r4
 80040cc:       40026070        andmi   r6, r2, r0, ror r0
 80040d0:       e000e100        and     lr, r0, r0, lsl #2

1 个答案:

答案 0 :(得分:1)

在启用外设时钟的任何操作后,是的,STM32F4和STM都有一个错误。 F7微型。需要一点延迟

我通常会使用__dsb();。您可以提供此延迟(它在勘误表中描述,但不是针对所有受影响的uC(实际上我没有找到任何未受影响的F4或F7))。我个人在F4勘误表中使用了dsb,它让我想起了这个错误。

  

2.1.5 RCC外设时钟使能后的延迟说明RCC外设时钟使能与有效之间的延迟   应考虑外围设备以便进行管理   外设读/写寄存器。这种延迟取决于   外设映射:•如果外设映射在AHB上:延迟   应该等于2个AHB周期。 •如果外围设备映射到APB:   延迟应等于1 +(AHB / APB预分频器)周期。   解决方法   1.使用DSB指令停止Cortex®   -M4 CPU管道直到指令完成。   2.在RCC使能双向写入和外设寄存器写入之间插入“n”个NOP(对于AHB外设,n = 2,n = 1 + AHB /   APB外设的APB预分频器)。   3.或者在启用外设时钟后立即从相应的寄存器中插入虚拟读操作。