zhuchunxia wrote on Monday, June 13, 2016:
Hi :
I have a trouble on portENABLE_INTERRUPTS and portDISABLE_INTERRUPTS. before I put the question out, I want to describe my CPU profile on interrupt. my CPU has no NVIC as similar as Cortex M3. it has a PSR register to disable interrupt and enable interrupt by set IE bit and clear IE bit
// default PSR value
portLONG cpu_psr = 0x80000100;
// x = 1, disable interrupt
// x = 0, enable interrupt
portLONG ulPortSetIPL( portLONG x)
{
if (x)
{
cpu_psr = GetCPUPSR();
}
else
{
SetCPUPSR(cpu_psr);
}
return cpu_psr;
}
/*
get PSR value and clear IE bit to disable interrupt
*/
static inline portLONG GetCPUPSR (void)
{
portLONG flags;
__asm__ __volatile__(
"mfcr %0, psr \n"
"psrclr ie\n"
:"=r"(flags)
:
:
);
return flags;
}
/*
set PSR value
*/
static inline void SetCPUPSR (portLONG newMask)
{
__asm__ __volatile__(
"mtcr %0, psr \n"
:
:"r" (newMask)
:"memory"
);
}
// enable interrupt by set IE bit in PSR
static inline void vPortEnableInterrupt(void)
{
__asm__ __volatile__(
"psrset ie\n"
"rts \n"
);
}
// disable interrupt by clear IE bit in PSR
static inline void vPortDisableInterrupt(void)
{
__asm__ __volatile__(
"psrclr ie\n"
"rts \n"
);
}
case 1
define portDISABLE_INTERRUPTS() ulPortSetIPL(1)
define portENABLE_INTERRUPTS() ulPortSetIPL(0)
define portSET_INTERRUPT_MASK_FROM_ISR() GetCPUPSR()
define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) SetCPUPSR(x)
result: all task can work correctly…
case 2
define portDISABLE_INTERRUPTS() vPortDisableInterrupt()
define portENABLE_INTERRUPTS() vPortEnableInterrupt()
define portSET_INTERRUPT_MASK_FROM_ISR() GetCPUPSR()
define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) SetCPUPSR(x)
result: first task can’t run and no task switch…
what I understand is portDISABLE_INTERRUPTS() and portENABLE_INTERRUPTS() is only used to disable all interrupts and enable interrupts purlly… but in case 1, ulPortSetIPL save PSR value in cpu_psr variable. and case 2 doesn’t save it …
is there other reason to cause it ?