物联网临界段实现原理:
一,FreeRTOS中断管理实现:
Cortex-M快速关中断指令
PRIMASK:这是个单一bit的寄存器。在它被置1后,就关闭所有可屏蔽的异常,只剩下NMI和硬FAULT可以响应。它被置0,表示没有关中断
FAULTMASK:这是个有1bit的寄存器。当它置1时,只要NMI才能响应,所有其他的异常,甚至是硬FAULT,也通通闭嘴,是0就表示没有关异常
DASEPRI:这个寄存器最多有9位(由表达优先级的位数决定)。它定义了被屏蔽优先级的阈值。当它被设成某个值后,所有优先级号大于等于此值得中断都被关(优先级越大,优先级越低)。但若被设置成0,则不关闭任何中断。
//中断优先级分组:
#define configPRIO_BITS 4
//最低优先级
#define cofigLIBRARY_LOWST_INTERRUPT_PRIORITY 15
//中断屏蔽门限值
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
//内核调度中断优先级
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
//中断屏蔽优先级
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
二,开关中断实现:
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
static portFORCE_INLINE
void vPortRaiseBASEPRI(void)
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
—asm
{
msr basepri, ulNewBASEPRI
dsb
isb
}
}
#define portENABLE_INTERRUPTS() vportSetBASEPRI(0)
static portFORCE_INLINE
void vPortBASEPRI(uint32_t ulBASEPRI)
{
—asm
{
msr basepri,ulBASEPRI
}
}
三,临界段实现:
#define taskENTER_CRITICAL() porENTER_CRITICAL()
#define portENTER_CRITICAL() vPortEnterCritical()
void vPortEnterCritical(void)
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
if(uxCriticalNesting == 1)
{
configASSERT((portNVIC_INT_CTRL_REG & portVECTIVE_MASK) == 0);
}
}
进入临界段(中断)
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{
uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
__asm
{
mrs ulReturn, basepri
msr basepri, ulNewBASEPRI
dsb
isb
}
return ulReturn;
}
退出临界段:
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define portEXIT_CRITICAL() vPortExitCritical()
void vPortExitCritical( void )
{
configASSERT( uxCriticalNesting );
uxCriticalNesting–;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
//退出临界段(中断)
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
__asm
{
msr basepri, ulBASEPRI
}
}