/* * uLipeQueueDelete() */ OsStatus_t uLipeQueueDelete(OsHandler_t *h) { uint32_t sReg; QueuePtr_t q = (QueuePtr_t)h; //check arguments: if( h == (OsHandler_t *)NULL) { return(kInvalidParam); } //Argument valid, then proceed: OS_CRITICAL_IN(); //Assert all tasks pending the queue will be destroyed: QueueDeleteLoop(*h); uLipeMemFree(q->queueBase); uLipeMemFree(q); //Destroy the reference: h = (OsHandler_t *)NULL; q = NULL; OS_CRITICAL_OUT(); uLipeKernelTaskYield(); //All gone well: return(kStatusOk); }
/* * uLipeFlagsDelete() */ OsStatus_t uLipeFlagsDelete(OsHandler_t *h) { FlagsGrpPtr_t f = (FlagsGrpPtr_t)h; uint32_t sReg = 0; //Check argument: if(h == NULL) { return(kInvalidParam); } //valid argument, then proceed: OS_CRITICAL_IN(); //Assert all flag events before to destroy it: FlagsDeleteLoop(*h); uLipeMemFree(f); OS_CRITICAL_OUT(); //Destroy this handler: *h = 0 ; f = NULL; uLipeKernelTaskYield(); //All gone well: return(kStatusOk); }
/* * uLipeQueueFlush() */ OsStatus_t uLipeQueueFlush(OsHandler_t h) { uint32_t sReg; QueuePtr_t q = (QueuePtr_t)h; //check parameters: if(h == 0) { return(kInvalidParam); } //So flush queue: OS_CRITICAL_IN(); q->queueBack = 0; q->queueFront = 0; q->usedSlots = 0; //Update for all pending tasks: QueueRemoveLoop(h); QueueInsertLoop(h); //Queue flushed: OS_CRITICAL_OUT(); //schedule a new task (if needed): uLipeKernelTaskYield(); return(kStatusOk); }
/* * uLipeFlagsPost() */ OsStatus_t uLipeFlagsPost(OsHandler_t h, uint32_t flags) { FlagsGrpPtr_t f = (FlagsGrpPtr_t)h; uint32_t sReg = 0; //Check argument: if(h == 0) { return(kInvalidParam); } //Valid argument, proceed: OS_CRITICAL_IN(); //Assert the flags in register: f->flagRegister |= flags; //Run the PostLoop to update the tasks pending: FlagsPostLoop(h); OS_CRITICAL_OUT(); //Check for a context switch: uLipeKernelTaskYield(); //All gone well: return(kStatusOk); }
/* * uLipeQueueRemove() */ void *uLipeQueueRemove(OsHandler_t h, uint8_t opt, uint16_t timeout, OsStatus_t *err) { QueuePtr_t q = (QueuePtr_t)h; uint32_t sReg = 0; void *ptr = NULL; //check arguments: if(q == 0) { if(err != NULL )*err = kInvalidParam ; return(NULL); } //Arguments valid, then proceed: OS_CRITICAL_IN(); //Check queue status first: if(q->usedSlots == 0) { OS_CRITICAL_OUT(); //Queue full, check options: switch(opt) { case OS_Q_BLOCK_EMPTY: { //task will block so: OS_CRITICAL_IN(); uLipePrioClr(currentTask->taskPrio, &taskPrioList); //prepare task to wait currentTask->taskStatus |= (1 << kTaskPendQueue); if(timeout != 0) { currentTask->taskStatus |= (1 << kTaskPendDelay); currentTask->delayTime = timeout; uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]); } //Adds task to wait list: currentTask->queueBmp = &q->queueInsertWait; uLipePrioSet(currentTask->taskPrio, &q->queueInsertWait); OS_CRITICAL_OUT(); //So check for a context switch: uLipeKernelTaskYield(); if(err != NULL )*err = kQueueEmpty; return(ptr); } break; case OS_Q_NON_BLOCK: { if(q->usedSlots != 0) break; else { OS_CRITICAL_OUT(); if(err != NULL )*err = kQueueEmpty; return(ptr); } } break; default: { //All other cases, only return: if(err != NULL )*err = kQueueEmpty; return(ptr); } break; } } //queue holds data, so remove it: ptr = (void *) q->queueBase[q->queueBack]; q->queueBack++; //queue bevahes as circular FIFO fashion if(q->queueBack > (q->numSlots - 1)) { q->queueBack = 0; } //Update the number of used slots: q->usedSlots--; //Update tasks wich pend this queue: QueueRemoveLoop(h); OS_CRITICAL_OUT(); //Check for context switching: uLipeKernelTaskYield(); if(err != NULL )*err = kStatusOk; //All gone well: return(ptr); }
/* * uLipeQueueInsert() */ OsStatus_t uLipeQueueInsert(OsHandler_t h, void *data, uint8_t opt, uint16_t timeout) { QueuePtr_t q = (QueuePtr_t)h; uint32_t sReg = 0; //check arguments: if(data == NULL) { return(kInvalidParam); } if(q == 0) { return(kInvalidParam); } //Arguments valid, proceed then: OS_CRITICAL_IN(); //Before insert, check queue status: if(q->usedSlots >= q->numSlots) { OS_CRITICAL_OUT(); //Queue full, check options: switch(opt) { case OS_Q_BLOCK_FULL: { //suspend current task: uLipePrioClr(currentTask->taskPrio, &taskPrioList); currentTask->taskStatus |= (1 << kTaskPendQueue); if(timeout != 0) { currentTask->taskStatus |= (1 << kTaskPendDelay); currentTask->delayTime = timeout; uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]); } currentTask->queueBmp = &q->queueSlotWait; //Adds task to wait list: uLipePrioSet(currentTask->taskPrio, &q->queueSlotWait); OS_CRITICAL_OUT(); //So check for a context switch: uLipeKernelTaskYield(); return(kQueueFull); } break; case OS_Q_NON_BLOCK: { if(q->usedSlots < q->numSlots) break; else { OS_CRITICAL_OUT(); return(kQueueFull); } } break; default: { OS_CRITICAL_OUT(); return(kQueueFull); } break; } } //freespace, Insert the data pointer on queue: q->queueBase[q->queueFront] = (void *)data; q->queueFront++; //queue behaves as a circular FIFO fashion: if(q->queueFront > (q->numSlots - 1)) { q->queueFront = 0; } //update number of used slots q->usedSlots++; //Run insertion update loop: QueueInsertLoop(h); OS_CRITICAL_OUT(); //check for a context switch: uLipeKernelTaskYield(); //All gone ok: return(kStatusOk); }
/* * uLipeQueueRemove() */ void *uLipeQueueRemove(OsHandler_t h, uint8_t opt, uint16_t timeout, OsStatus_t *err) { uint32_t sReg = 0; QueuePtr_t q = (QueuePtr_t)h; void *ptr = NULL; //check arguments: if(h == NULL) { return(kInvalidParam); } //Arguments valid, then proceed: OS_CRITICAL_IN(); //Check queue status first: if(q->usedSlots == 0) { OS_CRITICAL_OUT(); //Queue full, check options: switch(opt) { case OS_Q_BLOCK_EMPTY: { //task will block so: OS_CRITICAL_IN(); //suspend current task: uLipePrioClr(currentTask->taskPrio, &taskPrioList); currentTask->taskStatus = (1 << kTaskPendQueue) | (1 << kTaskPendDelay); currentTask->delayTime = timeout; #if OS_USE_DEPRECATED == 1 //Assert this task on queue wait list: q->tasksPending[currentTask->taskPrio] = OS_Q_PEND_EMPTY; #else //Adds task to wait list: uLipePrioSet(currentTask->taskPrio, &q->queueInsertWait); #endif OS_CRITICAL_OUT(); //So check for a context switch: uLipeKernelTaskYield(); *err = kQueueEmpty; return(ptr); } break; default: { //All other cases, only return: *err = kQueueEmpty; return(ptr); } break; } } //queue holds data, so remove it: ptr = (void *) q->queueBase[q->queueBack]; q->queueBack++; //queue bevahes as circular FIFO fashion if(q->queueBack > (q->numSlots - 1)) { q->queueBack = 0; } //Update the number of used slots: q->usedSlots--; //Update tasks wich pend this queue: QueueRemoveLoop(h); OS_CRITICAL_OUT(); //Check for context switching: uLipeKernelTaskYield(); *err = kStatusOk; //All gone well: return(ptr); }
/* * uLipeFlagsPend() */ OsStatus_t uLipeFlagsPend(OsHandler_t h, uint32_t flags, uint8_t opt, uint16_t timeout) { uint32_t sReg = 0; uint32_t mask = 0; uint16_t match = FALSE; FlagsGrpPtr_t f = (FlagsGrpPtr_t)h; //Check for valid handler if(h == 0) { return(kInvalidParam); } OS_CRITICAL_IN(); //Check if this task already asserted: mask = f->flagRegister & currentTask->flagsPending; //check the pend type: switch(opt & ~(OS_FLAGS_CONSUME)) { case OS_FLAGS_PEND_ALL: { if(mask != flags) { currentTask->taskStatus |= (1 << kTaskPendFlagAll); //check if wants to consume: if(opt & OS_FLAGS_CONSUME) { currentTask->taskStatus |= (1 << kTaskPenFlagConsume); } } else { if(opt & OS_FLAGS_CONSUME) { f->flagRegister &= ~currentTask->flagsPending; } //The flags of this task is already asserted match = TRUE; } } break; case OS_FLAGS_PEND_ANY: { if(f->flagRegister == 0x0000000) { currentTask->taskStatus |= (1 << kTaskPendFlagAny); //check if wants to consume: if(opt & OS_FLAGS_CONSUME) { currentTask->taskStatus |= (1 << kTaskPenFlagConsume); } } else { if(opt & OS_FLAGS_CONSUME) { f->flagRegister = 0; } //Any flags of this task was already assert match = TRUE; } } break; default: { //Invalid option, return with error: OS_CRITICAL_OUT(); return(kInvalidParam); } } //check for match: if(match != FALSE) { //Only return, without suspend task: OS_CRITICAL_OUT(); return(kStatusOk); } //Set the flags: currentTask->flagsPending |= flags; //if not, then suspend task: uLipePrioClr(currentTask->taskPrio, &taskPrioList); uLipePrioSet(currentTask->taskPrio, &f->waitTasks[f->activeList]); currentTask->flagsBmp = &f->waitTasks[0]; //adds the timeout if(timeout != 0) { currentTask->delayTime = timeout; currentTask->taskStatus |= (1 << kTaskPendDelay); uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]); } OS_CRITICAL_OUT(); //Check for a context switch: uLipeKernelTaskYield(); //all gone well: return(kStatusOk); }