コード例 #1
0
ファイル: semaphore.c プロジェクト: idmond/moped
StatusType WaitSemaphore( OsSemaphoreType *semPtr, TickType tmo ) {
    OsTaskVarType *pcbPtr;
    uint32_t flags;
    StatusType rv = E_OK;
    (void)tmo;

    Irq_Save(flags);

    --semPtr->val;

    pcbPtr = Os_SysTaskGetCurr();
    assert(OS_SYS_PTR->intNestCnt == 0 );

    if (pcbPtr->constPtr->proc_type != PROC_EXTENDED) {
        return E_OS_ACCESS;
    }

    if(semPtr->val < 0 ) {
        /* To WAITING state */
        if( tmo == 0 ) {
            /* Failed to acquire the semaphore */
            rv = E_NOT_OK;
        } else {
            /* Add this task to the semaphore */
            STAILQ_INSERT_TAIL(&semPtr->taskHead,pcbPtr,semEntry);

            Os_Dispatch(OP_WAIT_SEMAPHORE);
        }
    } else {
        /* We got the semaphore */
        if( tmo == 0 ) {

            rv = E_NOT_OK;
        } else {
            /*
             * Wait for the semaphore to be signaled or timeout
             */
            if ( Os_SchedulerResourceIsFree() ) {
                /* Set the timeout */
                if( tmo != TICK_MAX ) {
                    TAILQ_INSERT_TAIL(&OS_SYS_PTR->timerHead,pcbPtr,timerEntry);
                    pcbPtr->timerDec = tmo;
                }

                Os_Dispatch(OP_WAIT_SEMAPHORE);
            } else {
                /* We hold RES_SCHEDULER */
                rv = E_NOT_OK;
            }
        }
    }

    Irq_Restore(flags);

    return rv;
}
コード例 #2
0
ファイル: semaphore.c プロジェクト: idmond/moped
/**
 * Increase the semaphore value by 1. If
 *
 * @param semPtr
 */
