工具/软件:TI C/C++编译器
您好,
以下是我的客户看到的内容。 请告诉我。
我们在启用FPU支持后发现了一个特殊的症状:我们的PWM模块之一不再产生其方波输出。
经过一些调试后,我们发现在初始化时写入EPwm1Regs.TBCTL时,ePWM1的时钟仍处于关闭状态。 似乎当我们的代码使用C28x+FPU编译时,编译器正在重新排序对CpuSysRegs和EPwm1Regs的访问,尽管这两个结构都被声明为易失性。
下面是一个最小的示例(删除了无关代码),用于演示此重新排序。 下面粗体的寄存器在生成的装配体中以相反顺序写入。 以下装配体输出来自15.12 .3.LTS,但我们也在16.9 .1.LTS上看到此问题。
void PwmDriver_init(void)
{
const结构etps_bits regETPS ={
.INTPRD = 0U,
.INTCNT = 0U,
.INTPSSEL = 0U,
.SOCPSSEL = 1U,
.SOCAPRD = 0U,
.SOCACNT = 0U,
.SOCBPRD = 0U,
.SOCBCNT = 0U
};
const结构tbctl_bits regTBCTL ={
.CTRMODE =(uint16_t) TB_COUNT_UP,
.PHSEN =(uint16_t) TB_DISABLE,
.PRDLD = 1U,
.SYNCOSEL =(uint16_t) TB_CTR_ZERO,
.SWFSYNC = 0U,
.HSPCLKDIV = 0U,
.CLKDIV = 0U,
.PHSDIR = 0U,
.FREE_SOFT = 3U,
};
ASM (" EALLOW");
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0U;
EPwm4Regs.etps.bit = regETPS;
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1U;
EPwm1Regs.TBCTL.bit = regTBCTL;
ASM (" EDIS");
}
compiler_opts --abi=coffi --float_support=fpu32 --hll_source=on --mem_model:code=flat --mem_model:data=large --object_format=coff --silit_version=28 --symdebug:dwarf --symuebug:dwarf_version=3 --t0_support
_PwmDriver_init:
;* AR4 分配给$O$C1
;***695------------------ ASM (" EALLOW");
;***696 --------------------------- *((C1美元 =&CpuSysRegs)+35L)&= 0xFFBU;
;***697 ---------------------- *(&EPwm4Regs+166L)= 32U;
;***698 -------------------------------------------------- *(volatile struct PCLKCR2_bits *) C1美元+38L)|= 1U;
;***699 --------------------------- &EPwm1Regs = 0xc018u;
;***700 --------------------------- ASM (" EDIS");
;***--------------- 返回;
EALLOW
MOVW DP,#_EPwm1Regs.
MOVL XAR4,#_CpuSysRegs
MOV @_EPwm1Regs,#4.9176万
MOVL XAR5,XAR4
MOVW DP,#_EPwm4Regs+166
MOVB @_EPwm4Regs+166,#32,UNC
ADDB XAR4,#38
ADDB XAR5,#35
和 *+ XAR5[0],#0xFFFb
或 *+ XAR4[0],#0x0001
EDIS
SPM #0
LRETR
几个问题:
- 为什么编译器不尊重CpuSysRegs/EPwm1Regs的易失性? 如果这是编译器错误,请告知修复时间。
作为 临时解决方法,我们在写入之间插入了一个内嵌汇编NOP。 这是一种可靠的解决方法,还是有更好的解决方法?
- 是否有办法识别我们的代码中受此重新排序危险影响的其他易失性写入?