【问题标题】:Re-issue SysTick interrupt重新发出 SysTick 中断
【发布时间】:2021-01-27 21:34:49
【问题描述】:

我有一个SysTick中断每秒触发4次任务切换,如下图。

void SysTick_Handler(void) {
  SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV 
}

main 中的任务偶尔会通过其中一个 UART 输出一些消息,并且为了确保它们具有独占 I/O 访问权限,输出例程受到由 LDREX 和 STREX 设置的互斥锁保护。代码在 90% 以上的情况下都能完美运行。

但是,这种保护的一个副作用似乎是,在设置互斥锁期间发生 SysTick 时,不会发生任务切换,并且当时正在运行的任务将继续运行,直到下一次任务切换。

有没有办法在 10 毫秒后再次触发 SysTick,并一直这样做,直到当前正在运行的任务清除互斥锁?例如:

void SysTick_Handler(void) {
  if (mutex) {
    // set SysTick to trigger again in 10 ms 
  } else {
    SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV 
  } 
}

如果是,如何。

TIA

【问题讨论】:

    标签: timer arm interrupt cortex-m


    【解决方案1】:

    在您的互斥锁释​​放函数中设置 SysTick、PendSV、SVCall 或其他挂起的中断。

    如果您想避免不必要的中断成本,您可以在 systick 处理程序中设置一个原子标志,并在互斥锁释放函数中检查它,这样只有在您错过了计划的运行时才会触发中断。

    【讨论】:

      【解决方案2】:

      我按照 Tom V 的建议实施了一个解决方案,它就像一个魅力!谢谢!!

      关键部分:

      void SysTick_Handler(void)
      {
          if (mutex > 0) {
              sigint++; 
          } else {
              sigint = 0;
              SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV to pending
          }
      }
      

      和:

      // in mutex release
      if (sigint) {
          __asm(" CPSID i");  
          sigint = 0; 
          (*systick_ptr)(); 
          __asm(" CPSIE i"); 
      } 
      

      但是,请注意,此解决方案确实具有至少一个“功能”:如果此代码丢失了 1 个以上的中断,它将仅构成一个,但在我的情况下,丢失多个中断是极不可能的。

      【讨论】:

        猜你喜欢
        • 2021-05-28
        • 2019-06-23
        • 2017-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-26
        • 2021-12-30
        • 1970-01-01
        相关资源
        最近更新 更多