コード例 #1
0
static void prvRecursiveMutexPollingTask( void *pvParameters )
{
	/* Just to remove compiler warning. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Keep attempting to obtain the mutex.  We should only obtain it when
		the blocking task has suspended itself, which in turn should only
		happen when the controlling task is also suspended. */
		if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )
		{
			/* Is the blocking task suspended? */
			if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) )
			{
				xErrorOccurred = pdTRUE;
			}
			else
			{
				/* Keep count of the number of cycles this task has performed 
				so a stall can be detected. */
				uxPollingCycles++;

				/* We can resume the other tasks here even though they have a
				higher priority than the polling task.  When they execute they
				will attempt to obtain the mutex but fail because the polling
				task is still the mutex holder.  The polling task (this task)
				will then inherit the higher priority.  The Blocking task will
				block indefinitely when it attempts to obtain the mutex, the
				Controlling task will only block for a fixed period and an
				error will be latched if the polling task has not returned the
				mutex by the time this fixed period has expired. */				
				vTaskResume( xBlockingTaskHandle );
				#if configUSE_PREEMPTION == 0
					taskYIELD();
				#endif

				vTaskResume( xControllingTaskHandle );
				#if configUSE_PREEMPTION == 0
					taskYIELD();
				#endif

				/* The other two tasks should now have executed and no longer
				be suspended. */
				if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) )
				{
					xErrorOccurred = pdTRUE;
				}				
			
				/* Release the mutex, disinheriting the higher priority again. */
				if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
				{
					xErrorOccurred = pdTRUE;
				}

				#if configUSE_PREEMPTION == 0
					taskYIELD();
				#endif
			}
		}

		#if configUSE_PREEMPTION == 0
		{
			taskYIELD();
		}
		#endif
	}
}
コード例 #2
0
ファイル: queue.c プロジェクト: Paolo-Maffei/nxstack
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
{
signed portBASE_TYPE xReturn;
xTimeOutType xTimeOut;

	/* This function is very similar to xQueueSend().  See comments within
	xQueueSend() for a more detailed explanation.

	Make sure other tasks do not access the queue. */
	vTaskSuspendAll();

	/* Capture the current time status for future reference. */
	vTaskSetTimeOutState( &xTimeOut );

	/* Make sure interrupts do not access the queue. */
	prvLockQueue( pxQueue );

	do
	{
		/* If there are no messages in the queue we may have to block. */
		if( prvIsQueueEmpty( pxQueue ) )
		{
			/* There are no messages in the queue, do we want to block or just
			leave with nothing? */			
			if( xTicksToWait > ( portTickType ) 0 )
			{
				vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
				taskENTER_CRITICAL();
				{
					prvUnlockQueue( pxQueue );
					if( !xTaskResumeAll() )
					{
						taskYIELD();
					}
	
					vTaskSuspendAll();
					prvLockQueue( pxQueue );
				}
				taskEXIT_CRITICAL();
			}
		}
	
		taskENTER_CRITICAL();
		{
			if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
			{
				pxQueue->pcReadFrom += pxQueue->uxItemSize;
				if( pxQueue->pcReadFrom >= pxQueue->pcTail )
				{
					pxQueue->pcReadFrom = pxQueue->pcHead;
				}
				--( pxQueue->uxMessagesWaiting );
				memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
	
				/* Increment the lock count so prvUnlockQueue knows to check for
				tasks waiting for space to become available on the queue. */
				++( pxQueue->xRxLock );
				xReturn = pdPASS;
			}
			else
			{
				xReturn = errQUEUE_EMPTY;
			}
		}
		taskEXIT_CRITICAL();

		if( xReturn == errQUEUE_EMPTY )
		{
			if( xTicksToWait > 0 )
			{
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					xReturn = queueERRONEOUS_UNBLOCK;
				}
			}
		}
	} while( xReturn == queueERRONEOUS_UNBLOCK );

	/* We no longer require exclusive access to the queue. */
	prvUnlockQueue( pxQueue );
	xTaskResumeAll();

	return xReturn;
}
コード例 #3
0
ファイル: main.c プロジェクト: PaxInstruments/STM32CubeF3
/**
  * @brief  Mutex Low Priority Thread.
  * @param  argument: Not used
  * @retval None
  */
static void MutexLowPriorityThread(void const *argument)
{
  /* Just to remove compiler warning */
  (void) argument;

  for (;;)
  {
    /* Keep attempting to obtain the mutex.  We should only obtain it when
    the medium-priority thread has suspended itself, which in turn should only
    happen when the high-priority thread is also suspended */
    if (osMutexWait(osMutex, mutexNO_DELAY) == osOK)
    {
      /* Is the haigh and medium-priority threads suspended? */
      if ((osThreadGetState(osHighPriorityThreadHandle) != osThreadSuspended) || (osThreadGetState(osMediumPriorityThreadHandle) != osThreadSuspended))
      {
        /* Toggle LED3 to indicate error */
        BSP_LED_Toggle(LED3);
      }
      else
      {
        /* Keep count of the number of cycles this task has performed
        so a stall can be detected */
        LowPriorityThreadCycles++;
        BSP_LED_Toggle(LED4);

        /* We can resume the other tasks here even though they have a
        higher priority than the this thread. When they execute they
        will attempt to obtain the mutex but fail because the low-priority 
        thread is still the mutex holder.  this thread will then inherit 
        the higher priority.  The medium-priority thread will block indefinitely
        when it attempts to obtain the mutex, the high-priority thread will only
        block for a fixed period and an error will be latched if the
        high-priority thread has not returned the mutex by the time this
        fixed period has expired */
        osThreadResume(osMediumPriorityThreadHandle);
        osThreadResume(osHighPriorityThreadHandle);

        /* The other two tasks should now have executed and no longer
        be suspended */
        if ((osThreadGetState(osHighPriorityThreadHandle) == osThreadSuspended) || (osThreadGetState(osMediumPriorityThreadHandle) == osThreadSuspended))
        {
          /* Toggle LED3 to indicate error */
          BSP_LED_Toggle(LED3);
        }

        /* Release the mutex, disinheriting the higher priority again */
        if (osMutexRelease(osMutex) != osOK)
        {
          /* Toggle LED3 to indicate error */
          BSP_LED_Toggle(LED3);
        }
      }
    }

#if configUSE_PREEMPTION == 0
    {
      taskYIELD();
    }
#endif
  }
}
コード例 #4
0
ファイル: AltQTest.c プロジェクト: jgordo32/nrf24_andretti
static void prvSendFrontAndBackTest( void *pvParameters )
{
    unsigned portLONG ulData, ulData2;
    xQueueHandle xQueue;

#ifdef USE_STDIO
    void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );

    const portCHAR * const pcTaskStartMsg = "Alt queue SendToFront/SendToBack/Peek test started.\r\n";

    /* Queue a message for printing to say the task has started. */
    vPrintDisplayMessage( &pcTaskStartMsg );
