我的信号量有问题,有时在 ISR 中调用的 SemPost 似乎无效。
我的应用程序基于 Micrimum UCOS III,目标平台基于 Microsemi Smartfusion2 SoC (Cortex-M3)。我的应用程序包含两个任务(A 和 B),但是当问题发生时只有一个处于活动状态(另一个被卡在信号量上)。
当活动任务(我们称之为任务 A)执行以下操作时会出现问题:
- 写入某个寄存器以在触发中断后开始操作
- 等待操作完成在 semafore 上创建 OSSemPend(我们称之为 Sem A),将超时设置为 100 毫秒。
- 检查 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;
}