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