/** * 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); }
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); }