ISR内部的UC/OS III信号灯有时不起作用



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

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

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

  1. 写入某个寄存器以在触发中断后启动操作
  2. 等待操作完成,在semafore上生成OSSemPend(我们称之为Sem a),将时间设置为100毫秒
  3. 检查OSSemPend调用是否正常结束或是否发生i超时

当中断被触发时,相关ISR在Sem a上进行SemPost,以便在超时前解锁信号量。

当问题发生时,OSSemPend返回OS_ERR_TIMEOUT。我很少看到这个问题。

我确信:

  • 给出启动操作(参见第一点),并启动操作
  • 中断被触发并且在Sem A上执行OSSemPost
  • 中断在从开始小于500 usec(即<1msec)之后被触发

代码写得正确吗?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;
}
  1. 调用OSSemPost()时不需要禁用中断。OSSemPost()被认为是应用程序的原子操作w/r。

  2. Cortex-M3核心的ISR应该是这样的,这就是Microsemi部分的内容:

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

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

相关内容

  • 没有找到相关文章

最新更新