⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 events.c

📁 FreeRTOS is a portable, open source, mini Real Time Kernel - a free to download and royalty free RTO
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
}
/*-----------------------------------------------------------*/

static void prvEventControllerTask( void *pvParameters )
{
const portCHAR * const pcTaskStartMsg = "Multi event controller task started.\r\n";
portBASE_TYPE xDummy = 0;

	/* Just to stop warnings. */
	( void ) pvParameters;

	vPrintDisplayMessage( &pcTaskStartMsg );

	for( ;; )
	{
		/* All tasks are blocked on the queue.  When a message is posted one of
		the two tasks that share the highest priority should unblock to read
		the queue.  The next message written should unblock the other task with
		the same high priority, and so on in order.   No other task should 
		unblock to read data as they have lower priorities. */

		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );

		/* For the rest of these tests we don't need the second 'highest' 
		priority task - so it is suspended. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );



		/* Now suspend the other highest priority task.  The medium priority 
		task will then be the task with the highest priority that remains 
		blocked on the queue. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		
		/* This time, when we post onto the queue we will expect the medium
		priority task to unblock and preempt us. */
		prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );

		/* Now try resuming the highest priority task while the scheduler is
		suspended.  The task should start executing as soon as the scheduler
		is resumed - therefore when we post to the queue again, the highest
		priority task should again preempt us. */
		vTaskSuspendAll();
			vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		xTaskResumeAll();
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		
		/* Now we are going to suspend the high and medium priority tasks.  The
		low priority task should then preempt us.  Again the task suspension is 
		done with the whole scheduler suspended just for test purposes. */
		vTaskSuspendAll();
			vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
			vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		xTaskResumeAll();
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
		
		/* Do the same basic test another few times - selectively suspending
		and resuming tasks and each time calling prvCheckTaskCounters() passing
		to the function the number of the task we expected to be unblocked by 
		the	post. */

		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		
		vTaskSuspendAll(); /* Just for test. */
			vTaskSuspendAll(); /* Just for test. */
				vTaskSuspendAll(); /* Just for even more test. */
					vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
				xTaskResumeAll();
			xTaskResumeAll();
		xTaskResumeAll();
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
		
		vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );
		
		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );

		/* Now a slight change, first suspend all tasks. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		
		/* Now when we resume the low priority task and write to the queue 3 
		times.  We expect the low priority task to service the queue three
		times. */
		vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH );
		
		/* Again suspend all tasks (only the low priority task is not suspended
		already). */
		vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		
		/* This time we are going to suspend the scheduler, resume the low
		priority task, then resume the high priority task.  In this state we
		will write to the queue three times.  When the scheduler is resumed
		we expect the high priority task to service all three messages. */
		vTaskSuspendAll();
		{
			vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
			vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
			
			for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ )
			{
				if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
				{
					xHealthStatus = pdFAIL;
				}
			}			
			
			/* The queue should not have been serviced yet!.  The scheduler
			is still suspended. */
			if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
			{
				xHealthStatus = pdFAIL;
			}
		}
		xTaskResumeAll();

		/* We should have been preempted by resuming the scheduler - so by the
		time we are running again we expect the high priority task to have 
		removed three items from the queue. */
		xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH;
		if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
		{
			xHealthStatus = pdFAIL;
		}
		
		/* The medium priority and second high priority tasks are still 
		suspended.  Make sure to resume them before starting again. */
		vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );

		/* Just keep incrementing to show the task is still executing. */
		xCheckVariable++;
	}
}
/*-----------------------------------------------------------*/

static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement )
{
portBASE_TYPE xDummy = 0;

	/* Write to the queue the requested number of times.  The data written is
	not important. */
	for( xDummy = 0; xDummy < xIncrement; xDummy++ )
	{
		if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
		{
			/* Did not expect to ever find the queue full. */
			xHealthStatus = pdFAIL;
		}
	}

	/* All the tasks blocked on the queue have a priority higher than the 
	controlling task.  Writing to the queue will therefore have caused this
	task to be preempted.  By the time this line executes the event task will
	have executed and incremented its counter.  Increment the expected counter
	to the same value. */
	( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement;

	/* Check the actual counts and expected counts really are the same. */
	if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
	{
		/* The counters were not the same.  This means a task we did not expect
		to unblock actually did unblock. */
		xHealthStatus = pdFAIL;
	}
}
/*-----------------------------------------------------------*/

portBASE_TYPE xAreMultiEventTasksStillRunning( void )
{
static portBASE_TYPE xPreviousCheckVariable = 0;

	/* Called externally to periodically check that this test is still
	operational. */

	if( xPreviousCheckVariable == xCheckVariable )
	{
		xHealthStatus = pdFAIL;
	}
	
	xPreviousCheckVariable = xCheckVariable;
	
	return xHealthStatus;	
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -