FreeRTOS如何判断当前上下文是在中断还是在线程环境中

一、目的

        很多小伙伴在使用FreeRTOS API时,肯定看到过类似这样的接口:

xSemaphoreGiveFromISR
      (
        SemaphoreHandle_t xSemaphore,
        signed BaseType_t *pxHigherPriorityTaskWoken
      );

xSemaphoreGive( SemaphoreHandle_t xSemaphore );

        上图是释放信号量接口,这两个接口的区别:中断上下文中只能调用带FromISR后缀的接口 ;线程上下文中只能调用不带FromISR后缀的接口。存在这样的区别是因为FreeRTOS线程调度在线程中的实现与在中断中的实现方式不同,这个在以后的博文再解释。

        有时候我们封装接口时可能需要判断当前上下文是在中断还是线程中,那如何判断呢?

        由于跟硬件芯片平台强相关,所以FreeRTOS以xPortIsInsideInterrupt这个接口来适配不同平台,但是在Cortex-M系列的MCU上基本上实现方式都是一样的。

        第一种:

    portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
    {
        uint32_t ulCurrentInterrupt;
        BaseType_t xReturn;
 
        /* Obtain the number of the currently executing interrupt. */
        __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
 
        if( ulCurrentInterrupt == 0 )
        {
            xReturn = pdFALSE;
        }
        else
        {
            xReturn = pdTRUE;
        }
 
        return xReturn;
    }

         第二种:

/**
  \brief   Get IPSR Register
  \details Returns the content of the IPSR Register.
  \return               IPSR Register value
 */
__STATIC_INLINE uint32_t __get_IPSR(void)
{
  register uint32_t __regIPSR          __ASM("ipsr");
  return(__regIPSR);
}

        其实无论是哪种方式,关键的代码都是获取IPSR寄存器的值,那IPSR是什么寄存器呢?

二、原理

        从Cortex-M权威手册上我们可以找到准确的答案

Arm Cortex-M7 Devices Generic User Guide r1p2https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Processor/Programmers-model/Core-registers?lang=en

        

        IPSR寄存器记录着当前处理的异常/中断的中断号,如果为0,就说明当前不在中断上下文中。

         

        需要注意的是IPSR寄存器只能在特权级下访问。 

        下图就是寄存器组中关于IPSR的状态信息

        OK,本篇内容到此结束。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值