我正在为 NXP LPC1788 微控制器开发软件,我正在使用 embOS RTOS。每当通过 USB 接收到消息时,我想使用 OS_PutMailCond() 函数将 USB 消息存储在处理函数正在等待的邮箱中。换句话说,我想让消息处理由中断驱动。
embOS 用户手册可以在这里找到。第 145 页描述了 OS_PutMailCond() 函数。
每当接收到 USB 消息时,它都会触发 LPC 上的 USB 中断服务例程,但是为了让 embOS 知道这是一个 ISR,我必须将 OS_EnterInterrupt() 和 OS_LeaveInterrupt() 分别放在 ISR 的开头和结尾。如果我想在其中调用 embOS 函数,包括 OS_PutMailCond(),这是必要的。
问题是,如果我将 OS_EnterInterrupt()/OS_LeaveInterrupt() 放在 USB ISR 中的任何位置,USB 将停止正常工作,并且 Windows 会通知我设备出现故障。
我不知道为什么会这样。我们已经尝试过类似的方法来处理 CAN 上的消息,如下所示,并且效果很好。
void CAN_IRQHandler(void)
{
OS_EnterInterrupt();
...
if (MBfieldCANframeInitialised)
OS_PutMailCond (&MBfieldCANframe, &recMessage);
OS_LeaveInterrupt();
}
OS_EnterInterrupt() 和 OS_LeaveInterrupt() 在链接手册的第 252 和 253 页上进行了描述。从前者的附加信息部分:
如果使用 OS_EnterInterrupt(),它应该是在中断处理程序中调用的第一个函数。它必须与 OS_LeaveInterrupt() 一起使用,作为最后调用的函数。使用该功能有以下效果,它:
- 禁用任务开关
- 保持内部程序中的中断被禁用
编辑
我进行了进一步调查,发现在 USB ISR 中使用 OS_EnterInterrupt() 和 OS_LeaveInterrupt()(以及在引脚上检测到上升沿或下降沿时用于 GPIO 的其他 ISR)会导致操作系统错误。错误值为 166,表示“从 ISR 调用的具有高优先级的 OS 函数”。
如果我发现任何其他内容,我会更新。