#endif

    xQueue = ( xQueueHandle ) pvParameters;

    for( ;; )
    {
        /* The queue is empty, so sending an item to the back of the queue
        should have the same efect as sending it to the front of the queue.

        First send to the front and check everything is as expected. */
        xQueueAltSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );

        if( uxQueueMessagesWaiting( xQueue ) != 1 )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }

        /* The data we sent to the queue should equal the data we just received
        from the queue. */
        if( ulLoopCounter != ulData )
        {
            xErrorDetected = pdTRUE;
        }

        /* Then do the same, sending the data to the back, checking everything
        is as expected. */
        if( uxQueueMessagesWaiting( xQueue ) != 0 )
        {
            xErrorDetected = pdTRUE;
        }

        xQueueAltSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );

        if( uxQueueMessagesWaiting( xQueue ) != 1 )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }

        if( uxQueueMessagesWaiting( xQueue ) != 0 )
        {
            xErrorDetected = pdTRUE;
        }

        /* The data we sent to the queue should equal the data we just received
        from the queue. */
        if( ulLoopCounter != ulData )
        {
            xErrorDetected = pdTRUE;
        }

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif



        /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
        for( ulData = 2; ulData < 5; ulData++ )
        {
            xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );
        }

        /* Now the order in the queue should be 2, 3, 4, with 2 being the first
        thing to be read out.  Now add 1 then 0 to the front of the queue. */
        if( uxQueueMessagesWaiting( xQueue ) != 3 )
        {
            xErrorDetected = pdTRUE;
        }
        ulData = 1;
        xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );
        ulData = 0;
        xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );

        /* Now the queue should be full, and when we read the data out we
        should receive 0, 1, 2, 3, 4. */
        if( uxQueueMessagesWaiting( xQueue ) != 5 )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
        {
            xErrorDetected = pdTRUE;
        }

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif

        /* Check the data we read out is in the expected order. */
        for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
        {
            /* Try peeking the data first. */
            if( xQueueAltPeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
            {
                xErrorDetected = pdTRUE;
            }

            if( ulData != ulData2 )
            {
                xErrorDetected = pdTRUE;
            }


            /* Now try receiving the data for real.  The value should be the
            same.  Clobber the value first so we know we really received it. */
            ulData2 = ~ulData2;
            if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
            {
                xErrorDetected = pdTRUE;
            }

            if( ulData != ulData2 )
            {
                xErrorDetected = pdTRUE;
            }
        }

        /* The queue should now be empty again. */
        if( uxQueueMessagesWaiting( xQueue ) != 0 )
        {
            xErrorDetected = pdTRUE;
        }

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif


        /* Our queue is empty once more, add 10, 11 to the back. */
        ulData = 10;
        if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }
        ulData = 11;
        if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }

        if( uxQueueMessagesWaiting( xQueue ) != 2 )
        {
            xErrorDetected = pdTRUE;
        }

        /* Now we should have 10, 11 in the queue.  Add 7, 8, 9 to the
        front. */
        for( ulData = 9; ulData >= 7; ulData-- )
        {
            if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )
            {
                xErrorDetected = pdTRUE;
            }
        }

        /* Now check that the queue is full, and that receiving data provides
        the expected sequence of 7, 8, 9, 10, 11. */
        if( uxQueueMessagesWaiting( xQueue ) != 5 )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
        {
            xErrorDetected = pdTRUE;
        }

        if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )
        {
            xErrorDetected = pdTRUE;
        }

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif

        /* Check the data we read out is in the expected order. */
        for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
        {
            if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )
            {
                xErrorDetected = pdTRUE;
            }

            if( ulData != ulData2 )
            {
                xErrorDetected = pdTRUE;
            }
        }

        if( uxQueueMessagesWaiting( xQueue ) != 0 )
        {
            xErrorDetected = pdTRUE;
        }

        ulLoopCounter++;
    }
}
コード例 #5
0
ファイル: semtest.c プロジェクト: HclX/freertos
static portTASK_FUNCTION( prvSemaphoreTest, pvParameters )
{
xSemaphoreParameters *pxParameters;
volatile uint32_t *pulSharedVariable, ulExpectedValue;
uint32_t ulCounter;
short sError = pdFALSE, sCheckVariableToUse;

	/* See which check variable to use.  sNextCheckVariable is not semaphore 
	protected! */
	portENTER_CRITICAL();
		sCheckVariableToUse = sNextCheckVariable;
		sNextCheckVariable++;
	portEXIT_CRITICAL();

	/* A structure is passed in as the parameter.  This contains the shared 
	variable being guarded. */
	pxParameters = ( xSemaphoreParameters * ) pvParameters;
	pulSharedVariable = pxParameters->pulSharedVariable;

	/* If we are blocking we use a much higher count to ensure loads of context
	switches occur during the count. */
	if( pxParameters->xBlockTime > ( TickType_t ) 0 )
	{
		ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
	}
	else
	{
		ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
	}

	for( ;; )
	{
		/* Try to obtain the semaphore. */
		if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
		{
			/* We have the semaphore and so expect any other tasks using the
			shared variable to have left it in the state we expect to find
			it. */
			if( *pulSharedVariable != ulExpectedValue )
			{
				sError = pdTRUE;
			}
			
			/* Clear the variable, then count it back up to the expected value
			before releasing the semaphore.  Would expect a context switch or
			two during this time. */
			for( ulCounter = ( uint32_t ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
			{
				*pulSharedVariable = ulCounter;
				if( *pulSharedVariable != ulCounter )
				{
					sError = pdTRUE;
				}
			}

			/* Release the semaphore, and if no errors have occurred increment the check
			variable. */
			if(	xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
			{
				sError = pdTRUE;
			}

			if( sError == pdFALSE )
			{
				if( sCheckVariableToUse < semtstNUM_TASKS )
				{
					( sCheckVariables[ sCheckVariableToUse ] )++;
				}
			}

			/* If we have a block time then we are running at a priority higher
			than the idle priority.  This task takes a long time to complete
			a cycle	(deliberately so to test the guarding) so will be starving
			out lower priority tasks.  Block for some time to allow give lower
			priority tasks some processor time. */
			vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
		}
		else
		{
			if( pxParameters->xBlockTime == ( TickType_t ) 0 )
			{
				/* We have not got the semaphore yet, so no point using the
				processor.  We are not blocking when attempting to obtain the
				semaphore. */
				taskYIELD();
			}
		}
	}
}
コード例 #6
0
static void vPrimaryBlockTimeTestTask( void *pvParameters )
{
portBASE_TYPE xItem, xData;
TickType_t xTimeWhenBlocking;
TickType_t xTimeToBlock, xBlockedTime;

	( void ) pvParameters;

	for( ;; )
	{
		/*********************************************************************
        Test 1

        Simple block time wakeup test on queue receives. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* The queue is empty. Attempt to read from the queue using a block
			time.  When we wake, ensure the delta in time is as expected. */
			xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );

			xTimeWhenBlocking = xTaskGetTickCount();

			/* We should unblock after xTimeToBlock having not received
			anything on the queue. */
			if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )
			{
				xErrorOccurred = pdTRUE;
			}

			/* How long were we blocked for? */
			xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;

			if( xBlockedTime < xTimeToBlock )
			{
				/* Should not have blocked for less than we requested. */
				xErrorOccurred = pdTRUE;
			}

			if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
			{
				/* Should not have blocked for longer than we requested,
				although we would not necessarily run as soon as we were
				unblocked so a margin is allowed. */
				xErrorOccurred = pdTRUE;
			}
		}

		/*********************************************************************
        Test 2

        Simple block time wakeup test on queue sends.

		First fill the queue.  It should be empty so all sends should pass. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			#if configUSE_PREEMPTION == 0
				taskYIELD();
			#endif
		}

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* The queue is full. Attempt to write to the queue using a block
			time.  When we wake, ensure the delta in time is as expected. */
			xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );

			xTimeWhenBlocking = xTaskGetTickCount();

			/* We should unblock after xTimeToBlock having not received
			anything on the queue. */
			if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )
			{
				xErrorOccurred = pdTRUE;
			}

			/* How long were we blocked for? */
			xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;

			if( xBlockedTime < xTimeToBlock )
			{
				/* Should not have blocked for less than we requested. */
				xErrorOccurred = pdTRUE;
			}

			if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
			{
				/* Should not have blocked for longer than we requested,
				although we would not necessarily run as soon as we were
				unblocked so a margin is allowed. */
				xErrorOccurred = pdTRUE;
			}
		}

		/*********************************************************************
        Test 3

		Wake the other task, it will block attempting to post to the queue.
		When we read from the queue the other task will wake, but before it
		can run we will post to the queue again.  When the other task runs it
		will find the queue still full, even though it was woken.  It should
		recognise that its block time has not expired and return to block for
		the remains of its block time.

		Wake the other task so it blocks attempting to post to the already
		full queue. */
		xRunIndicator = 0;
		vTaskResume( xSecondary );

		/* We need to wait a little to ensure the other task executes. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			/* The other task has not yet executed. */
			vTaskDelay( bktSHORT_WAIT );
		}
		/* Make sure the other task is blocked on the queue. */
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* Now when we make space on the queue the other task should wake
			but not execute as this task has higher priority. */
			if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Now fill the queue again before the other task gets a chance to
			execute.  If the other task had executed we would find the queue
			full ourselves, and the other task have set xRunIndicator. */
			if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed. */
				xErrorOccurred = pdTRUE;
			}

			/* Raise the priority of the other task so it executes and blocks
			on the queue again. */
			vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );

			/* The other task should now have re-blocked without exiting the
			queue function. */
			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed outside of the
				queue function. */
				xErrorOccurred = pdTRUE;
			}

			/* Set the priority back down. */
			vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
		}

		/* Let the other task timeout.  When it unblockes it will check that it
		unblocked at the correct time, then suspend itself. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;


		/*********************************************************************
        Test 4

		As per test 3 - but with the send and receive the other way around.
		The other task blocks attempting to read from the queue.

		Empty the queue.  We should find that it is full. */
		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}
		}

		/* Wake the other task so it blocks attempting to read from  the
		already	empty queue. */
		vTaskResume( xSecondary );

		/* We need to wait a little to ensure the other task executes. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );
		xRunIndicator = 0;

		for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
		{
			/* Now when we place an item on the queue the other task should
			wake but not execute as this task has higher priority. */
			if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Now empty the queue again before the other task gets a chance to
			execute.  If the other task had executed we would find the queue
			empty ourselves, and the other task would be suspended. */
			if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed. */
				xErrorOccurred = pdTRUE;
			}

			/* Raise the priority of the other task so it executes and blocks
			on the queue again. */
			vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );

			/* The other task should now have re-blocked without exiting the
			queue function. */
			if( xRunIndicator == bktRUN_INDICATOR )
			{
				/* The other task should not have executed outside of the
				queue function. */
				xErrorOccurred = pdTRUE;
			}
			vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
		}

		/* Let the other task timeout.  When it unblockes it will check that it
		unblocked at the correct time, then suspend itself. */
		while( xRunIndicator != bktRUN_INDICATOR )
		{
			vTaskDelay( bktSHORT_WAIT );
		}
		vTaskDelay( bktSHORT_WAIT );

		xPrimaryCycles++;
	}
}
コード例 #7
0
ファイル: file_sp5K.c プロジェクト: ppeluffo/sp5KV4
//------------------------------------------------------------------------------------
size_t FF_fwrite( const void *pvBuffer, size_t xSize)
{
	// El archivo es del tipo circular FirstIN-LastOUT.
	// Escribe un registro en la posicion apuntada por el HEAD.
	// El registro que se pasa en pvBuffer es del tipo 'frameData_t' de 38 bytes
	// pero en la memoria voy a escribir de a paginas de 64 bytes.
	// Retorna el nro.de bytes escritos y setea la variable 'errno' del FCB
	// En la posicion 63 grabo un tag con el valor 0xC5 para poder luego
	// determinar si el registro esta ocupado o vacio.

	// TESTING:
	// Memoria vacia: OK
	// Memoria llena: OK
	// Memoria con HEAD(10) > TAIL(4), Free(10) OK
	// Memoria con HEAD(3) < TAIL(8), Free(5) OK
	// Condicion de borde 1: HEAD(15), TAIL(0), Free(1) OK
	// Condicion de borde 2: HEAD(0), TAIL(1), Free(1) OK

u16 val = 0;
size_t xReturn = 0U;
u16 tryes;

	// Lo primero es obtener el semaforo del I2C
	FreeRTOS_ioctl(&pdI2C,ioctlOBTAIN_BUS_SEMPH, NULL);
	FCB.ff_stat.errno = pdFF_ERRNO_NONE;

	// Si la memoria esta llena no puedo escribir: salgo
	if ( FCB.ff_stat.rcdsFree == 0 ) {
		FCB.ff_stat.errno = pdFF_ERRNO_MEMFULL;
		goto quit;
	}

	// inicializo la estructura lineal temporal en el FCB para copiar ahi los datos y
	// calcular el checksum antes de grabarlo en memoria.
	memset( FCB.ff_buffer,0, sizeof(FCB.ff_buffer) );
	// copio los datos recibidos del frame al buffer ( 0..(xSize-1))
	memcpy ( FCB.ff_buffer, pvBuffer, xSize );
	// Calculo y grabo el checksum a continuacion del frame (en la pos.xSize)
	// El checksum es solo del dataFrame por eso paso dicho size.
	FCB.ff_buffer[xSize] = pv_memChecksum(FCB.ff_buffer, xSize );
	// Grabo el tag para indicar que el registro esta escrito.
	FCB.ff_buffer[sizeof(FCB.ff_buffer) - 1] = FF_WRTAG;

	// EE WRITE:
	// Luego indicamos el periferico i2c en el cual queremos leer
	val = EE_ADDR;
	FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_DEVADDRESS, &val);
	// Luego indicamos la direccion a escribir del dispositivo: largo ( en la ee son 2 bytes )
	val = 2;
	FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_BYTEADDRESSLENGTH, &val);
	// y direccion interna en la EE.(comienzo del registro / frontera)
	val = FF_ADDR_START + FCB.ff_stat.HEAD * FF_RECD_SIZE;
	FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_BYTEADDRESS,&val);

	// Por ultimo escribo la memoria. Escribo un pagina entera, 64 bytes.
	// Reintento hasta 3 veces.
	for ( tryes = 0; tryes < 3; tryes++ ) {
		// Write
		xReturn = FreeRTOS_write(&pdI2C, &FCB.ff_buffer, FF_RECD_SIZE);
		taskYIELD();
		// Verify
		FreeRTOS_read(&pdI2C, &FCB.check_buffer, FF_RECD_SIZE);

		if ( memcmp (&FCB.check_buffer, &FCB.ff_buffer, FF_RECD_SIZE) == 0 )
			break;

		if  ( tryes == 3 ) {
			snprintf_P( debug_printfBuff,sizeof(debug_printfBuff),PSTR("FS WR ERR: [%d]\r\n\0"), val);
			FreeRTOS_write( &pdUART1, debug_printfBuff, sizeof(debug_printfBuff) );
			FCB.ff_stat.errno = pdFF_ERRNO_MEMWR;
			xReturn = 0U;
			goto quit;
		}
	}

	if (xReturn != FF_RECD_SIZE ) {
		// Errores de escritura ?
		FCB.ff_stat.errno = pdFF_ERRNO_MEMWR;
		xReturn = 0U;
		goto quit;
	} else {
		xReturn = xSize;
		// Avanzo el puntero de WR en modo circular
		FCB.ff_stat.HEAD = (++FCB.ff_stat.HEAD == FF_MAX_RCDS) ?  0 : FCB.ff_stat.HEAD;
		FCB.ff_stat.rcdsFree--;
	}

quit:
	// libero los semaforos
	FreeRTOS_ioctl(&pdI2C,ioctlRELEASE_BUS_SEMPH, NULL);
	return(xReturn);

}
コード例 #8
0
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
{
	/* Take the mutex.  It should be available now. */
	if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )
	{
		xErrorDetected = pdTRUE;
	}

	/* Set the guarded variable to a known start value. */
	ulGuardedVariable = 0;

	/* This task's priority should be as per that assigned when the task was
	created. */
	if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
	{
		xErrorDetected = pdTRUE;
	}

	/* Now unsuspend the high priority task.  This will attempt to take the
	mutex, and block when it finds it cannot obtain it. */
	vTaskResume( xHighPriorityMutexTask );

	#if configUSE_PREEMPTION == 0
		taskYIELD();
	#endif

	/* Ensure the task is reporting its priority as blocked and not
	suspended (as it would have done in versions up to V7.5.3). */
	#if( INCLUDE_eTaskGetState == 1 )
	{
		configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
	}
	#endif /* INCLUDE_eTaskGetState */

	/* The priority of the high priority task should now have been inherited
	as by now it will have attempted to get the mutex. */
	if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
	{
		xErrorDetected = pdTRUE;
	}

	/* Now unsuspend the medium priority task.  This should not run as the
	inherited priority of this task is above that of the medium priority
	task. */
	vTaskResume( xMediumPriorityMutexTask );

	/* If the medium priority task did run then it will have incremented the
	guarded variable. */
	if( ulGuardedVariable != 0 )
	{
		xErrorDetected = pdTRUE;
	}

	/* Take the local mutex too, so two mutexes are now held. */
	if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )
	{
		xErrorDetected = pdTRUE;
	}

	/* When the local semaphore is given back the priority of this task should
	not	yet be disinherited because the shared mutex is still held.  This is a
	simplification to allow FreeRTOS to be integrated with middleware that
	attempts to hold multiple mutexes without bloating the code with complex
	algorithms.  It is possible that the high priority mutex task will
	execute as it shares a priority with this task. */
	if( xSemaphoreGive( xLocalMutex ) != pdPASS )
	{
		xErrorDetected = pdTRUE;
	}

	#if configUSE_PREEMPTION == 0
		taskYIELD();
	#endif

	/* The guarded variable is only incremented by the medium priority task,
	which still should not have executed as this task should remain at the
	higher priority, ensure this is the case. */
	if( ulGuardedVariable != 0 )
	{
		xErrorDetected = pdTRUE;
	}

	if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
	{
		xErrorDetected = pdTRUE;
	}

	/* Now also give back the shared mutex, taking the held count back to 0.
	This time the priority of this task should be disinherited back to the
	priority at which it was created.  This means the medium priority task
	should execute and increment the guarded variable.  When this task next runs
	both the high and medium priority tasks will have been suspended again. */
	if( xSemaphoreGive( xMutex ) != pdPASS )
	{
		xErrorDetected = pdTRUE;
	}

	#if configUSE_PREEMPTION == 0
		taskYIELD();
	#endif

	/* Check the guarded variable did indeed increment... */
	if( ulGuardedVariable != 1 )
	{
		xErrorDetected = pdTRUE;
	}

	/* ... and that the priority of this task has been disinherited to
	genqMUTEX_LOW_PRIORITY. */
	if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
	{
		xErrorDetected = pdTRUE;
	}
}
コード例 #9
0
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_TaskYield
 * Description   : When a task calls this function, it will give up CPU and put
 * itself to the tail of ready list.
 *
 *END**************************************************************************/
