📄 arm_00_os_taskswitch.lst
字号:
ARM COMPILER V2.50a, ARM_00_OS_TaskSwitch 25/08/06 23:22:56 PAGE 1
ARM COMPILER V2.50a, COMPILATION OF MODULE ARM_00_OS_TaskSwitch
OBJECT MODULE PLACED IN ARM_00_OS_TaskSwitch.OBJ
COMPILER INVOKED BY: C:\Keil\ARM\BIN\CA.exe ARM_00_OS_TaskSwitch.c ARM INTERWORK DEBUG TABS(4)
stmt level source
1 /**********************************************************************************************
2 本程序只供学习使用,不得用于其它任何用途,否则后果自负。
3
4 ARM_00_OS_TaskSwitch.c file
5
6 注意:该文件必须设置为ARM模式。
7
8 作者:Computer-lov
9 建立日期:2006-5-1
10 修改日期:2006-5-16
11 最后修改时间:2006-08-25
12 版本:V1.0
13 版权所有,盗版必究。
14 任何技术问题可到我的博客上留言: http://computer00.21ic.org
15 Copyright(C) Computer-lov 2006-2016
16 All rights reserved
17 **********************************************************************************************/
18
19 #include "CPU.H"
20
21 #include "My_type.h"
22 #include "LED.H"
23 #include "UART.H"
24 #include "KEYS.H"
25 #include "interrupt.h"
26 #include "ARM_00_OS_Core.H"
27 #include "ARM_00_OS_TaskSwitch.H"
28
29 /**********************************************************************************************
30 功能:禁止中断。
31 入口参数1:DisEnabledBit。即CPSR中对应的I位和Q位。
32 头文件中有定义,#define OS_I_Bit 0x80 #define OS_F_Bit 0x40
33 关IRQ中断时,使用OS_I_Bit,关FIQ中断时,使用OS_F_Bit。
34 两个都关时,将两者按位或,即 OS_I_Bit | OS_F_Bit
35 返回:无。
36 使用资源:使用软中断号0。
37 备注:使用了内嵌的ARM指令,该函数所在的文件必须设置为ARM模式。
38 **********************************************************************************************/
39 void DisEnableInterrupt(uint32 DisEnableBit) __swi(0)
40 {
41 1 __asm LDMIA SP!,{R8} //堆栈中保存的是SPSR寄存器(参看SWI_VEC.s文件),将其弹出至R8中。
42 1 __asm ORR R8,R8,R0,LSL #0 //R8中的值,跟传递进来的DisEnableBit(被放在R0中)相或。{}
43 1 __asm STMDB SP!,{R8} //将设置好的SPSR寄存器,压回堆栈
44 1
45 1 DisEnableBit=0; //防止编译器警告。请不要删除该语句。如果删除该语句,编译器可能会删除某些语句
46 1 //从而导致程序运行错误
47 1 }
48 //////////////////////////////////End of function//////////////////////////////////////////////
49
50
51
52 /**********************************************************************************************
53 功能:使能中断。
54 入口参数1:EnabledBit。即CPSR中对应的I位和Q位。
55 头文件中有定义,#define OS_I_Bit 0x80 #define OS_F_Bit 0x40
56 关IRQ中断时,使用OS_I_Bit,关FIQ中断时,使用OS_F_Bit。
57 两个都关时,将两者按位或,即 OS_I_Bit | OS_F_Bit
58 返回:无。
59 使用资源:使用软中断号1。
ARM COMPILER V2.50a, ARM_00_OS_TaskSwitch 25/08/06 23:22:56 PAGE 2
60 备注:使用了内嵌的ARM指令,该函数所在的文件必须设置为ARM模式。
61 **********************************************************************************************/
62 void EnableInterrupt(uint32 EnableBit) __swi(1)
63 {
64 1 __asm LDMIA SP!,{R8} //堆栈中保存的是SPSR寄存器(参看SWI_VEC.s文件),将其弹出至R8中
65 1 __asm MVN R0,R0 //EnableBit(被放在R0中)取反{}
66 1 __asm AND R8,R8,R0 //R8中的值,跟R0相与{}
67 1 __asm STMDB SP!,{R8} //将设置好的SPSR寄存器,压回堆栈
68 1
69 1
70 1 EnableBit=0; //防止编译器警告。请不要删除该语句
71 1
72 1 }
73 //////////////////////////////////End of function//////////////////////////////////////////////
74
75
76
77 /**********************************************************************************************
78 功能:启动操作系统。
79 入口参数1:AddrOfSystemIdle。必须设置为系统空闲任务的入口地址。系统启动后,从系统空闲任务开始运行。
80 入口参数2:Mode。系统空闲任务代码的模式。可以选择ARM_MODE或者THUMB_MODE。
81 返回:无。
82 使用资源:使用软中断号2。
83 备注:使用了内嵌的ARM指令,该函数所在的文件必须设置为ARM模式。系统启动后,进入系统空闲任务。
84 **********************************************************************************************/
85 void OSStart(uint32 AddrOfSystemIdle,uint32 Mode) __swi(2)
86 {
87 1 __asm ADD SP,SP,#20 //{}调整SP,使其指向返回地址的前一个字
88 1 __asm STMDB SP,{R0} //将入口地址压入堆栈中的返回地址处
89 1
90 1 __asm SUB SP,SP,#20 //{}将堆栈指针调回
91 1
92 1 __asm LDMIA SP!,{R8} //将SPSR弹出,放入R8中
93 1
94 1 Mode|=~(0x20); //将传递进来的Mode其它位设置为1,只保留T位
95 1
96 1 __asm ORR R8,R8,#0x20 //将SPSR中的T位设置为1{}
97 1 __asm AND R8,R8,R1 //将SPSR的值与Mode相与。从而T位跟Mode的T位相同{}
98 1
99 1 __asm STMDB SP!,{R8} //将SPSR压回栈中
100 1
101 1
102 1 OSCurrentPcb=&OSSystemIdlePcb; //当前任务为系统空闲任务
103 1
104 1 AddrOfSystemIdle=0; //防止编译器警告。请不要删除该语句
105 1
106 1 }
107 //////////////////////////////////End of function//////////////////////////////////////////////
108
109
110 /**********************************************************************************************
111 功能:保存堆栈指针。堆栈指针被保存在当前任务的TaskSP成员中。
112 入口参数1:sp。当前任务堆栈指针的地址值。
113 返回:无。
114 备注:sp由R0寄存器传入。
115 **********************************************************************************************/
116 void OSSaveSP(uint32 sp)
117 {
118 1 OSCurrentPcb->TaskSP=sp; //保存当前堆栈指针
119 1 }
120 //////////////////////////////////End of function//////////////////////////////////////////////
121
122
123 /**********************************************************************************************
124 功能:恢复堆栈指针。将当前任务的堆栈指针恢复。
125 入口参数1:无。
ARM COMPILER V2.50a, ARM_00_OS_TaskSwitch 25/08/06 23:22:56 PAGE 3
126 返回:堆栈指针的地址值。被保存在R0中。
127 备注:无。
128 **********************************************************************************************/
129 uint32 OSResumeSP(void)
130 {
131 1 return OSCurrentPcb->TaskSP; //将堆栈指针的地址值返回
132 1 }
133 //////////////////////////////////End of function//////////////////////////////////////////////
134
135 /**********************************************************************************************
136 功能:设置堆栈。任务创建时,要设置好其堆栈,使其看起来,就像任务刚被切换的任务一样。
137 入口参数1:StackAddr。32位的堆栈入口地址值,堆栈是往下生长的,所以入口地址应该是堆栈区的最高地址。
138 入口参数2:TaskEntryAddr。32位的任务入口地址值。
139 入口参数3:Mode。被创建任务代码的模式。可选择为OS_ARM_MODE或者OS_THUMB_MODE。
140 返回:32位的堆栈地址。被压入堆栈后,堆栈指针会更新。
141 使用资源:使用软中断号4。
142 备注:无。
143 **********************************************************************************************/
144 uint32 OSSetStack(uint32 StackAddr,uint32 TaskEntryAddr,uint32 Mode) __swi(4)
145 {
146 1 #define PushedBytes (16*4) //压入了16个字,共64字节
147 1 //R0中保存的是堆栈入口地址
148 1 __asm MOV R12,R0 //{}StackAddr传进时,被放在了R0中。将R0转存至R12中。
149 1 __asm STMDB R12!,{R3} //入口地址被TaskEntryAddr被编译器转移至R3中。将R3压栈
150 1 __asm MOV R8,#0 //{}R8清零
151 1 __asm STMDB R12!,{R8} //该位置保存的是R3。将其清0。
152 1 __asm STMDB R12!,{R8} //该位置保存的是R2。将其清0。
153 1 __asm STMDB R12!,{R8} //该位置保存的是R1。将其清0。
154 1 __asm STMDB R12!,{R8} //该位置保存的是R0。将其清0。
155 1
156 1 __asm LDMIA SP,{R8} //将刚压入的SPSR(见SWI_VEC.S文件)出栈至R8中。
157 1
158 1
159 1 Mode|=~(0x20); //将Mode的其它位置1,只保留T位。
160 1 __asm ORR R8,R8,#0x20 //将SPSR中的T位置1。
161 1 __asm AND R8,R8,R2 //将SPSR的值与Mode相与。从而T位跟Mode的T位相同{}
162 1
163 1 __asm STMDB R12!,{R8} //将SPSR压栈。任务被调度时,SPSR将被返回至CPSR。
164 1
165 1 __asm MOV R8,#0 //R8清0{}
166 1
167 1 __asm STMDB R12!,{R8} //该位置保存的是用户模式下的R14。将其清0。
168 1
169 1 __asm STMDB R12!,{R8} //该位置保存的是R12。将其清0。
170 1 __asm STMDB R12!,{R8} //该位置保存的是R11。将其清0。
171 1 __asm STMDB R12!,{R8} //该位置保存的是R10。将其清0。
172 1 __asm STMDB R12!,{R8} //该位置保存的是9。将其清0。
173 1 __asm STMDB R12!,{R8} //该位置保存的是R8。将其清0。
174 1 __asm STMDB R12!,{R8} //该位置保存的是R7。将其清0。
175 1 __asm STMDB R12!,{R8} //该位置保存的是R6。将其清0。
176 1 __asm STMDB R12!,{R8} //该位置保存的是R5。将其清0。
177 1 __asm STMDB R12!,{R8} //该位置保存的是R4。将其清0。
178 1
179 1 TaskEntryAddr=0; //防止编译器警告。请不要删除该语句。
180 1
181 1 return StackAddr-PushedBytes; //返回堆栈指针
182 1 }
183 //////////////////////////////////End of function//////////////////////////////////////////////
184
185
186 /**********************************************************************************************
187 功能:切换任务。任务被切换到优先级最高的就绪态任务。
188 入口参数:无。
189 返回:无。
190 使用资源:使用软中断号3。
191 备注:该函数为任务切换函数,修改这里的代码是要注意,可能会导致跑飞。
ARM COMPILER V2.50a, ARM_00_OS_TaskSwitch 25/08/06 23:22:56 PAGE 4
192 **********************************************************************************************/
193 void OSTaskSwitch(void) __swi(3)
194 {
195 1 //将用户模式下的堆栈地址装入到R8中
196 1 __asm MOV R8,SP //{}特权模式下的堆栈指针暂时放到R8{}
197 1 __asm STMDB R8!,{R13}^ //将用户模式下的堆栈指针R13放入到特权模式下的堆栈中{}
198 1 __asm NOP //插入一个NOP指令,在访问用户模式下的寄存器后,后面不能紧跟访问备份寄存器的指令
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -