c - 为什么我的程序在 GCC 下不进入处理程序模式?

标签 c gcc embedded mode keil

我有这段代码可以在 KEIL 下运行,但不能在 GCC 下运行,我不知道为什么会这样。它测试了一些 RTX OS 功能。

处理程序:

void GenWait_IRQHandler (void) {

  switch (ISR_ExNum) {
    case 0: Stat_Isr = osDelay (10); break;
  #if (osFeatureWait)
    case 1: Stat_Isr = osWait  (10); break;
  #endif
  }
}

上面的代码是通过从 main 设置挂起的 IRQ 进入的:

...
ISR_ExNum = 0; /* Test: osDelay */
NVIC_SetPendingIRQ((IRQn_Type)SWI_HANDLER);
ASSERT_TRUE (Stat_Isr == osErrorISR);
...

问题是这个 ASSERT_TRUE() 失败了,因为 Stat_Isr 不等于 osErrorISR,它应该是调用 osDelay () 不允许来自 Handler 模式:

osStatus osDelay (uint32_t millisec) {
  if (__get_IPSR() != 0U) {
    return osErrorISR;                          // Not allowed in ISR
  }
  return __svcDelay(millisec);
}

正如我所说,在 KEIL 下编译时它工作正常,但在 GCC 下编译时它失败了。看起来 IPSR 在进入处理程序时没有更新,osDelay() 不知道它应该返回错误。知道为什么会这样吗?

SWI_Handler是software handler,我在里面调用了GenWait_IRQHandler()

编辑:

这是作为 RTX 验证从 KEIL Packs 获得的实现,我只是试图让它在我正在使用的芯片上工作。所以即使我从 ISR 调用函数它也应该工作。

此外,正如我在评论中所写:

(来自 www.keil.com):

Interrupt Service Routines (ISR) can call some CMSIS-RTOS functions. When a CMSIS-RTOS function cannot be called from ISR context, it rejects the invocation.

然后:

Functions that cannot be called from an ISR are verifying the interrupt status and return, in case they are called from an ISR context, the status code osErrorISR. In some implementations, this condition might be caught using the HARD FAULT vector.

编辑2:

将优化从 -O3 减少到 -O1 是固定问题,但我仍然不知道为什么要这样优化以及如何轻松防止编译器这样做。我知道最简单的答案是添加几个“volatile”,但我认为在这种情况下并不是这么简单。

最佳答案

感谢@kkrambo 提供的正确路径。问题出在指令顺序上。向 Stat_Isr 添加 volatiles 是不够的,但添加内存屏障对我来说很有效:

...
ISR_ExNum = 0; /* Test: osDelay */
NVIC_SetPendingIRQ((IRQn_Type)SWI_HANDLER);
__DMB();
ASSERT_TRUE (Stat_Isr == osErrorISR);
...

这是因为代码优化使得 ISR 在 ASSERT_TRUE (Stat_Isr == osErrorISR); 之后被调用。我认为现在很清楚了。

关于c - 为什么我的程序在 GCC 下不进入处理程序模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38076266/

相关文章:

c - MPI 连续类型示例给出 fatal error

c - 结构体中的结构体数组?

c - C 中的 rand() 输出不在指定范围内的数字

c - "int a=({10;});"这个表达式用C语言怎么解释?

c - IF 语句参数更新和函数调用

c - gets_s 给 gcc 错误

arrays - 找出数字的所有数字是否相等

c++ - 编译器与引用文献的差异

c++ - 当 std::atomic<T>::is_always_lock_free 为 false 时,std::atomic<T> 对于中断是否安全?

c++ - 如何为指向外部存储器的奇特指针实现 operator-> ?