我正在为恩智浦LPC1788微控制器开发软件,我正在使用embOS RTOS。每当通过USB接收消息时,我想使用OS_PutMailCond()函数将USB消息存储在处理程序函数正在等待的邮箱中。换句话说,我想让消息处理中断驱动。
可以找到embOS用户手册here。第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()(以及其他ISR,就像在检测到上升沿或下降沿时的GPIO那样)引脚)导致操作系统错误。错误值为166,这意味着"操作系统功能从具有高优先级的ISR调用"。
如果我发现其他任何内容,我会更新。
答案 0 :(得分:1)
问题解决了。事实证明,为CAN ISR工作的人改变了其中一个embOS源文件的代码,将CAN ISR优先级设置为0到29(更高级别=更低优先级)。我为USB ISR做了同样的事情:
void OS_InitHW(void) {
OS_IncDI();
//
// We assume, the PLL and core clock was already set by the SystemInit() function
// which was called from the startup code
// Therefore, we don't have to initailize any hardware here,
// we just ensure that the system clock variable is updated and then
// set the periodic system timer tick for embOS.
//
SystemCoreClockUpdate(); // Update the system clock variable (might not have been set before)
if (SysTick_Config (OS_PCLK_TIMER / OS_TICK_FREQ)) { // Setup SysTick Timer for 1 msec interrupts
while (1); // Handle Error
}
//
// Initialize NVIC vector base address. Might be necessary for RAM targets or application not running from 0
//
NVIC_VTOR = (OS_U32)&__Vectors;
//
// Set the interrupt priority for the system timer to 2nd lowest level to ensure the timer can preempt PendSV handler
//
NVIC_SetPriority(SysTick_IRQn, (1u << __NVIC_PRIO_BITS) - 2u);
NVIC_SetPriority(CANActivity_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
NVIC_SetPriority(CAN_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
NVIC_SetPriority(USB_IRQn, (1u << __NVIC_PRIO_BITS) - 3u);
OS_COM_INIT();
OS_DecRI();
}
我在embOS文档中找到了这个:
为什么高优先级ISR不能使用OS API?
embOS在修改embOS数据结构时禁用低优先级中断。在此期间,启用高优先级ISR。如果他们调用embOS函数(也修改了embOS数据),embOS数据结构就会被破坏。