osa_status_t OSA_TaskYield(void)
{
    taskYIELD();
    return kStatus_OSA_Success;
}
コード例 #10
0
portBASE_TYPE xProcessReceivedUDPPacket( xNetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
{
xListItem *pxListItem;
portBASE_TYPE xReturn = pdPASS;
xFreeRTOS_Socket_t *pxSocket;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

	vTaskSuspendAll();
	{
		/* See if there is a list item associated with the port number on the
		list of bound sockets. */
		pxListItem = pxListFindListItemWithValue( &xBoundSocketsList, ( portTickType ) usPort );
	}
	xTaskResumeAll();

	if( pxListItem != NULL )
	{
		/* The owner of the list item is the socket itself. */
		pxSocket = ( xFreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxListItem );

		vTaskSuspendAll();
		{
			#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
			{
				/* Is the socket a member of a select() group? */
				if( pxSocket->xSelectQueue != NULL )
				{
					/* Can the select group be notified that the socket is 
					ready to be read? */
					if( xQueueSendFromISR( pxSocket->xSelectQueue, &pxSocket, &xHigherPriorityTaskWoken ) != pdPASS )
					{
						/* Could not notify the select group. */
						xReturn = pdFAIL;
						iptraceFAILED_TO_NOTIFY_SELECT_GROUP( pxSocket );
					}				
				}
			}
			#endif 

			if( xReturn == pdPASS )
			{
				taskENTER_CRITICAL();
				{
					/* Add the network packet to the list of packets to be 
					processed by the socket. */
					vListInsertEnd( &( pxSocket->xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
				}
				taskEXIT_CRITICAL();

				/* The socket's counting semaphore records how many packets are 
				waiting	to be processed by the socket. */
				xSemaphoreGiveFromISR( pxSocket->xWaitingPacketSemaphore, &xHigherPriorityTaskWoken );
			}
		}
		if( xTaskResumeAll() == pdFALSE )
		{
			if( xHigherPriorityTaskWoken != pdFALSE )
			{
				taskYIELD();
			}
		}
	}
	else
	{
		xReturn = pdFAIL;
	}

	return xReturn;
}
コード例 #11
0
ファイル: OSAL_Task.c プロジェクト: comword/SmartIR-8051
/*---------------------------------------------------------------------------------------
   Name: osal_task_yield

   Purpose: Forces a context switch.
   Parameters:
      void
   Returns
      void
---------------------------------------------------------------------------------------*/
void osal_task_yield( void )
{
  taskYIELD();
}
コード例 #12
0
ファイル: main.c プロジェクト: xanth/Brew-Machine-MkIV
void vCheckTask(void *pvParameters)
{
  char buf[50];
  char pcBrewElapsedTime[50], pcStepElapsedTime[50];
  char pcBrewElapsedHours[50], pcBrewElapsedMinutes[50], pcBrewElapsedSeconds[50], pcBrewStep[50];
  char pcBrewStepElapsedHours[50], pcBrewStepElapsedMinutes[50], pcBrewStepElapsedSeconds[50], pcMashTemp[50], pcHLTTemp[50];
  char pcChillerPumpState[50], pcBoilState[50], pcHeapRemaining[50], pcBrewState[50], pcBoilDuty[50], pcLitresDelivered[50];
  int ii = 0;
  char upper_limit = 255, lower_limit = 255;
  unsigned int touch, hops, ds1820, timer, litres, check, low_level = 90, heap, print, serial, serialcontrol;
  unsigned int display_applet, stats_applet, res_applet, graph_applet, brew_task;
  static char cBuf[80];
  for (;;){

      touch = uxTaskGetStackHighWaterMark(xTouchTaskHandle);

      ds1820 =  uxTaskGetStackHighWaterMark(xDS1820TaskHandle);
      timer = uxTaskGetStackHighWaterMark(xTimerSetupHandle);
      litres = uxTaskGetStackHighWaterMark(xLitresToBoilHandle);
      print = uxTaskGetStackHighWaterMark(xPrintTaskHandle);
      hops = uxTaskGetStackHighWaterMark(xHopsTaskHandle);
      check = uxTaskGetStackHighWaterMark(NULL);
      serial = uxTaskGetStackHighWaterMark(xSerialHandlerTaskHandle);
      serialcontrol = uxTaskGetStackHighWaterMark(xSerialControlTaskHandle);
      heap = xPortGetFreeHeapSize();
      display_applet =  uiGetBrewAppletDisplayHWM();
      res_applet =  uiGetBrewResAppletHWM();
      stats_applet =  uiGetBrewStatsAppletHWM();
      graph_applet =  uiGetBrewGraphAppletHWM();
      brew_task =  uiGetBrewTaskHWM();



      sprintf(pcBrewElapsedHours, "4D51E338F02649DFA173631622024A90:%02u\r\n\0", ucGetBrewHoursElapsed());
      vConsolePrint(pcBrewElapsedHours);
      vTaskDelay(80);
      sprintf(pcBrewElapsedMinutes, "99A2038A62BF47E7BFB1922A43C0825C:%02u\r\n\0", ucGetBrewMinutesElapsed());
      vConsolePrint(pcBrewElapsedMinutes);
      vTaskDelay(80);
      sprintf(pcBrewElapsedSeconds, "E9C4FDDEDEBC41D7AC3A3F4C636759A2:%02u\r\n\0", ucGetBrewSecondsElapsed());
      vConsolePrint(pcBrewElapsedSeconds);
      vTaskDelay(80);
      sprintf(pcBrewStep, "1308CA31CAEE4A9A8AC5B353F5ACB594:%02u\r\n\0", ucGetBrewStep());
      vConsolePrint(pcBrewStep);
      vTaskDelay(80);
      sprintf(pcBrewStepElapsedSeconds, "02BA9C74C1384C069ECB648C3CEFFCBA:%02u\r\n\0", ucGetBrewStepSecondsElapsed());
      vConsolePrint(pcBrewStepElapsedSeconds);
      vTaskDelay(80);
      sprintf(pcBrewStepElapsedMinutes, "35C22A915227449C8F2A740F2C26B344:%02u\r\n\0", ucGetBrewStepMinutesElapsed());
      vConsolePrint(pcBrewStepElapsedMinutes);
      vTaskDelay(80);
      sprintf(pcMashTemp, "E21DFC36AFB24226A323D7931B6A1F30:%02u\r\n\0", (unsigned int)floor(ds1820_get_temp(MASH)));
      vConsolePrint(pcMashTemp);
      vTaskDelay(50);
      sprintf(pcHLTTemp, "81A73894E64546868F39EE1758D459AD:%02u\r\n\0", (unsigned int)floor(ds1820_get_temp(HLT)));
      vConsolePrint(pcHLTTemp);
      vTaskDelay(50);
      sprintf(pcChillerPumpState, "461F715060F5468883F6F8500CEAA4BC:%02u\r\n\0", ucGetChillerPumpState());
      vConsolePrint(pcChillerPumpState);
      vTaskDelay(80);
      sprintf(pcBoilState, "60140A1EB194439B8C9A198355FD93AA:%02u\r\n\0", ucGetBoilState());
      vConsolePrint(pcBoilState);
      vTaskDelay(80);
      sprintf(pcBrewState, "FB46F7E5DF914AF1816035EC02DEE0DC:%02u\r\n\0", ucGetBrewState());
      vConsolePrint(pcBrewState);
      vTaskDelay(80);
      sprintf(pcBoilDuty, "F066509116CA43F7B6845C8E2EBA69FA:%02u\r\n\0", uiGetBoilDuty());
      vConsolePrint(pcBoilDuty);
      vTaskDelay(80);
      sprintf(pcLitresDelivered, "3AEE6966D7664AA4BE05BBBBF48E2836:%02u\r\n\0", uiGetActualLitresDelivered());
            vConsolePrint(pcLitresDelivered);
            vTaskDelay(80);




      lower_limit = cI2cGetInput(CRANE_LOWER_LIMIT_PORT, CRANE_LOWER_LIMIT_PIN);
      upper_limit = cI2cGetInput(CRANE_UPPER_LIMIT_PORT, CRANE_UPPER_LIMIT_PIN);

      sprintf(buf, "BD52AA172CAE4F58A11EC35872EFEB99:%d \r \n", ii++%1024);
      sprintf(pcHeapRemaining, "*Heap:%u*low=%d,up=%d\r\n\0", heap, lower_limit, upper_limit);
      vConsolePrint(pcHeapRemaining);
      vTaskDelay(80);
      vConsolePrint(buf);

       if (touch < low_level ||
           timer < low_level ||
           litres < low_level||
           print < low_level ||
           hops < low_level ||
           check < low_level||
           display_applet < low_level ||
           res_applet < low_level ||
           stats_applet < low_level ||
           graph_applet < low_level ||
           brew_task < low_level)


        {
          //vTaskSuspendAll();
          vConsolePrint("=============================\r\n");
          sprintf(cBuf,"check task: idle ticks = %d\r\n", ulIdleCycleCount);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "touchwm = %d\r\n", touch);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "DS1820wm = %d\r\n", ds1820);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "TimerSetupwm = %d\r\n", timer);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "litreswm = %d\r\n", litres);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "hopswm = %d\r\n", hops);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "check = %d\r\n", check);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "serial = %d\r\n", serial);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "serialcontrol = %d\r\n", serialcontrol);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "brewtask = %d\r\n", brew_task);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "stats = %d\r\n", stats_applet);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "res = %d\r\n", res_applet);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "graph = %d\r\n", graph_applet);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "brew_display = %d\r\n", display_applet);
          vConsolePrint(cBuf);
          vTaskDelay(80);
          sprintf(cBuf, "print = %d\r\n", print);
          vConsolePrint(cBuf);
          vConsolePrint("=============================\r\n");
          //xTaskResumeAll();
          vTaskDelay(800);

        }
      vTaskDelay(800);
      taskYIELD();
  }
}
コード例 #13
0
ファイル: Main.c プロジェクト: OpenPicus/hack_a_fridge_alarm
void CmdCheck()
{
	#if MAX_UDP_SOCKETS_FREERTOS>0 //UDP Stack
	activeUdpSocket=0;
	while (activeUdpSocket < MAX_UDP_SOCKETS_FREERTOS) 
	{
		//Ring Buffer
		if(udpSocket[activeUdpSocket] != INVALID_UDP_SOCKET)
		{
			//reads udp data and adds in ring buffer
			udpRxLen[activeUdpSocket] = UDPIsGetReady(udpSocket[activeUdpSocket]);

			if(udpRxLen[activeUdpSocket] > (BUFFER_UDP_LEN[activeUdpSocket] - udpRxLenGlobal[activeUdpSocket]))
			{
				// Since there is not enough space to store the packet,
				// discard all the transceiver RAM content related to UDP
				datadiscard = udpRxLen[activeUdpSocket];
				
				// Set the Overflow Flags
				UDPoverflow = 1;
				UDPoverflowFlag[activeUdpSocket] = 1;
				
				// Now discard all remaining data in Udp Rx:
				// Create a dummy array
				BYTE removeArray[BUFFER_UDP_FIXED_LEN];
				// update the datadiscard value
				while(datadiscard > 0)
				{
					datadiscard -= UDPGetArray(removeArray, BUFFER_UDP_FIXED_LEN);
				}
			}
			
			if (udpRxLen[activeUdpSocket] > 0)
			{
				if( (p_udp_wifiram[activeUdpSocket]+udpRxLen[activeUdpSocket]) <= (udpBuffer[activeUdpSocket]+BUFFER_UDP_LEN[activeUdpSocket]) ) //append to buffer
				{
					UDPGetArray(p_udp_wifiram[activeUdpSocket], udpRxLen[activeUdpSocket]); //data
					p_udp_wifiram[activeUdpSocket] += udpRxLen[activeUdpSocket];
				}
				else //append to buffer near end, or add to buffer from start
				{
					tmp_len[activeUdpSocket] = ((udpBuffer[activeUdpSocket]+BUFFER_UDP_LEN[activeUdpSocket]) - p_udp_wifiram[activeUdpSocket]);  //free space on ring buffer
					if(tmp_len[activeUdpSocket] > 0) //fill buffer and add data from start
					{
						UDPGetArray(p_udp_wifiram[activeUdpSocket], tmp_len[activeUdpSocket]);
						p_udp_wifiram[activeUdpSocket] = udpBuffer[activeUdpSocket];
						UDPGetArray(p_udp_wifiram[activeUdpSocket], udpRxLen[activeUdpSocket] - tmp_len[activeUdpSocket] );
						p_udp_wifiram[activeUdpSocket] += (udpRxLen[activeUdpSocket] - tmp_len[activeUdpSocket]);
					}
					else //add data to buffer from start
					{ 
						p_udp_wifiram[activeUdpSocket] = udpBuffer[activeUdpSocket];
						UDPGetArray(p_udp_wifiram[activeUdpSocket], udpRxLen[activeUdpSocket]);
						p_udp_wifiram[activeUdpSocket] += udpRxLen[activeUdpSocket];
					}
				}
				udpRxLenGlobal[activeUdpSocket] += udpRxLen[activeUdpSocket];	
			
			} //end ring buffer
		}
		activeUdpSocket++;
	}
	#endif //UDP STACK

	if (Cmd != 0)
	{
		int fresult = 0;
		while (xSemaphoreTake(xSemFrontEnd,0) != pdTRUE);
		if (xFrontEndStat == 1)
		{
			fresult = FP[Cmd]();
			xFrontEndStat = xFrontEndStatRet;
			xSemaphoreGive(xSemFrontEnd);
			Cmd = 0;
			taskYIELD();
		}
	}
}
コード例 #14
0
ファイル: Task.cpp プロジェクト: germaneers/openstella
void Task::yield()
{
	taskYIELD();
}
コード例 #15
0
ファイル: menu.c プロジェクト: PeteHemery/Arms-Race-Code
/**
* @brief Menu Task.
*
*   This function allows the user to select which task to start:
*   Record a program or Play a program.
*
*   On initial launch, the arm may be in an unknown state so the first
*   function called is used to reset the arm into a known position.
*
*   Upon return to the menu task, from the record and play tasks,
*   the arm may be in an unknown position, so the reset task may
*   be called appropriately.
*
* @param [in] pvParameter Standard FreeRTOS method of passing parameters.
* @return Void.
*/
void vTaskMenu( void *pvParameters )
{
    portSHORT sReceivedValue;
    portBASE_TYPE xKeyPadQueueStatus;
    const portTickType xTicksToWait = 1000 / portTICK_RATE_MS;
    enum xChoice_t {RECORD_A_PROGRAM, PLAY_A_PROGRAM} xChoice;
    portCHAR *pcChoices[] =
    {
        "Record a Program",
        "Play a Program"
    };
    xChoice = RECORD_A_PROGRAM;

    printf("Menu\n");
    if (xSystemState != MENU_SELECT)
    {
        vWaitForReset();
    }

    vPrintToLCD(1,"Select Option:");
    vPrintToLCD(2,pcChoices[xChoice]);

    for(;;)
    {
        if( uxQueueMessagesWaiting( xKeyPadQueue ) != 0)
        {
            printf( "Queue should have been empty!\r\n" );
        }
        xKeyPadQueueStatus = xQueueReceive( xKeyPadQueue, &sReceivedValue, xTicksToWait );
        if( xKeyPadQueueStatus == pdPASS )
        {
//      printf( "Received = %d \t", sReceivedValue);
            switch (sReceivedValue)
            {

            case RESET:
                break;
            case PLAY:
                break;
            case PAUSE:
                break;
            case STOP:
                break;

            case ENTER:
                switch (xChoice)
                {
                case RECORD_A_PROGRAM:
                    printf("%s\n",pcChoices[xChoice]);
                    xSystemState = RECORDING;

                    xTaskCreate(vTaskRecord,
                                "Record Task",
                                2000,
                                NULL,
                                1,
                                &xRecordHandle);
                    /* Get out of here */
                    vTaskDelete( NULL);
                    break;

                case PLAY_A_PROGRAM:
                    printf("%s\n",pcChoices[xChoice]);
                    xSystemState = PLAYING;

                    xTaskCreate(vTaskPlay,
                                "Play Task",
                                PLAY_TASK_STACK_SIZE,
                                NULL,
                                1,
                                &xPlayHandle);
                    /* Get out of here */
                    vTaskDelete( NULL);
                    break;
                default:
                    break;
                }
                break;
            case CANCEL:
                break;

            case XUP:
            case UP:
            case XRIGHT:
            case RIGHT:
                if (++xChoice >= NUMBER_OF_CHOICES)
                {
                    xChoice = 0;
                }
                break;
            case XDOWN:
            case DOWN:
            case XLEFT:
            case LEFT:
                /* enum is an unsigned int, checking below zero doesn't work
                 * so check if value is above the max number aswell */
                --xChoice;
                if (xChoice < 0 || xChoice > NUMBER_OF_CHOICES)
                {
                    xChoice = NUMBER_OF_CHOICES - 1;
                }
                break;

            default:
                break;
            }
            vPrintToLCD(2,pcChoices[xChoice]);
        }
        else
        {
            //printf( "Could not receive from the queue.\r\n");
        }
        taskYIELD();
    }


    for (;;)
    {
        /* Catch a problem - Do nothing */
    }

    vTaskDelete(NULL);
}
コード例 #16
0
ファイル: QueueOverwrite.c プロジェクト: huhaihua/penfirm
static void prvQueueOverwriteTask( void *pvParameters )
{
QueueHandle_t xTaskQueue;
const unsigned portBASE_TYPE uxQueueLength = 1;
unsigned long ulValue, ulStatus = pdPASS, x;

	/* The parameter is not used. */
	( void ) pvParameters;

	/* Create the queue.  xQueueOverwrite() should only be used on queues that
	have a length of 1. */
	xTaskQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );
	configASSERT( xTaskQueue );

	for( ;; )
	{
		/* The queue is empty.  Writing to the queue then reading from the queue
		should return the item written. */
		ulValue = 10;
		xQueueOverwrite( xTaskQueue, &ulValue );

		ulValue = 0;
		xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );

		if( ulValue != 10 )
		{
			ulStatus = pdFAIL;
		}

		/* Now try writing to the queue several times.  Each time the value
		in the queue should get overwritten. */
		for( x = 0; x < qoLOOPS; x++ )
		{
			/* Write to the queue. */
			xQueueOverwrite( xTaskQueue, &x );

			/* Check the value in the queue is that written, even though the
			queue was not necessarily empty. */
			xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK );
			if( ulValue != x )
			{
				ulStatus = pdFAIL;
			}

			/* There should always be one item in the queue. */
			if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength )
			{
				ulStatus = pdFAIL;
			}
		}

		/* Empty the queue again. */
		xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );

		if( uxQueueMessagesWaiting( xTaskQueue ) != 0 )
		{
			ulStatus = pdFAIL;
		}

		if( ulStatus != pdFAIL )
		{
			/* Increment a counter to show this task is still running without
			error. */
			ulLoopCounter++;
		}

		#if( configUSE_PREEMPTION == 0 )
			taskYIELD();
		#endif
	}
}
コード例 #17
0
ファイル: terminal.c プロジェクト: glocklueng/MIOS32
s32 TERMINAL_PrintSdCardInfo(void *_output_function)
{
  void (*out)(char *format, ...) = _output_function;

  FRESULT res;
  FILINFO fno;
  DIR dir;
  char *fn;
  char str_buffer[128];

  MUTEX_MIDIOUT_TAKE;

  out("SD Card Informations\n");
  out("====================\n");

#if !defined(MIOS32_FAMILY_EMULATION)
  // this yield ensures, that Debug Messages are sent before we continue the execution
  // Since MIOS Studio displays the time at which the messages arrived, this allows
  // us to measure the delay of following operations
  taskYIELD();

  MUTEX_SDCARD_TAKE;
  FILE_PrintSDCardInfos();
  MUTEX_SDCARD_GIVE;
#endif

  out("\n");
  out("Reading Root Directory\n");
  out("======================\n");

  taskYIELD();

  if( !FILE_SDCardAvailable() ) {
    sprintf(str_buffer, "not connected");
  } else if( !FILE_VolumeAvailable() ) {
    sprintf(str_buffer, "Invalid FAT");
  } else {
    out("Retrieving SD Card informations - please wait!\n");
    MUTEX_MIDIOUT_GIVE;
    MUTEX_SDCARD_TAKE;
    FILE_UpdateFreeBytes();
    MUTEX_SDCARD_GIVE;
    MUTEX_MIDIOUT_TAKE;

    sprintf(str_buffer, "'%s': %u of %u MB free", 
	    FILE_VolumeLabel(),
	    (unsigned int)(FILE_VolumeBytesFree()/1000000),
	    (unsigned int)(FILE_VolumeBytesTotal()/1000000));
  }
  out("SD Card: %s\n", str_buffer);

  taskYIELD();

#if _USE_LFN
  static char lfn[_MAX_LFN * (_DF1S ? 2 : 1) + 1];
  fno.lfname = lfn;
  fno.lfsize = sizeof(lfn);
#endif

  MUTEX_SDCARD_TAKE;
  if( (res=f_opendir(&dir, "/")) != FR_OK ) {
    out("Failed to open root directory - error status: %d\n", res);
  } else {
    while( (f_readdir(&dir, &fno) == FR_OK) && fno.fname[0] ) {
#if _USE_LFN
      fn = *fno.lfname ? fno.lfname : fno.fname;
#else
      fn = fno.fname;
#endif
      char date[10];
      ShowFatDate(fno.fdate,(char*)&date);
      char time[12];
      ShowFatTime(fno.ftime,(char*)&time);
      out("[%s%s%s%s%s%s%s] %s  %s   %s %u %s\n",
		(fno.fattrib & AM_RDO ) ? "r" : ".",
		(fno.fattrib & AM_HID ) ? "h" : ".",
		(fno.fattrib & AM_SYS ) ? "s" : ".",
		(fno.fattrib & AM_VOL ) ? "v" : ".",
		(fno.fattrib & AM_LFN ) ? "l" : ".",
		(fno.fattrib & AM_DIR ) ? "d" : ".",
		(fno.fattrib & AM_ARC ) ? "a" : ".",
		date,time,
		(fno.fattrib & AM_DIR) ? "<DIR>" : " ",
		fno.fsize,fn);
    }
  }
  MUTEX_SDCARD_GIVE;

  taskYIELD();

  out("done.\n");
  MUTEX_MIDIOUT_GIVE;

  return 0; // no error
}
コード例 #18
0
void TASK_Bluetooth( void *pvParameters )
{
    UNUSED( pvParameters );
        
    static char rxBuffer[BLUETOOTH_MAX_RX_LEN];
    static char *Rx = rxBuffer;
    char Tx[BLUETOOTH_TX_BUFFER_LEN];
        
    /* Create a semaphore */
    rxSemaphoreBluetooth = xSemaphoreCreateBinary();
        
    /* Ensure that semaphore is valid */
    Assert( rxSemaphoreBluetooth );
        
    /* Create a queue */
    xBluetoothTxQueue = xQueueCreate( 3, BLUETOOTH_TX_BUFFER_LEN * sizeof( char ) );
    xBluetoothRxQueue = xQueueCreate( BLUETOOTH_MAX_RX_LEN, sizeof( uint16_t ) );
        
    /* Ensure that the queue is valid */
    Assert( xBluetoothTxQueue );
    Assert( xBluetoothRxQueue );

    /* Start reading */
    dma_start_transfer_job( &zDMA_BluetoothResourceRx );

    for(;;)
    {
        if( xQueueReceive( xBluetoothTxQueue, Tx, ( TickType_t ) 0 ) == pdTRUE )
        {
            strncpy((char *)Bluetooth_TxBuffer, Tx, sizeof(FTDI_TxBuffer));
            dma_start_transfer_job(&zDMA_BluetoothResourceTx);
            while( !( DMA_Status & _LS(BLUETOOTH_TX_DONE) ) )
            {
                taskYIELD();
            }
            DMA_Status &= !(_LS(BLUETOOTH_TX_DONE));
        }
            
        /* Block task until DMA read complete */
        if( xSemaphoreTake( rxSemaphoreBluetooth, 5 ) == pdTRUE )
        {
            if( xBluetoothTxQueue != 0)
            {
                xQueueSend( xBluetoothTxQueue, Bluetooth_RxBuffer, ( TickType_t ) 0 );
            }
            /* Look for backspace character */
            if( *Bluetooth_RxBuffer == 127 )
            {
                if( Rx != rxBuffer )
                {
                    Rx--;
                    *Rx = 0;
                }
            }
            else if( *Bluetooth_RxBuffer == 13 ) // Carriage return
            {
                memcpy( Rx, "\0", sizeof( char ) );
                /* Pass command to the main parser */
                if( xParserQueue != 0 )
                {
                    xQueueSend( xParserQueue, rxBuffer, ( TickType_t ) 10 );
                }
                Rx = rxBuffer;
            }
            else if( !strcmp( ( const char * ) Bluetooth_RxBuffer, "\027[D" ) ) // Left arrow ANSI
            {
                /* Move pointer around */
            }
            else if( !strcmp( ( const char * ) Bluetooth_RxBuffer, "\027[C" ) ) // Right arrow ANSI
            {
                /* Move pointer around */
            }
            else if( !strcmp( ( const char * ) Bluetooth_RxBuffer, "\027[A" ) ) // Up arrow ANSI
            {
                /* Previous command */
            }
            else if( !strcmp( ( const char * ) Bluetooth_RxBuffer, "\027[B" ) ) // Down arrow ANSI
            {
                /* Next command, if available */
            }
            else
            {
                /* Copy byte into buffer */
                *Rx = ( char ) *Bluetooth_RxBuffer;
                    
                /* Reset buffer pointer on overflow */
                if( Rx == &rxBuffer[BLUETOOTH_MAX_RX_LEN-1] )
                {
                    Rx = rxBuffer;
                }
                else
                {
                    Rx++;
                }
            }
            dma_start_transfer_job( &zDMA_BluetoothResourceRx );
        }

        taskYIELD();
    }
}
コード例 #19
0
ファイル: FRTOS-IO.c プロジェクト: ppeluffo/sp5KV5_3CH
//------------------------------------------------------------------------------------
size_t FreeRTOS_UART_write( Peripheral_Descriptor_t const pxPeripheral, const void *pvBuffer, const size_t xBytes )
{
	// Esta funcion debe poner los caracteres apuntados en pvBuffer en la cola de trasmision.
	// Actua como si fuese rprintfStr.
	// Debe tomar el semaforo antes de trasmitir. Los semaforos los manejamos en la capa FreeRTOS
	// y no en la de los drivers.

char cChar;
char *p;
size_t bytes2tx;
Peripheral_Control_t * const pxPeripheralControl = ( Peripheral_Control_t * const ) pxPeripheral;
UART_device_control_t *pUart;
size_t wBytes = 0;

	pUart = pxPeripheralControl->phDevice;
	// Controlo no hacer overflow en la cola de trasmision
	bytes2tx = xBytes;

	// Espero el semaforo en forma persistente.
	while ( xSemaphoreTake(pxPeripheralControl->xBusSemaphore, ( TickType_t ) 1 ) != pdTRUE )
		taskYIELD();

	// Trasmito.
	// Espero que los buffers esten vacios. ( La uart se va limpiando al trasmitir )
	if ( pUart->txBufferType == QUEUE ) {
		while  ( uxQueueMessagesWaiting( pUart->txStruct ) > 0 )
			taskYIELD();
	} else {
		while  ( uxFifoMessagesWaiting( pUart->txStruct ) > 0 )
			taskYIELD();
	}

	// Cargo el buffer en la cola de trasmision.
	p = (char *)pvBuffer;
	while (*p && (bytes2tx-- > 0) ) {

		// Voy cargando la cola de a uno.
		cChar = *p;
		pv_enqueue( pUart, &cChar );
		p++;
		wBytes++;	// Cuento los bytes que voy trasmitiendo

		// Si la cola esta llena, empiezo a trasmitir y espero que se vacie.
		if (  pv_queueReachHighWaterMark(pUart) ) {
			// Habilito a trasmitir para que se vacie
			vUartInterruptOn(pxPeripheralControl->portId);
			// Y espero que se haga mas lugar.
			while ( ! pv_queueReachLowWaterMark(pUart) )
				taskYIELD();
		}
	}

	// Luego inicio la trasmision invocando la interrupcion.
	vUartInterruptOn(pxPeripheralControl->portId);

	xSemaphoreGive( pxPeripheralControl->xBusSemaphore );

	//return xBytes;	// Puse todos los caracteres en la cola.
	return (wBytes);

}
コード例 #20
0
ファイル: onewire.c プロジェクト: tjomk/grolly2
//-----------------------------------------------------------------------------
// процедура общения с шиной 1-wire
// sendReset - посылать RESET в начале общения.
// 		OW_SEND_RESET или OW_NO_RESET
// command - массив байт, отсылаемых в шину. Если нужно чтение - отправляем OW_READ_SLOTH
// cLen - длина буфера команд, столько байт отошлется в шину
// data - если требуется чтение, то ссылка на буфер для чтения
// dLen - длина буфера для чтения. Прочитается не более этой длины
// readStart - с какого символа передачи начинать чтение (нумеруются с 0)
//		можно указать OW_NO_READ, тогда можно не задавать data и dLen
//-----------------------------------------------------------------------------
uint8_t OW_Send(uint8_t sendReset, uint8_t *command, uint8_t cLen,
		uint8_t *data, uint8_t dLen, uint8_t readStart) {

	// если требуется сброс - сбрасываем и проверяем на наличие устройств
	if (sendReset == OW_SEND_RESET) {
		if (OW_Reset() == OW_NO_DEVICE) {
			return OW_NO_DEVICE;
		}
	}

	while (cLen > 0) {

		OW_toBits(*command, ow_buf);
		command++;
		cLen--;

		DMA_InitTypeDef DMA_InitStructure;

		// DMA на чтение
		DMA_DeInit(OW_DMA_CH_RX);
		DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(USART2->DR);
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ow_buf;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
		DMA_InitStructure.DMA_BufferSize = 8;
		DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
		DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
		DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
		DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
		DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
		DMA_Init(OW_DMA_CH_RX, &DMA_InitStructure);

		// DMA на запись
		DMA_DeInit(OW_DMA_CH_TX);
		DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(USART2->DR);
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ow_buf;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
		DMA_InitStructure.DMA_BufferSize = 8;
		DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
		DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
		DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
		DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
		DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
		DMA_Init(OW_DMA_CH_TX, &DMA_InitStructure);

		// старт цикла отправки
		USART_ClearFlag(OW_USART, USART_FLAG_RXNE | USART_FLAG_TC | USART_FLAG_TXE);
		USART_DMACmd(OW_USART, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
		DMA_Cmd(OW_DMA_CH_RX, ENABLE);
		DMA_Cmd(OW_DMA_CH_TX, ENABLE);

		// Ждем, пока не примем 8 байт
		while (DMA_GetFlagStatus(OW_DMA_FLAG) == RESET){
#ifdef OW_GIVE_TICK_RTOS
			taskYIELD();
			IWDG_ReloadCounter();
#endif
		}

		// отключаем DMA
		DMA_Cmd(OW_DMA_CH_TX, DISABLE);
		DMA_Cmd(OW_DMA_CH_RX, DISABLE);
		USART_DMACmd(OW_USART, USART_DMAReq_Tx | USART_DMAReq_Rx, DISABLE);

		// если прочитанные данные кому-то нужны - выкинем их в буфер
		if (readStart == 0 && dLen > 0) {
			*data = OW_toByte(ow_buf);
			data++;
			dLen--;
		} else {
			if (readStart != OW_NO_READ) {
				readStart--;
			}
		}
	}

	return OW_OK;
}
コード例 #21
0
ファイル: file_sp5K.c プロジェクト: ppeluffo/sp5KV4
//------------------------------------------------------------------------------------
s08 FF_rewind(void)
{
	// Borra el archivo y lo lleva a su condicion inicial.
	// Inicializa la memoria. Como lleva bastante tiempo, tenemos problemas con el
	// watchdog. Por esto desde donde la invocamos debemos desactivarlo y esta
	// funcion SOLO debe usarse desde CMD.

u16 val = 0;
u16 tryes;
u16 xPos;

	wdt_reset();

	// Lo primero es obtener el semaforo del I2C
	FreeRTOS_ioctl(&pdI2C,ioctlOBTAIN_BUS_SEMPH, NULL);

	// inicializo la estructura lineal temporal del FCB.
	memset( FCB.ff_buffer,0, sizeof(FCB.ff_buffer) );

	// EE WRITE:
	// Luego indicamos el periferico i2c en el cual queremos leer
	val = EE_ADDR;
	FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_DEVADDRESS, &val);
	// Luego indicamos la direccion a escribir del dispositivo: largo ( en la ee son 2 bytes )
	val = 2;
	FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_BYTEADDRESSLENGTH, &val);
	// Ciclo de borrado
	for ( xPos = 0; xPos < FF_MAX_RCDS; xPos++) {
		// direccion interna en la EE.(comienzo del registro / frontera)
		val = FF_ADDR_START + xPos * FF_RECD_SIZE;
		FreeRTOS_ioctl(&pdI2C,ioctl_I2C_SET_BYTEADDRESS,&val);

		for ( tryes = 0; tryes < 3; tryes++ ) {
			// Borro: escribo un pagina entera, 64 bytes con los '\0'
			FreeRTOS_write(&pdI2C, &FCB.ff_buffer, FF_RECD_SIZE);
			taskYIELD();
			// Leo y verifico
			FreeRTOS_read(&pdI2C, &FCB.check_buffer, FF_RECD_SIZE);
			if ( memcmp (&FCB.check_buffer, &FCB.ff_buffer, FF_RECD_SIZE) == 0 )
				break;
			if  ( tryes == 3 ) {
				snprintf_P( debug_printfBuff,sizeof(debug_printfBuff),PSTR("FFrew ERR: %d,%d\r\n\0"),xPos, val);
				FreeRTOS_write( &pdUART1, debug_printfBuff, sizeof(debug_printfBuff) );
			}

		}
		// Imprimo realimentacion c/32 recs.
		if ( (xPos % 32) == 0 ) {
			FreeRTOS_write( &pdUART1, ".\0", sizeof(".\0") );
		}

		// Para no salir por wdg reset
		if ( (xPos % 64) == 0 ) {
			wdt_reset();
		}
	}

	FreeRTOS_write( &pdUART1, "\r\n\0", sizeof("\r\n\0") );
	FreeRTOS_ioctl(&pdI2C,ioctlRELEASE_BUS_SEMPH, NULL);
	// RESET
	u_reset();

}
コード例 #22
0
/*
 * Controller task as described above.
 */
