void vSoftwareInterruptHandler( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* 'Give' the semaphore multiple times. The first will unblock the handler task, the following 'gives' are to demonstrate that the semaphore latches the events to allow the handler task to process them in turn without any events getting lost. This simulates multiple interrupts being taken by the processor, even though in this case the events are simulated within a single interrupt occurrence.*/ xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xCountingSemaphore, &xHigherPriorityTaskWoken ); xSemaphoreGiveFromISR( xCountingSemaphore, &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 ); }
void vSoftwareInterruptHandler( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; static unsigned long ulReceivedNumber; /* The strings are declared static const to ensure they are not allocated to the interrupt service routine stack, and exist even when the interrupt service routine is not executing. */ static const char *pcStrings[] = { "String 0\n", "String 1\n", "String 2\n", "String 3\n" }; /* Loop until the queue is empty. */ while( xQueueReceiveFromISR( xIntegerQueue, &ulReceivedNumber, &xHigherPriorityTaskWoken ) != errQUEUE_EMPTY ) { /* Truncate the received value to the last two bits (values 0 to 3 inc.), then send the string that corresponds to the truncated value to the other queue. */ ulReceivedNumber &= 0x03; xQueueSendToBackFromISR( xStringQueue, &pcStrings[ ulReceivedNumber ], &xHigherPriorityTaskWoken ); } /* Clear the software interrupt bit using the interrupt controllers Clear Pending register. */ mainCLEAR_INTERRUPT(); /* xHigherPriorityTaskWoken was initialised to pdFALSE. It will have then been set to pdTRUE only if reading from or writing to a queue caused a task of equal or greater priority than the currently executing task to leave the Blocked state. When this is the case a context switch should be performed. In all other cases a context switch is not necessary. 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 ); }
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); }