📄 os_core.lst
字号:
145 1 {
146 2 if((OS_Task_List&(0x01<<i))==0) //如果找到可用资源
147 2 {
148 3 Task_ID=i; //则保存当前资源号
149 3 OS_Task_List|=0x01<<i; //并标志该资源被占用
150 3 OK_flag=1; //标志创建成功
151 3 break; //退出查找
152 3 }
153 2 }
154 1
155 1 if(!OK_flag) //如果所有资源都被占用
156 1 {
157 2 OS_Exit_Critical(); //退出临界段保护
158 2 return OS_Resource_Lack; //返回错误代码--资源不足
159 2 }
160 1
161 1 Stack_p=(unsigned char)OS_Stack[Task_ID]; //根据分配到的资源使用堆栈段
162 1
163 1 for(i=0;i<S_DEPTH;i++)
164 1 {
165 2 ((unsigned char idata *)Stack_p)[i]=0; //初始化清空堆栈
166 2 }
167 1
168 1
169 1 OS_pcb[Task_ID].Task_SP=Stack_p; //将该任务的堆栈栈低地址保存
170 1 ((unsigned char idata *)Stack_p)[0]=Task_p; //将任务入口地址保存在堆栈,压入低8位
171 1 OS_pcb[Task_ID].Task_SP++; //压入一个后,堆栈加1,因为51的堆栈是往上生长的
172 1 ((unsigned char idata *)Stack_p)[1]=Task_p>>8; //压入高8位
173 1
174 1 OS_pcb[Task_ID].Task_SP+=Num_PUSH_bytes; //设置好堆栈指针
175 1 //即任务开始进入时,堆栈要模仿成被切换返回时的样子
176 1 //这时寄存器是被压栈的,且是压入了Num_PUSH_bytes个
177 1
178 1
179 1 OS_pcb[Task_ID].Priority=Task_Priority; //设置任务优先级
C51 COMPILER V7.06 OS_CORE 02/25/2006 14:24:57 PAGE 4
180 1
181 1 OS_pcb[Task_ID].Delay=0; //任务初始不延时
182 1
183 1 OS_pcb[Task_ID].MSG=Msg_p; //消息指针
184 1
185 1
186 1
187 1
188 1
189 1 if(OS_Running)
190 1 {
191 2 OS_pcb[Task_ID].Suspend=0; //如果在运行中建立的任务,则不挂起
192 2 }
193 1 else
194 1 {
195 2 #ifdef CPU_STAT
196 2
197 2 OS_pcb[Task_ID].Suspend=1; //如果需要CPU使用率统计,则任务初始挂起
198 2
199 2 #else
OS_pcb[Task_ID].Suspend=0; //如果不需要CPU使用率统计,则任务初始不挂起
#endif
204 2
205 2 OS_Current_ID=Task_ID; //在开始运行之前建立的任务,要保存其ID号
206 2 }
207 1 OS_Exit_Critical(); //退出临界段保护
208 1
209 1 return OS_Successful+Task_ID; //返回创建成功及创建的任务ID号
210 1 }
211 /////////////////////////////////////////////////////////////////////////////////////////////
212
213
214 ///////////////////////////////// 释放资源 ////////////////////////////////////////////////
215 /////////////////// 当一个任务被删除时,需要释放其占有的资源,否则别的任务不能使用 /////////
216 void OS_Release_Resource(unsigned char Task_ID)
217 {
218 1 release_printer(Task_ID); //因为我们这里只有打印机资源,所以只释放打印机,及消息接收标志
219 1 if(Task_ID==Msg_1_Receiver) //如果需要接收消息的任务被删除,则需要告诉发消息者,无任务接收消息
220 1 {
221 2 Msg_1_Receiver=0; //
222 2 }
223 1 //如果有多个独占资源,在任务被删除时,一定要记得检查是否需要释放
224 1 //将释放资源的代码添加到此
225 1 }
226 /////////////////////////////////////////////////////////////////////////////////////////////
227
228
229 ///////////////////////////////// 删除一个任务 //////////////////////////////////////////////
230 unsigned int OS_Task_Kill(unsigned char Task_ID)
231 {
232 1 OS_Enter_Critical(); //进入临界段保护
233 1 if(Task_ID==0) //如果任务ID为0,即空闲任务,则
234 1 {
235 2 OS_Exit_Critical(); //退出临界段保护
236 2 return OS_Task_Cannot_Be_Killed+Task_ID; //返回错误代码---该任务不能被删除
237 2 }
238 1 if(Task_ID>=MAX_TASK) //如果该ID号比MAX_TASK大,则说明该任务不可能存在
239 1 {
240 2 OS_Exit_Critical();
241 2 return OS_Task_Not_Exist+Task_ID; //返回错误代码---该任务不存在
C51 COMPILER V7.06 OS_CORE 02/25/2006 14:24:57 PAGE 5
242 2 }
243 1 if(OS_Task_List&(0x01<<Task_ID)) //如果所要删除的任务存在
244 1 {
245 2 OS_pcb[Task_ID].Suspend=1; //则先将其挂起
246 2 OS_Task_List&=~(0x01<<Task_ID); //从任务列表中删除之
247 2 OS_Release_Resource(Task_ID); //并释放该任务所占用的资源
248 2 OS_Exit_Critical(); //退出临界段保护
249 2 if(Task_ID==OS_Current_ID) //如果删除的是自己,则
250 2 {
251 3 OS_Task_Switch(); //任务切换
252 3 }
253 2 return OS_Successful+Task_ID; //返回删除成功及被删除的任务的ID号
254 2 }
255 1 else
256 1 {
257 2 OS_Exit_Critical(); //如果所要删除的任务不存在
258 2 return OS_Task_Not_Exist+Task_ID; //则返回错误代码---该任务不存在
259 2 }
260 1 }
261 /////////////////////////////////////////////////////////////////////////////////////////////
262
263 ////////////////////////////////// OS 开始启动///////////////////////////////////////////////
264 void OS_Start(void)
265 {
266 1 OS_pcb[OS_Current_ID].Task_SP-=Num_PUSH_bytes; //调整任务堆栈指针,因为这时任务还未开始调度
267 1 //第一次进入中断时,会压栈。所以先将堆栈指针
268 1 //往下调Num_PUSH_bytes个字节,避免堆栈溢出
269 1 //调整后的SP紧接着的两个字节就是最后一个任务的入口地址
270 1 //在第一次中断发生时,返回地址被压入SP后面的两个地址
271 1 //在第一次进入中断后,将SP往前调整两字节,这样程序返回时,
272 1 //将返回到最后一个任务,而不再返回到主函数
273 1
274 1 SP=OS_pcb[OS_Current_ID].Task_SP; //修改堆栈指针。使其指向任务当前任务的堆栈段
275 1
276 1 TR2=1; //启动定时器2
277 1 EA=1; //开中断
278 1
279 1 while(1); //死循环。定时器中断发生后,任务开始调度
280 1 }
281 /////////////////////////////////////////////////////////////////////////////////////////////////
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 649 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 10 3
IDATA SIZE = 160 ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -