Beispiel #1
0
/*!
	Post (release) a semaphore.  If there are other tasks waiting for this 
	semaphore, the highest-priority task in the semaphore wait list will claim
	the semaphore and run.
	\fn BOOL Semaphore_Post(SEMAPHORE_STRUCT *pstSem_)
	\param pstSem_ - pointer to the semaphore to post
*/
void Semaphore_Post(SEMAPHORE_STRUCT *pstSem_)
{	
	BOOL bTaskWait = FALSE;
	
	//!! Disable scheduler + interrupts (callable from ISR)
	CS_ENTER();
	// Nothing is pending
	if (pstSem_->pstTask == NULL)
	{
		// Re-initialize the semaphore
		if (pstSem_->usSem < pstSem_->usMax)
		{
			pstSem_->usSem++;
		}
	}
	else
	{
		// Wake the highest priority task pending on the semaphore
		Semaphore_WakeNextPending(pstSem_);
		bTaskWait = TRUE;
	}	
	CS_EXIT();
	
	if (bTaskWait)
	{
		Task_YieldSWI();
	}
}
Beispiel #2
0
/*!
	Remove a task from the scheduler list.  Before attempting to remove the
	task, the owner should ensure that all connections of this task to other
	objects (plumber, semaphore, etc.) are removed PRIOR to calling this
	function, otherwise system corruption will likely occur.
	\fn BOOL Task_Remove(TASK_STRUCT *pstTask_)
	\sa Task_Add()
	\param pstTask_ - pointer to the task structure to remove
	\return (BOOL) TRUE on success, FAIL on failure
*/
BOOL Task_Remove(TASK_STRUCT *pstTask_)
{	
	TASK_STRUCT *pstPrev;
	TASK_STRUCT *pstTarget;
	
	CS_ENTER();
	
	// initialize the target
	pstPrev = pstTask_;
	pstTarget = pstTask_->pstNext;
	
	// Look through the circular list of tasks and find the connectors.
	while (pstTarget != pstTask_)
	{
		// iterate through...
		pstPrev = pstTarget;
		pstTarget = pstTarget->pstNext;
	}
	// Remove the target from the circularly linked list
	pstPrev->pstNext = pstTask_->pstNext;
	
	// De-initialize the "next" pointer in the task list.
	pstTask_->pstNext = NULL;
	
	// Set the task as uninitialized (require initialization before reuse)
	pstTask_->eState = TASK_UNINIT;
	
	CS_EXIT();
	
	// Call a context switch.
	Task_YieldSWI();
	
	// Will not return if the thread deletes itself.	
	return FALSE;
}
Beispiel #3
0
/*!
	Set a task to sleep for a period of time specified in the arguments
	\sa Task_Tick()
	\fn void Task_Sleep(USHORT usTime_)
	\param usTime_ - the time period in RTOS ticks to sleep through
*/
void Task_Sleep(USHORT usTime_)
{
	// Do this in a scheduler-disabled context
	CS_ENTER();
		
	pstCurrentTask->eState = TASK_SLEEP;
	pstCurrentTask->usTimeLeft = usTime_;
	
	CS_EXIT();
		
	// Call the scheduler immediately.
	Task_YieldSWI();
}
Beispiel #4
0
/*!
	Signal a task to wait for a semaphore.  If the semaphore is not available,
	the task will block and wait until the semaphore becomes available.
	\fn BOOL Semaphore_Pend(SEMAPHORE_STRUCT *pstSem_, USHORT usTime_)
	\param pstSem_ - pointer to the semaphore to pend on
	\param usTime_ - the time limit to wait for the semaphore. Integer number of ticks or TIME_FOREVER
	\return BOOL - TRUE on success, FALSE on timeout
*/
BOOL Semaphore_Pend(SEMAPHORE_STRUCT *pstSem_,  USHORT usTime_)
{
	BOOL bTaskWait = FALSE;
	BOOL bReturn = TRUE;
	TASK_STRUCT *pstTask;
	//!! Disable Scheduler !!
	CS_ENTER();
	pstTask = Task_GetCurrentTask();
	if (pstSem_->usSem != 0)
	{
		// Semaphore isn't claimed, claim it.
		pstSem_->usSem--;
	}
	else
	{	
		// Remove the task from the ready state - blocking on semaphore
		pstTask->eState = TASK_BLOCKED;
		pstTask->usTimeLeft = usTime_;

		// Add the task to the semaphore's waiting list.
		Semaphore_AddToList(pstSem_, pstTask);
	
		bTaskWait = TRUE;
	}
	CS_EXIT();
	
	if (bTaskWait)
	{
		// Switch tasks immediately
		Task_YieldSWI();
	
		CS_ENTER();
		if (pstTask->bTimeout)
		{
			// If there was a timeout waiting for the semaphore
			bReturn = FALSE;
			Semaphore_DeleteFromList(pstSem_, pstTask);
			pstTask->bTimeout = FALSE;	// Reset the task timeout flag				
		}
		CS_EXIT();
	}
	
	return bReturn;
}