static void vCounterControlTask( void * pvParameters )
{
unsigned long ulLastCounter;
short sLoops;
short sError = pdFALSE;
const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n";
const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n";

	/* Just to stop warning messages. */
	( void ) pvParameters;

	/* Queue a message for printing to say the task has started. */
	vPrintDisplayMessage( &pcTaskStartMsg );

	for( ;; )
	{
		/* Start with the counter at zero. */
		ulCounter = ( unsigned long ) 0;

		/* First section : */

		/* Check the continuous count task is running. */
		for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
		{
			/* Suspend the continuous count task so we can take a mirror of the
			shared variable without risk of corruption. */
			vTaskSuspend( xContinuousIncrementHandle );
				ulLastCounter = ulCounter;
			vTaskResume( xContinuousIncrementHandle );
			
			/* Now delay to ensure the other task has processor time. */
			vTaskDelay( priSLEEP_TIME );

			/* Check the shared variable again.  This time to ensure mutual 
			exclusion the whole scheduler will be locked.  This is just for
			demo purposes! */
			vTaskSuspendAll();
			{
				if( ulLastCounter == ulCounter )
				{
					/* The shared variable has not changed.  There is a problem
					with the continuous count task so flag an error. */
					sError = pdTRUE;
					xTaskResumeAll();
						vPrintDisplayMessage( &pcTaskFailMsg );
					vTaskSuspendAll();
				}
			}
			xTaskResumeAll();
		}


		/* Second section: */

		/* Suspend the continuous counter task so it stops accessing the shared variable. */
		vTaskSuspend( xContinuousIncrementHandle );

		/* Reset the variable. */
		ulCounter = ( unsigned long ) 0;

		/* Resume the limited count task which has a higher priority than us.
		We should therefore not return from this call until the limited count
		task has suspended itself with a known value in the counter variable. 
		The scheduler suspension is not necessary but is included for test
		purposes. */
		vTaskSuspendAll();
			vTaskResume( xLimitedIncrementHandle );
		xTaskResumeAll();

		/* Does the counter variable have the expected value? */
		if( ulCounter != priMAX_COUNT )
		{
			sError = pdTRUE;
			vPrintDisplayMessage( &pcTaskFailMsg );
		}

		if( sError == pdFALSE )
		{
			/* If no errors have occurred then increment the check variable. */
			portENTER_CRITICAL();
				usCheckVariable++;
			portEXIT_CRITICAL();
		}

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		/* Resume the continuous count task and do it all again. */
		vTaskResume( xContinuousIncrementHandle );
	}
}
コード例 #23
0
ファイル: AltQTest.c プロジェクト: jgordo32/nrf24_andretti
static void prvLowPriorityMutexTask( void *pvParameters )
{
    xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;

#ifdef USE_STDIO
    void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );

    const portCHAR * const pcTaskStartMsg = "Fast mutex with priority inheritance test started.\r\n";

    /* Queue a message for printing to say the task has started. */
    vPrintDisplayMessage( &pcTaskStartMsg );