void SignalSemaphore( OsSemaphoreType *semPtr ) {
    uint32_t flags;
    OsTaskVarType *taskPtr;

    Irq_Save(flags);

    assert( semPtr != NULL );

    ++semPtr->val;

    /* Remove the first task that waits at the semaphore */
    if( semPtr->val <= 0 ) {

        taskPtr = STAILQ_FIRST(&semPtr->taskHead);
        /* Make the first task ready */
        Os_TaskMakeReady(taskPtr);

        /* Release the first task in queue */
        STAILQ_REMOVE_HEAD(&semPtr->taskHead,semEntry);

        if( taskPtr->activePriority > Os_SysTaskGetCurr()->activePriority ) {
            Os_Dispatch(OP_SIGNAL_SEMAPHORE);
        }
    }

    Irq_Restore(flags);
}
コード例 #3
0
ファイル: resource.c プロジェクト: uincore/OpenSAR
StatusType ReleaseResource( ResourceType ResID) {
	StatusType rv = E_OK;
	OsTaskVarType *pcbPtr = Os_SysTaskGetCurr();
	OsResourceType *rPtr;
	uint32_t flags;

	Irq_Save(flags);
	if( ResID == RES_SCHEDULER ) {
		rPtr = &Os_Sys.resScheduler;
	} else {
		/* Check we can access it */
		if( (pcbPtr->constPtr->resourceAccess & (1<< ResID)) == 0 ) {
			rv = E_OS_ID;
			goto err;
		}
		rPtr = Os_ResourceGet(ResID);
	}

	/* Check for invalid configuration */
	if( rPtr->owner == NO_TASK_OWNER)
	{
		rv = E_OS_NOFUNC;
		Irq_Restore(flags);
		goto err;
	}

	if( (pcbPtr->activePriority < rPtr->ceiling_priority))
	{
		rv = E_OS_ACCESS;
		Irq_Restore(flags);
		goto err;
	}

	Os_TaskResourceRemove(rPtr,pcbPtr);

	/* do a rescheduling (in some cases) (see OSEK OS 4.6.1) */
	if ( (pcbPtr->constPtr->scheduling == FULL) &&
		 (Os_Sys.intNestCnt == 0) &&
		 (Os_SchedulerResourceIsFree()) ) {

		OsTaskVarType* top_pcb = Os_TaskGetTop();

		/* only dispatch if some other ready task has higher prio */
		if (top_pcb->activePriority > Os_SysTaskGetCurr()->activePriority) {
			Os_Dispatch(OP_RELEASE_RESOURCE);
		}
	}
	Irq_Restore(flags);

	OS_STD_END_1(OSServiceId_ReleaseResource,ResID);
}
コード例 #4
0
StatusType WaitEvent( EventMaskType Mask ) {

	OsTaskVarType *curr_pcb = Os_SysTaskGetCurr();
	StatusType rv = E_OK;
	imask_t state;

	OS_DEBUG(D_EVENT,"# WaitEvent %s\n",Os_SysTaskGetCurr()->constPtr->name);

	OS_VALIDATE( OS_SYS_PTR->intNestCnt == 0, E_OS_CALLEVEL);
	OS_VALIDATE( curr_pcb->constPtr->proc_type == PROC_EXTENDED,E_OS_ACCESS);
	OS_VALIDATE( !Os_TaskOccupiesResources(curr_pcb),E_OS_RESOURCE);
#if	(OS_NUM_CORES > 1)
	OS_VALIDATE( !Os_TaskOccupiesSpinlocks(curr_pcb) != 0,E_OS_SPINLOCK);       /* @req 4.1.2/SWS_Os_00622 */
#endif

	/* Remove from ready queue */
	Irq_Save(state);

	// OSEK/VDX footnote 5. The call of WaitEvent does not lead to a waiting state if one of the events passed in the event mask to
    // WaitEvent is already set. In this case WaitEvent does not lead to a rescheduling.
	if( !(curr_pcb->ev_set & Mask) ) {

		curr_pcb->ev_wait = Mask;

		if ( Os_SchedulerResourceIsFree() ) {
			// Os_TaskMakeWaiting(currTaskPtr);
			Os_Dispatch(OP_WAIT_EVENT);
			assert( curr_pcb->state & ST_RUNNING );
		} else {
			Os_TaskMakeWaiting(curr_pcb);
		}
	}

	Irq_Restore(state);

	// The following line disables the unused label warning. Remove when
	// proper error handling is implemented.
	if (0) goto err;

	OS_STD_END_1(OSServiceId_WaitEvent,Mask);
}
コード例 #5
0
StatusType SetEvent( TaskType TaskID, EventMaskType Mask ) {
	StatusType rv = E_OK;
	OsTaskVarType *destPcbPtr;
	OsTaskVarType *currPcbPtr;
	uint32_t flags;

	OS_DEBUG(D_EVENT,"# SetEvent %s\n",Os_SysTaskGetCurr()->constPtr->name);

	TASK_CHECK_ID(TaskID);

	destPcbPtr = Os_TaskGet(TaskID);
	currPcbPtr = Os_SysTaskGetCurr();

#if (OS_SC3==STD_ON) || (OS_SC4==STD_ON)

	if( destPcbPtr->constPtr->applOwnerId != OS_SYS_PTR->currApplId ) {
		ApplicationType appId;
	    APPL_CHECK_STATE(destPcbPtr->constPtr->applOwnerId);
    	/* Do we have access to the task we are activating */
        if(OS_SYS_PTR->intNestCnt == 0 ) {
        	appId = currPcbPtr->constPtr->applOwnerId;
        } else {
        	appId = Os_SysIsrGetCurr()->constPtr->appOwner;
        }

        APPL_CHECK_ACCESS( appId , destPcbPtr->constPtr->accessingApplMask);

#if (OS_NUM_CORES > 1)
	    if (Os_ApplGetCore(destPcbPtr->constPtr->applOwnerId) != GetCoreID()) {
	                StatusType status = Os_NotifyCore(Os_ApplGetCore(destPcbPtr->constPtr->applOwnerId),
	                                                  OSServiceId_SetEvent,
	                                                  TaskID,
	                                                  Mask,
	                                                  0);
	                return status;
#endif

	}
#endif

	OS_VALIDATE( destPcbPtr->constPtr->proc_type == PROC_EXTENDED, E_OS_ACCESS );
	OS_VALIDATE( !(destPcbPtr->state & ST_SUSPENDED ), E_OS_STATE);

	Irq_Save(flags);

	/* Calling  SetEvent  causes  the  task  <TaskID>  to be  transferred
	 * to  the  ready  state,  if  it  was  waiting  for  at  least one of the
	 * events specified in <Mask>.
	 *
	 * OSEK/VDX 4.6.1,  rescheduling is performed in all of the following cases:
	 * ..
	 * Setting an event to a waiting task at task level (e.g. system service SetEvent,
	 * see chapter 13.5.3.1, message notification mechanism, alarm expiration, if event setting
	 * defined, see chapter 9.2)
	 * ... */

	destPcbPtr->ev_set |= Mask;

	if( (Mask & destPcbPtr->ev_wait) ) {
		/* We have an event match */
		if( destPcbPtr->state & ST_WAITING) {
			Os_TaskMakeReady(destPcbPtr);

			currPcbPtr = Os_SysTaskGetCurr();
			/* Checking "4.6.2  Non preemptive scheduling" it does not dispatch if NON  */
			if( (OS_SYS_PTR->intNestCnt == 0) &&
				(currPcbPtr->constPtr->scheduling == FULL) &&
				(destPcbPtr->activePriority > currPcbPtr->activePriority) &&
				(Os_SchedulerResourceIsFree()) )
			{
				Os_Dispatch(OP_SET_EVENT);
			}

		}  else if(destPcbPtr->state & (ST_READY|ST_RUNNING|ST_SLEEPING) ) {
			/* Hmm, we do nothing */
		} else {
			assert( 0 );
		}
	}

	Irq_Restore(flags);

	OS_STD_END_2(OSServiceId_SetEvent,TaskID, Mask);
}


/**
 * This service returns the current state of all event bits of the task
 * <TaskID>, not the events that the task is waiting for.
 * The service may be called from interrupt service routines, task
 * level and some hook routines (see Figure 12-1).
 *  The current status of the event mask of task <TaskID> is copied
 * to <Event>.
 *
 * @param TaskId Task whose event mask is to be returned.
 * @param Mask   Reference to the memory of the return data.
 * @return
 */
StatusType GetEvent( TaskType TaskId, EventMaskRefType Mask) {

	OsTaskVarType *destPcbPtr;
	StatusType rv = E_OK;

	TASK_CHECK_ID(TaskId);

	destPcbPtr = Os_TaskGet(TaskId);

	OS_VALIDATE( (destPcbPtr->constPtr->proc_type == PROC_EXTENDED) ,E_OS_ACCESS);
	OS_VALIDATE( !(destPcbPtr->state & ST_SUSPENDED),E_OS_STATE);

	*Mask = destPcbPtr->ev_set;

	if (0) goto err;

	OS_STD_END_2(OSServiceId_GetEvent,TaskId, Mask);
}