项目中遇到同一个函数既会在中断中调用,也会在任务中调用。可以写两个函数,分别使用FreeRTOS提供的中断使用的API和任务使用的API,来达到目的。但是总感觉这种方式需要写两个函数,代码重复,且不利于代码统一和维护。
这种判断,操作系统本身肯定会用到,要不然它就无法判断自己当前运行在哪个上下文了,但是是否有提供给用户使用的接口呢,查了一下,还真有。一个是:
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
另一个是:
static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */
__asm
{
/* *INDENT-OFF* */
mrs ulCurrentInterrupt, ipsr
/* *INDENT-ON* */
}
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
自己使用的第二个接口,完美解决问题。
当时项目进度关系,接口拿来使用,功能实现了,就没太注意细节。今天看到这段代码,突然感觉有点怪怪的,为什么static inline函数能够在我的代码中被调用?不是说static函数限定了函数只能在当前文件使用吗?带着疑问,决定一探究竟。
确认了两个接口函数实体都是在头文件中实现的,并非是源文件中。那么可以确定应该是跟这个有关系的,static和inline的单独使用的方法就不多说了,网上搜索找到有文章解释了static inline在头文件中的使用,大概意思是,在头文件中定义static inline函数,源文件包含了这个头文件,在编译时会把源文件中调用的xPortIsInsideInterrupt()函数替换为头文件中这段代码,并且不会出现重定义的编译告警,如果不加static修饰,只有inline的话,多个源文件包含这个头文件时会出现重定义。
解答了心中的疑惑,简单记录下。