|
本帖最后由 zhouwenjing 于 2012-5-5 23:37 编辑
就弄了两个任务,两个死循环,没有考虑中断什么的,仅供学习之用啊,呵呵
程序运行于非特权模式,使用PSP寄存器
- #include <LPC17xx.H>
- void task2(void);
- void task1(void);
- int stack1[256];
- int stack2[256];
- int *spt1=&stack1[256-1];
- int *spt2=&stack2[256];
- extern void SVC_CALL(int );
- void SVC_CALLin(void);
- void main(void)
- {
- //register int i=10,t=19;
- //8个自动压栈内容,最底下四个个是r0-r3,通过这几个寄存器可以给任务传递参数,创建带参数的任务
- *spt1--=0x21000000;//程序装态寄存器
- *spt1--=(unsigned long)task1;//任务入口地址,你懂的
- *spt1--=0x44d;
- *spt1--=0;
- *spt1--=0;
- *spt1--=0;
- *spt1--=0;
- *spt1=0;
-
- //*spt2=(unsigned long)task2;
- *spt2--=0x21000000;
- *spt2--=(unsigned long)task2;
- *spt2--=0x44d;
- *spt2--=0;
- *spt2--=0;
- *spt2--=0;
- *spt2--=0;
- *spt2=0;
-
- //启动任务
- SVC_CALLin();
-
- }
- __asm void SVC_Handler(void)
- {
- import spt1
- import spt2
- tst lr,#4
- mrseq r0,msp
- mrsne r0,psp
- ldr r1,[r0,#24]
- ldrb r1,[r1,#-2]
- ;//根据以前的栈内容,确定SVC指令后面的标号
- ;//存放于R1中
-
- CMP r1,#0x0
- ;//如果标号为0,表示从main函数中进入,
- bne sw_context;//否则是任务切换请求,跳转到任务指令位置
- ldr r2,=spt1
- ldr r0,[r2]
- msr psp,r0
- bx lr
-
- sw_context
- ;//任务切换指令位置
- CMP r1,#1
- bne sw_task2
- sw_task1
- ldr r2,=spt1
- ldr r3,=spt2
- b ret
- sw_task2
- ldr r2,=spt2
- ldr r3,=spt1
- ret
- ldr r0,[r2]
- mrs r1,psp ;//将当前栈保存到指针
- str r1,[r3]
- msr psp,r0 ;//将下一个任务的栈指针保存到psp,进行任务切换
- bx lr ;//
- }
- __asm void SVC_CALL(int id)
- {
- push {R4-r12};//压栈,保存现场,P1-p3,lr,进入异常模式时自动压栈,这里不用处理
-
- CMP r0,#1
- SVCEQ #1
- SVCNE #2
- pop {r4-r12};//异常返回后。出栈
- bx lr;
- }
- __asm void SVC_CALLin(void)
- {
- SVC #0
- bx lr
- }
- void task1(void)
- {
- int i,n;
- for(i=0;i<100000000;i++)
- {
- for(n=0;n<1999;n++);
- SVC_CALL(2);//切换到任务2
- }
- ;
- }
- void task2(void)
- {
- int i,n;
- for(i=0;i<100000000;i+=2)
- {
- for(n=0;n<3000;n++);
- SVC_CALL(1);//切换到任务1
- }
- ;
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|