搜索
bottom↓
回复: 6

闲着没事,研究了一些M3的任务切换模型,贴出代码来,大家...

[复制链接]

出0入0汤圆

发表于 2012-5-5 23:29:18 | 显示全部楼层 |阅读模式
本帖最后由 zhouwenjing 于 2012-5-5 23:37 编辑

就弄了两个任务,两个死循环,没有考虑中断什么的,仅供学习之用啊,呵呵

程序运行于非特权模式,使用PSP寄存器


  1. #include <LPC17xx.H>

  2. void task2(void);
  3. void task1(void);

  4. int stack1[256];
  5. int stack2[256];

  6. int *spt1=&stack1[256-1];
  7. int *spt2=&stack2[256];

  8. extern void SVC_CALL(int );
  9. void SVC_CALLin(void);
  10. void main(void)
  11. {
  12.      //register int i=10,t=19;
  13.      //8个自动压栈内容,最底下四个个是r0-r3,通过这几个寄存器可以给任务传递参数,创建带参数的任务
  14.      *spt1--=0x21000000;//程序装态寄存器
  15.      *spt1--=(unsigned long)task1;//任务入口地址,你懂的
  16.      *spt1--=0x44d;
  17.      *spt1--=0;
  18.      *spt1--=0;
  19.      *spt1--=0;
  20.      *spt1--=0;
  21.      *spt1=0;

  22.      
  23.      //*spt2=(unsigned long)task2;
  24.      *spt2--=0x21000000;
  25.      *spt2--=(unsigned long)task2;
  26.      *spt2--=0x44d;
  27.      *spt2--=0;
  28.      *spt2--=0;
  29.      *spt2--=0;
  30.      *spt2--=0;
  31.      *spt2=0;
  32.      
  33.      //启动任务
  34.     SVC_CALLin();
  35.    

  36. }


  37. __asm void SVC_Handler(void)
  38. {
  39.         import spt1
  40.         import spt2
  41.         tst lr,#4
  42.         mrseq r0,msp
  43.         mrsne r0,psp
  44.         ldr r1,[r0,#24]
  45.         ldrb r1,[r1,#-2]
  46.         ;//根据以前的栈内容,确定SVC指令后面的标号
  47.      ;//存放于R1中
  48.         
  49.      CMP r1,#0x0
  50.         ;//如果标号为0,表示从main函数中进入,
  51.      bne sw_context;//否则是任务切换请求,跳转到任务指令位置
  52.      ldr r2,=spt1
  53.         ldr r0,[r2]
  54.         msr psp,r0   
  55.         bx lr
  56.         
  57. sw_context
  58.         ;//任务切换指令位置                  
  59.      CMP r1,#1
  60.         bne sw_task2
  61. sw_task1
  62.         ldr r2,=spt1
  63.         ldr r3,=spt2
  64.         b ret
  65. sw_task2        
  66.         ldr r2,=spt2
  67.         ldr r3,=spt1

  68. ret
  69.         ldr r0,[r2]
  70.         mrs r1,psp  ;//将当前栈保存到指针
  71.      str r1,[r3]
  72.         msr psp,r0  ;//将下一个任务的栈指针保存到psp,进行任务切换
  73.      bx lr       ;//
  74. }

  75. __asm void SVC_CALL(int id)
  76. {
  77.     push {R4-r12};//压栈,保存现场,P1-p3,lr,进入异常模式时自动压栈,这里不用处理
  78.   
  79.    CMP r0,#1  
  80.     SVCEQ #1   
  81.     SVCNE #2
  82.     pop {r4-r12};//异常返回后。出栈
  83.    bx lr;

  84. }

  85. __asm void SVC_CALLin(void)
  86. {
  87.     SVC #0
  88.     bx lr
  89. }

  90. void task1(void)
  91. {
  92.     int i,n;
  93.     for(i=0;i<100000000;i++)
  94.     {
  95.         for(n=0;n<1999;n++);
  96.         SVC_CALL(2);//切换到任务2
  97.     }
  98.     ;
  99. }




  100. void task2(void)
  101. {
  102.     int i,n;
  103.     for(i=0;i<100000000;i+=2)
  104.     {
  105.         for(n=0;n<3000;n++);
  106.         SVC_CALL(1);//切换到任务1
  107.     }
  108.     ;
  109. }

复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2012-5-5 23:41:01 | 显示全部楼层
为了换取ID还真不容易啊

出0入0汤圆

 楼主| 发表于 2012-5-6 10:51:42 | 显示全部楼层
确实,挺麻烦的
第一步,读lr的值,判断之前用的是哪一个栈指针寄存器
第二步,读栈指针寄存器到通用寄存器
第三步,找到对应栈中PC的位置,为什么是24,因为前面有24个字节:r0,r1,r2,r3,r12,lr
第四步,读取SVC代码内容,获取标号,注意偏移量

出0入0汤圆

发表于 2012-5-8 13:51:40 | 显示全部楼层
支持一下,很好

出0入0汤圆

 楼主| 发表于 2012-5-9 09:27:42 来自手机 | 显示全部楼层
后面,有空写个定时任务调度器,玩玩

出0入0汤圆

 楼主| 发表于 2012-5-9 11:40:51 | 显示全部楼层
后面,有时间写个任务定时调度器玩玩

出0入0汤圆

发表于 2014-6-18 17:21:54 | 显示全部楼层
谢谢,SVCall 调用程序
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 22:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表