This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28386D:软件嵌套导致的数学运算错误

Guru**** 2209720 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1331200/tms320f28386d-error-in-math-operation-due-to-sw-nesting

器件型号:TMS320F28386D

您好、C2000专家!

我正在编写用于电机控制的裸机代码。

我有与定时器1和定时器2触发的两个中断嵌套相关的问题。

具体而言、ISR2由计时器2触发、ISR1由计时器1触发。  

首先, 让我澄清一下 两个中断的嵌套效果很好:我可以在 ISR2中嵌套 ISR1。

但是、我注意到如果 ISR1在 数学运算期间内嵌套 ISR2、则会出现一些问题。

如下图所示:  

VADC =-1.5;

IPCA=vADC/16.6664;

 

预期结果 IADC =-0.09

已获得的结果 IADC =-0.0312

为什么会发生这种情况?

很明显、我注意到、  如果 我在指令  IADC 执行期间禁用嵌套、则不会出现此问题;IADC = vADC/16.6664。

例如、

IER = 0x0;//禁用嵌套

 IPCA=vADC/16.6664;

IER = 0x2000;//启用 嵌套

另一方面,如果我用 IPCA=vADC*0.06000096 (实际上0.06000096是16.6664的倒数)替换前面的等式,问题就不会发生。

我愿意做进一步的说明。

等待您的帮助...

此致、

贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Benito、

    您是否启用了任何优化? 如果是、禁用它们时是否会出现问题? 如果您在程序中有问题的位置放置了一个断点、您能否检查用于条件/方程的所有变量的值?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的先生: Amir,Omer

    感谢您的反馈

    您是否打开了任何优化? 如果是,则禁用它们时是否会出现问题?

    否、我尚未启用编译器优化  

    如果您在程序中有问题的位置放置一个断点,您可以检查用于条件/方程的所有变量的值吗?

    就在这里。  

    您可以看到、第583行(绿线)有一个断点。

    左侧(选项卡表达式)显示了变量:

    VADC 实际上等于-1.5。

    空间碎片协委会=-1.5/16.6664=-0.03125. 这是错误的结果。 正确结果应为-0.09。

    如果我修改代码以禁用嵌套、同时微控制器执行计算 IADC = vADC/16.6664、不会发生这个错误。

    同样,如果我 用等效的乘法替换除法(例如 IADC = vADC*0.060),也不会发生此错误。

    我可作进一步澄清。

    此致、

    贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Benito、

    类似地,如果我 用等效的乘法替换除法(例如 IADC = vADC*0.060),则不会发生此错误。

    您能否共享 以下汇编代码的屏幕截图:

    1. 启用嵌套
    2. 禁用嵌套
    3. 乘法而不是除法

    是否有任何其他修改 vADC 或 IADC 的位置? 这些地方中是否有一个像中断一样的地方有可能发生在 线路 IADC = vADC/16.6664并且达到条件的时间内?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的先生: Amir,Omer

    公式的汇编代码、该公式使用 乘法

     

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    761F002C MOVW DP, #0x2c
    088d08: 0E00 MOVU ACC, @0x0
    088d09: BDA90F12 MOV32 R0H, @ACC
    088d0b: 7700 NOP
    088d0c: E801F839 MOVIZ R1, #0x3f07
    088d0e: E80852A9 MOVXI R1H, #0xa55
    088d10: E904CBE9 MOVIX R1L, #0x997d
    088d12: E6870000 UI32TOF64 R0, R0H
    088d14: E90F5659 MOVXI R1L, #0xeacb
    088d16: E7800040 MPYF64 R0, R0, R1
    088d18: E801FDB9 MOVIZ R1, #0x3fb7
    088d1a: E80852A9 MOVXI R1H, #0xa55
    088d1c: E904CBE9 MOVIX R1L, #0x997d
    088d1e: E90F5659 MOVXI R1L, #0xeacb
    088d20: E7A00040 SUBF64 R0, R0, R1
    088d22: E8020699 MOVIZ R1, #0x40d3
    088d24: E80C4001 MOVXI R1H, #0x8800
    088d26: E9000001 MOVIX R1L, #0x0
    088d28: E9080001 MOVXI R1L, #0x0
    088d2a: E7800040 MPYF64 R0, R0, R1
    088d2c: 7700 NOP
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    下面、使用德州仪器 TI.com.cn 分部:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    088d0a: 761F002C MOVW DP, #0x2c
    088d0c: 0E00 MOVU ACC, @0x0
    088d0d: BDA90F12 MOV32 R0H, @ACC
    088d0f: 7700 NOP
    088d10: E802069C MOVIZ R4, #0x40d3
    088d12: E80C4004 MOVXI R4H, #0x8800
    088d14: E8020183 MOVIZ R3, #0x4030
    088d16: E6870000 UI32TOF64 R0, R0H
    088d18: E9000004 MOVIX R4L, #0x0
    088d1a: E94FD200 MPYF64 R0, #0x3f48, R0
    088d1c: E80D54CB MOVXI R3H, #0xaa99
    088d1e: E90185F3 MOVIX R3L, #0x30be
    088d20: E9AFFE02 ADDF64 R2, #0xbff8, R0
    088d22: E9086F6B MOVXI R3L, #0xded
    088d24: E9080004 MOVXI R4L, #0x0
    088d26: E5BE PREDIVF64 R0H, R2, R1, R3
    088d27: E566 SUBC3F64 R2, R1, R3
    088d28: E566 SUBC3F64 R2, R1, R3
    088d29: E566 SUBC3F64 R2, R1, R3
    088d2a: E566 SUBC3F64 R2, R1, R3
    088d2b: E566 SUBC3F64 R2, R1, R3
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    下面、托管乘法/除法的函数的代码:  

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    E20204BD MOV32 *SP++, R4L
    0875d4: E20304BD MOV32 *SP++, R4H
    0875d6: E20205BD MOV32 *SP++, R5L
    0875d8: E20305BD MOV32 *SP++, R5H
    0875da: E20206BD MOV32 *SP++, R6L
    0875dc: E20306BD MOV32 *SP++, R6H
    0875de: E20207BD MOV32 *SP++, R7L
    0875e0: E20307BD MOV32 *SP++, R7H
    0875e2: FE0A ADDB SP, #10
    647 i1Rout = 0.0; i1Sout = 0.0; i1Tout = 0.0;
    0875e3: E590 ZERO R0
    0875e4: E2020046 MOV32 *-SP[6], R0L
    0875e6: E2030044 MOV32 *-SP[4], R0H
    0875e8: E202004A MOV32 *-SP[10], R0L
    0875ea: E2030048 MOV32 *-SP[8], R0H
    0875ec: E597 ZERO R7
    648 vRSout = 0.0; vSTout = 0.0; vTRout = 0.0;
    0875ed: E596 ZERO R6
    0875ee: E595 ZERO R5
    0875ef: E594 ZERO R4
    650 indWin++;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    是否有任何其他位置修改 vADC 或 IADC? 这些地方中是否有一个像中断一样的地方可能发生在 线路 IADC = vADC/16.6664且达到条件的时间内?

    我进行了此检查、因为出现了问题。

    没有其它修改 vADC 或 IADC 的点。  

    感谢您的支持。

    贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Benito、

    从效率和解决问题的角度来看、我想说您可能应该使用乘法而不是除法:

    您为嵌套而附加的代码不会显示在 getAdcc4函数中 IADC 和 vADC 正在修改的位置、请仅限制您附加的汇编、以便我可以进行适当的一对一比较。  你有一个使用乘法的权变措施、所以你可以继续这样做、但是如果你想要调试带有嵌套中断的除法、那么我将需要这个信息。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Omer:

    根据您的要求、我在此处附上  getAdcc4函数在三种情况下的汇编代码:

    1)乘法+嵌套启用(无错误)

    2) 2)除法+嵌套启用(错误)

    3) 3)除法+嵌套禁用(无错误)

    1) 1)在下方   使用乘法的 getAdcc4函数

    C 函数  

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    signed int getAdcc4(unsigned int k_trasd, unsigned int k)
    {
    static float vADC = 0;
    static float iADC = 0;
    static float iLem = 0;
    static unsigned int err = 0;
    vADC = -1.5;
    if ((vADC > -1.45) || (vADC < -1.55))
    err++;
    iADC = vADC*0.06000096;
    if ((iADC > -0.09) || (iADC < -0.1))
    err++;
    iLem = (k*k_trasd*iADC)+0.5;
    if (iLem > -1700)
    err++;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    汇编代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    getAdcc4():
    FE04 ADDB SP, #4
    08b333: 9744 MOV *-SP[4], AH
    08b334: 9643 MOV *-SP[3], AL
    575 vADC = -1.5;
    08b335: E805FE00 MOVIZ R0, #0xbfc0
    08b337: 761F02A4 MOVW DP, #0x2a4
    08b339: E203001C MOV32 @0x1c, R0H
    576 if ((vADC > -1.45) || (vADC < -1.55))
    08b33b: E805FFB9 MOVIZ R1, #0xbff7
    08b33d: E8099999 MOVXI R1H, #0x3333
    08b33f: E28C001C F32TOF64 R0, @0x1c
    08b341: E9019999 MOVIX R1L, #0x3333
    08b343: E9099999 MOVXI R1L, #0x3333
    08b345: E6980008 CMPF64 R0, R1
    08b347: AD14 MOVST0 NF,ZF
    08b348: 620F SB $C$L104, GT
    08b349: E805FFC1 MOVIZ R1, #0xbff8
    08b34b: E28C001C F32TOF64 R0, @0x1c
    08b34d: E80E6661 MOVXI R1H, #0xcccc
    08b34f: E9066661 MOVIX R1L, #0xcccc
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    2) 2)在下方   使用除法的 getAdcc4函数

    C 函数  

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    signed int getAdcc4(unsigned int k_trasd, unsigned int k)
    {
    static float vADC = 0;
    static float iADC = 0;
    static float iLem = 0;
    static unsigned int err = 0;
    vADC = -1.5;
    if ((vADC > -1.45) || (vADC < -1.55))
    err++;
    iADC = vADC/16.6664;
    if ((iADC > -0.09) || (iADC < -0.1))
    err++;
    iLem = (k*k_trasd*iADC)+0.5;
    if (iLem > -1700)
    err++;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    汇编代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    getAdcc4():
    08ae58: FE04 ADDB SP, #4
    08ae59: 9744 MOV *-SP[4], AH
    08ae5a: 9643 MOV *-SP[3], AL
    575 vADC = -1.5;
    08ae5b: E805FE00 MOVIZ R0, #0xbfc0
    08ae5d: 761F02A4 MOVW DP, #0x2a4
    08ae5f: E203001C MOV32 @0x1c, R0H
    576 if ((vADC > -1.45) || (vADC < -1.55))
    08ae61: E805FFB9 MOVIZ R1, #0xbff7
    08ae63: E8099999 MOVXI R1H, #0x3333
    08ae65: E28C001C F32TOF64 R0, @0x1c
    08ae67: E9019999 MOVIX R1L, #0x3333
    08ae69: E9099999 MOVXI R1L, #0x3333
    08ae6b: E6980008 CMPF64 R0, R1
    08ae6d: AD14 MOVST0 NF,ZF
    08ae6e: 620F SB $C$L104, GT
    08ae6f: E805FFC1 MOVIZ R1, #0xbff8
    08ae71: E28C001C F32TOF64 R0, @0x1c
    08ae73: E80E6661 MOVXI R1H, #0xcccc
    08ae75: E9066661 MOVIX R1L, #0xcccc
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    3)在下面    禁用除法和嵌套的 getAdcc4函数

    C 函数  

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    signed int getAdcc4(unsigned int k_trasd, unsigned int k)
    {
    static float vADC = 0;
    static float iADC = 0;
    static float iLem = 0;
    static unsigned int err = 0;
    vADC = -1.5;
    if ((vADC > -1.45) || (vADC < -1.55))
    err++;
    IER = 0;
    iADC = vADC/16.6664;
    IER = M_INT13 ;
    if ((iADC > -0.09) || (iADC < -0.1))
    err++;
    iLem = (k*k_trasd*iADC)+0.5;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    汇编代码

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    getAdcc4():
    08ae58: FE04 ADDB SP, #4
    08ae59: 9744 MOV *-SP[4], AH
    08ae5a: 9643 MOV *-SP[3], AL
    575 vADC = -1.5;
    08ae5b: E805FE00 MOVIZ R0, #0xbfc0
    08ae5d: 761F02A4 MOVW DP, #0x2a4
    08ae5f: E203001C MOV32 @0x1c, R0H
    576 if ((vADC > -1.45) || (vADC < -1.55))
    08ae61: E805FFB9 MOVIZ R1, #0xbff7
    08ae63: E8099999 MOVXI R1H, #0x3333
    08ae65: E28C001C F32TOF64 R0, @0x1c
    08ae67: E9019999 MOVIX R1L, #0x3333
    08ae69: E9099999 MOVXI R1L, #0x3333
    08ae6b: E6980008 CMPF64 R0, R1
    08ae6d: AD14 MOVST0 NF,ZF
    08ae6e: 620F SB $C$L104, GT
    08ae6f: E805FFC1 MOVIZ R1, #0xbff8
    08ae71: E28C001C F32TOF64 R0, @0x1c
    08ae73: E80E6661 MOVXI R1H, #0xcccc
    08ae75: E9066661 MOVIX R1L, #0xcccc
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    感谢您的支持!

    此致、

    贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Benito、

    是否可以尝试用全局浮点变量(volatile 和非 voltail)和宏(即#define)替换16.6664值? 我想看看这是否与操作数是一个常数相关。

    如果结果相同、我认为这可能与浮点运算之间所需的 NOP 相关。 在单步执行代码时、是否可以复制情况2 (启用嵌套的除法)中的问题?  如果是、您能看到浮点寄存器(即 R0、R1、R2和 R3)加载了哪些值、并将其与情况3进行比较吗? 这些值必须不同、但大会中没有任何内容向我表明这一点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的先生: Amir,Omer  

    您能尝试用全局浮点变量(volatile 和非 voltail)和宏(即#define)替换16.6664值吗? 我想看看这是否与操作数是一个常量相关。

    我在调试开始时进行了此测试、并验证了是否发生了错误。

    然后我用常数值16.6664...替换了宏或变量

    。 在单步执行代码时、是否可以复制情况2 (启用嵌套的除法)中的问题?  如果是、您能看到浮点寄存器(即 R0、R1、R2和 R3)加载了哪些值、并将其与情况3进行比较吗?

    下面我附上了您建议的测试结果。

    启用嵌套的除法  

    下面、 如果 没有发生错误、FP 寄存器会在除法之后的状态:

    如下所示、  发生错误时 FP 寄存器会在除法之后的状态

    禁用嵌套的除法  

    下面是 fp 寄存器的状态、然后是除法。 在 这种情况下、不会发生错误。

    如果您需要进一步的数据、请告诉我。

    感谢您的支持、

    贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Benito、

    是否可以向我发送您项目的压缩版本? 此调试的其余部分需要单步执行汇编代码、并观察 R0-R3寄存器的加载方式  之前 通过除法了解这些值为何不同。 如果您无法发送工程、则需要执行此操作并尝试找出寄存器值差异的根本原因。 当您找到  为什么 值是不同的、您可以在此处发布、我可以进一步帮助您。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的先生: Amir,Omer

    很遗憾、我 无法 发送项目的版本。

    我将尝试监控寄存器 R0-R3。

    贝尼托

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Benito、

      欧默尔本周不在办公室。 我们将等待您的监控寄存器 R0-R3的结果。