licensing and training services.\r
*/\r
\r
+/*\r
+ * This file defines the button push task and ISR as described at the top of\r
+ * main.c. The ISR is called from a wrapper function defined in ButtonISR.s26.\r
+ */\r
+\r
+/* Kernel includes. */\r
#include "FreeRTOS.h"\r
#include "task.h"\r
#include "semphr.h"\r
\r
-static xSemaphoreHandle xButtonSemaphore;\r
+/* The LED output used by the button push task. */\r
+#define butLED1 P7_bit.no7\r
+\r
+/* A short delay used for button debouncing. */\r
+#define butDEBOUNCE_DELAY ( 200 / portTICK_RATE_MS )\r
\r
-#define LED01 P7_bit.no7\r
+/* The semaphore used to synchronise the button push task with the interrupt. */\r
+static xSemaphoreHandle xButtonSemaphore;\r
\r
+/*\r
+ * The definition of the button task itself. See the comments at the top of\r
+ * main.c.\r
+ */\r
void vButtonTask( void *pvParameters )\r
{\r
+ /* Ensure the semaphore is created before it gets used. */\r
vSemaphoreCreateBinary( xButtonSemaphore );\r
\r
for( ;; )\r
{\r
+ /* Block on the semaphore to wait for an interrupt event. The semaphore\r
+ is 'given' from vButtonISRHandler() below. Using portMAX_DELAY as the\r
+ block time will cause the task to block indefinitely provided\r
+ INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. */\r
xSemaphoreTake( xButtonSemaphore, portMAX_DELAY );\r
- LED01 = !LED01;\r
+\r
+ /* The button must have been pushed for this line to be executed.\r
+ Simply toggle the LED. */\r
+ butLED1 = !butLED1;\r
\r
- vTaskDelay( 200 / portTICK_RATE_MS );\r
+ /* Wait a short time then clear any pending button pushes as a crude\r
+ method of debouncing the switch. xSemaphoreTake() uses a block time of\r
+ zero this time so it returns immediately rather than waiting for the\r
+ interrupt to occur. */\r
+ vTaskDelay( butDEBOUNCE_DELAY );\r
xSemaphoreTake( xButtonSemaphore, 0 );\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/*\r
+ * The C portion of the interrupt handler. Interrupts are triggered by pushing\r
+ * the button on the target board. This interrupt can cause a context switch\r
+ * so has an assembly file wrapper defined within ButtonISR.s26.\r
+ */\r
void vButtonISRHandler( void )\r
{\r
short sHigherPriorityTaskWoken = pdFALSE;\r
\r
+ /* 'Give' the semaphore to unblock the button task. */\r
xSemaphoreGiveFromISR( xButtonSemaphore, &sHigherPriorityTaskWoken );\r
\r
+ /* If giving the semaphore unblocked a task, and the unblocked task has a\r
+ priority that is higher than the currently running task, then\r
+ sHigherPriorityTaskWoken will have been set to pdTRUE. Passing a pdTRUE\r
+ value to portYIELD_FROM_ISR() will cause this interrupt to return directly\r
+ to the higher priority unblocked task. */\r
portYIELD_FROM_ISR( sHigherPriorityTaskWoken );\r
}\r
/*-----------------------------------------------------------*/\r