/********************************************************************* * @fn Util_constructClock * * @brief Initialize a TIRTOS Clock instance. * * @param pClock - pointer to clock instance structure. * @param clockCB - callback function upon clock expiration. * @param clockDuration - longevity of clock timer in milliseconds * @param clockPeriod - if set to a value other than 0, the first * expiry is determined by clockDuration. All * subsequent expiries use the clockPeriod value. * @param startFlag - TRUE to start immediately, FALSE to wait. * @param arg - argument passed to callback function. * * @return Clock_Handle - a handle to the clock instance. */ Clock_Handle Util_constructClock(Clock_Struct *pClock, Clock_FuncPtr clockCB, uint32_t clockDuration, uint32_t clockPeriod, uint8_t startFlag, UArg arg) { Clock_Params clockParams; // Convert clockDuration in milliseconds to ticks. uint32_t clockTicks = clockDuration * (1000 / Clock_tickPeriod); // Setup parameters. Clock_Params_init(&clockParams); // Setup argument. clockParams.arg = arg; // If period is 0, this is a one-shot timer. clockParams.period = clockPeriod * (1000 / Clock_tickPeriod); // Starts immediately after construction if true, otherwise wait for a call // to start. clockParams.startFlag = startFlag; // Initialize clock instance. Clock_construct(pClock, clockCB, clockTicks, &clockParams); return Clock_handle(pClock); }
/* * ======== PowerCC3200_initPolicy ======== */ void PowerCC3200_initPolicy() { Clock_Params clockParams; /* construct Clock object */ Clock_Params_init(&clockParams); clockParams.period = 0; clockParams.startFlag = FALSE; Clock_construct(&clockObj, &PowerCC3200_dummyClockFunc, 0, &clockParams); }
/* * ======== Task_sleep ======== */ Void Task_sleep(UInt timeout) { Task_PendElem elem; UInt hwiKey, tskKey; Clock_Struct clockStruct; if (timeout == BIOS_NO_WAIT) { return; } Assert_isTrue((timeout != BIOS_WAIT_FOREVER), Task_A_badTimeout); /* add Clock event if timeout is not FOREVER */ if (BIOS_clockEnabled) { Clock_Params clockParams; Clock_Params_init(&clockParams); clockParams.arg = (UArg)&elem; clockParams.startFlag = FALSE; /* will start when necessary, thankyou */ Clock_construct(&clockStruct, (Clock_FuncPtr)Task_sleepTimeout, timeout, &clockParams); elem.clock = Clock_handle(&clockStruct); } hwiKey = Hwi_disable(); /* lock scheduler */ tskKey = Task_disable(); /* get task handle and block tsk */ elem.task = Task_self(); Task_blockI(elem.task); if (BIOS_clockEnabled) { Clock_startI(elem.clock); } /* Only needed for Task_delete() */ Queue_elemClear(&elem.qElem); elem.task->pendElem = (Ptr)(&elem); Hwi_restore(hwiKey); Log_write3(Task_LM_sleep, (UArg)elem.task, (UArg)elem.task->fxn, (UArg)timeout); Task_restore(tskKey); /* the calling task will block here */ /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled) { Clock_destruct(Clock_struct(elem.clock)); } }
static Int32 IpcFramesInLink_createPrdObj(IpcFramesInLink_Obj * pObj) { Clock_Params clockParams; Clock_Params_init(&clockParams); clockParams.arg = (UArg) pObj; UTILS_assert(pObj->prd.clkHandle == NULL); Clock_construct(&(pObj->prd.clkStruct), IpcFramesInLink_prdCalloutFcn, 1, &clockParams); pObj->prd.clkHandle = Clock_handle(&pObj->prd.clkStruct); pObj->prd.clkStarted = FALSE; return IPC_FRAMES_IN_LINK_S_SUCCESS; }
/********************************************************************* * @fn initBuzzTimer * * @brief Set up timer for buzz generation (use PWM when RTOS driver in place) * * @param none * * @return none */ static void initBuzzTimer(void) { Clock_Params clockParams; // Setup parameters. Clock_Params_init(&clockParams); // Setup argument. clockParams.arg = 0; // Period clockParams.period = BUZZER_PERIOD; // Do not start until called. clockParams.startFlag = false; // Initialize clock instance. Clock_construct(&buzzClockStruct, timerIsr, BUZZER_PERIOD, &clockParams); buzzClockHandle = Clock_handle(&buzzClockStruct); }
/* * ======== Semaphore_pend ======== */ Bool Semaphore_pend(Semaphore_Object *sem, UInt timeout) { UInt hwiKey, tskKey; Semaphore_PendElem elem; Queue_Handle pendQ; Clock_Struct clockStruct; Log_write3(Semaphore_LM_pend, (IArg)sem, (UArg)sem->count, (IArg)((Int)timeout)); /* * Consider fast path check for count != 0 here!!! */ /* * elem is filled in entirely before interrupts are disabled. * This significantly reduces latency. */ /* add Clock event if timeout is not FOREVER nor NO_WAIT */ if (BIOS_clockEnabled && (timeout != BIOS_WAIT_FOREVER) && (timeout != BIOS_NO_WAIT)) { Clock_Params clockParams; Clock_Params_init(&clockParams); clockParams.arg = (UArg)&elem; clockParams.startFlag = FALSE; /* will start when necessary, thankyou */ Clock_construct(&clockStruct, (Clock_FuncPtr)Semaphore_pendTimeout, timeout, &clockParams); elem.tpElem.clock = Clock_handle(&clockStruct); elem.pendState = Semaphore_PendState_CLOCK_WAIT; } else { elem.tpElem.clock = NULL; elem.pendState = Semaphore_PendState_WAIT_FOREVER; } pendQ = Semaphore_Instance_State_pendQ(sem); hwiKey = Hwi_disable(); /* check semaphore count */ if (sem->count == 0) { if (timeout == BIOS_NO_WAIT) { Hwi_restore(hwiKey); return (FALSE); } Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), Semaphore_A_badContext); /* lock task scheduler */ tskKey = Task_disable(); /* get task handle and block tsk */ elem.tpElem.task = Task_self(); /* leave a pointer for Task_delete() */ elem.tpElem.task->pendElem = (Task_PendElem *)&(elem); Task_blockI(elem.tpElem.task); if (((UInt)sem->mode & 0x2) != 0) { /* if PRIORITY bit is set */ Semaphore_PendElem *tmpElem; Task_Handle tmpTask; UInt selfPri; tmpElem = Queue_head(pendQ); selfPri = Task_getPri(elem.tpElem.task); while (tmpElem != (Semaphore_PendElem *)pendQ) { tmpTask = tmpElem->tpElem.task; /* use '>' here so tasks wait FIFO for same priority */ if (selfPri > Task_getPri(tmpTask)) { break; } else { tmpElem = Queue_next((Queue_Elem *)tmpElem); } } Queue_insert((Queue_Elem *)tmpElem, (Queue_Elem *)&elem); } else { /* put task at the end of the pendQ */ Queue_enqueue(pendQ, (Queue_Elem *)&elem); } /* start Clock if appropriate */ if (BIOS_clockEnabled && (elem.pendState == Semaphore_PendState_CLOCK_WAIT)) { Clock_startI(elem.tpElem.clock); } Hwi_restore(hwiKey); Task_restore(tskKey); /* the calling task will block here */ /* Here on unblock due to Semaphore_post or timeout */ if (Semaphore_supportsEvents && (sem->event != NULL)) { /* synchronize Event state */ hwiKey = Hwi_disable(); Semaphore_eventSync(sem->event, sem->eventId, sem->count); Hwi_restore(hwiKey); } /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_destruct(Clock_struct(elem.tpElem.clock)); } elem.tpElem.task->pendElem = NULL; return ((Bool)(elem.pendState)); } else { --sem->count; if (Semaphore_supportsEvents && (sem->event != NULL)) { /* synchronize Event state */ Semaphore_eventSync(sem->event, sem->eventId, sem->count); } Hwi_restore(hwiKey); /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_destruct(Clock_struct(elem.tpElem.clock)); } return (TRUE); } }
/* * ======== Event_pend ======== */ UInt Event_pend(Event_Object *event, UInt andMask, UInt orMask, UInt timeout) { UInt hwiKey, tskKey; Event_PendElem elem; UInt matchingEvents; Queue_Handle pendQ; Clock_Struct clockStruct; Assert_isTrue(((andMask | orMask) != 0), Event_A_nullEventMasks); Log_write5(Event_LM_pend, (UArg)event, (UArg)event->postedEvents, (UArg)andMask, (UArg)orMask, (IArg)((Int)timeout)); /* * elem is filled in entirely before interrupts are disabled. * This significantly reduces latency at the potential cost of wasted time * if it turns out that there is already an event match. */ /* add Clock event if timeout is not FOREVER nor NO_WAIT */ if (BIOS_clockEnabled && (timeout != BIOS_WAIT_FOREVER) && (timeout != BIOS_NO_WAIT)) { Clock_Params clockParams; Clock_Params_init(&clockParams); clockParams.arg = (UArg)&elem; clockParams.startFlag = FALSE; /* will start when necessary, thankyou */ Clock_construct(&clockStruct, (Clock_FuncPtr)Event_pendTimeout, timeout, &clockParams); elem.tpElem.clock = Clock_handle(&clockStruct); elem.pendState = Event_PendState_CLOCK_WAIT; } else { elem.tpElem.clock = NULL; elem.pendState = Event_PendState_WAIT_FOREVER; } /* fill in this task's Event_PendElem */ elem.andMask = andMask; elem.orMask = orMask; pendQ = Event_Instance_State_pendQ(event); /* get task handle */ elem.tpElem.task = Task_self(); /* leave a pointer for Task_delete() */ elem.tpElem.task->pendElem = (Task_PendElem *)&(elem); /* Atomically check for a match and block if none */ hwiKey = Hwi_disable(); /* check if events are already available */ matchingEvents = checkEvents(event, andMask, orMask); if (matchingEvents != 0) { Hwi_restore(hwiKey); /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_destruct(Clock_struct(elem.tpElem.clock)); } return (matchingEvents);/* yes, then return with matching bits */ } if (timeout == BIOS_NO_WAIT) { Hwi_restore(hwiKey); return (0); /* No match, no wait */ } Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), Event_A_badContext); /* lock scheduler */ tskKey = Task_disable(); /* only one Task allowed!!! */ Assert_isTrue(Queue_empty(pendQ), Event_A_eventInUse); /* add it to Event_PendElem queue */ Queue_enqueue(pendQ, (Queue_Elem *)&elem); Task_blockI(elem.tpElem.task); if (BIOS_clockEnabled && (elem.pendState == Event_PendState_CLOCK_WAIT)) { Clock_startI(elem.tpElem.clock); } Hwi_restore(hwiKey); /* unlock task scheduler and block */ Task_restore(tskKey); /* the calling task will switch out here */ /* Here on unblock due to Event_post or Event_pendTimeout */ /* deconstruct Clock if appropriate */ if (BIOS_clockEnabled && (elem.tpElem.clock != NULL)) { Clock_destruct(Clock_struct(elem.tpElem.clock)); } elem.tpElem.task->pendElem = NULL; /* event match? */ if (elem.pendState != Event_PendState_TIMEOUT) { return (elem.matchingEvents); } else { return (0); /* timeout */ } }