c - 在 LPC1788 的 USB ISR 中使用 embOS 函数

标签 c usb microcontroller rtos lpc

我正在为 NXP LPC1788 微 Controller 开发软件,我正在使用 embOS RTOS。每当通过 USB 收到消息时,我想使用 OS_PutMailCond() 函数将 USB 消息存储在处理函数正在等待的邮箱中。换句话说,我想让消息处理中断驱动。

可以找到 embOS 用户手册 here .第 145 页描述了 OS_PutMailCond() 函数。

每当收到 USB 消息时,它都会触发 LPC 上的 USB 中断服务例程,但为了让 embOS 知道这是一个 ISR,我必须分别在 ISR 的开始和结束处放置 OS_EnterInterrupt() 和 OS_LeaveInterrupt() .如果我想在其中调用 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 页有描述。来自前者的附加信息部分:

If OS_EnterInterrupt() is used, it should be the first function to be called in the interrupt handler. It must be used with OS_LeaveInterrupt() as the last function called. The use of this function has the following effects, it:

  • disables task switches
  • keeps interrupts in internal routines disabled

编辑

我进一步调查发现,在 USB ISR(以及其他 ISR,例如在引脚上检测到上升沿或下降沿时用于 GPIO 的 ISR)中使用 OS_EnterInterrupt() 和 OS_LeaveInterrupt() 会导致操作系统错误.错误值为 166,表示“从具有高优先级的 ISR 调用的 OS 函数”。

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

最佳答案

问题解决了。事实证明,为 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 文档中找到了这个:

Why can a high priority ISR not use the OS API ?

embOS disables low priority interrupts when embOS data structures are modified. During this time high priority ISR are enabled. If they would call an embOS function, which also modifies embOS data, the embOS data structures would be corrupted.

关于c - 在 LPC1788 的 USB ISR 中使用 embOS 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24820370/

相关文章:

c - STM32F401RE Nucleo 板,无法切换用户 LED

c - 找到一个c程序的输出

c - 替代数据格式

windows - 如何检测连接的 USB 打印机是打开还是关闭?

java - UsbInterface 声明失败

embedded - SPI通信中CPOL/CPHA设置的使用

c - malloc on char** 读写错误

c - Win32 API : process WM_* in tab control's wndproc instead of parent's

USB闪存驱动器上的Ubuntu

使用 cryptoauthlib 配置 ATEC608A