Example #1
0
StatusType GetResource( ResourceType ResID ) {
	StatusType rv = E_OK;
	OsResourceType *rPtr;
	uint32_t flags;

#if	(OS_APPLICATION_CNT > 1)

	if (ResID != RES_SCHEDULER) {
		rv = Os_ApplHaveAccess( Os_ResourceGet(ResID)->accessingApplMask );
		if( rv != E_OK ) {
			goto err;
		}
	}

#endif

	Irq_Save(flags);

	if( Os_Sys.intNestCnt != 0 ) {

		/* For interrupts to the scheduler resource seems just dumb to get */
		OsIsrVarType *isrPtr = Os_SysIsrGetCurr();

		/* Check we can access it */
		if( ((isrPtr->constPtr->resourceMask & (1<< ResID)) == 0) ||
			( ResID == RES_SCHEDULER )	) {
			rv = E_OS_ID;
			goto err;
		}

		rPtr = Os_ResourceGet(ResID);

		/* ceiling prio for ISR seems strange...so no */
		if( rPtr->owner != NO_TASK_OWNER ) {
			rv = E_OS_ACCESS;
			Irq_Restore(flags);
			goto err;
		}
		/* Add the resource to the list of resources held by this isr */
		Os_IsrResourceAdd(rPtr,isrPtr);

	} else {
		OsTaskVarType *taskPtr = Os_SysTaskGetCurr();

		if( ResID == RES_SCHEDULER ) {
			rPtr = &Os_Sys.resScheduler;
		} else {
			/* Check we can access it */
			if( (taskPtr->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) ||
			(taskPtr->activePriority > rPtr->ceiling_priority) )
		{
			rv = E_OS_ACCESS;
			Irq_Restore(flags);
			goto err;
		}
		/* Add the resource to the list of resources held by this task */
		Os_TaskResourceAdd(rPtr,taskPtr);
	}

	Irq_Restore(flags);

	if (rv != E_OK)
		goto err;

	OS_STD_END_1(OSServiceId_GetResource,ResID);
}
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);
}