licensing and training services.\r
*/\r
\r
+\r
+/* \r
+ * Defines the 'dice' tasks as described at the top of main.c\r
+ */\r
+\r
+\r
+/* Kernel includes. */\r
#include "FreeRTOS.h"\r
#include "task.h"\r
#include "semphr.h"\r
\r
-#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 )\r
-#define diceRUN_TIME ( 2000 / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )\r
-\r
-\r
-#define diceEND_DELAY ( 5000 / portTICK_RATE_MS )\r
+/* Delays used within the dice functionality. All delays are defined in milliseconds. */\r
+#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 / portTICK_RATE_MS )\r
+#define diceSHAKE_TIME ( ( 2000 / portTICK_RATE_MS ) / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )\r
+#define diceSHORT_PAUSE_BEFORE_SHAKE ( 1000 / portTICK_RATE_MS )\r
+#define diceDELAY_WHILE_DISPLAYING_RESULT ( 5000 / portTICK_RATE_MS )\r
\r
-#define dice7SEG_Value( x ) *( pucDisplayOutput[ x ] )\r
+/* Macro to access the display ports. */\r
+#define dice7SEG_Value( x ) ( *( pucDisplayOutput[ x ] ) )\r
\r
+/* Checks the semaphore use to communicate button push events. A block time\r
+can be specified - this is the time to wait for a button push to occur should\r
+one have not already occurred. */\r
#define prvButtonHit( ucIndex, xTicksToWait ) xSemaphoreTake( xSemaphores[ ucIndex ], xTicksToWait )\r
\r
+/* Defines the outputs required for each digit on the display. */\r
static const char cDisplaySegments[ 2 ][ 11 ] =\r
{\r
- { 0x48, 0xeb, 0x8c, 0x89, 0x2b, 0x19, 0x18, 0xcb, 0x08, 0x09, 0xf7 },\r
- { 0xa0, 0xf3, 0xc4, 0xc1, 0x93, 0x89, 0x88, 0xe3, 0x80, 0x81, 0x7f }\r
+ { 0x48, 0xeb, 0x8c, 0x89, 0x2b, 0x19, 0x18, 0xcb, 0x08, 0x09, 0xf7 }, /* Left display. */\r
+ { 0xa0, 0xf3, 0xc4, 0xc1, 0x93, 0x89, 0x88, 0xe3, 0x80, 0x81, 0x7f } /* Right display. */\r
};\r
\r
+/* The semaphores used to communicate button push events between the button\r
+input interrupt handlers and the dice tasks. Two dice tasks are created so two\r
+semaphores are required. */\r
static xSemaphoreHandle xSemaphores[ 2 ] = { 0 };\r
\r
+/* Defines the ports used to write to the display. This variable is defined in\r
+partest.c, which contains the LED set/clear/toggle functions. */\r
extern volatile unsigned char *pucDisplayOutput[ 2 ];\r
\r
/*-----------------------------------------------------------*/\r
\r
+/* \r
+ * Defines the 'dice' tasks as described at the top of main.c\r
+ */\r
void vDiceTask( void *pvParameters )\r
{\r
unsigned char ucDiceValue, ucIndex;\r
unsigned long ulDiceRunTime;\r
extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );\r
\r
+\r
+\r
/* Two instances of this task are created so the task parameter is used\r
- to pass in an index that allows this task to know which file scope variables\r
- it should use. Cast this index into a usable type. */\r
+ to pass in a constant that indicates whether this task is controlling\r
+ the left side or right side display. The constant is used as an index\r
+ into the arrays defined at file scope within this file. */\r
ucIndex = ( unsigned char ) pvParameters;\r
\r
/* A binary semaphore is used to signal button push events. Create the\r
/* Make sure the semaphore starts in the wanted state - no button pushes \r
pending. This call will just clear any button pushes that are latched.\r
Passing in 0 as the block time means the call will not wait for any further\r
- button pushes. */\r
+ button pushes but instead return immediately. */\r
prvButtonHit( ucIndex, 0 );\r
\r
/* Seed the random number generator. */\r
- srand( ( unsigned char ) diceRUN_TIME );\r
+ srand( ( unsigned char ) diceSHAKE_TIME );\r
+\r
+\r
\r
+\r
+ /* Start the task proper. A loop will be performed each time a button is\r
+ pushed. The task will remain in the blocked state (sleeping) until a \r
+ button is pushed. */\r
for( ;; )\r
{\r
/* Wait for a button push. This task will enter the Blocked state\r
prvButtonHit( ucIndex, portMAX_DELAY );\r
\r
/* The next line will only execute after a button has been pushed -\r
- initialise the variable used to shake the dice. */\r
- ulDiceRunTime = diceRUN_TIME;; \r
+ initialise the variable used to control the time the dice is shaken\r
+ for. */\r
+ ulDiceRunTime = diceSHAKE_TIME; \r
\r
/* Suspend the flash tasks so this task has exclusive access to the\r
display. */\r
vSuspendFlashTasks( ucIndex, pdTRUE );\r
\r
+ /* Clear the display and pause for a short time, before starting to\r
+ shake. */\r
+ *pucDisplayOutput[ ucIndex ] = 0xff;\r
+ vTaskDelay( diceSHORT_PAUSE_BEFORE_SHAKE );\r
+\r
+ /* Keep generating and displaying random numbers until the shake time\r
+ expires. */\r
while( ulDiceRunTime > 0 )\r
{\r
ulDiceRunTime--;\r
\r
/* Block/sleep for a very short time before generating the next\r
random number. */\r
- vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms / portTICK_RATE_MS );\r
+ vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms );\r
}\r
\r
- /* Wait for a short time before resuming (un-suspending) the flash \r
- task. The flash tasks are only restarted if a button is not pushed\r
- during this delay - if a button is pushed then the dice are shaken\r
- again. \r
\r
- First...clear any button pushes that are already pending. Again a\r
- block time of zero is used so the function does not wait for any \r
- pushes. */\r
+\r
+ /* Clear any button pushes that are pending because a button bounced, or\r
+ was pressed while the dice were shaking. Again a block time of zero is \r
+ used so the function does not wait for any pushes but instead returns\r
+ immediately. */\r
prvButtonHit( ucIndex, 0 );\r
\r
- /* Second...peek the semaphore. This task will block/sleep until a\r
- button is pushed again, but because the peek function is used a \r
- button being pushed will unblock the task but remain pending. */\r
- if( xQueuePeek( xSemaphores[ ucIndex ], NULL, diceEND_DELAY ) == pdFALSE )\r
- {\r
- *pucDisplayOutput[ ucIndex ] = 0xff;\r
- vSuspendFlashTasks( ucIndex, pdFALSE );\r
- }\r
+ /* Delay for a short while to display the dice shake result. Use a queue\r
+ peek here instead of a vTaskDelay() allows the delay to be interrupted by\r
+ a button push. If a button is pressed xQueuePeek() will return but the\r
+ button push will remain pending to be read again at the top of this for\r
+ loop. It is safe to uses a queue function on a semaphore handle as\r
+ semaphores are implemented as macros that uses queues, so the two are \r
+ basically the same thing. */\r
+ xQueuePeek( xSemaphores[ ucIndex ], NULL, diceDELAY_WHILE_DISPLAYING_RESULT );\r
+\r
+ /* Clear the display then resume the tasks or co-routines that were using\r
+ the segments of the display. */\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/* Handler for the SW2 button push interrupt. */\r
__interrupt void vExternalInt8Handler( void )\r
{\r
short sHigherPriorityTaskWoken = pdFALSE;\r
/* Reset the interrupt. */\r
EIRR1_ER8 = 0;\r
\r
- xSemaphoreGiveFromISR( xSemaphores[ 0 ], &sHigherPriorityTaskWoken );\r
+ /* Check the semaphore has been created before attempting to use it. */\r
+ if( xSemaphores[ configLEFT_DISPLAY ] != NULL )\r
+ {\r
+ /* Send a message via the semaphore to the dice task that controls the\r
+ left side display. This will unblock the task if it is blocked waiting\r
+ for a button push. */\r
+ xSemaphoreGiveFromISR( xSemaphores[ configLEFT_DISPLAY ], &sHigherPriorityTaskWoken );\r
+ }\r
\r
+ /* If sending the semaphore unblocked a task, and the unblocked task has a\r
+ priority that is higher than the currently running task, then force a context\r
+ switch. */\r
if( sHigherPriorityTaskWoken != pdFALSE )\r
{\r
portYIELD_FROM_ISR();\r
}\r
/*-----------------------------------------------------------*/\r
\r
+/* As per vExternalInt8Handler(), but for SW3 and the right side display. */\r
__interrupt void vExternalInt9Handler( void )\r
{\r
short sHigherPriorityTaskWoken = pdFALSE;\r
/* Reset the interrupt. */\r
EIRR1_ER9 = 0;\r
\r
- xSemaphoreGiveFromISR( xSemaphores[ 1 ], &sHigherPriorityTaskWoken );\r
+ if( xSemaphores[ configRIGHT_DISPLAY ] != NULL )\r
+ {\r
+ xSemaphoreGiveFromISR( xSemaphores[ configRIGHT_DISPLAY ], &sHigherPriorityTaskWoken );\r
+ }\r
\r
if( sHigherPriorityTaskWoken != pdFALSE )\r
{\r
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. \r
*----------------------------------------------------------*/\r
-#define configUSE_PREEMPTION 1\r
-#define configUSE_IDLE_HOOK 1\r
-#define configUSE_TICK_HOOK 0\r
-#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 180 ) /* This can be greatly reduced when using the small or medium memory model. */\r
-#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */\r
-#define configCLKP1_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */\r
-#define configTICK_RATE_HZ ( (portTickType) 1000 )\r
-#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 )\r
-#define configTOTAL_HEAP_SIZE ( (size_t) (5000) )\r
-#define configMAX_TASK_NAME_LEN ( 20 )\r
-#define configUSE_16_BIT_TICKS 1\r
-#define configIDLE_SHOULD_YIELD 1\r
-#define configUSE_MUTEXES 1\r
-#define configUSE_TRACE_FACILITY 1\r
+#define configUSE_PREEMPTION 1\r
+#define configUSE_IDLE_HOOK 1\r
+#define configUSE_TICK_HOOK 0\r
+#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 180 ) /* This can be greatly reduced when using the small or medium memory model. */\r
+#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */\r
+#define configCLKP1_CLOCK_HZ ( ( unsigned portLONG ) 56000000 ) /* Clock setup from start.asm in the demo application. */\r
+#define configTICK_RATE_HZ ( (portTickType) 1000 )\r
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 )\r
+#define configTOTAL_HEAP_SIZE ( (size_t) (5000) )\r
+#define configMAX_TASK_NAME_LEN ( 20 )\r
+#define configUSE_16_BIT_TICKS 1\r
+#define configIDLE_SHOULD_YIELD 1\r
+#define configUSE_MUTEXES 1\r
+#define configUSE_TRACE_FACILITY 0\r
+#define configCHECK_FOR_STACK_OVERFLOW 0\r
\r
/* Co-routine definitions. */\r
#define configUSE_CO_ROUTINES 1\r
-#define configMAX_CO_ROUTINE_PRIORITIES ( 4 )\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
\r
/* Set the following definitions to 1 to include the API function, or zero\r
to exclude the API function. */\r
-#define INCLUDE_vTaskPrioritySet 1\r
-#define INCLUDE_uxTaskPriorityGet 1\r
-#define INCLUDE_vTaskDelete 1\r
-#define INCLUDE_vTaskCleanUpResources 1\r
+#define INCLUDE_vTaskPrioritySet 0\r
+#define INCLUDE_uxTaskPriorityGet 0\r
+#define INCLUDE_vTaskDelete 0\r
+#define INCLUDE_vTaskCleanUpResources 0\r
#define INCLUDE_vTaskSuspend 1\r
-#define INCLUDE_vResumeFromISR 1\r
+#define INCLUDE_vResumeFromISR 0\r
#define INCLUDE_vTaskDelayUntil 1\r
#define INCLUDE_vTaskDelay 1\r
-#define INCLUDE_xTaskGetSchedulerState 1\r
-#define INCLUDE_xTaskGetCurrentTaskHandle 1\r
+#define INCLUDE_xTaskGetSchedulerState 0\r
+#define INCLUDE_xTaskGetCurrentTaskHandle 0\r
\r
\r
#define configKERNEL_INTERRUPT_PRIORITY 6\r
\r
+/* Passed into the Dice tasks to let then know if they are controlling the \r
+display on the left side or the right side. */\r
+#define configLEFT_DISPLAY 0\r
+#define configRIGHT_DISPLAY 1\r
+\r
#endif /* FREERTOS_CONFIG_H */\r
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\croutine.obj"\r
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\DiceTask.obj"\r
-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\ParTest.obj"\r
--a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\flash.obj"\r
+-a "C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\SegmentToggleTasks.obj"\r
\r
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\croutine.obj"\r
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\DiceTask.obj"\r
"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\ParTest.obj"\r
-"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\flash.obj"\r
+"C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\OBJ\SegmentToggleTasks.obj"\r
\r
--- /dev/null
+/*\r
+ FreeRTOS.org V5.1.1 - Copyright (C) 2003-2008 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section \r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ ***************************************************************************\r
+ * *\r
+ * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *\r
+ * and even write all or part of your application on your behalf. *\r
+ * See http://www.OpenRTOS.com for details of the services we provide to *\r
+ * expedite your project. *\r
+ * *\r
+ ***************************************************************************\r
+ ***************************************************************************\r
+\r
+ Please ensure to read the configuration and relevant port sections of the\r
+ online documentation.\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and \r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety \r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting, \r
+ licensing and training services.\r
+*/\r
+\r
+/**\r
+ * This version of flash .c is for use on systems that have limited stack space\r
+ * and no display facilities. The complete version can be found in the \r
+ * Demo/Common/Full directory.\r
+ * \r
+ * Three tasks are created, each of which flash an LED at a different rate. The first \r
+ * LED flashes every 200ms, the second every 400ms, the third every 600ms.\r
+ *\r
+ * The LED flash tasks provide instant visual feedback. They show that the scheduler \r
+ * is still operational.\r
+ *\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "croutine.h"\r
+\r
+/* Demo program include files. */\r
+#include "partest.h"\r
+#include "flash.h"\r
+\r
+#define ledSTACK_SIZE configMINIMAL_STACK_SIZE\r
+#define ledNUMBER_OF_LEDS ( 7 )\r
+#define ledFLASH_RATE_BASE ( ( portTickType ) 333 )\r
+\r
+#define ledMAX_FLASH_CO_ROUTINES 7\r
+#define ledCO_ROUTINE_PRIORITY 0\r
+\r
+/* The task that is created three times. */\r
+static void vLEDFlashTask( void *pvParameters );\r
+static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex );\r
+\r
+/* This task is created once, but itself creates 7 co-routines. */\r
+static void vLEDCoRoutineControlTask( void *pvParameters );\r
+\r
+static xTaskHandle xFlashTaskHandles[ ledNUMBER_OF_LEDS ] = { 0 };\r
+static xTaskHandle xCoroutineTask;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCreateFlashTasksAndCoRoutines( void )\r
+{\r
+signed short sLEDTask;\r
+\r
+ /* Create the three tasks that flash segments on the first LED. */\r
+ for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )\r
+ {\r
+ /* Spawn the task. */\r
+ xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDt", ledSTACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );\r
+ }\r
+\r
+ /* Create the task in which the co-routines run. */\r
+ xTaskCreate( vLEDCoRoutineControlTask, ( signed char * ) "LEDc", ledSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )\r
+{\r
+short sLEDTask;\r
+\r
+ if( ucIndex == 0 )\r
+ {\r
+ for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )\r
+ {\r
+ if( xFlashTaskHandles[ sLEDTask ] != NULL )\r
+ {\r
+ if( sSuspendTasks == pdTRUE )\r
+ {\r
+ vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );\r
+ }\r
+ else\r
+ {\r
+ vTaskResume( xFlashTaskHandles[ sLEDTask ] );\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if( sSuspendTasks == pdTRUE )\r
+ {\r
+ vTaskSuspend( xCoroutineTask );\r
+ }\r
+ else\r
+ {\r
+ vTaskResume( xCoroutineTask );\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vLEDFlashTask( void * pvParameters )\r
+{\r
+portTickType xFlashRate, xLastFlashTime;\r
+unsigned short usLED;\r
+\r
+ /* The LED to flash is passed in as the task parameter. */\r
+ usLED = ( unsigned short ) pvParameters;\r
+\r
+ /* Calculate the rate at which this task is going to toggle its LED. */\r
+ xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) usLED );\r
+ xFlashRate /= portTICK_RATE_MS;\r
+\r
+ /* We will turn the LED on and off again in the delay period, so each\r
+ delay is only half the total period. */\r
+ xFlashRate /= ( portTickType ) 2;\r
+\r
+ /* We need to initialise xLastFlashTime prior to the first call to \r
+ vTaskDelayUntil(). */\r
+ xLastFlashTime = xTaskGetTickCount();\r
+\r
+ for(;;)\r
+ {\r
+ /* Delay for half the flash period then turn the LED on. */\r
+ vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
+ vParTestToggleLED( usLED );\r
+\r
+ /* Delay for half the flash period then turn the LED off. */\r
+ vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
+ vParTestToggleLED( usLED );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vLEDCoRoutineControlTask( void *pvParameters )\r
+{\r
+unsigned short usCoroutine;\r
+\r
+ ( void ) pvParameters;\r
+\r
+ for( usCoroutine = 0; usCoroutine < ledMAX_FLASH_CO_ROUTINES; usCoroutine++ )\r
+ {\r
+ xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );\r
+ }\r
+\r
+ for( ;; )\r
+ {\r
+ vCoRoutineSchedule();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex )\r
+{\r
+/* The usIndex parameter of the co-routine function is used as an index into\r
+the xFlashRates array to obtain the delay period to use. */\r
+static const portTickType xFlashRates[ ledMAX_FLASH_CO_ROUTINES ] = { 150 / portTICK_RATE_MS,\r
+ 300 / portTICK_RATE_MS,\r
+ 450 / portTICK_RATE_MS,\r
+ 600 / portTICK_RATE_MS,\r
+ 750 / portTICK_RATE_MS,\r
+ 900 / portTICK_RATE_MS,\r
+ 1050 / portTICK_RATE_MS };\r
+\r
+ /* Co-routines MUST start with a call to crSTART. */\r
+ crSTART( xHandle );\r
+\r
+ for( ;; )\r
+ {\r
+ vParTestToggleLED( usIndex + 8 );\r
+ crDELAY( xHandle, xFlashRates[ usIndex ] );\r
+ }\r
+\r
+ /* Co-routines MUST end with a call to crEND. */\r
+ crEND();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
F9=0 c ..\..\Source\tasks.c\r
F10=0 f Demo Source\r
F11=0 c DiceTask.c\r
-F12=0 c flash.c\r
-F13=0 c main.c\r
-F14=0 a mb96356rs.asm\r
-F15=0 c ParTest\ParTest.c\r
+F12=0 c main.c\r
+F13=0 a mb96356rs.asm\r
+F14=0 c ParTest\ParTest.c\r
+F15=0 c SegmentToggleTasks.c\r
F16=0 a START.ASM\r
F17=0 c vectors.c\r
\r
F12-8=- ..\..\Source\Include\task.h\r
F12-9=- ..\..\Source\Include\list.h\r
F12-10=- ..\..\Source\Include\croutine.h\r
-F13=9 c 1 DiceTask.c\r
+F13=11 c 1 DiceTask.c\r
F13-1=- ..\..\Source\Include\FreeRTOS.h\r
F13-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h\r
F13-3=- ..\..\Source\Include\projdefs.h\r
F13-7=- ..\..\Source\portable\Softune\MB96340\portmacro.h\r
F13-8=- ..\..\Source\Include\task.h\r
F13-9=- ..\..\Source\Include\list.h\r
+F13-10=- ..\..\Source\Include\semphr.h\r
+F13-11=- ..\..\Source\Include\queue.h\r
F14=10 c 1 ParTest\ParTest.c\r
F14-1=- ..\..\Source\Include\FreeRTOS.h\r
F14-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h\r
F14-8=- ..\..\Source\Include\task.h\r
F14-9=- ..\..\Source\Include\list.h\r
F14-10=- ..\Common\Include\ParTest.h\r
-F15=12 c 1 flash.c\r
-F15-1=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stdlib.h\r
-F15-2=- ..\..\..\..\..\..\devtools\Softune\LIB\907\INCLUDE\stddef.h\r
-F15-3=- ..\..\Source\Include\FreeRTOS.h\r
-F15-4=- ..\..\Source\Include\projdefs.h\r
-F15-5=- FreeRTOSConfig.h\r
-F15-6=- mb96356rs.h\r
-F15-7=- ..\..\Source\Include\portable.h\r
-F15-8=- ..\..\Source\portable\Softune\MB96340\portmacro.h\r
-F15-9=- ..\..\Source\Include\task.h\r
-F15-10=- ..\..\Source\Include\list.h\r
-F15-11=- ..\Common\Include\ParTest.h\r
-F15-12=- ..\Common\Include\Flash.h\r
+F15=0 c 1 SegmentToggleTasks.c\r
\r
[BUILDMODE-Debug]\r
kernel=0\r
WSP=C:\E\Dev\FreeRTOS\WorkingCopy3\Demo\MB96350_Softune_Dice_Kit\\r
\r
[EditState]\r
-STATE-1=vectors.c:40\r
-Count=1\r
+Count=0\r
\r
+++ /dev/null
-/*\r
- FreeRTOS.org V5.1.1 - Copyright (C) 2003-2008 Richard Barry.\r
-\r
- This file is part of the FreeRTOS.org distribution.\r
-\r
- FreeRTOS.org is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; either version 2 of the License, or\r
- (at your option) any later version.\r
-\r
- FreeRTOS.org is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with FreeRTOS.org; if not, write to the Free Software\r
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-\r
- A special exception to the GPL can be applied should you wish to distribute\r
- a combined work that includes FreeRTOS.org, without being obliged to provide\r
- the source code for any proprietary components. See the licensing section \r
- of http://www.FreeRTOS.org for full details of how and when the exception\r
- can be applied.\r
-\r
- ***************************************************************************\r
- ***************************************************************************\r
- * *\r
- * SAVE TIME AND MONEY! We can port FreeRTOS.org to your own hardware, *\r
- * and even write all or part of your application on your behalf. *\r
- * See http://www.OpenRTOS.com for details of the services we provide to *\r
- * expedite your project. *\r
- * *\r
- ***************************************************************************\r
- ***************************************************************************\r
-\r
- Please ensure to read the configuration and relevant port sections of the\r
- online documentation.\r
-\r
- http://www.FreeRTOS.org - Documentation, latest information, license and \r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety \r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting, \r
- licensing and training services.\r
-*/\r
-\r
-/**\r
- * This version of flash .c is for use on systems that have limited stack space\r
- * and no display facilities. The complete version can be found in the \r
- * Demo/Common/Full directory.\r
- * \r
- * Three tasks are created, each of which flash an LED at a different rate. The first \r
- * LED flashes every 200ms, the second every 400ms, the third every 600ms.\r
- *\r
- * The LED flash tasks provide instant visual feedback. They show that the scheduler \r
- * is still operational.\r
- *\r
- */\r
-\r
-\r
-#include <stdlib.h>\r
-\r
-/* Scheduler include files. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "croutine.h"\r
-\r
-/* Demo program include files. */\r
-#include "partest.h"\r
-#include "flash.h"\r
-\r
-#define ledSTACK_SIZE configMINIMAL_STACK_SIZE\r
-#define ledNUMBER_OF_LEDS ( 7 )\r
-#define ledFLASH_RATE_BASE ( ( portTickType ) 333 )\r
-\r
-#define ledMAX_FLASH_CO_ROUTINES 7\r
-#define ledCO_ROUTINE_PRIORITY 0\r
-\r
-/* The task that is created three times. */\r
-static void vLEDFlashTask( void *pvParameters );\r
-static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex );\r
-\r
-/* This task is created once, but itself creates 7 co-routines. */\r
-static void vLEDCoRoutineControlTask( void *pvParameters );\r
-\r
-static xTaskHandle xFlashTaskHandles[ ledNUMBER_OF_LEDS ] = { 0 };\r
-static xTaskHandle xCoroutineTask;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vCreateFlashTasksAndCoRoutines( void )\r
-{\r
-signed short sLEDTask;\r
-\r
- /* Create the three tasks that flash segments on the first LED. */\r
- for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )\r
- {\r
- /* Spawn the task. */\r
- xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDt", ledSTACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );\r
- }\r
-\r
- /* Create the task in which the co-routines run. */\r
- xTaskCreate( vLEDCoRoutineControlTask, ( signed char * ) "LEDc", ledSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )\r
-{\r
-short sLEDTask;\r
-\r
- if( ucIndex == 0 )\r
- {\r
- for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )\r
- {\r
- if( xFlashTaskHandles[ sLEDTask ] != NULL )\r
- {\r
- if( sSuspendTasks == pdTRUE )\r
- {\r
- vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );\r
- }\r
- else\r
- {\r
- vTaskResume( xFlashTaskHandles[ sLEDTask ] );\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- if( sSuspendTasks == pdTRUE )\r
- {\r
- vTaskSuspend( xCoroutineTask );\r
- }\r
- else\r
- {\r
- vTaskResume( xCoroutineTask );\r
- }\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vLEDFlashTask( void * pvParameters )\r
-{\r
-portTickType xFlashRate, xLastFlashTime;\r
-unsigned short usLED;\r
-\r
- /* The LED to flash is passed in as the task parameter. */\r
- usLED = ( unsigned short ) pvParameters;\r
-\r
- /* Calculate the rate at which this task is going to toggle its LED. */\r
- xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) usLED );\r
- xFlashRate /= portTICK_RATE_MS;\r
-\r
- /* We will turn the LED on and off again in the delay period, so each\r
- delay is only half the total period. */\r
- xFlashRate /= ( portTickType ) 2;\r
-\r
- /* We need to initialise xLastFlashTime prior to the first call to \r
- vTaskDelayUntil(). */\r
- xLastFlashTime = xTaskGetTickCount();\r
-\r
- for(;;)\r
- {\r
- /* Delay for half the flash period then turn the LED on. */\r
- vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
- vParTestToggleLED( usLED );\r
-\r
- /* Delay for half the flash period then turn the LED off. */\r
- vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
- vParTestToggleLED( usLED );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void vLEDCoRoutineControlTask( void *pvParameters )\r
-{\r
-unsigned short usCoroutine;\r
-\r
- ( void ) pvParameters;\r
-\r
- for( usCoroutine = 0; usCoroutine < ledMAX_FLASH_CO_ROUTINES; usCoroutine++ )\r
- {\r
- xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );\r
- }\r
-\r
- for( ;; )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex )\r
-{\r
-/* The usIndex parameter of the co-routine function is used as an index into\r
-the xFlashRates array to obtain the delay period to use. */\r
-static const portTickType xFlashRates[ ledMAX_FLASH_CO_ROUTINES ] = { 150 / portTICK_RATE_MS,\r
- 300 / portTICK_RATE_MS,\r
- 450 / portTICK_RATE_MS,\r
- 600 / portTICK_RATE_MS,\r
- 750 / portTICK_RATE_MS,\r
- 900 / portTICK_RATE_MS,\r
- 1050 / portTICK_RATE_MS };\r
-\r
- /* Co-routines MUST start with a call to crSTART. */\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- vParTestToggleLED( usIndex + 8 );\r
- crDELAY( xHandle, xFlashRates[ usIndex ] );\r
- }\r
-\r
- /* Co-routines MUST end with a call to crEND. */\r
- crEND();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
licensing and training services.\r
*/\r
\r
+\r
+/*****\r
+ *\r
+ * See http://www.freertos.org/Documentation/FreeRTOS-documentation-and-book.html\r
+ * for an introductory guide to using real time kernels, and FreeRTOS in \r
+ * particular. \r
+ *\r
+ *****\r
+ * \r
+ * The DICE-KIT-16FX has two 7 segment displays and two buttons that can\r
+ * generate interrupts. This example uses this IO as follows:\r
+ *\r
+ *\r
+ * - Left 7 segment display - \r
+ *\r
+ * 7 'flash' tasks are created, each of which toggles a single segment of the \r
+ * left display. Each task executes at a fixed frequency, with a different \r
+ * frequency being used by each task.\r
+ *\r
+ * When button SW2 is pressed an interrupt is generated that wakes up a 'dice'\r
+ * task. The dice task suspends the 7 tasks that are accessing the left display\r
+ * before simulating a dice being thrown by generating a random number between\r
+ * 1 and 6. After the number has been generated the task sleeps for 5 seconds,\r
+ * if SW2 is pressed again within the 5 seconds another random number is \r
+ * generated, if SW2 is not pressed within the 5 seconds then the 7 tasks are\r
+ * un-suspended and will once again toggle the segments of the left hand display.\r
+ *\r
+ *\r
+ * - Right 7 segment display -\r
+ *\r
+ * Control of the right side 7 segment display is very similar to that of the\r
+ * left, except co-routines are used to toggle the segments instead of tasks,\r
+ * and button SW3 is used instead of SW2.\r
+ *\r
+ *\r
+ * - Notes -\r
+ *\r
+ * Only one dice task is actually defined. Two instances of this single\r
+ * definition are created, the first to simulate a dice being thrown on the left\r
+ * display, and the other to simulate a dice being thrown on the right display.\r
+ * The task parameter is used to let the dice tasks know which display to \r
+ * control.\r
+ *\r
+ * Both dice tasks and the flash tasks operate completely independently under\r
+ * the control of FreeRTOS. 11 tasks and 7 co-routines are created in total,\r
+ * including the idle task. \r
+ *\r
+ * The co-routines all execute within a single low priority task.\r
+ *\r
+ *****/\r
+\r
/* Kernel includes. */\r
#include "FreeRTOS.h"\r
#include "Task.h"\r
#include "ParTest.h"\r
#include "Flash.h"\r
\r
+/* The priority at which the dice task execute. */\r
+#define mainDICE_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+\r
+/*\r
+ * Sets up the MCU IO for the 7 segment displays and the button inputs.\r
+ */\r
static void prvSetupHardware( void );\r
\r
-#define mainDISPLAY_1 0\r
-#define mainDISPLAY_2 1\r
+/*\r
+ * The function that creates the flash tasks and co-routines (the tasks and\r
+ * co-routines that toggle the 7 segment display segments.\r
+ */\r
+extern vCreateFlashTasksAndCoRoutines( void );\r
\r
-#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
/*-----------------------------------------------------------*/\r
\r
void main( void )\r
{\r
+ /* Setup the MCU IO. */\r
prvSetupHardware();\r
\r
- vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );\r
+ /* Create the tasks and co-routines that toggle the display segments. */\r
+ vCreateFlashTasksAndCoRoutines();\r
+\r
+ /* Create a 'dice' task to control the left hand display. */\r
+ xTaskCreate( vDiceTask, ( signed char * ) "Dice1", configMINIMAL_STACK_SIZE, ( void * ) configLEFT_DISPLAY, mainDICE_PRIORITY, NULL );\r
\r
- xTaskCreate( vDiceTask, ( signed char * ) "Dice1", configMINIMAL_STACK_SIZE, ( void * ) mainDISPLAY_1, tskIDLE_PRIORITY, NULL );\r
- xTaskCreate( vDiceTask, ( signed char * ) "Dice2", configMINIMAL_STACK_SIZE, ( void * ) mainDISPLAY_2, tskIDLE_PRIORITY, NULL );\r
+ /* Create a 'dice' task to control the right hand display. */\r
+ xTaskCreate( vDiceTask, ( signed char * ) "Dice2", configMINIMAL_STACK_SIZE, ( void * ) configRIGHT_DISPLAY, mainDICE_PRIORITY, NULL );\r
\r
+ /* Start the scheduler running. */\r
vTaskStartScheduler();\r
\r
+ /* If this loop is executed then there was insufficient heap memory for the\r
+ idle task to be created - causing vTaskStartScheduler() to return. */\r
while( 1 );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vApplicationIdleHook( void )\r
-{\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
static void prvSetupHardware( void )\r
{\r
/* Setup interrupt hardware - interrupts are kept disabled for now to\r
ELVRL1_LB9 = 1;\r
ELVRL1_LA9 = 1;\r
\r
- /* Reset and enable the interrput request. */\r
+ /* Reset and enable the interrupt request. */\r
EIRR1_ER9 = 0;\r
ENIR1_EN9 = 1; \r
}\r
$other\r
-Xset_rora\r
$time\r
-1233330876\r
+1233411019\r
$end\r
$3\r
-dt s,d,r,a\r
-Xdof\r
$other\r
$time\r
-1233330876\r
+1233411019\r
$end\r
$4\r
-Xdof\r