微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > μC/OS-II 移植笔记 2(FreeScale 68HCS12 核单片机)

μC/OS-II 移植笔记 2(FreeScale 68HCS12 核单片机)

时间:11-20 来源:互联网 点击:

  1. OS_STK*OSTaskStkInit(void(*task)(void*pd),void*p_arg,OS_STK*ptos,INT16Uopt)
  2. {
  3. INT16U*wstk;
  4. INT8U*bstk;
  5. (void)opt;/*optisnotused,preventwarning*/
  6. ptos--;/*需要这么调整一下栈顶地址,否则存的第一个int16的低Byte会溢出堆栈*/
  7. wstk=(INT16U*)ptos;/*Loadstackpointer*/
  8. *wstk--=(INT16U)task;/*Returnaddress.Format:PCH:PCL*/
  9. *wstk--=(INT16U)task;/*Returnaddress.Format:PCH:PCL*/
  10. *wstk--=(INT16U)0x2222;/*YRegister*/
  11. *wstk--=(INT16U)0x1111;/*XRegister*/
  12. *wstk=(INT16U)p_arg;/*Simulatecalltofunctionwithargument(InDRegister)*/
  13. bstk=(INT8U*)wstk;/*ConvertWORDptrtoBYTEptrtosetCCR*/
  14. bstk--;
  15. *bstk=(0xC0);/*CCRRegister(DisableSTOPinstructionandXIRQ)*/
  16. return((OS_STK*)bstk);/*Returnpointertonewtop-of-stack*/
  17. }

其中有几点需要特别注意:
(1)68HC12 内核与 68HC11 内核一个大的区别就是 SP 指向的是实栈顶。老的68HC11的移植代码都是 *--wstk = XXXX。移植到68HC12 内核就要改为*wstk-- = XXXX。否则会浪费掉堆栈的前两个字节。
(2)先要执行 ptos--;否则第一个双字节会有一半溢出堆栈空间。
(3)任务的参数传递是通过寄存器 D 的,而不是堆栈。网上代码多数是:

[cpp]view plaincopy

  1. *wstk--=(INT16U)p_arg;
  2. *wstk--=(INT16U)task;

这样参数是传递不进来的,只有像我的代码中这样写才是正确的。
(4)代码中 *wstk-- = (INT16U)task; 重复了两遍,千万别以为这是我的笔误。堆栈中先存的(INT16U)task实际上是 task 函数的返回地址。虽然 μC/OS-II 要求任务不能返回,但是作为 C 语言的调用约定,在调用一个 C 函数之前要将 C 函数的返回地址先入栈。因此我将 task 的地址重复了两次,实际上第一的地址是什么都不重要,因为程序运行中觉得不会用到。甚至不要这行也行,还能节省堆栈中两个字节的空间。不过我还是选择了保留这行,使其看起来更加符合 C 语言的调用规范。

除此之外,OS_CPU_C.C 还包括一系列的 Hook 函数:

  1. #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>203
  2. voidOSInitHookBegin(void)
  3. {
  4. #ifOS_TMR_EN>0
  5. OSTmrCtr=0;
  6. #endif
  7. }
  8. voidOSInitHookEnd(void)
  9. {
  10. }
  11. #endif
  12. #ifOS_CPU_HOOKS_EN>0
  13. voidOSTaskCreateHook(OS_TCB*ptcb)
  14. {
  15. #ifOS_APP_HOOKS_EN>0
  16. App_TaskCreateHook(ptcb);
  17. #else
  18. (void)ptcb;
  19. #endif
  20. }
  21. voidOSTaskDelHook(OS_TCB*ptcb)
  22. {
  23. #ifOS_APP_HOOKS_EN>0
  24. App_TaskDelHook(ptcb);
  25. #else
  26. (void)ptcb;
  27. #endif
  28. }
  29. voidOSTaskStatHook(void)
  30. {
  31. #ifOS_APP_HOOKS_EN>0
  32. App_TaskStatHook();
  33. #endif
  34. }
  35. voidOSTaskSwHook(void)
  36. {
  37. #ifOS_APP_HOOKS_EN>0
  38. App_TaskSwHook();
  39. #endif
  40. }
  41. #endif
  42. #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>=251
  43. voidOSTaskIdleHook(void)
  44. {
  45. #ifOS_APP_HOOKS_EN>0
  46. App_TaskIdleHook();
  47. #endif
  48. }
  49. #endif
  50. #ifOS_CPU_HOOKS_EN>0&&OS_VERSION>203
  51. voidOSTCBInitHook(OS_TCB*ptcb)
  52. {
  53. #ifOS_APP_HOOKS_EN>0
  54. App_TCBInitHook(ptcb);
  55. #else
  56. (void)ptcb;/*Preventcompilerwarning*/
  57. #endif
  58. }
  59. #endif
  60. #ifOS_CPU_HOOKS_EN>0
  61. voidOSTimeTickHook(void)
  62. {
  63. #ifOS_APP_HOOKS_EN>0
  64. App_TimeTickHook();
  65. #endif
  66. #ifOS_TMR_EN>0
  67. OSTmrCtr++;
  68. if(OSTmrCtr>=(OS_TICKS_PER_SEC/OS_TMR_CFG_TICKS_PER_SEC))
  69. {
  70. OSTmrCtr=0;
  71. OSTmrSignal();
  72. }
  73. #endif
  74. }
  75. #endif

代码中 OS_APP_HOOKS_EN 和 OS_TMR_EN 在v2.52 版本中还没出现,我在这里这样写是为了移植到后面版本时更轻松。

至此,移植代码就基本完成了。不过这样还不能运行,因为两个中断处理函数(OSCtxSw和OSTickISR)还没有和对应的中断产生关联。将这二者关联起来的方法有几种,比如直接在 PRM 文件中制定,我用了种比较笨的办法,从网上找了个 vector.c 文件,虽然看起来不是很优雅,但确实是正确的代码。

  1. /*******************************************************************
  2. *
  3. *FreescaleMC9S12DP256ISRVectorDefinitions
  4. *
  5. *FileName:vectors.c
  6. *Version:1.0
  7. *Date:Jun/22/2004
  8. *Programmer:EricShufro
  9. ********************************************************************/
  10. /********************************************************************
  11. *EXTERNALISRFUNCTIONPROTOTYPES
  12. *********************************************************************/
  13. externvoidnear_Startup(void);/*StartupRoutine.*/
  14. externvoidnearOSTickISR(void);/*OSTimeTickRoutine.*/
  15. externvoidnearOSCtxSw(void);/*OSContectSwitchRoutine.*/
  16. externvoidnearSCI1_ISR(void);/*SCI1Routine.*/
  17. externvoidnearSCI0_

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top