基于时间片的52操作系统

2020-01-30 14:02发布

本帖最后由 zjsxwc 于 2013-3-21 16:53 编辑

今天在看了rainyss大神的帖子后,在我的52上写了个调度器。
  1. #include <reg52.h>


  2. #define MAX_TASKS 3      
  3. #define MAX_TASK_DEP 24  
  4. unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP]={0};
  5. unsigned char idata * task_sp[MAX_TASKS];


  6. unsigned char idata  task_old[MAX_TASKS]={0};
  7. unsigned char task_id;

  8. unsigned char idata task_die[MAX_TASKS]={0};


  9. unsigned char task_time_slice[MAX_TASKS][2]={
  10.         {0xC0,0xFF},//ʱ¼äƬ
  11.         {0xC2,0xFF},               
  12.         {0xC1,0xFF},       
  13. };



  14. void Task_clear_REG(){
  15.         ACC=0;
  16.         B=0;
  17.         PSW=0;

  18. }

  19. void Start_Timer2(){
  20.         EXEN2=0;
  21.         C_T2=0;
  22.         RCLK=0;
  23.         TCLK=0;
  24.         CP_RL2=0;
  25.        
  26.         RCAP2L=task_time_slice[0][0];
  27.         RCAP2H=task_time_slice[0][1];
  28.         TL2=task_time_slice[0][0];
  29.         TH2=task_time_slice[0][1];
  30.        
  31.         PT2=1;
  32.         TR2=1;
  33.         ET2=1;
  34.         EA=1;

  35. }



  36. void Init_OS(){
  37.         Start_Timer2();
  38. }

  39. void Kill_task(unsigned char tid){
  40.         task_die[tid]=1;
  41. }
  42. void Revive_task(unsigned char tid){
  43.         task_die[tid]=0;
  44. }


  45. void task_load(unsigned int fn, unsigned char tid){
  46.         task_sp[tid] = task_stack[tid] + 1;
  47.         task_stack[tid][0] = (unsigned int)fn & 0xff;
  48.         task_stack[tid][1] = (unsigned int)fn >> 8;
  49. }





  50. #define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}



  51. void task1()
  52. {
  53. static unsigned char i;

  54.        
  55.         while(1){
  56.                 i++;
  57.         }
  58. }

  59. void task2()
  60. {
  61. static unsigned char j;

  62.        
  63.         while(1){
  64.                 j+=1;
  65.                 j+=2;
  66.                 j+=3;
  67.                 j+=4;
  68.                 j+=5;
  69.                 j+=6;
  70.                 j+=7;
  71.                 j*=8;
  72.                 j+=9;
  73.                 j+=10;
  74.                 j+=55;
  75.                 j+=767;
  76.                 j+=2;
  77.                 j+=2;
  78.                 j+=44;
  79.                 j*=3;
  80.                 j+=1;
  81.                 j+=66;
  82.                 j*=43;
  83.                 j+=7;
  84.                 j+=98;
  85.                 j*=7;
  86.                 j+=332;
  87.                 j+=44;
  88.                 j+=33;
  89.                 j+=324;
  90.                 Kill_task(1);//finish task2,and suicide
  91.         }
  92. }

  93. void task3(){
  94. static unsigned char k;

  95.        
  96.         while(1){
  97.                 k+=3;
  98.         }
  99. }

  100. void main(){

  101.         task_load(task1, 0);
  102.         task_load(task2, 1);
  103.         task_load(task3, 2);
  104.         Init_OS();
  105.         os_start(0);

  106. }




  107. void task_switch() interrupt 5
  108. {


  109.         unsigned char  R[5]={0};//let keil C51 know that R0--R7/B/acc/psw/dptr must be pushpop in the stack!
  110.         TR2=0;


  111.         task_old[task_id]=1;
  112.         task_sp[task_id]=SP;
  113.        
  114.                                
  115.         while(1){
  116.                 if(++task_id == MAX_TASKS)
  117.                 task_id = 0;
  118.                 if         (task_die[task_id]!=1) break;                                                               
  119.         }       
  120.                                
  121.         if (task_old[task_id])
  122.                 SP=task_sp[task_id];
  123.         else{       
  124.                 *(task_sp[task_id]+1)=0;//acc
  125.                 *(task_sp[task_id]+2)=0;//B
  126.                 *(task_sp[task_id]+3)=0;//dpoh
  127.                 *(task_sp[task_id]+4)=0;//dpol
  128.                 *(task_sp[task_id]+5)=0;//psw
  129.                 *(task_sp[task_id]+6)=0;//r0
  130.                 *(task_sp[task_id]+7)=0;//r1
  131.                 *(task_sp[task_id]+8)=0;//r2
  132.                 *(task_sp[task_id]+9)=0;//r3
  133.                 *(task_sp[task_id]+10)=0;//r4
  134.                 *(task_sp[task_id]+11)=0;//r5
  135.                 *(task_sp[task_id]+12)=0;//r6
  136.                 *(task_sp[task_id]+13)=0;//r7
  137.                
  138.                 task_sp[task_id]=task_sp[task_id]+13;
  139.                 SP = task_sp[task_id];
  140.         }

  141.        
  142.         TF2=0;       
  143.         TL2=task_time_slice[task_id][0];
  144.         TH2=task_time_slice[task_id][1];
  145.         TR2=1;
  146.         return;
  147. }  
复制代码已改,由于使用中断服务函数时C51会自动保持ACCPSWBR0--R7dptr到相应任务堆栈所以省下了开辟空间保证这些寄存器的事情.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
沙漏
1楼-- · 2020-01-30 14:31
 精彩回答 2  元偷偷看……
zjsxwc
2楼-- · 2020-01-30 15:33
本帖最后由 zjsxwc 于 2013-3-20 21:39 编辑

占用了52的T2计时器 以及 level 1特权的中断。
zjsxwc
3楼-- · 2020-01-30 21:05
沙漏 发表于 2013-3-20 18:26
移植了操作系统吗

只是由原来手动切任务,变成按时间片自动切任务,利用了52多出来的T2计数器。
barryliu
4楼-- · 2020-01-31 02:04
R0~R7、PSW、ACC等重要寄存器没保存,任务切换会死人的。
你的测试程序例子太简单,所以你没看出来问题。
zjsxwc
5楼-- · 2020-01-31 06:41
本帖最后由 zjsxwc 于 2013-3-21 16:30 编辑
barryliu 发表于 2013-3-21 09:42
R0~R7、PSW、ACC等重要寄存器没保存,任务切换会死人的。
你的测试程序例子太简单,所以你没看出来问题。 ...


多谢提醒,
已修改源程序
zjsxwc
6楼-- · 2020-01-31 10:18
 精彩回答 2  元偷偷看……

一周热门 更多>