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

📄 tasks.c

📁 modbus开发程序包
💻 C
📖 第 1 页 / 共 4 页
字号:


			vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );

		}

		taskEXIT_CRITICAL();



		/* We may have just suspended the current task. */

		if( ( void * ) pxTaskToSuspend == NULL )

		{

			taskYIELD();

		}

	}



#endif

/*-----------------------------------------------------------*/



#if ( INCLUDE_vTaskSuspend == 1 )



	void vTaskResume( xTaskHandle pxTaskToResume )

	{

	tskTCB *pxTCB;



		/* Remove the task from whichever list it is currently in, and place

		it in the ready list. */

		pxTCB = ( tskTCB * ) pxTaskToResume;



		/* The parameter cannot be NULL as it is impossible to resume the

		currently executing task. */

		if( pxTCB != NULL )

		{

			taskENTER_CRITICAL();

			{

				/* Is the task we are attempting to resume actually suspended? */

				if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )

				{

					/* Has the task already been resumed from within an ISR? */

					if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )

					{			

						/* As we are in a critical section we can access the ready 

						lists even if the scheduler is suspended. */

						vListRemove(  &( pxTCB->xGenericListItem ) );

						prvAddTaskToReadyQueue( pxTCB );



						/* We may have just resumed a higher priority task. */

						if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )

						{

							/* This yield may not cause the task just resumed to run, but

							will leave the lists in the correct state for the next yield. */

							taskYIELD();

						}

					}

				}

			}

			taskEXIT_CRITICAL();

		}

	}



#endif



/*-----------------------------------------------------------*/



#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )



	portBASE_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )

	{

	portBASE_TYPE xYieldRequired = pdFALSE;

	tskTCB *pxTCB;



		pxTCB = ( tskTCB * ) pxTaskToResume;



		/* Is the task we are attempting to resume actually suspended? */

		if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )

		{

			/* Has the task already been resumed from within an ISR? */

			if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )

			{

				if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )

				{

					xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );

					vListRemove(  &( pxTCB->xGenericListItem ) );	

					prvAddTaskToReadyQueue( pxTCB );

				}

				else

				{

					/* We cannot access the delayed or ready lists, so will hold this

					task pending until the scheduler is resumed, at which point a 

					yield will be preformed if necessary. */

					vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );

				}

			}

		}



		return xYieldRequired;

	}



#endif









/*-----------------------------------------------------------

 * PUBLIC SCHEDULER CONTROL documented in task.h

 *----------------------------------------------------------*/





void vTaskStartScheduler( void )

{

portBASE_TYPE xReturn;



	/* Add the idle task at the lowest priority. */

	xReturn = xTaskCreate( prvIdleTask, ( signed portCHAR * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );



	if( xReturn == pdPASS )

	{

		/* Interrupts are turned off here, to ensure a tick does not occur

		before or during the call to xPortStartScheduler().  The stacks of

		the created tasks contain a status word with interrupts switched on

		so interrupts will automatically get re-enabled when the first task

		starts to run.

		

		STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE

		DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */

		portDISABLE_INTERRUPTS();



		xSchedulerRunning = pdTRUE;

		xTickCount = ( portTickType ) 0;



		/* Setting up the timer tick is hardware specific and thus in the

		portable interface. */

		if( xPortStartScheduler() )

		{

			/* Should not reach here as if the scheduler is running the

			function will not return. */

		}

		else

		{

			/* Should only reach here if a task calls xTaskEndScheduler(). */

		}

	}

}

/*-----------------------------------------------------------*/



void vTaskEndScheduler( void )

{

	/* Stop the scheduler interrupts and call the portable scheduler end

	routine so the original ISRs can be restored if necessary.  The port

	layer must ensure interrupts enable	bit is left in the correct state. */

	portDISABLE_INTERRUPTS();

	xSchedulerRunning = pdFALSE;

	vPortEndScheduler();

}

/*----------------------------------------------------------*/



void vTaskSuspendAll( void )

{

	portENTER_CRITICAL();

		++uxSchedulerSuspended;

	portEXIT_CRITICAL();

}

/*----------------------------------------------------------*/



signed portBASE_TYPE xTaskResumeAll( void )

{

register tskTCB *pxTCB;

signed portBASE_TYPE xAlreadyYielded = pdFALSE;



	/* It is possible that an ISR caused a task to be removed from an event

	list while the scheduler was suspended.  If this was the case then the

	removed task will have been added to the xPendingReadyList.  Once the

	scheduler has been resumed it is safe to move all the pending ready

	tasks from this list into their appropriate ready list. */

	portENTER_CRITICAL();

	{

		--uxSchedulerSuspended;



		if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )

		{			

			if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 )

			{

				portBASE_TYPE xYieldRequired = pdFALSE;

				

				/* Move any readied tasks from the pending list into the

				appropriate ready list. */

				while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY(  ( ( xList * ) &xPendingReadyList ) ) ) != NULL )

				{

					vListRemove( &( pxTCB->xEventListItem ) );

					vListRemove( &( pxTCB->xGenericListItem ) );

					prvAddTaskToReadyQueue( pxTCB );

					

					/* If we have moved a task that has a priority higher than

					the current task then we should yield. */

					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )

					{

						xYieldRequired = pdTRUE;

					}

				}



				/* If any ticks occurred while the scheduler was suspended then

				they should be processed now.  This ensures the tick count does not

				slip, and that any delayed tasks are resumed at the correct time. */

				if( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )

				{

					while( uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )

					{

						vTaskIncrementTick();

						--uxMissedTicks;

					}



					/* As we have processed some ticks it is appropriate to yield

					to ensure the highest priority task that is ready to run is

					the task actually running. */

					xYieldRequired = pdTRUE;

				}

				

				if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )

				{

					xAlreadyYielded = pdTRUE;

					xMissedYield = pdFALSE;

					taskYIELD();

				}

			}

		}

	}

	portEXIT_CRITICAL();



	return xAlreadyYielded;

}













/*-----------------------------------------------------------

 * PUBLIC TASK UTILITIES documented in task.h

 *----------------------------------------------------------*/







portTickType xTaskGetTickCount( void )

{

portTickType xTicks;



	/* Critical section required if running on a 16 bit processor. */

	taskENTER_CRITICAL();

	{

		xTicks = xTickCount;

	}

	taskEXIT_CRITICAL();



	return xTicks;

}

/*-----------------------------------------------------------*/



unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void )

{

unsigned portBASE_TYPE uxNumberOfTasks;



	taskENTER_CRITICAL();

		uxNumberOfTasks = uxCurrentNumberOfTasks;

	taskEXIT_CRITICAL();



	return uxNumberOfTasks;

}

/*-----------------------------------------------------------*/



#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_vTaskDelete == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )



	void vTaskList( signed portCHAR *pcWriteBuffer )

	{

	unsigned portBASE_TYPE uxQueue;



		/* This is a VERY costly function that should be used for debug only.

		It leaves interrupts disabled for a LONG time. */



        vTaskSuspendAll();

		{

			/* Run through all the lists that could potentially contain a TCB and

			report the task name, state and stack high water mark. */



			pcWriteBuffer[ 0 ] = ( signed portCHAR ) 0x00;

			strcat( ( portCHAR * ) pcWriteBuffer, ( const portCHAR * ) "\r\n" );



			uxQueue = uxTopUsedPriority + 1;



			do

			{

				uxQueue--;



				if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )

				{

					prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );			

				}

			}while( uxQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY );



			if( !listLIST_IS_EMPTY( pxDelayedTaskList ) )

			{

				prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxDelayedTaskList, tskBLOCKED_CHAR );

			}



			if( !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) )

			{

				prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) pxOverflowDelayedTaskList, tskBLOCKED_CHAR );

			}



			if( !listLIST_IS_EMPTY( &xTasksWaitingTermination ) )

			{

				prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xTasksWaitingTermination, tskDELETED_CHAR );

			}



			if( !listLIST_IS_EMPTY( &xSuspendedTaskList ) )

			{

				prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &xSuspendedTaskList, tskSUSPENDED_CHAR );

			}

		}

        xTaskResumeAll();

	}



#endif

/*----------------------------------------------------------*/



#if ( configUSE_TRACE_FACILITY == 1 )



	void vTaskStartTrace( signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize )

	{

		portENTER_CRITICAL();

		{

			pcTraceBuffer = ( volatile signed portCHAR * volatile )pcBuffer;

			pcTraceBufferStart = pcBuffer;

			pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );

			xTracing = pdTRUE;

		}

		portEXIT_CRITICAL();

	}



#endif

/*----------------------------------------------------------*/



#if ( configUSE_TRACE_FACILITY == 1 )



	unsigned portLONG ulTaskEndTrace( void )

	{

	unsigned portLONG ulBufferLength;



		portENTER_CRITICAL();

			xTracing = pdFALSE;

		portEXIT_CRITICAL();



		ulBufferLength = ( unsigned portLONG ) ( pcTraceBuffer - pcTraceBufferStart );



		return ulBufferLength;

	}



#endif







/*-----------------------------------------------------------

 * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES

 * documented in task.h

 *----------------------------------------------------------*/





inline void vTaskIncrementTick( void )

{

	/* Called by the portable layer each time a tick interrupt occurs.

	Increments the tick then checks to see if the new tick value will cause any

	tasks to be unblocked. */

	if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )

	{

		++xTickCount;

		if( xTickCount == ( portTickType ) 0 )

		{

			xList *pxTemp;



			/* Tick count has overflowed so we need to swap the delay lists.  

			If there are any items in pxDelayedTaskList here then there is 

			an error! */

			pxTemp = pxDelayedTaskList;

			pxDelayedTaskList = pxOverflowDelayedTaskList;

			pxOverflowDelayedTaskList = pxTemp;

            xNumOfOverflows++;

		}



		/* See if this tick has made a timeout expire. */

		prvCheckDelayedTasks();

	}

	else

	{

		++uxMissedTicks;



		/* The tick hook gets called at regular intervals, even if the 

		scheduler is locked. */

		#if ( configUSE_TICK_HOOK == 1 )

		{

			extern void vApplicationTickHook( void );



			vApplicationTickHook();

		}

		#endif

	}



	#if ( configUSE_TICK_HOOK == 1 )

	{

		extern void vApplicationTickHook( void );



		/* Guard against the tick hook being called when the missed tick

		count is being unwound (when the scheduler is being unlocked. */

		if( uxMissedTicks == 0 )

		{

			vApplicationTickHook();

		}

	}

	#endif

}

/*-----------------------------------------------------------*/



#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )



	void vTaskCleanUpResources( void )

	{

	unsigned portSHORT usQueue;

	volatile tskTCB *pxTCB;



		usQueue = ( unsigned portSHORT ) uxTopUsedPriority + ( unsigned portSHORT ) 1;



		/* Remove any TCB's from the ready queues. */

		do

		{

			usQueue--;



			while( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ usQueue ] ) ) )

			{

				listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &( pxReadyTasksLists[ usQueue ] ) );

				vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );



				prvDeleteTCB( ( tskTCB * ) pxTCB );

			}

		}while( usQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY );



		/* Remove any TCB's from the delayed queue. */

		while( !listLIST_IS_EMPTY( &xDelayedTaskList1 ) )

		{

			listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList1 );

			vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );



			prvDeleteTCB( ( tskTCB * ) pxTCB );

		}



		/* Remove any TCB's from the overflow delayed queue. */

		while( !listLIST_IS_EMPTY( &xDelayedTaskList2 ) )

		{

			listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xDelayedTaskList2 );

			vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );



⌨️ 快捷键说明

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