⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scheduler.c

📁 Jan 04, 2007 1. Add SPI support, see spi.h and spi.c 2. Add driver.h 3. Modified keyboard modu
💻 C
字号:
/** * Copyright (c) 2006-2008 iWESUN (ShenZhen) Inf. * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without modification,  * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  * OF SUCH DAMAGE. * * This file is part of the AvrcX MTOS *  * Author: Winter Hu  <winter.hu@gmail.com> * Create: Nov 28, 2006 *//*Changlog:Jan 4, 2007,  Re-write  sleep methods in assembler*/#include "scheduler.h"/* Kernel data */KernelData kernel;/** * Initizlize Scheduler * This must be invoked before tasks schedulling */void init_scheduler(void){  into_critical();  kernel.RunQueue.head = NULL;  kernel.TimerQueue.head = NULL;  kernel.BlockedQueue = NULL;  kernel.Running = NULL;  kernel.Context = (void*) SP+2;  kernel.TmSlices= 0x00;  kernel.SysLevel= 0; // Default is kernel mode  kernel.SysTicks= 0L;}/** * Start scheduler * This method never return */void start(void){  TCCR0 = TMC8_CK256;  TCNT0 = TCNT0_INIT;  TIMSK |= _BV(TOIE0);    into_critical();  kernel.SysLevel = USER_MODE;  prologue(); // Save context  swapping(); // Swap a task from RunQueue to kernel  epilogue();   // Restore context}/** * Create and resume the task into RunQueue *  * @param TCB*, The pointer to the Task Control Block */void run_task(TCB* tcb){  resume_task(create_task(tcb));}/** * Retrieves current running task * * @return PID*, the pointer to the current running task PID */PID* get_running(void){  return kernel.Running;}/** * Retreives system ticks * * @return unsigned long, The ticks from power on */unsigned long get_systicks(void){  return kernel.SysTicks;}/** * Causes the currently executing task to temporarily pause and allow  * other tasks to execute. */void  yield(void) {  into_critical();    prologue();  // Save current task PID locally  PID* pid = kernel.Running;  // Swap a new task PID from RunQueue  swapping();  // Re-schedule previous task   resume_task(pid);  epilogue();}/** * Causes the currently executing task to temporarily pause in TimQueue * until delay expire.  * * @param unsigned int, Ticks for sleeping */// Jan 4, 2007 Implements in assembler// @see scheduler.asm.S/*void NAKED sleep(unsigned int ticks){  into_critical();  prologue();    delayTask(kernel.Running, ticks);  swapping();  epilogue();}*//** * Swap the first PID from RunQueue to current env */void swapping(void){  kernel.Running = remove_first(&(kernel.RunQueue));  if (kernel.Running != NULL){    kernel.TmSlices = ((PCB*)(kernel.Running->pData))->tmslices;  }}/** * Insert the PID into RunQueue * * @param PID*, The pointer to the PID */void resume_task(PID* pid){  if (pid != NULL){    PCB* pcb = (PCB*)(pid->pData);    pid->priority = pcb->priority;    pcb->timer.pid= pid;    pcb->tid.pData= &(pcb->timer);    insert_ordered(&(kernel.RunQueue), pid);    //insert_relative(&(kernel.RunQueue), pid);  }}/** * Insert the PID into TimerQueue * * @param PID*, The pointer to the PID * @param unsigned int, The ticks to delay */void delay_task(PID* pid, unsigned int ticks){  PCB* pcb = (PCB*)(pid->pData);  pcb->status |= TASK_DELAY;  if (ticks <= MAX_WAIT_TICKS){    pcb->tid.priority = (unsigned char)ticks;    pcb->timer.ticks = 0;  }else{    pcb->tid.priority = MAX_WAIT_TICKS;    pcb->timer.ticks = ticks - MAX_WAIT_TICKS;  }    insert_relative(&(kernel.TimerQueue), &(pcb->tid));}void resume_delay(TID*);/** ISR for Timer0 overflow */void NAKED SIG_OVERFLOW0(void);void SIG_OVERFLOW0(void){  into_critical();  prologue();  TCNT0 = TCNT0_INIT;  // Increments system ticks   kernel.SysTicks++;  // Check task delay in TimerQueue  TID* tid = get_first(&(kernel.TimerQueue));  if (tid != NULL) resume_delay(tid);  PID *pid = kernel.Running;  if (pid != NULL){    kernel.TmSlices--;    if (kernel.TmSlices <= 0){      // Time slice is exhausted, so swap to next task      swapping();            if (kernel.Running != NULL){	resume_task(pid);      }else{	kernel.Running = pid;	kernel.TmSlices = ((PCB*)(pid->pData))->tmslices;      }    }  }else{    swapping();  }    epilogue();}void resume_delay(TID* tid){  PID* pid = ((TSTimer*)(tid->pData))->pid;  PCB* pcb = (PCB*)(pid->pData);  tid->priority = (tid->priority > 0) ? tid->priority - 1 : 0;  if (tid->priority > 0) return;    // tid->priority == 0  tid = remove_first(&(kernel.TimerQueue));  TSTimer* tt = (TSTimer*)(tid->pData);  if (tt->ticks > 0){    delay_task(pid, tt->ticks);    return;  }  // It's time to wakeup and preemptive   pcb->status &= ~TASK_DELAY;  if (kernel.Running != NULL){    if (pcb->priority >= 	((PCB*)(kernel.Running->pData))->priority){      resume_task(pid);    }else{      // preemptived      resume_task(kernel.Running);      kernel.Running = pid;      kernel.TmSlices= pcb->tmslices + 1;    }  }else{// kernel.Running == NULL    kernel.Running = pid;    kernel.TmSlices= pcb->tmslices + 1;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -