OS_CPU_C.C
上传用户:tzjinxin1
上传日期:2022-08-08
资源大小:272k
文件大小:13k
开发平台:

Visual C++

  1. /*
  2. *********************************************************************************************************
  3. *                                               uC/OS-II
  4. *                                               实时内核
  5. *
  6. *                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
  7. *                                               版权所有
  8. *
  9. *                                            MCU-51 专用代码
  10. *                                           KEIL C51大模式编译
  11. *
  12. * 文件名 : OS_CPU_C.C
  13. * 作者   : Jean J. Labrosse
  14. * 改编   : 杨屹 gdtyy@ri.gdt.com.cn 巨龙公司系统集成开发部 2002.09.27
  15. * 改编   : 钟文青,升级到与ucOS-II 2.51的代码,2003.5
  16. *********************************************************************************************************
  17. */
  18. #define  OS_CPU_GLOBALS
  19. #include "sourceincludes.h"
  20. /*
  21. *********************************************************************************************************
  22. *                                        初始化任务堆栈
  23. *
  24. * 描述       : 这个函数被OSTaskCreate()或OSTaskCreateExt()调用,以便初始化新创建任务的堆栈结构。本函数
  25. *              与处理器高度相关。
  26. *
  27. * 参数       : task          指向任务代码的指针
  28. *
  29. *              pdata         当任务第一次执行时将要传入任务的用户数据结构指针
  30. *
  31. *              ptos          栈顶指针。ptos指针被默认为用户堆栈入口指针。如果OS_STK_GROWTH被置1,那么,
  32. *                            ptos指向用户堆栈的最高有效地址。同样地,如果OS_STK_GROWTH清0,ptos将指向
  33. *                            用户堆栈的最低有效地址。
  34. *
  35. *              opt           指定可以改变OSTaskStkInit()行为的选项。(见uCOS_II.H for OS_TASK_OPT_???)。
  36. *
  37. * 返回值     : 我修改了原来的程序,使函数总是返回用户堆栈空间的最低有效地址。这样修改提高了TCB换入换出
  38. *              的效率。
  39. *
  40. * 注意       : 任务堆栈结构:
  41. *
  42. *                                    ---------- -
  43. *                 用户栈最高地址---->|        | |
  44. *                                    ---------- |
  45. *                                    |   ...  | 仿真堆栈空间
  46. *----------                          ---------- | 每任务一个
  47. *|OSTCBCur|               ?C_XBP---->|        | | KEIL自动处理
  48. *----------                          ---------- -
  49. *    |                               |空闲间隔|
  50. *    |     -----------------------   ----------                           ----------
  51. *    ---->|OSTCBCur->OSTCBStkPtr|   |?C_XBP低|                    SP---->|        |
  52. *          -----------------------   ----------                           ----------
  53. *                     |              |?C_XBP高|                           |        |
  54. *                     |              ---------- -                         ----------
  55. *                     |              |        | |                         |   .    |
  56. *                     |              ---------- |                         |   .    |
  57. *                     |              |        | |                         |   .    |
  58. *                     |              ---------- |                         ----------
  59. *                     |              |   .    |长度                       |        | +1
  60. *                     |              |   .    | |                         ----------
  61. *                     |              |   .    | |             OSStack---->|        | 0
  62. *                     |              ---------- |                         ----------
  63. *                     |              |        | |          OSStkStart---->| 不关心 | -1  低地址
  64. *                     |              ---------- -                         ----------
  65. *                     ------------->|  长度  | 低地址                   系统硬件堆栈
  66. *                                    ----------
  67. *                                     用户堆栈                       长度=SP-OSStkStart
  68. *********************************************************************************************************
  69. */
  70. OS_STK *OSTaskStkInit (void (*task)(void *pd) reentrant, void *ppdata, OS_STK *ptos, INT16U opt) reentrant
  71. {    
  72.     OS_STK *stk;
  73.     ppdata = ppdata;
  74.     opt    = opt;                               //opt没被用到,保留此语句防止告警产生    
  75.     stk    = ptos;                              //用户堆栈最低有效地址
  76.     *stk++ = 15;                                //用户堆栈长度
  77.     *stk++ = (INT16U)task & 0xFF;               //任务地址低8位
  78.     *stk++ = (INT16U)task >> 8;                 //任务地址高8位    
  79.     *stk++ = 0x0A;                              //ACC
  80.     *stk++ = 0x0B;                              //B
  81.     *stk++ = 0x00;                              //DPH
  82.     *stk++ = 0x00;                              //DPL
  83.     *stk++ = 0x00;                              //PSW
  84.     *stk++ = 0x00;                              //R0
  85.     
  86. //R3、R2、R1用于传递任务参数ppdata,其中R3代表存储器类型,R2为高字节偏移,R1为低字节位移。
  87. //通过分析KEIL汇编,了解到任务的void *ppdata参数恰好是用R3、R2、R1传递,不是通过虚拟堆栈。
  88.     *stk++ = (INT16U)ppdata & 0xFF;             //R1
  89.     *stk++ = (INT16U)ppdata >> 8;               //R2
  90.     *stk++ = 0x01;                              //R3  因为我用的全是XDATA,所以存储器类型固定为1,见C51.PDF第178页说明。
  91.     *stk++ = 0x04;                              //R4
  92.     *stk++ = 0x05;                              //R5
  93.     *stk++ = 0x06;                              //R6
  94.     *stk++ = 0x07;                              //R7
  95.                                                 //不用保存SP,任务切换时根据用户堆栈长度计算得出。    
  96.     *stk++ = (INT16U) (ptos+MaxStkSize) >> 8;   //?C_XBP 仿真堆栈指针高8位
  97.     *stk++ = (INT16U) (ptos+MaxStkSize) & 0xFF; //?C_XBP 仿真堆栈指针低8位
  98.         
  99.     return ((void *)ptos);
  100. }
  101. #if OS_CPU_HOOKS_EN
  102. /*
  103. *********************************************************************************************************
  104. *                                       OS INITIALIZATION HOOK
  105. *                                            (BEGINNING)
  106. *
  107. * Description: This function is called by OSInit() at the beginning of OSInit().
  108. *
  109. * Arguments  : none
  110. *
  111. * Note(s)    : 1) Interrupts should be disabled during this call.
  112. *********************************************************************************************************
  113. */
  114. #if OS_VERSION > 203
  115. void OSInitHookBegin (void) reentrant
  116. {
  117. }
  118. #endif
  119. /*
  120. *********************************************************************************************************
  121. *                                       OS INITIALIZATION HOOK
  122. *                                               (END)
  123. *
  124. * Description: This function is called by OSInit() at the end of OSInit().
  125. *
  126. * Arguments  : none
  127. *
  128. * Note(s)    : 1) Interrupts should be disabled during this call.
  129. *********************************************************************************************************
  130. */
  131. #if OS_VERSION > 203
  132. void OSInitHookEnd (void) reentrant
  133. {
  134. }
  135. #endif
  136. /*
  137. *********************************************************************************************************
  138. *                                          任务创建钩挂函数
  139. *
  140. * 描述       : 任务创建时调用
  141. *
  142. * 参数       : ptcb是指向将被创建任务的任务控制块的指针。
  143. *
  144. * 注意       : 1) 调用期间中断被禁止
  145. *********************************************************************************************************
  146. */
  147. void OSTaskCreateHook (OS_TCB *ptcb) reentrant
  148. {
  149.     ptcb = ptcb;                       /* Prevent compiler warning                                     */
  150. }
  151. /*
  152. *********************************************************************************************************
  153. *                                          任务删除钩挂函数
  154. *
  155. * 描述       : 任务删除时调用
  156. *
  157. * 参数       : ptcb是指向将被删除任务的任务控制块的指针。
  158. *
  159. * 注意       : 1) 调用期间中断被禁止
  160. *********************************************************************************************************
  161. */
  162. #if OS_TASK_DEL_EN > 0
  163. void OSTaskDelHook (OS_TCB *ptcb) reentrant
  164. {
  165.     ptcb = ptcb;                       /* Prevent compiler warning                                     */
  166. }
  167. #endif
  168. /*
  169. *********************************************************************************************************
  170. *                                          任务切换钩挂函数
  171. *
  172. * 描述       : 执行任务切换时调用。这允许你在上下文切换期间执行其它操作。
  173. *
  174. * 参数       : 无
  175. *
  176. * 注意       : 1) 调用期间中断被禁止
  177. *              2) 假定全局指针'OSTCBHighRdy'已经指向了将要被换入的任务控制块(即:最高优先级任务),并且
  178. *                 'OSTCBCur'指向了将被换出的任务(即:当前任务)。
  179. *********************************************************************************************************
  180. */
  181. void OSTaskSwHook (void) reentrant
  182. {
  183. }
  184. /*
  185. *********************************************************************************************************
  186. *                                          统计任务钩挂函数
  187. *
  188. * 描述       : 这个函数每秒钟被uC/OS-II统计任务调用。这么做使你的应用程序可以增加统计任务的功能。
  189. *
  190. * 注意       : 无
  191. *********************************************************************************************************
  192. */
  193. #if OS_TASK_STAT_EN > 0
  194. void OSTaskStatHook (void) reentrant
  195. {
  196. }
  197. #endif
  198. /*
  199. *********************************************************************************************************
  200. *                                           OSTCBInit() HOOK
  201. *
  202. * Description: This function is called by OSTCBInit() after setting up most of the TCB.
  203. *
  204. * Arguments  : ptcb    is a pointer to the TCB of the task being created.
  205. *
  206. * Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
  207. *********************************************************************************************************
  208. */
  209. #if OS_VERSION > 203
  210. void OSTCBInitHook (OS_TCB *ptcb) reentrant
  211. {
  212.     ptcb = ptcb;                                           /* Prevent Compiler warning                 */
  213. }
  214. #endif
  215. /*
  216. *********************************************************************************************************
  217. *                                          定时钩挂函数
  218. *
  219. * 描述       : 本函数每一滴答被调用一次。
  220. *
  221. * 参数       : 无
  222. *
  223. * 注意       : 1) 在本调用期间中断可以或不可以使能。
  224. *********************************************************************************************************
  225. */
  226. void OSTimeTickHook (void) reentrant
  227. {
  228. }
  229. /*
  230. *********************************************************************************************************
  231. *                                             IDLE TASK HOOK
  232. *
  233. * Description: This function is called by the idle task.  This hook has been added to allow you to do  
  234. *              such things as STOP the CPU to conserve power.
  235. *
  236. * Arguments  : none
  237. *
  238. * Note(s)    : 1) Interrupts are enabled during this call.
  239. *********************************************************************************************************
  240. */
  241. #if OS_VERSION >= 251
  242. void OSTaskIdleHook (void) reentrant
  243. {
  244. }
  245. #endif
  246. #endif
  247. /*
  248.    使用C语言的中断处理函数有助与提高程序的移植性。建议中断程序不要太长,如果长则使用信号量来与任务同步,
  249.    在外部任务中实现大量的处理。
  250.    中断处理例程都放在下面。
  251. */
  252. void UserTickTimer(void)
  253. {
  254.     TH0=0x70;     //普通51定时器方式1,必须在发生中断时,重新赋值并再次启动计时
  255.     TL0=0;             //Tick=50次/秒(即0.02秒/次),晶振22.1184M
  256.     TR0=1;
  257. }
  258. /* 
  259.   ucOS-II系统时钟中断处理程序
  260. */
  261. void OSTickISR(void) interrupt 1
  262. {
  263.     OSIntEnter(); // Must be called first at every hardware interrupt entry point 
  264.     UserTickTimer(); // User functions can be called here.
  265.     OSTimeTick(); // Must be called during tick isr 
  266.     OSIntExit(); // Must be called finally at every hardware interupt exit point 
  267. }
  268. /*--------------------------------------------------------------*/
  269. /* ucOS-II的中断服务程序示例                                    */
  270. /*--------------------------------------------------------------*/
  271. #include "sourceserial.h"
  272. void SerialISR(void) interrupt 4
  273. {
  274. #if OS_CRITICAL_METHOD == 3         // Allocate storage for CPU status register 
  275.     OS_CPU_SR  cpu_sr;
  276. #endif 
  277.     OSIntEnter(); // Must be called first at every hardware interrupt entry point 
  278.     OS_ENTER_CRITICAL();
  279.     if(TI)
  280. {
  281.   TI=0;
  282.       pc_send.ptr++;
  283.       if (pc_send.ptr < pc_send.count)
  284.         SBUF=pc_send.buffer[pc_send.ptr];
  285. }
  286. else if(RI)
  287. {
  288.     RI=0;
  289. //处理输入字符
  290. }
  291.     OS_EXIT_CRITICAL();
  292.     OSIntExit(); // Must be called finally at every hardware interupt exit point 
  293. }
  294. /*
  295.   设置硬件寄存器的初始值。
  296.   初始化定时器0,作为ucOS-II的系统时钟。
  297.   还有其他的与硬件相关的初始化也可以放在这里。
  298. */
  299. //串口初始化  0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200
  300. void InitHardware(void) reentrant
  301. {   
  302.     TMOD = 0x21;   //定时器0:模式1(16位定时器),仅受TR0控制;定时器1:波特率发生器
  303.     TH0  = 0x70;   //定义Tick=50次/秒(即0.02秒/次),TH,TL值与CPU的频率有关(22.1184M)
  304.     TL0  = 0x00;   //OS_CPU_C.C中定时器中断响应也要设置,OS_CFG.H中OS_TICKS_PER_SEC也有关系
  305.     //ET0  = 1;    //允许T0中断(在第一个任务开始执行时才开时钟中断,否则万一中断系统进入不可知状态)
  306.     TR0  = 1;
  307.     TH1   = 0xFA;  //晶振22.1084, 波特率 9600
  308.     ET1   = 0;
  309.     TR1   = 1;    //start timer1
  310.     SCON  = 0x50;
  311.     ES   = 1;
  312.     //设置串口收发的初始值
  313.     pc_send.ptr=0;
  314.     pc_send.count=0;
  315. ET0=1;  //开时钟节拍中断
  316. }