1

ST2M32F103REY Cortex M3 で、汎用タイマーのオーバーフロー、比較一致、およびキャプチャ機能を同時に使用したいと考えています。CC1 はコンペアマッチとして設定され、CC3 はキャプチャとして設定されます。IRQ ハンドラは次のようになります。

void TIM3_IRQHandler(void) {
  if(TIM3->SR & TIM_SR_UIF){
      TIM3->SR &= ~TIM_SR_UIF;
      // do something on overflow
  }

  if(TIM3->SR & TIM_SR_CC1IF) {
     TIM3->SR &= ~TIM_SR_CC1IF;
     // do something on compare match
  }

  if(TIM3->SR & TIM_SR_CC3IF) {
     TIM3->SR &= ~TIM_SR_CC3IF;
     // do something on capture
  }
}

原則としては問題なく動作しますが、一部をスキップしているように見えることがあります。私の理論では、IRQ フラグをリセットする操作がTIM3->SR &= ~TIM_SR_UIFアトミックではないため、たとえば、ロードとストアの間に発生する TIM_SR_CC1IF が上書きされる可能性があるためです。

※命令の分解は以下の通り

8012e02:    8a13        ldrh    r3, [r2, #16]
8012e06:    f023 0301   bic.w   r3, r3, #1
8012e0a:    041b        lsls    r3, r3, #16
8012e0c:    0c1b        lsrs    r3, r3, #16
8012e0e:    8213        strh    r3, [r2, #16]
  • これはもっともらしいですか?IRQハンドラの実行中にTIM3→SRレジスタの内容が変化することはありますか?
  • TIM3->SR レジスタに対してアトミックな読み取りと書き込みを行う可能性はありますか?
  • 別の適切な解決策はありますか?

ちなみに、同様の質問がありますが、それは複数のプロセスまたはコアによるアクセスの保護に関するものであり、ソフトウェアとハ​​ードウェアによる同時アクセスの保護に関するものではありません。

4

1 に答える 1