跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YTM32B1M系列
  4. SDK的RTC驱动对闹钟的处理不完善导致频繁进中断并看门狗复位问题

SDK的RTC驱动对闹钟的处理不完善导致频繁进中断并看门狗复位问题

已定时 已固定 已锁定 已移动 YTM32B1M系列
4 帖子 3 发布者 6 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • oneiotworldO 离线
    oneiotworldO 离线
    oneiotworld
    编写于 最后由 oneiotworld 编辑
    #1

    在SDK的RTC驱动存在一个BUG,公司生产项目有遇到,最近发现新版本SDK还没修复。
    主要问题是RTC_DRV_IRQHandler中没有对alarm触发且alarmConfig为NULL的情况做处理,然后会一直触发RTC中断,最终导致MCU看门狗复位(复位也不会恢复,会一直持续复位)。

    复现流程:

    • 正常上电
    • 设置RTC闹钟
    • 在RTC闹钟触发前软复位MCU(会导致alarmConfig变为NULL)
    • 到RTC闹钟时间时会一直进RTC中断
    • 看门狗复位

    代码位置:

    void RTC_DRV_IRQHandler(uint32_t instance)
    {
        DEV_ASSERT(instance < RTC_INSTANCE_COUNT);
    
        uint32_t tempSeconds;
        /* Get the alarm configuration */
        rtc_alarm_config_t *alarmConfig = g_rtcRuntimeConfig[instance].alarmConfig;
        /* Get the fault interrupt configuration */
        const rtc_overflow_config_t *const overflowConfig = g_rtcRuntimeConfig[instance].overflowConfig;
    
        /* Check if an alarm has occurred */
        if (RTC_GetTimeAlarmFlag(g_rtcBase[instance]) == true)
        {
            /* If the alarm interrupt configuration has been defined process the
             * alarm IRQ
             */
            if ((alarmConfig != NULL))
            {
                /* If recurrence is enabled modify the alarm register to the next
                 * alarm.
                 */
                if ((alarmConfig->numberOfRepeats > 0UL) || (alarmConfig->repeatForever == true))
                {
                    /* Get current time */
                    tempSeconds = RTC_GetTimeSecondsRegister(g_rtcBase[instance]);
                    /* Current time is incremented with the repetition value */
                    tempSeconds += alarmConfig->repetitionInterval - 1UL;
                    /* Set new value to trigger the alarm */
                    RTC_SetTimeAlarmRegister(g_rtcBase[instance], tempSeconds);
    
                    g_rtcRuntimeConfig[instance].isAlarmTimeNew = true;
                    /* If the alarm repeats forever, set number of repeats to 0
                     * to avoid an accidental trigger of the core overflow flag
                     */
                    alarmConfig->numberOfRepeats = (alarmConfig->repeatForever == false) ? (alarmConfig->numberOfRepeats -
                                                                                            1UL) : 0UL;
                } else
                {
                    /* If the alarm does not repeat, write 0 to ALM to clear the
                     * alarm flag.
                     */
                    RTC_SetTimeAlarmRegister(g_rtcBase[instance], 0UL);
                    /* Set the internal variable which indicates that a new alarm is enabled to false */
                    g_rtcRuntimeConfig[instance].isAlarmTimeNew = false;
                }
                /* If the user has defined a callback, call it */
                if (alarmConfig->rtcAlarmCallback != NULL)
                {
                    alarmConfig->rtcAlarmCallback(alarmConfig->callbackParams);
                }
            }
            // 这里else 分支没有处理
        }
            /* If the IRQ is not caused by the alarm then call the user callback if
             * defined.
             */
        else if (overflowConfig != NULL)
        {
            if (overflowConfig->rtcOverflowCallback != NULL)
            {
                /* Call the RTC interrupt callback function with callback parameter */
                overflowConfig->rtcOverflowCallback(overflowConfig->callbackParams);
            }
        } else
        {
            /* Do nothing*/
        }
    }
    

    修复方案:
    补充else分支,清除RTC闹钟

    diff --git a/platform/drivers/src/rtc/rtc_driver.c b/platform/drivers/src/rtc/rtc_driver.c
    index 439a400..512f49a 100644
    --- a/platform/drivers/src/rtc/rtc_driver.c
    +++ b/platform/drivers/src/rtc/rtc_driver.c
    @@ -736,6 +736,14 @@ void RTC_DRV_IRQHandler(uint32_t instance)
                 {
                     alarmConfig->rtcAlarmCallback(alarmConfig->callbackParams);
                 }
    +        } else
    +        {
    +            /* If the alarm interrupt configuration is NULL (it may happen if the
    +             * alarm is not arrived but the chip has been reset by any reason),
    +             * So we should write 0 to ALM to clear the alarm flag */
    +            RTC_SetTimeAlarmRegister(g_rtcBase[instance], 0UL);
    +            /* Set the internal variable which indicates that a new alarm is enabled to false */
    +            g_rtcRuntimeConfig[instance].isAlarmTimeNew = false;
             }
         }
             /* If the IRQ is not caused by the alarm then call the user callback if
    
    1 条回复 最后回复
    0
    • qinzhaoQ 离线
      qinzhaoQ 离线
      qinzhao YunTu
      编写于 最后由 编辑
      #2

      RTC的寄存器在不断电复位是会保持的,也就是说会继续之前的配置工作,demo的使用方法是先deinit,再init

      oneiotworldO 1 条回复 最后回复
      0
      • oneiotworldO 离线
        oneiotworldO 离线
        oneiotworld
        回复了qinzhao 最后由 编辑
        #3

        qinzhao 您说的deinit再init是在MCU启动时初始化吧,但是如果中断是在那之前触发(应该有概率出现?),是否也一样会一直进中断,之前也和FAE讨论过这个问题。所以我们的最终方案就是加了else分支,在alarmConfig 为NULL时直接清除寄存器的alarm配置

        1 条回复 最后回复
        0
        • majorM 离线
          majorM 离线
          major YunTu
          编写于 最后由 编辑
          #4

          这个问题出现的原因是RTC不同中断共用相同向量号导致函数未注册时候被异常触发,可以通过如下方式进行修复:

          image.png
          改问题在新版本中修复(新版本尚在发布流程中)

          1 条回复 最后回复
          0

        • 云途开发生态介绍

          快速上手云途开发生态

        • 云途论坛规则/Yuntu Forum Rules

          发帖前请查看

        • YT CONFIG TOOL调查问卷

          帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

        • can
          24
          demo
          20
          uds
          13
          lin stack
          12
          md14
          6
          fbl
          5
          yt-link
          5
          adc模块
          4
          Online Users
          • 登录

          • 登录或注册以进行搜索。
          • 第一个帖子
            最后一个帖子
          0
          • 版块
          • 最新
          • 标签
          • 热门