//YKEventPend unsigned YKEventPend(YKEVENT *event, unsigned eventMask, int waitMode) { int i; YKEnterMutex(); if(waitMode == EVENT_WAIT_ALL) { if(event->flags == eventMask) { return event->flags; } } else // wait mode any { if((event->flags & eventMask) > 0) { return event->flags; } } YKReadyList->waitMode = waitMode; YKReadyList->eventMask = eventMask; YKMoveTCB(YKReadyList, &YKReadyList, &(event->blockedList)); YKScheduler(1); return event->flags; }
void YKNewTask(void (* task)(void), void *taskStack, unsigned char priority) { /* Create the Task’s TCB Call the Scheduler to see if a higher priority interrupt should run */ YKCtxSwCount++; // addTCB(); TCBPtr tmp, tmp2; tmp = YKAvailTCBList; YKAvailTCBList = tmp->next; /* code to insert an entry in doubly linked ready list sorted by priority numbers (lowest number first). tmp points to TCB to be inserted */ if (YKRdyList == NULL) { /* is this first insertion? */ YKRdyList = tmp; tmp->next = NULL; tmp->prev = NULL; } else { /* not first insertion */ tmp2 = YKRdyList; /* insert in sorted ready list */ while (tmp2->priority < tmp->priority) tmp2 = tmp2->next; /* assumes idle task is at end */ if (tmp2->prev == NULL) /* insert in list before tmp2 */ YKRdyList = tmp; else tmp2->prev->next = tmp; tmp->prev = tmp2->prev; tmp->next = tmp2; tmp2->prev = tmp; tmp->stackptr = *taskStack; tmp->priority = priority; } if (priority > tmp->priority) YKScheduler(); }
void YKNewTask(void (* task)(void), void *taskStack, unsigned char priority) { tcb_t *cur_tcb = YKAvailTCBList; YKAvailTCBList++; cur_tcb->ax = 0; cur_tcb->bx = 0; cur_tcb->cx = 0; cur_tcb->dx = 0; cur_tcb->ip = task; cur_tcb->sp = taskStack; cur_tcb->bp = taskStack; cur_tcb->si = 0; cur_tcb->di = 0; cur_tcb->cs = 0; cur_tcb->ss = 0; cur_tcb->ds = 0; cur_tcb->es = 0; cur_tcb->flags = 512; //O:0 D:0 I:1 T:0 S:0 Z:0 A:00 P:00 C:00 cur_tcb->priority = priority; cur_tcb->state = READY; cur_tcb->delay = 0; cur_tcb->semaphore = NULL; cur_tcb->queue = NULL; cur_tcb->eventState.event = NULL; cur_tcb->eventState.eventMask = 0; cur_tcb->eventState.waitMode = 0; cur_tcb->prev = 0; cur_tcb->next = 0; YKAddReadyTask(cur_tcb); if (YKRunFlag) { YKScheduler(); } }
//YKEventSet void YKEventSet(YKEVENT *event, unsigned eventMask) { TCBptr current, next; int i; YKEnterMutex(); current = event->blockedList; event->flags = event->flags | eventMask; while(current != NULL) { next = current->next; if(current->waitMode == EVENT_WAIT_ALL) { if(current->eventMask == event->flags) { YKMoveTCB(current, &(event->blockedList), &YKReadyList); } } else { if((event->flags & eventMask) > 0) { YKMoveTCB(current, &(event->blockedList), &YKReadyList); } } current = next; } if(nestedInterruptLevel == 0) //if not in an interrupt { YKScheduler(1); } }
unsigned YKEventPend(YKEVENT *event, unsigned eventMask, int waitMode){ int conditionMet = 0; int i; unsigned flags; TCBptr temp, temp2, iter; YKEnterMutex(); // ------- Test if Conditions are met --------// conditionMet = checkConditions(event->flags, eventMask, waitMode); // -------- If condition met, return. Else, block --------// if (conditionMet){ flags = event->flags; YKExitMutex(); return flags; } else{ // Remove calling task's TCB from ready list temp = YKRdyList; // Hold the first ready task // Remove it from Ready list YKRdyList = temp->next; if (YKRdyList != NULL) YKRdyList->prev = NULL; // modify TCB, put in suspended list temp->state = BLOCKED; temp->flags = eventMask; temp->waitMode = waitMode; // Put task at event's blocked list if (event->waitingOn == NULL){ event->waitingOn = temp; temp->next = NULL; temp->prev = NULL; } else{ iter = event->waitingOn; temp2 = NULL; while (iter != NULL && iter->priority < temp->priority){ temp2 = iter; iter = iter->next; } if (iter == NULL){//At end temp2->next = temp; temp->prev = temp; temp->next = NULL; } else{ // insert before iterator temp->next = iter; temp->prev = temp2; iter->prev = temp; if (temp2 == NULL)//inserted at beginning of list event->waitingOn = temp; else temp2->next = temp; } } YKScheduler(ContextNotSaved); flags = event->flags; YKExitMutex(); } return flags; }
int YKQPost(YKQ *queue, void *msg) { int return_value; // put message into queue YKEnterMutex(); if (queue->size != queue->max_length ) { ++(queue->size); queue->base_addr[queue->tail] = msg; if ( queue->tail == (queue->max_length - 1) ) queue->tail = 0; else ++(queue->tail); if (queue->size == 1) { YKBlockQ2Ready(queue); if (YKISRDepth == 0) { YKExitMutex(); YKScheduler(); } } return_value = 1; } else return_value = 0; YKExitMutex(); return return_value; }
void YKExitISR() { nestingLevel--; if (nestingLevel == 0 && running) { YKScheduler(ContextSaved); } }
void *YKQPend(YKQ *queue){ void * tempMsg; TCBptr temp, temp2, iter; TOP: YKEnterMutex(); if (queue->numOfMsgs > 0){ // not empty // remove oldest message tempMsg = queue->baseAddress[queue->removeLoc]; queue->removeLoc++; // handle roll over if (queue->removeLoc >= queue->numOfEntries){ queue->removeLoc = 0; } queue->numOfMsgs--; } else { // Remove calling task's TCB from ready list temp = YKRdyList; // Hold the first ready task // Remove it from Ready list YKRdyList = temp->next; if (YKRdyList != NULL) YKRdyList->prev = NULL; // modify TCB, put in suspended list temp->state = BLOCKED; // Put task at queue's blocked list if (queue->blockedOn == NULL){ queue->blockedOn = temp; temp->next = NULL; temp->prev = NULL; } else{ iter = queue->blockedOn; temp2 = NULL; while (iter != NULL && iter->priority < temp->priority){ temp2 = iter; iter = iter->next; } if (iter == NULL){//At end temp2->next = temp; temp->prev = temp; temp->next = NULL; } else{ // insert before iterator temp->next = iter; temp->prev = temp2; iter->prev = temp; if (temp2 == NULL)//inserted at beginning of list queue->blockedOn = temp; else temp2->next = temp; } } YKScheduler(ContextNotSaved); goto TOP; } YKExitMutex(); return tempMsg; }
void YKRun(void){ //printString("YKRun\n"); //Calls the scheduler and begins the operation of the program //printTasks(); firstRun = 0; YKScheduler(); }
void YKNewTask(void (* task)(void), void *stackptr, unsigned char priority){ int i; unsigned *stackIter; TCBptr insertion, iter2; YKEnterMutex(); insertion = YKAvailTCBList; if(insertion == NULL){ return; } YKAvailTCBList = insertion->next; insertion->state = READY; insertion->priority = priority; insertion->delay = 0; insertion->flags = 0; insertion->waitMode = 0; if (YKRdyList == NULL) /* is this first insertion? */ { YKRdyList = insertion; insertion->next = NULL; insertion->prev = NULL; } else /* not first insertion */ { iter2 = YKRdyList; /* insert in sorted ready list */ while (iter2->priority < insertion->priority) iter2 = iter2->next; /* assumes idle task is at end */ if (iter2->prev == NULL) /* insert in list before tmp2 */ YKRdyList = insertion; else iter2->prev->next = insertion; insertion->prev = iter2->prev; insertion->next = iter2; iter2->prev = insertion; } stackIter = (unsigned *)stackptr; stackIter -=13; for(i=0; i<13; i++) { if (i == 10) { stackIter[i] = (unsigned)task; } else if (i == 12) { stackIter[i] = FLAGB; // Set the interrupt flag } else { stackIter[i] = 0; } } insertion->stackptr = (void *)stackIter; if(running == 1) { YKScheduler(ContextNotSaved); } YKExitMutex(); }
void YKExitISR(void) { YKEnterMutex(); nestedInterruptLevel--; if(nestedInterruptLevel == 0) { YKScheduler(0); } }
void YKExitISR(void) { YKEnterMutex(); ISRCallDepth--; if (ISRCallDepth == 0) { YKExitMutex(); YKScheduler(); } YKExitMutex(); }
void YKRun(void) { YKEnterMutex(); kernelState = K_RUNNING; YKScheduler(); YKExitMutex(); return; }
void YKDelayTask(int count) { /* Delays a task for specified number of clock ticks*/ YKEnterMutex(); runningTask->delay=count; suspendTask(runningTask); YKExitMutex(); YKScheduler(0); }
void YKDelayTask(unsigned count) { YKEnterMutex(); YKReadyList->delay = count; YKMoveTCB(YKReadyList, &YKReadyList, &YKSuspList); YKScheduler(1); }
void YKNewTask (void (*task)(void), void* taskStack, int priority) { //Creates a new task //sets up tcb and stack frame int i; int temp; //Set up new TCB for task //printString("YAK is creating a new task"); //printWord(task); //printNewLine(); YKEnterMutex(); YKAvailTCBList->task = task; YKAvailTCBList->stackptr = taskStack; YKAvailTCBList->state = READY; YKAvailTCBList->priority = priority; YKAvailTCBList->delay = 0; (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES; temp = YKAvailTCBList->stackptr; //Set Top of ready queue to point to this task //printString("SAVING CONTEXT\n\r"); //printString("STACK PTR START = "); //printWord(YKAvailTCBList->stackptr); //printNewLine(); *((int*)YKAvailTCBList->stackptr) = INIT_CFLAGS; //cflags (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES; *((int*)YKAvailTCBList->stackptr) = 0; //CS (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES; *((int*)YKAvailTCBList->stackptr) = (int*)task; // ip (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES; for(i = 0; i < NUM_REGS; i++) { *((int*)YKAvailTCBList->stackptr) = 0x0; (int*)YKAvailTCBList->stackptr = (int*)YKAvailTCBList->stackptr - WORD_SIZE_IN_BYTES; } *((int*)YKAvailTCBList->stackptr) = temp; //printString("STACK PTR end = "); //printWord(YKAvailTCBList->stackptr); //printNewLine(); //printString("CONTEXT SAVED\n\r"); if(curTask == NULL) { curTask = YKReadyList; } YKMoveTCB(YKAvailTCBList, &YKAvailTCBList, &YKReadyList); if(curTask->priority == YKReadyList->priority) { return; } if(!initializing) { YKScheduler(1); } }
void YKRun() { //Set global flag to indicate kernel started initializing = 0; //Call scheduler YKScheduler(0); // Never Return }
void YKExitISR(void) { --YKISRDepth; /*printNewLine(); printString("ISR Depth:"); printInt(YKISRDepth); printNewLine();*/ if (YKISRDepth == 0) { YKScheduler(); } }
void YKExitISR(void){ //printString("YKExitISR\n"); //Decrement call depth callDepth--; // if(call depth is 0) // call scheduler if(callDepth == 0 && curTCB != null) { YKScheduler(); } }
void YKDelayTask(unsigned count){ //printString("YKDelayTask\n"); //if (count > 0)Sets the state of the TCB to delayed and then calls the scheduler. if(count > 0) { curTCB->delay = count; curTCB->state = DELAYED; delayedHead = addToQueue(curTCB, delayedHead); YKScheduler(); } }
void YKEventSet(YKEVENT *event, unsigned eventMask){ int i; int taskMadeReady = 0; TCBptr iter, temp, temp2, next; unsigned flags; YKEnterMutex(); // ----- Set Flag Group ---- // for (i = 0; i < 16; i++){ if (eventMask & BIT(i)){ event->flags |= BIT(i); } } flags = event->flags; // ----- check Conditions ---- // iter = event->waitingOn; while (iter != NULL){ // if conditions are met for that task, put in ready list if (checkConditions(flags, iter->flags, iter->waitMode)){ // remove from pending list next = iter->next; // check if the task to remove is the head if (iter == event->waitingOn){ event->waitingOn = iter->next; } if (iter->prev != NULL) iter->prev->next = iter->next; if (iter->next != NULL) iter->next->prev = iter->prev; // modify TCB of that task, place in ready list iter->state = READY; // Put in Rdy List temp2 = YKRdyList; while (temp2->priority < iter->priority){ temp2 = temp2->next; } if (temp2->prev == NULL){ YKRdyList = iter; } else{ temp2->prev->next = iter; } iter->prev = temp2->prev; iter->next = temp2; temp2->prev = iter; taskMadeReady = 1; iter = next; } else { iter = iter->next; } } // call scheduler if not called from ISR and a task was made ready if (taskMadeReady && nestingLevel == 0) YKScheduler(ContextNotSaved); YKExitMutex(); }
void YKEventSet(YKEVENT *event, unsigned eventMask) { // set the flags event->flags = event->flags | eventMask; // grab things from the blocked list and move to ready YKEnterMutex(); YKBlockEvent2Ready(event); YKExitMutex(); if (YKISRDepth == 0) YKScheduler(); }
void YKRun() { //Set global flag to indicate kernel started //printString("RUN\n\r"); initializing = 0; //YKExitMutex(); //Call scheduler YKScheduler(0); // Never Return }
void YKDelayTask(unsigned count) { YKEnterMutex(); //printString("BEFORE DELAY\n\r"); //printAllLists(); YKReadyList->delay = count; YKMoveTCB(YKReadyList, &YKReadyList, &YKSuspList); //printString("AFTER DELAY\n\r"); //printAllLists(); YKScheduler(1); }
//Semaphore Post void YKSemPost(YKSEM* sem) { YKEnterMutex(); (sem->count)++; YKMoveTCB(sem->blockedList, &(sem->blockedList), &YKReadyList); //If we're not in an interrupt, call the scheduler (possible blocked TCB's may be able to run) if(!nestedInterruptLevel) { YKScheduler(1); } YKExitMutex(); }
void eventBlock(YKEVENT* e){ TCBptr task, list; task = dequeue(&YKRdyList); task->state = SUSPENDED; list = e->tasks; if(list == NULL) e->tasks = task; else{ task->next = list; e->tasks = task; } YKScheduler(0); }
void YKExitISR(void) { YKEnterMutex(); nestedInterruptLevel--; // printInt(nestedInterruptLevel); // printNewLine(); if(nestedInterruptLevel == 0) { YKScheduler(0); } //printString("EXIT EXITISR\n\r"); }
void YKDelayTask(unsigned count) { // modify tcb to add delay count YKCurrTask->delay = count; YKCurrTask->state = DELAYED; // block the current task YKEnterMutex(); YKBlockTask(); YKExitMutex(); // call scheduler YKScheduler(); }
void YKSemPend(YKSEM *semaphore){ TCBptr temp, temp2, iter; int index; // disable interrupts YKEnterMutex(); if (semaphore->value-- > 0){ // enable interrupts YKExitMutex(); return; } // Remove calling task's TCB from ready list temp = YKRdyList; // Hold the first ready task // Remove it from Ready list YKRdyList = temp->next; if (YKRdyList != NULL) YKRdyList->prev = NULL; // modify TCB, put in suspended list temp->state = BLOCKED; // Put task at semaphore's blocked list if (semaphore->blockedOn == NULL){ semaphore->blockedOn = temp; temp->next = NULL; temp->prev = NULL; } else{ iter = semaphore->blockedOn; temp2 = NULL; while (iter != NULL && iter->priority < temp->priority){ temp2 = iter; iter = iter->next; } if (iter == NULL){//At end temp2->next = temp; temp->prev = temp; temp->next = NULL; } else{ // insert before iterator temp->next = iter; temp->prev = temp2; iter->prev = temp; if (temp2 == NULL)//inserted at beginning of list semaphore->blockedOn = temp; else temp2->next = temp; } } // call scheduler YKScheduler(ContextNotSaved); // enable interrupts YKExitMutex(); }
void YKSemPend(YKSEM* semaphore){ TCBptr task; YKEnterMutex(); if(semaphore->value-- > 0){ YKExitMutex(); return; } task = dequeue(&YKRdyList); task->state = SUSPENDED; YKPendList[semaphore->ID] = queue(YKPendList[semaphore->ID],task); YKScheduler(0); YKExitMutex(); }