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.

[参考译文] TMS320F28075:异步读取 EcapxRegs.CAPy 至 eCAP 中断时的竞态条件

Guru**** 2551110 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/894083/tms320f28075-a-race-condition-when-reading-ecapxregs-capy-asynchronously-to-ecap-interrupts

器件型号:TMS320F28075

您好!

我的客户希望使用计时器 ISR 函数(@1sec)并读取最新的 EcapxRegs.CAPy 值。

我们担心 CPU 读取和 EcapxRegs.CAPy 更新之间的竞争条件、因为 CPU 读取与 ECAP 事件不同步。

我们害怕从寄存器中读取错误或未正确更新的值。  

问题1. 请告知您是否有可能出现比赛情况?

问题2. 如果是、您能建议解决方案吗? 我想知道 CAPLDEN 位将起作用。

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

    您好!

    是的、我认为可能存在竞态条件、因为传入信号和 CPU ISR 之间没有同步。 但是、如果客户仍然有兴趣每隔1秒读取一次最新的 CAPy 值、则 ECAP 的单次触发模式可能会很有用、而不是连续捕获模式。 因此、我建议可以在计时器 ISR 函数内(@1sec)触发一次性 ECAP 捕获、然后捕获 ECAP 事件可以触发另一个可读取值的 ISR。 代码序列如下所示:

    //
    //定时器 ISR (@1sec)
    //
    _interrupt void timerISR (void)
    {
    //
    //启动 eCAP
    //
    eCAP_rearm (eCAP1_base); 
    
    //
    //如果有任何其他代码
    //
    
    //
    //确认此中断以从组1接收更多中断
    //
    interrupt_clearACKGroup (interrupt_ACK_Group1);
    } 


    //
    // eCAP 1 ISR
    //
    _interrupt void ecap1ISR (void)
    {
    //
    //读取捕获的值
    //
    cap1Count = ECAP_getEventTimeStamp (ECAP1_base、ECAP_EVENT_1);
    cap2Count = ECAP_getEventTimeStamp (ECAP1_base、ECAP_EVENT_2);
    
    //
    //对捕获的数据进行任何其他处理
    //
    
    //
    //清除更多中断的中断标志。
    //
    ECAP_clearInterrupt (ECAP1_base、ECAP_ISR_SOURCE、CAPTURE_EVENT_2);
    ECAP_clearGlobalInterrupt (ECAP1_base);
    
    //
    //确认组中断以获得更多中断。
    //
    interrupt_clearACKGroup (interrupt_ack_group4);
    } 

    //
    // initECAP -配置 eCAP
    //
    void initECAP ()
    {
    //
    //禁用,清除所有捕获标志和中断
    //
    ECAP_disableInterrupt (ECAP1_base、
    (ECAP_ISR_SOURC_CAPTURE_EVENT_1 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_2 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_3 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_4 |
    ECAP_ISR_SOURC_COUNTER_OVERflow |
    ECAP_ISR_SOURC_COUNTER_PERIOD |
    eCAP_ISR_SOURC_COUNTER_COMPARE);
    ECAP_clearInterrupt (ECAP1_base、
    (ECAP_ISR_SOURC_CAPTURE_EVENT_1 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_2 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_3 |
    ECAP_ISR_SOURC_CAPTURE_EVENT_4 |
    ECAP_ISR_SOURC_COUNTER_OVERflow |
    ECAP_ISR_SOURC_COUNTER_PERIOD |
    eCAP_ISR_SOURC_COUNTER_COMPARE);
    
    //
    //禁用 CAP1-CAP4寄存器加载
    //
    ECAP_disableTimeStampCapture (ECAP1_BASE);
    
    //
    //配置 eCAP
    //启用捕捉模式。
    //单次触发模式,在事件2停止捕捉。
    //将事件的极性设置为上升沿、下降沿。
    //将捕捉设置为时间差模式。
    //启用 eCAP 模块。
    //启用中断。
    //
    ECAP_STOPCounter (ECAP1_BASE);
    ECAP_enableCaptureMode (ECAP1_BASE);
    
    ECAP_setCaptureMode (ECAP1_base、ECAP_One_SHOT_CAPTURE_MODE、ECAP_EVENT_2); 
    
    ECAP_setEventPolarity (ECAP1_base、ECAP_EVENT_1、ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity (ECAP1_base、ECAP_EVENT_2、ECAP_EVNT_RISTING _EDGE);
    
    ECAP_enableCounterResetOnEvent (ECAP1_base、ECAP_EVENT_2);
    eCAP_enableLoadCounter (ECAP1_base);
    
    ECAP_startCounter (ECAP1_base);
    ECAP_enableTimeStampCapture (ECAP1_BASE);
    eCAP_rearm (eCAP1_base);
    
    ECAP_enableInterrupt (ECAP1_base、ECAP_ISR_SOURCE、CAPTURE_EVENT_2);
    } 

    希望此配置有助于解决该问题。 如果我的回复回答了您的问题、请点击位于我帖子底部的"我的问题已解决"按钮。

    此致

    Himanshu

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

    Himanshu、

    非常感谢。 非常清楚。