#endif

    ( void ) pvParameters;


    for( ;; )
    {
        /* Take the mutex.  It should be available now. */
        if( xSemaphoreAltTake( xMutex, genqNO_BLOCK ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }

        /* Set our guarded variable to a known start value. */
        ulGuardedVariable = 0;

        /* Our priority should be as per that assigned when the task was
        created. */
        if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
        {
            xErrorDetected = pdTRUE;
        }

        /* Now unsuspend the high priority task.  This will attempt to take the
        mutex, and block when it finds it cannot obtain it. */
        vTaskResume( xHighPriorityMutexTask );

        /* We should now have inherited the prioritoy of the high priority task,
        as by now it will have attempted to get the mutex. */
        if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
        {
            xErrorDetected = pdTRUE;
        }

        /* We can attempt to set our priority to the test priority - between the
        idle priority and the medium/high test priorities, but our actual
        prioroity should remain at the high priority. */
        vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
        if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
        {
            xErrorDetected = pdTRUE;
        }

        /* Now unsuspend the medium priority task.  This should not run as our
        inherited priority is above that of the medium priority task. */
        vTaskResume( xMediumPriorityMutexTask );

        /* If the did run then it will have incremented our guarded variable. */
        if( ulGuardedVariable != 0 )
        {
            xErrorDetected = pdTRUE;
        }

        /* When we give back the semaphore our priority should be disinherited
        back to the priority to which we attempted to set ourselves.  This means
        that when the high priority task next blocks, the medium priority task
        should execute and increment the guarded variable.   When we next run
        both the high and medium priority tasks will have been suspended again. */
        if( xSemaphoreAltGive( xMutex ) != pdPASS )
        {
            xErrorDetected = pdTRUE;
        }

        /* Check that the guarded variable did indeed increment... */
        if( ulGuardedVariable != 1 )
        {
            xErrorDetected = pdTRUE;
        }

        /* ... and that our priority has been disinherited to
        genqMUTEX_TEST_PRIORITY. */
        if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
        {
            xErrorDetected = pdTRUE;
        }

        /* Set our priority back to our original priority ready for the next
        loop around this test. */
        vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );

        /* Just to show we are still running. */
        ulLoopCounter2++;

#if configUSE_PREEMPTION == 0
        taskYIELD();
#endif
    }
}
コード例 #24
0
signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{
signed portBASE_TYPE xReturn = pdTRUE;
xTimeOutType xTimeOut;

	do
	{
    	/* If xTicksToWait is zero then we are not going to block even
    	if there is no room in the queue to post. */
		if( xTicksToWait > ( portTickType ) 0 )
		{
			vTaskSuspendAll();
			prvLockQueue( pxQueue );

			if( xReturn == pdTRUE )
			{
				/* This is the first time through - we need to capture the
				time while the scheduler is locked to ensure we attempt to
				block at least once. */
				vTaskSetTimeOutState( &xTimeOut );
			}

			if( prvIsQueueFull( pxQueue ) )
			{
	    		/* Need to call xTaskCheckForTimeout again as time could
	    		have passed since it was last called if this is not the
	    		first time around this loop.  */
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					traceBLOCKING_ON_QUEUE_SEND( pxQueue );
					vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
						
					/* Unlocking the queue means queue events can effect the
					event list.  It is possible	that interrupts occurring now
					remove this task from the event	list again - but as the
					scheduler is suspended the task will go onto the pending
					ready last instead of the actual ready list. */
					prvUnlockQueue( pxQueue );
						
					/* Resuming the scheduler will move tasks from the pending
					ready list into the ready list - so it is feasible that this
					task is already in a ready list before it yields - in which
					case the yield will not cause a context switch unless there
					is also a higher priority task in the pending ready list. */
					if( !xTaskResumeAll() )
					{
						taskYIELD();
					}
				}
				else
				{
					prvUnlockQueue( pxQueue );
					( void ) xTaskResumeAll();
				}
			}
			else
			{
    			/* The queue was not full so we can just unlock the
    			scheduler and queue again before carrying on. */
				prvUnlockQueue( pxQueue );
				( void ) xTaskResumeAll();
			}
		}
    			
  		/* Higher priority tasks and interrupts can execute during
  		this time and could possible refill the queue - even if we
  		unblocked because space became available. */
    		
		taskENTER_CRITICAL();
		{
  			/* Is there room on the queue now?  To be running we must be
  			the highest priority task wanting to access the queue. */
			if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
			{
				traceQUEUE_SEND( pxQueue );
				prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
				xReturn = pdPASS;
					
				/* If there was a task waiting for data to arrive on the
				queue then unblock it now. */
				if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
				{
					if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
					{
					    /* The unblocked task has a priority higher than
					    our own so yield immediately. */
					    taskYIELD();
					}
				}
			}
			else
			{
  				/* Setting xReturn to errQUEUE_FULL will force its timeout
  				to be re-evaluated.  This is necessary in case interrupts
  				and higher priority tasks accessed the queue between this
  				task being unblocked and subsequently attempting to write
  				to the queue. */
				xReturn = errQUEUE_FULL;
			}
		}
		taskEXIT_CRITICAL();

		if( xReturn == errQUEUE_FULL )
		{
			if( xTicksToWait > ( portTickType ) 0 )
			{
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					xReturn = queueERRONEOUS_UNBLOCK;
				}
				else
				{
					traceQUEUE_SEND_FAILED( pxQueue );
				}
			}
			else
			{
				traceQUEUE_SEND_FAILED( pxQueue );
			}
		}
	}
	while( xReturn == queueERRONEOUS_UNBLOCK );

	return xReturn;
}
コード例 #25
0
ファイル: queue.c プロジェクト: Paolo-Maffei/nxstack
signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
{
signed portBASE_TYPE xReturn;
xTimeOutType xTimeOut;

	/* Make sure other tasks do not access the queue. */
	vTaskSuspendAll();

	/* Capture the current time status for future reference. */
	vTaskSetTimeOutState( &xTimeOut );

	/* It is important that this is the only thread/ISR that modifies the
	ready or delayed lists until xTaskResumeAll() is called.  Places where
	the ready/delayed lists are modified include:

		+ vTaskDelay() -  Nothing can call vTaskDelay as the scheduler is
		  suspended, vTaskDelay() cannot be called from an ISR.
		+ vTaskPrioritySet() - Has a critical section around the access.
		+ vTaskSwitchContext() - This will not get executed while the scheduler
		  is suspended.
		+ prvCheckDelayedTasks() - This will not get executed while the
		  scheduler is suspended.
		+ xTaskCreate() - Has a critical section around the access.
		+ vTaskResume() - Has a critical section around the access.
		+ xTaskResumeAll() - Has a critical section around the access.
		+ xTaskRemoveFromEventList - Checks to see if the scheduler is
		  suspended.  If so then the TCB being removed from the event is
		  removed from the event and added to the xPendingReadyList.
	*/

	/* Make sure interrupts do not access the queue event list. */
	prvLockQueue( pxQueue );

	/* It is important that interrupts to not access the event list of the
	queue being modified here.  Places where the event list is modified
	include:

		+ xQueueSendFromISR().  This checks the lock on the queue to see if
		  it has access.  If the queue is locked then the Tx lock count is
		  incremented to signify that a task waiting for data can be made ready
		  once the queue lock is removed.  If the queue is not locked then
		  a task can be moved from the event list, but will not be removed
		  from the delayed list or placed in the ready list until the scheduler
		  is unlocked.

		+ xQueueReceiveFromISR().  As per xQueueSendFromISR().
	*/
		
	/* If the queue is already full we may have to block. */
	do
	{
		if( prvIsQueueFull( pxQueue ) )
		{
			/* The queue is full - do we want to block or just leave without
			posting? */
			if( xTicksToWait > ( portTickType ) 0 )
			{
				/* We are going to place ourselves on the xTasksWaitingToSend event
				list, and will get woken should the delay expire, or space become
				available on the queue.
				
				As detailed above we do not require mutual exclusion on the event
				list as nothing else can modify it or the ready lists while we
				have the scheduler suspended and queue locked.
				
				It is possible that an ISR has removed data from the queue since we
				checked if any was available.  If this is the case then the data
				will have been copied from the queue, and the queue variables
				updated, but the event list will not yet have been checked to see if
				anything is waiting as the queue is locked. */
				vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
	
				/* Force a context switch now as we are blocked.  We can do
				this from within a critical section as the task we are
				switching to has its own context.  When we return here (i.e. we
				unblock) we will leave the critical section as normal.
				
				It is possible that an ISR has caused an event on an unrelated and
				unlocked queue.  If this was the case then the event list for that
				queue will have been updated but the ready lists left unchanged -
				instead the readied task will have been added to the pending ready
				list. */
				taskENTER_CRITICAL();
				{
					/* We can safely unlock the queue and scheduler here as
					interrupts are disabled.  We must not yield with anything
					locked, but we can yield from within a critical section.
					
					Tasks that have been placed on the pending ready list cannot
					be tasks that are waiting for events on this queue.  See
					in comment xTaskRemoveFromEventList(). */
					prvUnlockQueue( pxQueue );
	
					/* Resuming the scheduler may cause a yield.  If so then there
					is no point yielding again here. */
					if( !xTaskResumeAll() )
					{
						taskYIELD();
					}
	
					/* Before leaving the critical section we have to ensure
					exclusive access again. */
					vTaskSuspendAll();
					prvLockQueue( pxQueue );				
				}
				taskEXIT_CRITICAL();
			}
		}
			
		/* When we are here it is possible that we unblocked as space became
		available on the queue.  It is also possible that an ISR posted to the
		queue since we left the critical section, so it may be that again there
		is no space.  This would only happen if a task and ISR post onto the
		same queue. */
		taskENTER_CRITICAL();
		{
			if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
			{
				/* There is room in the queue, copy the data into the queue. */			
				prvCopyQueueData( pxQueue, pvItemToQueue );		
				xReturn = pdPASS;
	
				/* Update the TxLock count so prvUnlockQueue knows to check for
				tasks waiting for data to become available in the queue. */
				++( pxQueue->xTxLock );
			}
			else
			{
				xReturn = errQUEUE_FULL;
			}
		}
		taskEXIT_CRITICAL();

		if( xReturn == errQUEUE_FULL )
		{
			if( xTicksToWait > 0 )
			{
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					xReturn = queueERRONEOUS_UNBLOCK;
				}
			}
		}
	}
	while( xReturn == queueERRONEOUS_UNBLOCK );

	prvUnlockQueue( pxQueue );
	xTaskResumeAll();

	return xReturn;
}
コード例 #26
0
	signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
	{
	signed portBASE_TYPE xReturn = pdPASS;
	xTimeOutType xTimeOut;

		/* The source code that implements the alternative (Alt) API is
		simpler	because it makes more use of critical sections.  This is	
		the approach taken by many other RTOSes, but FreeRTOS.org has the
		preferred fully featured API too.  The fully featured API has more
		complex	code that takes longer to execute, but makes less use of
		critical sections.  */

		do
		{
    		/* If xTicksToWait is zero then we are not going to block even
    		if there is no room in the queue to post. */
			if( xTicksToWait > ( portTickType ) 0 )
			{
				portENTER_CRITICAL();
				{
					if( xReturn == pdPASS )
					{
						/* This is the first time through - capture the time
						inside the critical section to ensure we attempt to
						block at least once. */
						vTaskSetTimeOutState( &xTimeOut );
					}
					
					if( prvIsQueueFull( pxQueue ) )
					{
	    				/* Need to call xTaskCheckForTimeout again as time could
	    				have passed since it was last called if this is not the
	    				first time around this loop.  */
						if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
						{
							traceBLOCKING_ON_QUEUE_SEND( pxQueue );
							vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );

							/* This will exit the critical section, then re-enter when
							the task next runs. */
							taskYIELD();
						}
					}
				}
				portEXIT_CRITICAL();
			}
    				
   			/* Higher priority tasks and interrupts can execute during
   			this time and could possible refill the queue - even if we
   			unblocked because space became available. */
    			
			taskENTER_CRITICAL();
			{
   				/* Is there room on the queue now?  To be running we must be
   				the highest priority task wanting to access the queue. */
				if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
				{
					traceQUEUE_SEND( pxQueue );
					prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
					xReturn = pdPASS;
						
					/* If there was a task waiting for data to arrive on the
					queue then unblock it now. */
					if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
					{
						if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
						{
							/* The unblocked task has a priority higher than
							our own so yield immediately. */
							taskYIELD();
						}
					}
				}
				else
				{
   					/* Setting xReturn to errQUEUE_FULL will force its timeout
   					to be re-evaluated.  This is necessary in case interrupts
   					and higher priority tasks accessed the queue between this
   					task being unblocked and subsequently attempting to write
   					to the queue. */
					xReturn = errQUEUE_FULL;
				}
			}
			taskEXIT_CRITICAL();

			if( xReturn == errQUEUE_FULL )
			{
				if( xTicksToWait > ( portTickType ) 0 )
				{
					if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
					{
						xReturn = queueERRONEOUS_UNBLOCK;
					}
					else
					{
						traceQUEUE_SEND_FAILED( pxQueue );
					}
				}
				else
				{
					traceQUEUE_SEND_FAILED( pxQueue );
				}
			}
		}
		while( xReturn == queueERRONEOUS_UNBLOCK );

		return xReturn;
	}
