Ejemplo n.º 1
0
static void prvTestMasterTask( void *pvParameters )
{
    BaseType_t xError;

    /* The handle to the slave task is passed in as the task parameter. */
    TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;

    /* Avoid compiler warnings. */
    ( void ) pvParameters;

    /* Create the event group used by the tasks ready for the initial tests. */
    xEventGroup = xEventGroupCreate();
    configASSERT( xEventGroup );

    /* Perform the tests that block two tasks on different combinations of bits,
    then set each bit in turn and check the correct tasks unblock at the correct
    times. */
    xError = prvSelectiveBitsTestMasterFunction();

    for( ;; ) {
        /* Recreate the event group ready for the next cycle. */
        xEventGroup = xEventGroupCreate();
        configASSERT( xEventGroup );

        /* Perform the tests that check the behaviour when a single task is
        blocked on various combinations of event bits. */
        xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );

        /* Perform the task synchronisation tests. */
        xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );

        /* Delete the event group. */
        vEventGroupDelete( xEventGroup );

        /* Now all the other tasks should have completed and suspended
        themselves ready for the next go around the loop. */
        if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) {
            xError = pdTRUE;
        }

        if( eTaskGetState( xSyncTask1 ) != eSuspended ) {
            xError = pdTRUE;
        }

        if( eTaskGetState( xSyncTask2 ) != eSuspended ) {
            xError = pdTRUE;
        }

        /* Only increment the cycle variable if no errors have been detected. */
        if( xError == pdFALSE ) {
            ulTestMasterCycles++;
        }

        configASSERT( xError == pdFALSE );
    }
}
Ejemplo n.º 2
0
void test_task_get_state(void* arg)
{
    //Current task should return eRunning
    TEST_ASSERT(eTaskGetState(xTaskGetCurrentTaskHandle()) == eRunning);
    //Idle task of current core should return eReady
    TEST_ASSERT(eTaskGetState(xTaskGetIdleTaskHandle()) == eReady);
    //Blocked Task should return eBlocked
    TEST_ASSERT(eTaskGetState(blocked_task_handle) == eBlocked);
    //Suspended Task should return eSuspended
    TEST_ASSERT(eTaskGetState(suspended_task_handle) == eSuspended);

    xSemaphoreGive(done_sem);
    vTaskDelete(NULL);
}
Ejemplo n.º 3
0
// returns whether the given task state is consistent with its current RTOS state (given by its task handle state)
static bool task_state_consistent(bool expected_state, task_type_t task_id) {
	configASSERT(task_handles[task_id] != NULL && *task_handles[task_id] != NULL);
	eTaskState task_state_rtos = eTaskGetState(*task_handles[task_id]);
	// a task is "running" (expected_state should be true) if it's NOT suspended
	// see https://www.freertos.org/RTOS-task-states.html
	return expected_state == (task_state_rtos != eSuspended);
}
Ejemplo n.º 4
0
void Task::suspend() {
    if (mTaskHandle && eTaskGetState(mTaskHandle) != eSuspended) {
        debug::log("Suspend task: " + getName());
        vTaskSuspend(mTaskHandle);
        afterSuspension();
    } 
}
Ejemplo n.º 5
0
/**
* @brief Check if a thread is already suspended or not.
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @retval status code that indicates the execution status of the function.
*/
osStatus osThreadIsSuspended(osThreadId thread_id)
{
  if (eTaskGetState(thread_id) == eSuspended)
    return osOK;
  else
    return osErrorOS;
}
Ejemplo n.º 6
0
/**
* @brief  Obtain the state of any thread.
* @param   thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @retval  the stae of the thread, states are encoded by the osThreadState enumerated type.
*/
osThreadState osThreadGetState(osThreadId thread_id)
{
  eTaskState ThreadState;
  osThreadState result;
  
  ThreadState = eTaskGetState(thread_id);
  
  switch (ThreadState)
  {
  case eRunning :
    result = osThreadRunning;
    break;
  case eReady :
    result = osThreadReady;
    break;
  case eBlocked :
    result = osThreadBlocked;
    break;
  case eSuspended :
    result = osThreadSuspended;
    break;
  case eDeleted :
    result = osThreadDeleted;
    break;
  default:
    result = osThreadError;
  } 
  
  return result;
}
Ejemplo n.º 7
0
void print_task_info(void) {
	print("\n\n===========Task Information===========\n");
	print("state consistency: %s\n", 
		check_task_state_consistency() ? "consistent": "!! INCONSISTENT TASK STATES !!");
	for (int task = 0; task < NUM_TASKS; task++) {
		eTaskState task_state = eTaskGetState(*(task_handles[task]));
		uint16_t stack_space_left = uxTaskGetStackHighWaterMark(*task_handles[task]) * sizeof(portSTACK_TYPE);
		uint16_t stack_size = get_task_stack_size(task);
		uint16_t stack_space_available = stack_size * sizeof(portSTACK_TYPE);
		// note watchdog task as checked out in sys test so it doesn't look like something's up
		bool checked_in = (task == WATCHDOG_TASK) ? false : _get_task_checked_in(task);
		uint32_t last_check_in = _get_task_checked_in_time(task);
		uint32_t task_freq = get_task_freq(task);
		
		print("%s: %s (%s) LRT: %5d (%3d%%) stack: %4d / %4d (%3d%%)\n", 
			get_task_str(task), 
			get_task_state_str(task_state),
			checked_in ? "checked in " : "checked out",
			checked_in ? (xTaskGetTickCount() - last_check_in) : 0,
			checked_in ? (100 * (xTaskGetTickCount() - last_check_in) / task_freq) : 0,
			stack_space_available - stack_space_left,
			stack_space_available,
			(100 * (stack_space_available - stack_space_left)) / stack_space_available);
	}
}
dispatch_queue::~dispatch_queue()
{
	BaseType_t status;

	// Signal to dispatch threads that it's time to wrap up
	quit_ = true;

	// We will join each thread to confirm exiting
	for (size_t i = 0; i < threads_.size(); ++i) {
		eTaskState state;

		do {
			// Signal wake - check exit flag
			xEventGroupSetBits(notify_flags_, DISPATCH_WAKE_EVT);

			// Wait until a thread signals exit. Timeout is acceptable.
			xEventGroupWaitBits(notify_flags_, DISPATCH_EXIT_EVT, pdTRUE, pdFALSE, 10);

			// If it was not thread_[i], that is ok, but we will loop around
			// until threads_[i] has exited
			state = eTaskGetState(threads_[i].thread);
		} while (state != eDeleted);

		threads_[i].name.clear();
	}

	// Cleanup event flags and mutex
	vEventGroupDelete(notify_flags_);

	vSemaphoreDelete(mutex_);
}
Ejemplo n.º 9
0
void vButtonTask(void* pvParameters){

	xSemaphoreTake(xButtonSemaphore,buttonNO_BLOCK);
	for(;;){
		xSemaphoreTake(xButtonSemaphore, portMAX_DELAY);
		ulButtonPressCount++;
		xSemaphoreGive(xStatusSemaphore);
		if(eTaskGetState(xLedTaskHandle)== eBlocked || eTaskGetState(xLedTaskHandle)== eRunning ){
			vTaskSuspend(xLedTaskHandle);
		}
		else if(eTaskGetState(xLedTaskHandle)==eSuspended){
			vTaskResume(xLedTaskHandle);
		}

		vTaskDelay(500);
	}
}
Ejemplo n.º 10
0
eTaskState MPU_eTaskGetState( TaskHandle_t pxTask )
{
    BaseType_t xRunningPrivileged = prvRaisePrivilege();
    eTaskState eReturn;

    eReturn = eTaskGetState( pxTask );
    portRESET_PRIVILEGE( xRunningPrivileged );
    return eReturn;
}
Ejemplo n.º 11
0
	eTaskState MPU_eTaskGetState( xTaskHandle pxTask )
	{
    portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
	eTaskState eReturn;

		eReturn = eTaskGetState( pxTask );
        portRESET_PRIVILEGE( xRunningPrivileged );
		return eReturn;
	}
