0

我的信号量有问题,有时在 ISR 中调用的 SemPost 似乎无效。

我的应用程序基于 Micrimum UCOS III,目标平台基于 Microsemi Smartfusion2 SoC (Cortex-M3)。我的应用程序包含两个任务(A 和 B),但是当问题发生时只有一个处于活动状态(另一个被卡在信号量上)。

当活动任务(我们称之为任务 A)执行以下操作时会出现问题:

  1. 写入某个寄存器以在触发中断后开始操作
  2. 等待操作完成在 semafore 上创建 OSSemPend(我们称之为 Sem A),将超时设置为 100 毫秒。
  3. 检查 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;
}
4

1 回答 1

0
  1. 调用 OSSemPost() 时不需要禁用中断。OSSemPost() 被认为是对您的应用程序的原子操作。

  2. 对于 Cortex-M3 内核,ISR 应该如下所示,这是 Microsemi 部分中的内容:

    void MyISR (void)
    {
       CPU_SR_ALLOC();
    
       CPU_CRITICAL_ENTER();
       OSIntEnter();
       CPU_CRITICAL_EXIT();
       OSSemPost(...);
       OSIntExit();
    }
    

这允许您告诉 uC/OS-III 您正在启动 ISR。如果它是准备运行的最高优先级,这对于允许内核调度发布的任务是必要的。

于 2016-04-19T02:12:55.753 回答