📄 sched.c
字号:
#include "../include/kernel/sched.h"#include "../include/kernel/sys.h"#include "../include/kernel/irq.h"#include "../include/kernel/task.h"#include "../include/kernel/typedef.h"#include "../include/s3c2410/timer.h"#include "../include/s3c2410/cpu.h"#include "../include/mm/mm.h"#include "../include/kernel/gui.h"#define TASK_MEM_LIMIT (1024*1024*32)//#define _SCHEDULE_DEBUG/* * 任务数组指针 */int volatile jiffies=0;struct task_struct* task[NR_TASKS];struct task_struct* current;unsigned int last_pid;extern struct irq_ctrl_object irq_ctrl_object;extern void restorer();extern int main(void);#define FIRST_TASK &task[0]#define LAST_TASK &task[NR_TASKS-1]//得到user模式下的cpsr的值#define USER ({ \int reg; \reg=read_cpsr();\reg&=~(0x1f);\reg|=UserMode;\ reg; })#define TASK0_CONTEXT_START 0#define TASK0_CONTEXT_END TASK0_CONTEXT_START+TASK_MEM_LIMIT-1struct task_struct task_0={ .state =TASK_RUNNING, .priority =15, .counter =15, .signal =0, .deal_signal =0, .blocked =0, .sigaction ={0,}, .alarm =0, .utime =0, .stime =0, .cutime =0, .cstime =0, .start_time =0, .exit_code =0, .context_start =TASK0_CONTEXT_START, .context_end =TASK0_CONTEXT_END, .pid =0, .father =0, .cpu_registers={/* r0 */ .r0=0,/* r1 */ .r1=0,/* r2 */ .r2=0,/* r3 */ .r3=0,/* r4 */ .r4=0,/* r5 */ .r5=0,/* r6 */ .r6=0,/* r7 */ .r7=0,/* r8 */ .r8=0,/* r9 */ .r9=0,/* r10 */ .r10=0,/* r11 */ .r11=0,/* r12 */ .r12=0,/* sp */ .sp=TASK0_CONTEXT_START+TASK_MEM_LIMIT-4,/* lr */ .lr=0,/* pc */ .pc=0,/* cpsr */ .cpsr=0 }, .next=0};#define BLOCK(n) ((n)*32*512)//设置系统的时钟滴答void set_sched_freq(unsigned int freq){ timer_enable(TIMER_0,freq);}void clean_stack(char *addr){ int i; for(i=0;i<1024*1024;i++) { addr[i]='\0'; }}void tasks_init(){ int i; unsigned int *tmp; for(i=0;i<NR_TASKS;i++) { task[i]=0; } last_pid=0; task_0.cpu_registers.cpsr=USER; task[0]=&task_0; current=task[0]; clean_stack((current->context_end)-1024*1024); nf_read(BLOCK(10),current->context_start,1024*12); tmp=&((current)->cpu_registers); jiffies=0; set_sched_freq(50); //时钟滴答为50赫兹 enable_watchdog(); set_process_id(0);//设置process Identifier switch_cpu_mode(UserMode);//进入用户模式 //启动0号进程 asm volatile( "ldr r0,%0 \n\t" "ldmib r0!,{r1-r15} \n\t" : :"m"(tmp) );}void schedule(struct cpu_registers *regs){ struct task_struct** p; feed_dog(); //对已存在的任务进行信号处理(未完成) for(p=FIRST_TASK;p<LAST_TASK;p++) { if(*p) { //get_task_state(*p); } } //下面进行任务调度(未完成)}/*void save_cpu_context(unsigned int *regs){ unsigned int *p_reglist=&p_current_task->cpu_registers.r0; int regid; for(regid=0;regid<REGS;regid++) { p_reglist[regid]=regs[regid]; } p_reglist[PC]=regs[PC]-4;}void load_cpu_context(unsigned int *regs){ unsigned int *p_reglist=&p_current_task->cpu_registers.r0; int regid; for(regid=0;regid<REGS;regid++) { regs[regid]=p_reglist[regid]; } regs[PC]=p_reglist[PC]+4;}*//* * 任务切换函数 * 我已经尽可能地让它简单了,我很喜欢这段代码,一来它能把任务切 * 换的工作做得很好,二来它也是这个多任务系统的基础void schedule(struct cpu_registers *regs){ feed_dog(); p_current_task->alarm--; if(p_current_task->alarm<=0) { save_cpu_context(regs); p_last_task=p_current_task; if((p_current_task=p_current_task->next)==NULL) { p_current_task=task_queue_head.next; } p_current_task->state=RUNABLE; p_last_task->state=READY; p_last_task->alarm=p_last_task->priority; load_cpu_context(regs); }}*//* * 查看任务p当前的详细信息 * */void dump_task(struct task_struct* p){ int nr; for(nr=0;nr<NR_TASKS;nr++) { if(p==task[nr]) break; } printk("task %d details\n",nr); printk("handle:0x%08x next:0x%08x\n",p,p->next); printk("state\t\tpriority\tcounter\t\tsignal\t\tblocked\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->state,p->priority,p->counter,p->signal,p->blocked); printk("utime\t\tstime\t\tcutime\t\tcstime\t\tstart_time\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->utime,p->stime,p->cutime,p->cstime,p->start_time); printk("alarm\t\texit_code\tcontext_start\tcontext_end\tpid\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->alarm,p->exit_code,p->context_start,p->context_end,p->pid); printk("father\n0x%08x\n",p->father); printk("r0\t\tr1\t\tr2\t\tr3\t\tr4\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->cpu_registers.r0,p->cpu_registers.r1,p->cpu_registers.r2, p->cpu_registers.r3,p->cpu_registers.r4); printk("r5\t\tr6\t\tr7\t\tr8\t\tr9\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->cpu_registers.r5,p->cpu_registers.r6,p->cpu_registers.r7, p->cpu_registers.r8,p->cpu_registers.r9); printk("r10\t\tr11\t\tr12\t\tsp\t\tlr\n0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n", p->cpu_registers.r10,p->cpu_registers.r11,p->cpu_registers.r12, p->cpu_registers.sp,p->cpu_registers.lr); printk("pc\t\tcpsr\n0x%08x\t0x%08x\n\n",p->cpu_registers.pc,p->cpu_registers.cpsr); }void get_task_state(struct task_struct* p){ printk("task %d ",p->pid); switch(p->state) { case TASK_RUNNING: printk(" RUNNING\n"); break; case TASK_INTERRUPTIBLE: printk(" INTERRUPTIBLE\n"); break; case TASK_UNINTERRUPTIBLE: printk(" UNINTERRUPTIBLE\n"); break; case TASK_ZOMBIE: printk(" ZOMBIE\n"); break; case TASK_STOPPED: printk(" STOPPED\n"); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -