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 レジスタに対してアトミックな読み取りと書き込みを行う可能性はありますか?
- 別の適切な解決策はありますか?
ちなみに、同様の質問がありますが、それは複数のプロセスまたはコアによるアクセスの保護に関するものであり、ソフトウェアとハードウェアによる同時アクセスの保護に関するものではありません。