Ejemplo n.º 12
0
	eTaskState MPU_eTaskGetState( TaskHandle_t pxTask )
	{
	BaseType_t xRunningPrivileged = xPortRaisePrivilege();
	eTaskState eReturn;

		eReturn = eTaskGetState( pxTask );
		vPortResetPrivilege( xRunningPrivileged );
		return eReturn;
	}
Ejemplo n.º 13
0
void Task::start() {
    if (mTaskHandle == NULL) {
        debug::log("Creating task: " + getName());
        
        // get task name
        String taskName = getName();

        // start the task
        if (xTaskCreate(_task, taskName.c_str(), ( uint8_t ) 255, static_cast<void*>(this), 2, &mTaskHandle) != pdPASS) {
            debug::stopWithMessage("Failed to create " + getName() + " task");
        }
    } else if (eTaskGetState(mTaskHandle) == eSuspended) {
        debug::log("Resume task: " + getName());
        beforeResume();
        vTaskResume(mTaskHandle);
    }
}
Ejemplo n.º 14
0
void metal_finish_threads(int threads, void *tids)
{
	int i;
	TaskHandle_t *tid_p = (TaskHandle_t *)tids;

	if (!tids) {
		metal_log(METAL_LOG_ERROR, "invalid argument, tids is NULL.\n");
		return;
	}

	for (i = 0; i < threads; i++) {
		eTaskState ts;
		do {
			taskYIELD();
			ts=eTaskGetState(tid_p[i]);
		} while (ts != eDeleted);
	}
}
Ejemplo n.º 15
0
// resumes the given task if it was suspended, and (always) checks it in to the watchdog
void task_resume(task_type_t task_id)
{
	TaskHandle_t* task_handle = task_handles[task_id];
	configASSERT(task_handle != NULL && *task_handle != NULL);

	// always check in for watchdog when called
	// (in case it wasn't, for example on BOOT)
	// this is only called here so doesn't need to be safe
	check_in_task_unsafe(task_id);

	if (task_handle != NULL && *task_handle != NULL
		&& eTaskGetState(*task_handle) == eSuspended)
	{
		// actually resume task (will be graceful if task_handle task is not actually suspended)
		vTaskResume(*task_handle);
	}
	// if task_handle or it's value was NULL, we're in for a watchdog reset
	// which is what we want because somethings very wrong
}
Ejemplo n.º 16
0
// suspends the given task if it was not already suspended, and (always) checks it out of the watchdog
void task_suspend(task_type_t task_id) {
	TaskHandle_t* task_handle = task_handles[task_id];
	configASSERT(task_handle != NULL && *task_handle != NULL); // the latter would suspend THIS task

	configASSERT(task_id != BATTERY_CHARGING_TASK
				&& task_id != STATE_HANDLING_TASK 
				&& task_id != WATCHDOG_TASK 
				&& task_id != PERSISTENT_DATA_BACKUP_TASK);

	// always check out of watchdog when called (to be double-sure)
	// this is only called here so doesn't need to be safe
	check_out_task_unsafe(task_id);
	if (task_handle != NULL && *task_handle != NULL
		&& eTaskGetState(*task_handle) != eSuspended) 
	{
		// actually suspend using handle
		vTaskSuspend(*task_handle);
	}
	// if task_handle or it's value was NULL, we're in for a watchdog reset
	// which is what we want because somethings very wrong
}
Ejemplo n.º 17
0
static void prvTakeAndGiveInTheOppositeOrder( void )
{
    /* Ensure the slave is suspended, and that this task is running at the
    lower priority as expected as the start conditions. */
#if( INCLUDE_eTaskGetState == 1 )
    {
        configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended );
    }
