summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2009-01-31 12:56:33 +0000
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2009-01-31 12:56:33 +0000
commit03bcc24ff3ecd77b8b171f4691f5100a0462d2ab (patch)
treed166b7483af29650f527d57f12efbb535467a782
parent3a45279f9dbbcb99a1ba10ee79c3eb7672eacb7a (diff)
downloadfreertos-03bcc24ff3ecd77b8b171f4691f5100a0462d2ab.tar.gz
freertos-03bcc24ff3ecd77b8b171f4691f5100a0462d2ab.tar.bz2
freertos-03bcc24ff3ecd77b8b171f4691f5100a0462d2ab.tar.xz
Extend FX16 functionality.
git-svn-id: https://freertos.svn.sourceforge.net/svnroot/freertos/trunk@658 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
-rw-r--r--Demo/MB96350_Softune_Dice_Kit/DiceTask.c114
-rw-r--r--Demo/MB96350_Softune_Dice_Kit/flash.c134
-rw-r--r--Demo/MB96350_Softune_Dice_Kit/vectors.c8
3 files changed, 160 insertions, 96 deletions
diff --git a/Demo/MB96350_Softune_Dice_Kit/DiceTask.c b/Demo/MB96350_Softune_Dice_Kit/DiceTask.c
index 849b4b72..33deebf1 100644
--- a/Demo/MB96350_Softune_Dice_Kit/DiceTask.c
+++ b/Demo/MB96350_Softune_Dice_Kit/DiceTask.c
@@ -51,14 +51,9 @@
#include "task.h"
#include "semphr.h"
-#define diceMIN 1
-#define diceMAX 6
-#define diceRUN_MIN 600000L
-#define diceRUN_MAX 1200000L
+#define diceDELAY_BETWEEN_RANDOM_NUMBERS_ms ( 20 )
+#define diceRUN_TIME ( 2000 / diceDELAY_BETWEEN_RANDOM_NUMBERS_ms )
-#define diceSTATE_STOPPED 0
-#define diceSTATE_STARTUP 1
-#define diceSTATE_RUNNING 2
#define diceEND_DELAY ( 5000 / portTICK_RATE_MS )
@@ -80,61 +75,72 @@ extern volatile unsigned char *pucDisplayOutput[ 2 ];
void vDiceTask( void *pvParameters )
{
-char cDiceState = diceSTATE_STOPPED;
unsigned char ucDiceValue, ucIndex;
-unsigned long ulDiceRunTime, ulDiceDelay, ulDiceDelayReload;
-extern void vToggleFlashTaskSuspendState( void );
+unsigned long ulDiceRunTime;
+extern void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks );
+ /* Two instances of this task are created so the task parameter is used
+ to pass in an index that allows this task to know which file scope variables
+ it should use. Cast this index into a usable type. */
ucIndex = ( unsigned char ) pvParameters;
+
+ /* A binary semaphore is used to signal button push events. Create the
+ semaphore before it is used. */
vSemaphoreCreateBinary( xSemaphores[ ucIndex ] );
- srand( ( unsigned char ) diceRUN_MIN );
+
+ /* Make sure the semaphore starts in the wanted state - no button pushes
+ pending. This call will just clear any button pushes that are latched.
+ Passing in 0 as the block time means the call will not wait for any further
+ button pushes. */
+ prvButtonHit( ucIndex, 0 );
+
+ /* Seed the random number generator. */
+ srand( ( unsigned char ) diceRUN_TIME );
for( ;; )
{
- switch( cDiceState )
+ /* Wait for a button push. This task will enter the Blocked state
+ (will not run again) until after a button has been pushed. */
+ prvButtonHit( ucIndex, portMAX_DELAY );
+
+ /* The next line will only execute after a button has been pushed -
+ initialise the variable used to shake the dice. */
+ ulDiceRunTime = diceRUN_TIME;;
+
+ /* Suspend the flash tasks so this task has exclusive access to the
+ display. */
+ vSuspendFlashTasks( ucIndex, pdTRUE );
+
+ while( ulDiceRunTime > 0 )
+ {
+ ulDiceRunTime--;
+
+ /* Generate and display a random number. */
+ ucDiceValue = rand() % 6 + 1;
+ dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ ucDiceValue ];
+
+ /* Block/sleep for a very short time before generating the next
+ random number. */
+ vTaskDelay( diceDELAY_BETWEEN_RANDOM_NUMBERS_ms / portTICK_RATE_MS );
+ }
+
+ /* Wait for a short time before resuming (un-suspending) the flash
+ task. The flash tasks are only restarted if a button is not pushed
+ during this delay - if a button is pushed then the dice are shaken
+ again.
+
+ First...clear any button pushes that are already pending. Again a
+ block time of zero is used so the function does not wait for any
+ pushes. */
+ prvButtonHit( ucIndex, 0 );
+
+ /* Second...peek the semaphore. This task will block/sleep until a
+ button is pushed again, but because the peek function is used a
+ button being pushed will unblock the task but remain pending. */
+ if( xQueuePeek( xSemaphores[ ucIndex ], NULL, diceEND_DELAY ) == pdFALSE )
{
- case diceSTATE_STOPPED:
-
- prvButtonHit( ucIndex, portMAX_DELAY );
- ulDiceRunTime = diceRUN_MIN;
- cDiceState = diceSTATE_RUNNING;
- ulDiceDelay = 1;
- ulDiceDelayReload = 1;
- cDiceState = diceSTATE_RUNNING;
- if( ucIndex == 0 )
- {
- vToggleFlashTaskSuspendState();
- }
-
- break;
-
- case diceSTATE_RUNNING:
-
- ulDiceRunTime--;
- ulDiceDelay--;
-
- if( !ulDiceDelay )
- {
- ucDiceValue = rand() % 6 + 1;
- dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ ucDiceValue ];
- ulDiceDelayReload = ulDiceDelayReload + 100;
- ulDiceDelay = ulDiceDelayReload;
- }
-
- if( ulDiceRunTime == 0 )
- {
- dice7SEG_Value( ucIndex ) = ( dice7SEG_Value( ucIndex ) | 0xf7 ) & cDisplaySegments[ ucIndex ][ rand() % 6 + 1 ];
- cDiceState = diceSTATE_STOPPED;
-
- if( ucIndex == 0 )
- {
- vTaskDelay( diceEND_DELAY );
- *pucDisplayOutput[ ucIndex ] = 0xff;
- vToggleFlashTaskSuspendState();
- }
- }
-
- break;
+ *pucDisplayOutput[ ucIndex ] = 0xff;
+ vSuspendFlashTasks( ucIndex, pdFALSE );
}
}
}
diff --git a/Demo/MB96350_Softune_Dice_Kit/flash.c b/Demo/MB96350_Softune_Dice_Kit/flash.c
index d8bd0341..bbf97f59 100644
--- a/Demo/MB96350_Softune_Dice_Kit/flash.c
+++ b/Demo/MB96350_Softune_Dice_Kit/flash.c
@@ -66,80 +66,92 @@
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
+#include "croutine.h"
/* Demo program include files. */
#include "partest.h"
#include "flash.h"
#define ledSTACK_SIZE configMINIMAL_STACK_SIZE
-#define ledNUMBER_OF_LEDS ( 3 )
+#define ledNUMBER_OF_LEDS ( 7 )
#define ledFLASH_RATE_BASE ( ( portTickType ) 333 )
-/* Variable used by the created tasks to calculate the LED number to use, and
-the rate at which they should flash the LED. */
-static volatile unsigned portBASE_TYPE uxFlashTaskNumber = 0;
+#define ledMAX_FLASH_CO_ROUTINES 7
+#define ledCO_ROUTINE_PRIORITY 0
/* The task that is created three times. */
-static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters );
+static void vLEDFlashTask( void *pvParameters );
+static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex );
+
+/* This task is created once, but itself creates 7 co-routines. */
+static void vLEDCoRoutineControlTask( void *pvParameters );
static xTaskHandle xFlashTaskHandles[ ledNUMBER_OF_LEDS ] = { 0 };
+static xTaskHandle xCoroutineTask;
/*-----------------------------------------------------------*/
void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority )
{
-signed portBASE_TYPE xLEDTask;
+signed short sLEDTask;
- /* Create the three tasks. */
- for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )
+ /* Create the three tasks that flash segments on the first LED. */
+ for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )
{
/* Spawn the task. */
- xTaskCreate( vLEDFlashTask, ( signed portCHAR * ) "LEDx", ledSTACK_SIZE, NULL, uxPriority, &( xFlashTaskHandles[ xLEDTask ] ) );
+ xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDt", ledSTACK_SIZE, ( void * ) sLEDTask, uxPriority, &( xFlashTaskHandles[ sLEDTask ] ) );
}
+
+ /* Create the task in which the co-routines run. */
+ xTaskCreate( vLEDCoRoutineControlTask, ( signed char * ) "LEDc", ledSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );
}
/*-----------------------------------------------------------*/
-void vSuspendFlashTasks( short sSuspendTasks )
+void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )
{
-signed portBASE_TYPE xLEDTask;
+short sLEDTask;
- for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )
+ if( ucIndex == 0 )
{
- if( xFlashTaskHandles[ xLEDTask ] != NULL )
+ for( sLEDTask = 0; sLEDTask < ledNUMBER_OF_LEDS; ++sLEDTask )
{
- if( sSuspendTasks == pdTRUE )
+ if( xFlashTaskHandles[ sLEDTask ] != NULL )
{
- vTaskSuspend( xFlashTaskHandles[ xLEDTask ] );
- }
- else
- {
- vTaskResume( xFlashTaskHandles[ xLEDTask ] );
+ if( sSuspendTasks == pdTRUE )
+ {
+ vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );
+ }
+ else
+ {
+ vTaskResume( xFlashTaskHandles[ sLEDTask ] );
+ }
}
}
}
+ else
+ {
+ if( sSuspendTasks == pdTRUE )
+ {
+ vTaskSuspend( xCoroutineTask );
+ }
+ else
+ {
+ vTaskResume( xCoroutineTask );
+ }
+ }
}
/*-----------------------------------------------------------*/
-static portTASK_FUNCTION( vLEDFlashTask, pvParameters )
+static void vLEDFlashTask( void * pvParameters )
{
portTickType xFlashRate, xLastFlashTime;
-unsigned portBASE_TYPE uxLED;
+unsigned short usLED;
- /* The parameters are not used. */
- ( void ) pvParameters;
-
- /* Calculate the LED and flash rate. */
- portENTER_CRITICAL();
- {
- /* See which of the eight LED's we should use. */
- uxLED = uxFlashTaskNumber;
-
- /* Update so the next task uses the next LED. */
- uxFlashTaskNumber++;
- }
- portEXIT_CRITICAL();
+ /* The LED to flash is passed in as the task parameter. */
+ usLED = ( unsigned short ) pvParameters;
- xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) uxLED );
+ /* Calculate the rate at which this task is going to toggle its LED. */
+ xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) usLED );
xFlashRate /= portTICK_RATE_MS;
/* We will turn the LED on and off again in the delay period, so each
@@ -154,11 +166,57 @@ unsigned portBASE_TYPE uxLED;
{
/* Delay for half the flash period then turn the LED on. */
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
- vParTestToggleLED( uxLED );
+ vParTestToggleLED( usLED );
/* Delay for half the flash period then turn the LED off. */
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
- vParTestToggleLED( uxLED );
+ vParTestToggleLED( usLED );
}
-} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */
+}
+/*-----------------------------------------------------------*/
+
+static void vLEDCoRoutineControlTask( void *pvParameters )
+{
+unsigned short usCoroutine;
+
+ ( void ) pvParameters;
+
+ for( usCoroutine = 0; usCoroutine < ledMAX_FLASH_CO_ROUTINES; usCoroutine++ )
+ {
+ xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );
+ }
+
+ for( ;; )
+ {
+ vCoRoutineSchedule();
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvFixedDelayCoRoutine( xCoRoutineHandle xHandle, unsigned short usIndex )
+{
+/* The usIndex parameter of the co-routine function is used as an index into
+the xFlashRates array to obtain the delay period to use. */
+static const portTickType xFlashRates[ ledMAX_FLASH_CO_ROUTINES ] = { 150 / portTICK_RATE_MS,
+ 300 / portTICK_RATE_MS,
+ 450 / portTICK_RATE_MS,
+ 600 / portTICK_RATE_MS,
+ 750 / portTICK_RATE_MS,
+ 900 / portTICK_RATE_MS,
+ 1050 / portTICK_RATE_MS };
+
+ /* Co-routines MUST start with a call to crSTART. */
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ vParTestToggleLED( usIndex + 8 );
+ crDELAY( xHandle, xFlashRates[ usIndex ] );
+ }
+
+ /* Co-routines MUST end with a call to crEND. */
+ crEND();
+}
+/*-----------------------------------------------------------*/
+
diff --git a/Demo/MB96350_Softune_Dice_Kit/vectors.c b/Demo/MB96350_Softune_Dice_Kit/vectors.c
index 193db79c..6276081f 100644
--- a/Demo/MB96350_Softune_Dice_Kit/vectors.c
+++ b/Demo/MB96350_Softune_Dice_Kit/vectors.c
@@ -34,10 +34,10 @@ void InitIrqLevels(void)
ICR = (irq << 8) | DEFAULT_ILM_MASK;
}
- ICR = ( (54 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* Reload Timer 0 */
- ICR = ( (12 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* Delayed interrupt of 16FX Family */
- ICR = ( (24 & 0xFF) << 8 ) | ( configKERNEL_INTERRUPT_PRIORITY - 1 ); /* INT8 */
- ICR = ( (25 & 0xFF) << 8 ) | ( configKERNEL_INTERRUPT_PRIORITY - 1 ); /* INT9 */
+ ICR = ( (54 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* Reload Timer 0 */
+ ICR = ( (12 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* Delayed interrupt of 16FX Family */
+ ICR = ( (24 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* INT8 */
+ ICR = ( (25 & 0xFF) << 8 ) | configKERNEL_INTERRUPT_PRIORITY; /* INT9 */
}
/*---------------------------------------------------------------------------