乐鑫技术交流
直播中

任凭风吹

9年用户 994经验值
擅长:可编程逻辑 电源/新能源 MEMS/传感技术 制造/封装 模拟技术
私信 关注
[问答]

ESP32S2如何判断当前代码是否在中断?

想要移植使用rt-thread的软件包,做了接口适配。
但是比如事件组,在rt-thread里是一个统一接口无需判断是否在中断,FreeRTOS里是区分普通代码和中断代码调用不同的API。
所以问题是,我怎么判断当前代码是否在中断中执行?


  • rt_err_t IRAM_ATTR rt_event_send(rt_event_t event, rt_uint32_t set)
  • {
  •     if (vPortGetiPSR())
  •     {
  •         BaseType_t xHigherPriorityTaskWoken;
  •         BaseType_t xResult;
  •         xHigherPriorityTaskWoken = pdFALSE;
  •         xResult = xEventGroupSetBitsFromISR(event->xHandler, set, &xHigherPriorityTaskWoken);
  •         if (xResult != pdFAIL)
  •         {
  •             /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
  •             switch should be requested.  The macro used is port specific and will
  •             be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
  •             the documentation page for the port being used. */
  •             portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  •         }
  •     }
  •     else
  •     {
  •         xEventGroupSetBits(event->xHandler, set);
  •     }
  •     return  RT_EOK;
  • }

回帖(1)

王焕锁

2024-6-21 16:43:30
要判断ESP32S2当前代码是否在中断中执行,您可以使用FreeRTOS提供的函数`vPortGetIPSR()`。这个函数会返回当前的中断程序状态寄存器(IPSR)的值。如果返回值不为0,表示当前代码正在中断中执行。

在您提供的代码示例中,已经使用了`vPortGetIPSR()`来判断是否在中断中执行。以下是对您的代码的解释:

1. 首先,使用`vPortGetIPSR()`获取当前的IPSR值,存储在变量`ipsr`中。
2. 然后,使用`if`语句判断`ipsr`是否为非零值。如果为非零值,表示当前代码在中断中执行。
3. 在中断中执行的情况下,使用`xHigherPriorityTaskWoken`和`xResult`变量来处理中断服务例程(ISR)唤醒的任务。

以下是修改后的代码示例:

```c
rt_err_t IRAM_ATTR rt_event_send(rt_event_t event, rt_uint32_t set)
{
    uint32_t ipsr = vPortGetIPSR(); // 获取当前的IPSR值

    if (ipsr) // 如果在中断中执行
    {
        BaseType_t xHigherPriorityTaskWoken;
        BaseType_t xResult;

        // 在中断中执行的代码
        xResult = xEventGroupSetBitsFromISR(event, set, &xHigherPriorityTaskWoken);

        if (xHigherPriorityTaskWoken != pdFALSE)
        {
            portYIELD_FROM_ISR(); // 如果需要,从中断中唤醒任务
        }
    }
    else // 如果不在中断中执行
    {
        // 在普通代码中执行的代码
        rt_err_t result = rt_event_send_direct(event, set);

        return result;
    }
}
```

在这个示例中,我们首先检查是否在中断中执行。如果是,我们使用`xEventGroupSetBitsFromISR()`函数来设置事件组的位,并处理可能唤醒的任务。如果不是在中断中执行,我们使用`rt_event_send_direct()`函数来直接发送事件。这样,您的代码就可以根据当前是否在中断中执行来选择合适的API。
举报

更多回帖

×
20
完善资料,
赚取积分