コード例 #27
0
ファイル: dynamic.c プロジェクト: AskDrCatcher/FreeRTOS
/*
 * Controller task as described above.
 */
static portTASK_FUNCTION( vCounterControlTask, pvParameters )
{
uint32_t ulLastCounter;
short sLoops;
short sError = pdFALSE;

	/* Just to stop warning messages. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Start with the counter at zero. */
		ulCounter = ( uint32_t ) 0;

		/* First section : */

		/* Check the continuous count task is running. */
		for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
		{
			/* Suspend the continuous count task so we can take a mirror of the
			shared variable without risk of corruption.  This is not really
			needed as the other task raises its priority above this task's
			priority. */
			vTaskSuspend( xContinuousIncrementHandle );
			{
				#if( INCLUDE_eTaskGetState == 1 )
				{
					configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended );
				}
				#endif /* INCLUDE_eTaskGetState */

				ulLastCounter = ulCounter;
			}
			vTaskResume( xContinuousIncrementHandle );

			#if( configUSE_PREEMPTION == 0 )
				taskYIELD();
			#endif

			#if( INCLUDE_eTaskGetState == 1 )
			{
				configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady );
			}
			#endif /* INCLUDE_eTaskGetState */

			/* Now delay to ensure the other task has processor time. */
			vTaskDelay( priSLEEP_TIME );

			/* Check the shared variable again.  This time to ensure mutual
			exclusion the whole scheduler will be locked.  This is just for
			demo purposes! */
			vTaskSuspendAll();
			{
				if( ulLastCounter == ulCounter )
				{
					/* The shared variable has not changed.  There is a problem
					with the continuous count task so flag an error. */
					sError = pdTRUE;
				}
			}
			xTaskResumeAll();
		}

		/* Second section: */

		/* Suspend the continuous counter task so it stops accessing the shared
		variable. */
		vTaskSuspend( xContinuousIncrementHandle );

		/* Reset the variable. */
		ulCounter = ( uint32_t ) 0;

		#if( INCLUDE_eTaskGetState == 1 )
		{
			configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
		}
		#endif /* INCLUDE_eTaskGetState */

		/* Resume the limited count task which has a higher priority than us.
		We should therefore not return from this call until the limited count
		task has suspended itself with a known value in the counter variable. */
		vTaskResume( xLimitedIncrementHandle );

		#if( configUSE_PREEMPTION == 0 )
			taskYIELD();
		#endif

		/* This task should not run again until xLimitedIncrementHandle has
		suspended itself. */
		#if( INCLUDE_eTaskGetState == 1 )
		{
			configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
		}
		#endif /* INCLUDE_eTaskGetState */

		/* Does the counter variable have the expected value? */
		if( ulCounter != priMAX_COUNT )
		{
			sError = pdTRUE;
		}

		if( sError == pdFALSE )
		{
			/* If no errors have occurred then increment the check variable. */
			portENTER_CRITICAL();
				usCheckVariable++;
			portEXIT_CRITICAL();
		}

		/* Resume the continuous count task and do it all again. */
		vTaskResume( xContinuousIncrementHandle );

		#if( configUSE_PREEMPTION == 0 )
			taskYIELD();
		#endif
	}
}
コード例 #28
0
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
{
signed portBASE_TYPE xReturn = pdTRUE;
xTimeOutType xTimeOut;
signed portCHAR *pcOriginalReadPosition;

	do
	{
		/* If there are no messages in the queue we may have to block. */
		if( xTicksToWait > ( portTickType ) 0 )
		{
			vTaskSuspendAll();
			prvLockQueue( pxQueue );

			if( xReturn == pdTRUE )
			{
				/* This is the first time through - we need to capture the
				time while the scheduler is locked to ensure we attempt to
				block at least once. */
				vTaskSetTimeOutState( &xTimeOut );
			}

			if( prvIsQueueEmpty( pxQueue ) )
			{
	    		/* Need to call xTaskCheckForTimeout again as time could
	    		have passed since it was last called if this is not the
	    		first time around this loop. */
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );

					#if ( configUSE_MUTEXES == 1 )
					{
						if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
						{
							portENTER_CRITICAL();
								vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
							portEXIT_CRITICAL();
						}
					}
					#endif

					vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
					prvUnlockQueue( pxQueue );
					if( !xTaskResumeAll() )
					{
						taskYIELD();
					}
				}
				else
				{
					prvUnlockQueue( pxQueue );
					( void ) xTaskResumeAll();
				}
			}
			else
			{
				prvUnlockQueue( pxQueue );
				( void ) xTaskResumeAll();
			}
		}
	
		taskENTER_CRITICAL();
		{
			if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
			{
				/* Remember our read position in case we are just peeking. */
				pcOriginalReadPosition = pxQueue->pcReadFrom;

				prvCopyDataFromQueue( pxQueue, pvBuffer );

				if( xJustPeeking == pdFALSE )
				{
					traceQUEUE_RECEIVE( pxQueue );

					/* We are actually removing data. */
					--( pxQueue->uxMessagesWaiting );

					#if ( configUSE_MUTEXES == 1 )
					{
						if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
						{
							/* Record the information required to implement
							priority inheritance should it become necessary. */
							pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
						}
					}
					#endif
						
					if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
					{
						if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
						{
							taskYIELD();
						}
					}
				}
				else
				{
					traceQUEUE_PEEK( pxQueue );

					/* We are not removing the data, so reset our read
					pointer. */
					pxQueue->pcReadFrom = pcOriginalReadPosition;

					/* The data is being left in the queue, so see if there are
					any other tasks waiting for the data. */
					if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
					{
						/* Tasks that are removed from the event list will get added to
						the pending ready list as the scheduler is still suspended. */
						if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
						{
							/* The task waiting has a higher priority that this task. */
							taskYIELD();
						}
					}			

				}
				
				xReturn = pdPASS;					
			}
			else
			{
				xReturn = errQUEUE_EMPTY;
			}
		}
		taskEXIT_CRITICAL();

		if( xReturn == errQUEUE_EMPTY )
		{
			if( xTicksToWait > ( portTickType ) 0 )
			{
				if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
				{
					xReturn = queueERRONEOUS_UNBLOCK;
				}
				else
				{
					traceQUEUE_RECEIVE_FAILED( pxQueue );
				}
			}
			else
			{
				traceQUEUE_RECEIVE_FAILED( pxQueue );
			}
		}
	} while( xReturn == queueERRONEOUS_UNBLOCK );

	return xReturn;
}
コード例 #29
0
ファイル: flop_hercules.c プロジェクト: bookie/freertos
static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
{
volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
volatile unsigned long *pulTaskCheckVariable;
const size_t xArraySize = 10;
size_t xPosition;
short sError = pdFALSE;

	/* Must be called before any hardware floating point operations are
	performed to let the RTOS portable layer know that this task requires
	a floating point context. */
	#if __TI_VFP_SUPPORT__
		vPortTaskUsesFPU();
	#endif

	/* The variable this task increments to show it is still running is passed in 
	as the parameter. */
	pulTaskCheckVariable = ( unsigned long * ) pvParameters;

	pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );

	/* Keep filling an array, keeping a running total of the values placed in the 
	array.  Then run through the array adding up all the values.  If the two totals 
	do not match, stop the check variable from incrementing. */
	for( ;; )
	{
		dTotal1 = 0.0;
		dTotal2 = 0.0;

		for( xPosition = 0; xPosition < xArraySize; xPosition++ )
		{
			pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;
			dTotal1 += ( portDOUBLE ) xPosition + 5.5;	
		}

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		for( xPosition = 0; xPosition < xArraySize; xPosition++ )
		{
			dTotal2 += pdArray[ xPosition ];
		}

		dDifference = dTotal1 - dTotal2;
		if( fabs( dDifference ) > 0.001 )
		{
			sError = pdTRUE;
		}

		#if configUSE_PREEMPTION == 0
			taskYIELD();
		#endif

		if( sError == pdFALSE )
		{
			/* If the calculation has always been correct, increment the check 
			variable so we know	this task is still running okay. */
			( *pulTaskCheckVariable )++;
		}
	}
}
コード例 #30
0
static void prvRecursiveMutexControllingTask( void *pvParameters )
{
unsigned portBASE_TYPE ux;

	/* Just to remove compiler warning. */
	( void ) pvParameters;

	for( ;; )
	{
		/* Should not be able to 'give' the mutex, as we have not yet 'taken'
		it.   The first time through, the mutex will not have been used yet,
		subsequent times through, at this point the mutex will be held by the
		polling task. */
		if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
		{
			xErrorOccurred = pdTRUE;
		}

		for( ux = 0; ux < recmuMAX_COUNT; ux++ )
		{
			/* We should now be able to take the mutex as many times as
			we like.
			
			The first time through the mutex will be immediately available, on
			subsequent times through the mutex will be held by the polling task
			at this point and this Take will cause the polling task to inherit
			the priority of this task.  In this case the block time must be
			long enough to ensure the polling task will execute again before the
			block time expires.  If the block time does expire then the error
			flag will be set here. */
			if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			/* Ensure the other task attempting to access the mutex (and the
			other demo tasks) are able to execute to ensure they either block
			(where a block time is specified) or return an error (where no 
			block time is specified) as the mutex is held by this task. */
			vTaskDelay( recmuSHORT_DELAY );
		}

		/* For each time we took the mutex, give it back. */
		for( ux = 0; ux < recmuMAX_COUNT; ux++ )
		{
			/* Ensure the other task attempting to access the mutex (and the
			other demo tasks) are able to execute. */
			vTaskDelay( recmuSHORT_DELAY );

			/* We should now be able to give the mutex as many times as we
			took it.  When the mutex is available again the Blocking task
			should be unblocked but not run because it has a lower priority
			than this task.  The polling task should also not run at this point
			as it too has a lower priority than this task. */
			if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
			{
				xErrorOccurred = pdTRUE;
			}

			#if configUSE_PREEMPTION == 0
				taskYIELD();
			#endif
		}

		/* Having given it back the same number of times as it was taken, we
		should no longer be the mutex owner, so the next give should fail. */
		if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
		{
			xErrorOccurred = pdTRUE;
		}

		/* Keep count of the number of cycles this task has performed so a 
		stall can be detected. */
		uxControllingCycles++;

		/* Suspend ourselves so the blocking task can execute. */
		xControllingIsSuspended = pdTRUE;
		vTaskSuspend( NULL );
		xControllingIsSuspended = pdFALSE;
	}
}