FRDM-K66F FromISR() APIs freezing the ISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FRDM-K66F FromISR() APIs freezing the ISR

Jump to solution
1,401 Views
mahendranmanoha
Contributor III

Hi,

I am using the freeRTOS sample code for event with FRDM-K66F board. In that, I added an ISR routine for switch SW3 with PortA interrupt. The interrupt routine is as below.

void BOARD_SW_IRQ_HANDLER(void)
{
/* Clear external interrupt flag. */
GPIO_PortClearInterruptFlags(BOARD_SW_GPIO, 1U << BOARD_SW_GPIO_PIN);
BaseType_t xHigherPriorityTaskWoken, xResult;
/* xHigherPriorityTaskWoken must be initialised to pdFALSE. */
xHigherPriorityTaskWoken = pdFALSE;
/* Set bit 0 in event_group. */
xResult = xEventGroupSetBitsFromISR(
event_group, /* The event group being updated. */
B0, /* The bits being set. */
&xHigherPriorityTaskWoken );
/* Was the message posted successfully? */
if( xResult != pdFAIL )
{
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
SDK_ISR_EXIT_BARRIER;
}


Whenever I am using ISR safe routines such as "FromISR", the program ended in freezing. However, when I try to use global variable to communicate to interrupt everything works fine.

I have gone through the page "https://www.freertos.org/RTOS-Cortex-M3-M4.html". After reading through the page, I am still unsure what number should be assigned to configMAX_SYSCALL_INTERRUPT_PRIORITY. By default maximum numerical number 0xF0 was allocated to "configKERNEL_INTERRUPT_PRIORITY"

Besides, I do not know how to assign priority to every interrupt such as GPIO, ADC, eDMA, and so on.

Can you please help me in resolving the situation?

best regards,

Mahendran.

0 Kudos
1 Solution
1,381 Views
mahendranmanoha
Contributor III

Thank you very much for sharing the links, Carlos. Last few days, I have gone through several articles including many of those you mentioned. I think I understood properly, updated my code and the program is working exactly as I expected. Just for the benefit of others (if required) I would like to summarise my understanding. Please correct me if anything is wrong or misleading.

Just to be clear with basics for beginners.
Peripheral interrupts are Microcontroller dependent and are serviced by bare metal Interrupt Service Routines (ISR), which are to implemented by the programer.
"fromISR()" APIs and Kernel APIs are provided by FreeRTOS.

For the FreeRTOS application to run as intended, priorities have to be defined, even for the simplest of applications using ISR and FreeRTOS.

Interrupt priorities are defined by following parameters in FreeRTOSConfig.h

configLIBRARY_LOWEST_INTERRUPT_PRIORITY

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

configKERNEL_INTERRUPT_PRIORITY

configMAX_SYSCALL_INTERRUPT_PRIORITY

All the above interrupt priority levels are decided by Priority Bits, whose number of bits depends on the Microcontroller core. In FRDM-K66F it is 4, so the values can be from 0 to 15, where 0 is for most urgent priority and 15 is for least urgent priority.

configLIBRARY_LOWEST_INTERRUPT_PRIORITY is ISR's lowest possible interrupt priority, which is usually 15 (1111b).
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is ISR's highest possible interrupt priority, which can be from 0 to 15, depending upon the need. I set that as 2.

Any Peripheral ISR that is going to be implemented in the program has to be defined priority level between the above two levels (else the program is prone to crash) in the main() program with the function

NVIC_SetPriority(IRQ_Number, Prioiritylevel);

In FreeRTOSConfig.h, I noticed the priority levels of configLIBRARY_LOWEST_INTERRUPT_PRIORITY and configKERNEL_INTERRUPT_PRIORITY are the same and configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY are same, BUT the values are left shifted for KERNEL and MAX_SYSCALL interrupts in FreeRTOSConfig.h.

The values need not be the same. For instance, I assigned configMAX_SYSCALL_INTERRUPT_PRIORITY as 4 (01000000b), so I can have two levels of ISRs that are not interrupted by "fromISR()" APIs.

In the program, any Peripheral ISR, whose priority level is equal to or higher value (less urgent) than configMAX_SYSCALL_INTERRUPT_PRIORITY can use fromISR() APIs of FreeRTOS and still cannot use normal kernel APIs of FreeRTOS.

NB: Task and Timer priorities are at configKERNEL_INTERRUPT_PRIORITY priority. However, Tasks and Timers can have their priority levels from 0 to configMAX_PRIORITIES (From FreeRTOSConfig.h), where 0 priority level is for idle task and sleep mode or low power mode tasks. Unlike the interrupt priorities, Task priorities having a higher number means more urgent.

View solution in original post

4 Replies
1,382 Views
mahendranmanoha
Contributor III

Thank you very much for sharing the links, Carlos. Last few days, I have gone through several articles including many of those you mentioned. I think I understood properly, updated my code and the program is working exactly as I expected. Just for the benefit of others (if required) I would like to summarise my understanding. Please correct me if anything is wrong or misleading.

Just to be clear with basics for beginners.
Peripheral interrupts are Microcontroller dependent and are serviced by bare metal Interrupt Service Routines (ISR), which are to implemented by the programer.
"fromISR()" APIs and Kernel APIs are provided by FreeRTOS.

For the FreeRTOS application to run as intended, priorities have to be defined, even for the simplest of applications using ISR and FreeRTOS.

Interrupt priorities are defined by following parameters in FreeRTOSConfig.h

configLIBRARY_LOWEST_INTERRUPT_PRIORITY

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

configKERNEL_INTERRUPT_PRIORITY

configMAX_SYSCALL_INTERRUPT_PRIORITY

All the above interrupt priority levels are decided by Priority Bits, whose number of bits depends on the Microcontroller core. In FRDM-K66F it is 4, so the values can be from 0 to 15, where 0 is for most urgent priority and 15 is for least urgent priority.

configLIBRARY_LOWEST_INTERRUPT_PRIORITY is ISR's lowest possible interrupt priority, which is usually 15 (1111b).
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is ISR's highest possible interrupt priority, which can be from 0 to 15, depending upon the need. I set that as 2.

Any Peripheral ISR that is going to be implemented in the program has to be defined priority level between the above two levels (else the program is prone to crash) in the main() program with the function

NVIC_SetPriority(IRQ_Number, Prioiritylevel);

In FreeRTOSConfig.h, I noticed the priority levels of configLIBRARY_LOWEST_INTERRUPT_PRIORITY and configKERNEL_INTERRUPT_PRIORITY are the same and configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY are same, BUT the values are left shifted for KERNEL and MAX_SYSCALL interrupts in FreeRTOSConfig.h.

The values need not be the same. For instance, I assigned configMAX_SYSCALL_INTERRUPT_PRIORITY as 4 (01000000b), so I can have two levels of ISRs that are not interrupted by "fromISR()" APIs.

In the program, any Peripheral ISR, whose priority level is equal to or higher value (less urgent) than configMAX_SYSCALL_INTERRUPT_PRIORITY can use fromISR() APIs of FreeRTOS and still cannot use normal kernel APIs of FreeRTOS.

NB: Task and Timer priorities are at configKERNEL_INTERRUPT_PRIORITY priority. However, Tasks and Timers can have their priority levels from 0 to configMAX_PRIORITIES (From FreeRTOSConfig.h), where 0 priority level is for idle task and sleep mode or low power mode tasks. Unlike the interrupt priorities, Task priorities having a higher number means more urgent.

1,374 Views
CarlosGarabito
NXP TechSupport
NXP TechSupport

Hi @mahendranmanoha I am sure that your explanation will help more than one person, thank you very much.

Have an excellent day

0 Kudos
1,365 Views
mahendranmanoha
Contributor III

Yes, Carlos.

I would be glad if more people find this useful.