在USB ISR中为LPC1788使用embOS功能

时间:2014-07-18 08:21:06

标签: c usb microcontroller rtos lpc

我正在为恩智浦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调用"。

如果我发现其他任何内容,我会更新。

1 个答案:

答案 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数据结构就会被破坏。