FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [June 2016 Threads]
Hi :
I have a trouble on portENABLEINTERRUPTS and portDISABLEINTERRUPTS. 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 cpupsr = 0x80000100;
// x = 1, disable interrupt
// x = 0, enable interrupt
portLONG ulPortSetIPL( portLONG x)
{
if (x)
{
cpupsr = 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 ien"
"rts n"
);
}
// disable interrupt by clear IE bit in PSR
static inline void vPortDisableInterrupt(void)
{
asm volatile(
"psrclr ien"
"rts n"
);
}
~~~
case 1
define portDISABLEINTERRUPTS() ulPortSetIPL(1)
define portENABLEINTERRUPTS() ulPortSetIPL(0)
define portSETINTERRUPTMASKFROMISR() GetCPUPSR()
define portCLEARINTERRUPTMASKFROMISR(x) SetCPUPSR(x)
result: all task can work correctly..
case 2
define portDISABLEINTERRUPTS() vPortDisableInterrupt()
define portENABLEINTERRUPTS() vPortEnableInterrupt()
define portSETINTERRUPTMASKFROMISR() GetCPUPSR()
define portCLEARINTERRUPTMASKFROMISR(x) SetCPUPSR(x)
result: first task can't run and no task switch..
what I understand is portDISABLEINTERRUPTS() and portENABLEINTERRUPTS() 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 ?
Dont know about your code but these macros always have to work the same way.
portDISABLEINTERRUPTS() -> leave interrupts disabled
portENABLEINTERRUPTS() -> leave interrupts enabled
portSETINTERRUPTMASKFROMISR() -> leave interrupts disabled and return prior interrupt state, only needed when interrupt nesting is supported otherwise leave undefined
portCLEARINTERRUPTMASKFROMISR(x) -> set interrupt state to x, only needed when interrupt nesting is supported otherwise leave undefined
if interrupt nesting is not support,,, no need define portCLEARINTERRUPTMASKFROMISR(x) and portSETINTERRUPTMASKFROMISR() macro ?
I use a soft trap as pendSV trap to switch task.. but the cpu has no NVIC to set the trap in lower priority.. does it bring the result ?
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.