- vPortSetInterruptHandler( mainINTERRUPT_NUMBER, ulExampleInterruptHandler );
- vPortGenerateSimulatedInterrupt( mainINTERRUPT_NUMBER );
FreeRTOS efm32gg – simulating interrupts
I’m trying to convert a windows FreeRTOS sempahore example to be used with efm32gg. This is example 16 in Amazon’s FreeRTOS Developer Guide located here
I believe I narrowed down the conversion to the difference between two commands:
FreeRTOS efm32gg – simulating interrupts
There is no equivalent – the Windows port is a bit unique here in that you can’t install a real handler. In the other ports (real MCUs), just install the interrupt handler in the vector table as you would any other.
- vPortSetInterruptHandler( mainINTERRUPT_NUMBER, ulExampleInterruptHandler );
The Cortex-M has a set of SetPending registers, where if you set a bit for a particular interrupt, that interrupt will execute if it is enabled. There are probably CMSIS functions for the same, but I’m not sure. Here is an example mainTRIGGER_INTERRUPT() macro from the LPC17xx version of the book examples, which does actually appear to be using a CMSIS function to pend the interrupt, despite what I just wrote above:
- vPortGenerateSimulatedInterrupt( mainINTERRUPT_NUMBER );
#define mainTRIGGER_INTERRUPT() NVIC_SetPendingIRQ( mainSW_INTERRUPT_ID )This is how the interrupt was configured in the first place:
static void prvSetupSoftwareInterrupt( void ) { /* The interrupt service routine uses an (interrupt safe) FreeRTOS API function so the interrupt priority must be at or below the priority defined by configSYSCALL_INTERRUPT_PRIORITY. */ NVIC_SetPriority( mainSW_INTERRUPT_ID, mainSOFTWARE_INTERRUPT_PRIORITY ); /* Enable the interrupt. */ NVIC_EnableIRQ( mainSW_INTERRUPT_ID ); }and here is the handler:
void vSoftwareInterruptHandler( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* 'Give' the semaphore to unblock the task. */ xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken ); /* Clear the software interrupt bit using the interrupt controllers Clear Pending register. */ mainCLEAR_INTERRUPT(); /* Giving the semaphore may have unblocked a task - if it did and the unblocked task has a priority equal to or above the currently executing task then xHigherPriorityTaskWoken will have been set to pdTRUE and portEND_SWITCHING_ISR() will force a context switch to the newly unblocked higher priority task. NOTE: The syntax for forcing a context switch within an ISR varies between FreeRTOS ports. The portEND_SWITCHING_ISR() macro is provided as part of the Cortex M3 port layer for this purpose. taskYIELD() must never be called from an ISR! */ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); }