#endif /* INCLUDE_eTaskGetState */

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

    /* Take the semaphore that is shared with the slave. */
    if( xSemaphoreTake( xMasterSlaveMutex, intsemNO_BLOCK ) != pdPASS ) {
        xErrorDetected = pdTRUE;
    }

    /* This task now has the mutex.  Unsuspend the slave so it too
    attempts to take the mutex. */
    vTaskResume( xSlaveHandle );

    /* The slave has the higher priority so should now have executed and
    blocked on the semaphore. */
#if( INCLUDE_eTaskGetState == 1 )
    {
        configASSERT( eTaskGetState( xSlaveHandle ) == eBlocked );
    }
#endif /* INCLUDE_eTaskGetState */

    /* This task should now have inherited the priority of the slave
    task. */
    if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) {
        xErrorDetected = pdTRUE;
    }

    /* Now wait a little longer than the time between ISR gives to also
    obtain the ISR mutex. */
    xOkToGiveMutex = pdTRUE;
    if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS ) {
        xErrorDetected = pdTRUE;
    }
    xOkToGiveMutex = pdFALSE;

    /* Attempting to take again immediately should fail as the mutex is
    already held. */
    if( xSemaphoreTake( xISRMutex, intsemNO_BLOCK ) != pdFAIL ) {
        xErrorDetected = pdTRUE;
    }

    /* Should still be at the priority of the slave task. */
    if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) {
        xErrorDetected = pdTRUE;
    }

    /* Give back the shared semaphore to ensure the priority is not disinherited
    as the ISR mutex is still held.  The higher priority slave task should run
    before this task runs again. */
    if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS ) {
        xErrorDetected = pdTRUE;
    }

    /* Should still be at the priority of the slave task as this task still
    holds one semaphore (this is a simplification in the priority inheritance
    mechanism. */
    if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) {
        xErrorDetected = pdTRUE;
    }

    /* Give back the ISR semaphore, which should result in the priority being
    disinherited as it was the last mutex held. */
    if( xSemaphoreGive( xISRMutex ) != pdPASS ) {
        xErrorDetected = pdTRUE;
    }

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

    /* Reset the mutex ready for the next round. */
    xQueueReset( xISRMutex );
}
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 )
		{
			#if( INCLUDE_eTaskGetState == 1 )
			{
				configASSERT( eTaskGetState( xControllingTaskHandle ) == eSuspended );
				configASSERT( eTaskGetState( xBlockingTaskHandle ) == eSuspended );
			}
			#endif /* INCLUDE_eTaskGetState */

			/* 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 );
                vTaskResume( xControllingTaskHandle );

				/* The other two tasks should now have executed and no longer
				be suspended. */
				if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) )
				{
					xErrorOccurred = pdTRUE;
				}

				#if( INCLUDE_uxTaskPriorityGet == 1 )
				{
					/* Check priority inherited. */
					configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY );
				}
				#endif /* INCLUDE_uxTaskPriorityGet */

				#if( INCLUDE_eTaskGetState == 1 )
				{
					configASSERT( eTaskGetState( xControllingTaskHandle ) == eBlocked );
					configASSERT( eTaskGetState( xBlockingTaskHandle ) == eBlocked );
				}
				#endif /* INCLUDE_eTaskGetState */

				/* Release the mutex, disinheriting the higher priority again. */
				if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
				{
					xErrorOccurred = pdTRUE;
				}

				#if( INCLUDE_uxTaskPriorityGet == 1 )
				{
					/* Check priority disinherited. */
					configASSERT( uxTaskPriorityGet( NULL ) == recmuPOLLING_TASK_PRIORITY );
				}
				#endif /* INCLUDE_uxTaskPriorityGet */
			}
		}

		#if configUSE_PREEMPTION == 0
		{
			taskYIELD();
		}
		#endif
	}
}
Ejemplo n.º 19
0
/*
 * 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
	}
}
Ejemplo n.º 20
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;
	}
}
Ejemplo n.º 21
0
static BaseType_t prvSelectiveBitsTestMasterFunction( void )
{
BaseType_t xError = pdFALSE;
EventBits_t uxBit;

	/* Used in a test that blocks two tasks on various different bits within an 
	event group - then sets each bit in turn and checks that the correct tasks 
	unblock at the correct times.  The two other tasks (xSyncTask1 and 
	xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in
	this test.

	Both other tasks should start in the suspended state. */
	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* Test each bit in the byte individually. */
	for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
	{
		/* Resume both tasks. */
		vTaskResume( xSyncTask1 );
		vTaskResume( xSyncTask2 );

		/* Now both tasks should be blocked on the event group. */
		if( eTaskGetState( xSyncTask1 ) != eBlocked )
		{
			xError = pdTRUE;
		}

		if( eTaskGetState( xSyncTask2 ) != eBlocked )
		{
			xError = pdTRUE;
		}

		/* Set one bit. */
		xEventGroupSetBits( xEventGroup, uxBit );

		/* Is the bit set in the first set of selective bits?  If so the first
		sync task should have unblocked and returned to the suspended state. */
		if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
		{
			/* Task should not have unblocked. */
			if( eTaskGetState( xSyncTask1 ) != eBlocked )
			{
				xError = pdTRUE;
			}
		}
		else
		{
			/* Task should have unblocked and returned to the suspended state. */
			if( eTaskGetState( xSyncTask1 ) != eSuspended )
			{
				xError = pdTRUE;
			}
		}

		/* Same checks for the second sync task. */
		if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
		{
			/* Task should not have unblocked. */
			if( eTaskGetState( xSyncTask2 ) != eBlocked )
			{
				xError = pdTRUE;
			}
		}
		else
		{
			/* Task should have unblocked and returned to the suspended state. */
			if( eTaskGetState( xSyncTask2 ) != eSuspended )
			{
				xError = pdTRUE;
			}
		}
	}

	/* Ensure both tasks are blocked on the event group again, then delete the
	event group so the other tasks leave this portion of the test. */
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	/* Deleting the event group is the signal that the two other tasks should
	leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main
	part of their functionality. */
	vEventGroupDelete( xEventGroup );

	return xError;
}
Ejemplo n.º 22
0
static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
{
EventBits_t uxBits;

	/* Resume the other task.  It will block, pending a single bit from
	within ebCOMBINED_BITS. */
	vTaskResume( xTestSlaveTaskHandle );

	/* Ensure the other task is blocked on the task. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only
	blocked waiting for one of them. */
	xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );

	/* The 'test slave' task should now have executed, clearing ebBIT_1 (the
	bit it was blocked on), then re-entered the Blocked state to wait for
	all the other bits in ebCOMBINED_BITS to be set again.  First check
	ebBIT_1 is clear. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
	{
		xError = pdTRUE;
	}

	/* Ensure the other task is still in the blocked state. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set all the bits other than ebBIT_1 - which is the bit that must be
	set before the other task unblocks. */
	xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );

	/* Ensure all the expected bits are still set. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
	{
		xError = pdTRUE;
	}

	/* Ensure the other task is still in the blocked state. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Now also set ebBIT_1, which should unblock the other task, which will
	then suspend itself. */
	xEventGroupSetBits( xEventGroup, ebBIT_1 );

	/* Ensure the other task is suspended. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* The other task should not have cleared the bits - so all the bits
	should still be set. */
	if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )
	{
		xError = pdTRUE;
	}

	/* Clear ebBIT_1 again. */
	if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )
	{
		xError = pdTRUE;
	}

	/* Resume the other task - which will wait on all the ebCOMBINED_BITS
	again - this time clearing the bits when it is unblocked. */
	vTaskResume( xTestSlaveTaskHandle );

	/* Ensure the other task is blocked once again. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set the bit the other task is waiting for. */
	xEventGroupSetBits( xEventGroup, ebBIT_1 );

	/* Ensure the other task is suspended once again. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* The other task should have cleared the bits in ebCOMBINED_BITS.
	Clear the remaining bits. */
	uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );

	if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
	{
		xError = pdTRUE;
	}

	/* Clear all bits ready for the sync with the other three tasks.  The
	value returned is the value prior to the bits being cleared. */
	if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
	{
		xError = pdTRUE;
	}

	/* The bits should be clear now. */
	if( xEventGroupGetBits( xEventGroup ) != 0x00 )
	{
		xError = pdTRUE;
	}

	return xError;
}
Ejemplo n.º 23
0
static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
{
EventBits_t uxBits;

	/* The three tasks that take part in the synchronisation (rendezvous) are
	expected to be in the suspended state at the start of the test. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	/* Try a synch with no other tasks involved.  First set all the bits other
	than this task's bit. */
	xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );

	/* Then wait on just one bit - the bit that is being set. */
	uxBits = xEventGroupSync( xEventGroup,			/* The event group used for the synchronisation. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */
							portMAX_DELAY );		/* The maximum time to wait for the sync condition to be met. */

	/* A sync with a max delay should only exit when all the synchronise
	bits are set...check that is the case.  In this case there is only one
	sync bit anyway. */
	if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again, leaving all the other
	bits set (as only one bit was being waited for). */
	if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )
	{
		xError = pdTRUE;
	}

	/* Clear all the bits to zero again. */
	xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}

	/* Unsuspend the other tasks then check they have executed up to the
	synchronisation point. */
	vTaskResume( xTestSlaveTaskHandle );
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Set this task's sync bit. */
	uxBits = xEventGroupSync( xEventGroup,			/* The event group used for the synchronisation. */
							ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
							ebALL_SYNC_BITS,		/* The bits to wait for - these bits are set by the other tasks that take part in the sync. */
							portMAX_DELAY );		/* The maximum time to wait for the sync condition to be met. */

	/* A sync with a max delay should only exit when all the synchronise
	bits are set...check that is the case. */
	if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again. */
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}


	/* The other tasks should now all be suspended again, ready for the next
	synchronisation. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eSuspended )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eSuspended )
	{
		xError = pdTRUE;
	}


	/* Sync again - but this time set the last necessary bit as the
	highest priority task, rather than the lowest priority task.  Unsuspend
	the other tasks then check they have executed up to the	synchronisation
	point. */
	vTaskResume( xTestSlaveTaskHandle );
	vTaskResume( xSyncTask1 );
	vTaskResume( xSyncTask2 );

	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	/* Raise the priority of this task above that of the other tasks. */
	vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );

	/* Set this task's sync bit. */
	uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );

	/* A sync with a max delay should only exit when all the synchronisation
	bits are set... */
	if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
	{
		xError = pdTRUE;
	}

	/* ...but now the sync bits should be clear again. */
	if( xEventGroupGetBits( xEventGroup ) != 0 )
	{
		xError = pdTRUE;
	}


	/* The other tasks should now all be in the ready state again, but not
	executed yet as this task still has a higher relative priority. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eReady )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eReady )
	{
		xError = pdTRUE;
	}


	/* Reset the priority of this task back to its original value. */
	vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );

	/* Now all the other tasks should have reblocked on the event bits
	to test the behaviour when the event bits are deleted. */
	if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask1 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	if( eTaskGetState( xSyncTask2 ) != eBlocked )
	{
		xError = pdTRUE;
	}

	return xError;
}
Ejemplo n.º 24
0
static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
{
TaskHandle_t xCreatedTask;

/* The variable that will hold the TCB of tasks created by this function.  See
the comments above the declaration of the xCreatorTaskTCBBuffer variable for
more information. */
StaticTask_t xTCBBuffer;

/* This buffer that will be used as the stack of tasks created by this function.
See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
above for more information. */
static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];

	/* Create the task.  xTaskCreateStatic() has two more parameters than
	the usual xTaskCreate() function.  The first new parameter is a pointer to
	the pre-allocated stack.  The second new parameter is a pointer to the
	StaticTask_t structure that will hold the task's TCB.  If both pointers are
	passed as NULL then the respective object will be allocated dynamically as
	if xTaskCreate() had been called. */
	xCreatedTask = xTaskCreateStatic(
						prvStaticallyAllocatedTask, 	/* Function that implements the task. */
						"Static",						/* Human readable name for the task. */
						configMINIMAL_STACK_SIZE,		/* Task's stack size, in words (not bytes!). */
						NULL,							/* Parameter to pass into the task. */
						uxTaskPriorityGet( NULL ) + 1,	/* The priority of the task. */
						&( uxStackBuffer[ 0 ] ),		/* The buffer to use as the task's stack. */
						&xTCBBuffer );					/* The variable that will hold that task's TCB. */

	/* Check the task was created correctly, then delete the task. */
	if( xCreatedTask == NULL )
	{
		xErrorOccurred = pdTRUE;
	}
	else if( eTaskGetState( xCreatedTask ) != eSuspended )
	{
		/* The created task had a higher priority so should have executed and
		suspended itself by now. */
		xErrorOccurred = pdTRUE;
	}
	else
	{
		vTaskDelete( xCreatedTask );
	}

	/* Now do the same using a dynamically allocated task to ensure the delete
	function is working correctly in both the static and dynamic allocation
	cases. */
	#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	{
	BaseType_t xReturned;

		xReturned = xTaskCreate(
									prvStaticallyAllocatedTask,		/* Function that implements the task - the same function is used but is actually dynamically allocated this time. */
									"Static",						/* Human readable name for the task. */
									configMINIMAL_STACK_SIZE,		/* Task's stack size, in words (not bytes!). */
									NULL,							/* Parameter to pass into the task. */
									uxTaskPriorityGet( NULL ) + 1,	/* The priority of the task. */
									&xCreatedTask );				/* Handle of the task being created. */

		if( eTaskGetState( xCreatedTask ) != eSuspended )
		{
			xErrorOccurred = pdTRUE;
		}

		configASSERT( xReturned == pdPASS );
		if( xReturned != pdPASS )
		{
			xErrorOccurred = pdTRUE;
		}
		vTaskDelete( xCreatedTask );
	}
	#endif
}
Ejemplo n.º 25
0
static void prvMultipleSocketTxTask( void *pvParameters )
{
uint32_t ulTxValue = 0;
struct freertos_sockaddr xDestinationAddress;
uint32_t ulIPAddress, ulFirstDestinationPortNumber, xPortNumber;
xSocket_t xTxSocket;
uint32_t ulSendCount[ selNUMBER_OF_SOCKETS ];

	memset( ulSendCount, '\0', sizeof( ulSendCount ) );

	/* The first destination port number is passed in as the task parameter.
	Other destination port numbers used are consecutive from this. */
	ulFirstDestinationPortNumber = ( uint32_t ) pvParameters;

	/* Create the socket used to send to the sockets created by the Rx task.
	Let the IP stack select a port to bind to. */
	xTxSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
	FreeRTOS_bind( xTxSocket, NULL, sizeof( struct freertos_sockaddr ) );

	/* The Rx and Tx tasks execute at the same priority so it is possible that
	the Tx task will fill up the send queue - set a Tx block time to ensure
	flow control is managed if this happens. */
	FreeRTOS_setsockopt( xTxSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendBlockTime, sizeof( xSendBlockTime ) );

	/* It is assumed that this task is not created until the network is up,
	so the IP address can be obtained immediately.  Store the IP address being
	used in ulIPAddress.  This is done so the socket can send to a different
	port on the same IP address. */
	FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL );

	/* This test sends to itself, so data sent from here is received by a server
	socket on the same IP address.  Setup the freertos_sockaddr structure with
	this nodes IP address. */
	xDestinationAddress.sin_addr = ulIPAddress;

	/* Block for a short time to ensure the task implemented by the
	prvMultipleSocketRxTask() function has finished creating the Rx sockets. */
	while( eTaskGetState( xRxTaskHandle ) != eSuspended )
	{
		vTaskDelay( xSendBlockTime );
	}
	vTaskResume( xRxTaskHandle );

	for( ;; )
	{
		/* Pseudo randomly select the destination port number from the range of
		valid destination port numbers. */
		xPortNumber = ipconfigRAND32() % selNUMBER_OF_SOCKETS;
		ulSendCount[ xPortNumber ]++;
		xDestinationAddress.sin_port = ( uint16_t ) ( ulFirstDestinationPortNumber + xPortNumber );
		xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port );

		/* Send an incrementing value to the pseudo randomly selected port. */
		FreeRTOS_sendto( xTxSocket, &ulTxValue, sizeof( ulTxValue ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) );
		ulTxValue++;

		if( ulTxValue >= selMAX_TX_VALUE )
		{
			/* Start over. */
			ulTxValue = 0;

			/* As a sanity check that this demo is valid, ensure each socket has
			been used at least once. */
			for( xPortNumber = 0; xPortNumber < selNUMBER_OF_SOCKETS; xPortNumber++ )
			{
				if( ulSendCount[ xPortNumber ] == 0 )
				{
					ulErrorOccurred = pdTRUE;
				}

				ulSendCount[ xPortNumber ] = 0;
			}

			/* Allow the Rx task to check it has received all the values. */
			while( eTaskGetState( xRxTaskHandle ) != eSuspended )
			{
				vTaskDelay( xSendBlockTime );
			}
			vTaskResume( xRxTaskHandle );

			/* Increment to show this task is still executing. */
			ulTxCycles++;
		}

		/* Delay here because in the Windows simulator the MAC interrupt
		simulator delays, so network traffic cannot be received any faster than
		this. */
		vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY << 2 );
	}
}
Ejemplo n.º 26
0
bool os_threadIsRunning(os_threadHandle_t handle)
{
    return (eTaskGetState(handle->threadHandle) == eRunning);
}
Ejemplo n.º 27
0
bool os_threadIsPaused(os_threadHandle_t handle)
{
    return (eTaskGetState(handle->threadHandle) == eSuspended);
}