セマフォに問題があります。ISR 内で呼び出された SemPost が有効でない場合があるようです。
私のアプリケーションは Micrimum UCOS III に基づいており、ターゲット プラットフォームは Microsemi Smartfusion2 SoC (Cortex-M3) に基づいています。私のアプリケーションは 2 つのタスク (A と B) で構成されていますが、問題が発生したときにアクティブになるのは 1 つだけです (もう 1 つのタスクはセマフォでスタックしています)。
問題は、アクティブなタスク (タスク A と呼びましょう) が次のアクションを実行するときに発生します。
- 割り込みがトリガーされた後に操作を開始するためにいくつかのレジスタに書き込みます
- 100ミリ秒のタイムアウトを設定して、セマフォ(Sem Aと呼びましょう)でOSSemPendを作成して操作の完了を待ちます。
- OSSemPend 呼び出しが正常に終了したかどうか、またはタイムアウトが発生したかどうかを確認します
割り込みがトリガーされると、タイムアウト前にセマフォのロックを解除するために、関連する ISR が Sem A で SemPost を作成します。
問題が発生すると、OSSemPend は OS_ERR_TIMEOUT を返します。この問題は非常にまれにしか見られません。
私は確信しています:
- 開始操作 (ポイント 1 を参照) が与えられ、操作が開始されます。
- 割り込みがトリガーされ、Sem A の OSSemPost が実行されます。
- 割り込みは、開始から 500 マイクロ秒未満 (つまり、1 ミリ秒未満) 後にトリガーされます。
コードは適切に記述されていますか? ISR 内でのセマフォの使用に制限はありますか? 誰かが私を助けることができますか?ありがとうございました
コードの簡略版を同封します
/*
* the interrupt handler, triggered at the end of the operation
*/
void FabricIrq2_IRQHandler(void)
{
OS_ERR os_err;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
/*
* write in a register of the ip core generating the interrupt in order
* to reset the interrupt
*/
OSSemPost(&Sem_A, OS_OPT_POST_ALL, &os_err);
OSSemSet(&Sem_Tx, 0, &os_err); /* not relevant for this problem */
CPU_CRITICAL_EXIT();
}
void startOp()
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
/*
* write in an ip core register in order to start operation
*/
CPU_CRITICAL_EXIT();
}
/*
* task a **partial**
*/
uint8_t task_a(void)
{
uint8_t ret;
OS_ERR os_err;
startOp();
OSSemPend(&Sem_A, (OS_TICK)10, OS_OPT_PEND_BLOCKING, NULL, &os_err);
switch (os_err){
/* manage errors*/
}
return ret;
}