os_cpu_c.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. *********************************************************************************************************
  3. * uC/OS-III
  4. * The Real-Time Kernel
  5. *
  6. *
  7. * (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
  8. * All rights reserved. Protected by international copyright laws.
  9. *
  10. * ARM Cortex-M3 Port
  11. *
  12. * File : OS_CPU_C.C
  13. * Version : V3.01.2
  14. * By : JJL
  15. * BAN
  16. *
  17. * LICENSING TERMS:
  18. * ---------------
  19. * uC/OS-III is provided in source form to registered licensees ONLY. It is
  20. * illegal to distribute this source code to any third party unless you receive
  21. * written permission by an authorized Micrium representative. Knowledge of
  22. * the source code may NOT be used to develop a similar product.
  23. *
  24. * Please help us continue to provide the Embedded community with the finest
  25. * software available. Your honesty is greatly appreciated.
  26. *
  27. * You can contact us at www.micrium.com.
  28. *
  29. * For : ARMv7M Cortex-M3
  30. * Mode : Thumb2
  31. * Toolchain : IAR EWARM
  32. *********************************************************************************************************
  33. */
  34. #define OS_CPU_GLOBALS
  35. #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
  36. const CPU_CHAR *os_cpu_c__c = "$Id: $";
  37. #endif
  38. /*$PAGE*/
  39. /*
  40. *********************************************************************************************************
  41. * INCLUDE FILES
  42. *********************************************************************************************************
  43. */
  44. #include <os.h>
  45. /*
  46. *********************************************************************************************************
  47. * IDLE TASK HOOK
  48. *
  49. * Description: This function is called by the idle task. This hook has been added to allow you to do
  50. * such things as STOP the CPU to conserve power.
  51. *
  52. * Arguments : None.
  53. *
  54. * Note(s) : None.
  55. *********************************************************************************************************
  56. */
  57. void OSIdleTaskHook (void)
  58. {
  59. #if OS_CFG_APP_HOOKS_EN > 0u
  60. if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
  61. (*OS_AppIdleTaskHookPtr)();
  62. }
  63. #endif
  64. }
  65. /*$PAGE*/
  66. /*
  67. *********************************************************************************************************
  68. * OS INITIALIZATION HOOK
  69. *
  70. * Description: This function is called by OSInit() at the beginning of OSInit().
  71. *
  72. * Arguments : None.
  73. *
  74. * Note(s) : None.
  75. *********************************************************************************************************
  76. */
  77. void OSInitHook (void)
  78. {
  79. OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
  80. }
  81. /*$PAGE*/
  82. /*
  83. *********************************************************************************************************
  84. * STATISTIC TASK HOOK
  85. *
  86. * Description: This function is called every second by uC/OS-III's statistics task. This allows your
  87. * application to add functionality to the statistics task.
  88. *
  89. * Arguments : None.
  90. *
  91. * Note(s) : None.
  92. *********************************************************************************************************
  93. */
  94. void OSStatTaskHook (void)
  95. {
  96. #if OS_CFG_APP_HOOKS_EN > 0u
  97. if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
  98. (*OS_AppStatTaskHookPtr)();
  99. }
  100. #endif
  101. }
  102. /*$PAGE*/
  103. /*
  104. *********************************************************************************************************
  105. * TASK CREATION HOOK
  106. *
  107. * Description: This function is called when a task is created.
  108. *
  109. * Arguments : p_tcb Pointer to the task control block of the task being created.
  110. *
  111. * Note(s) : None.
  112. *********************************************************************************************************
  113. */
  114. void OSTaskCreateHook (OS_TCB *p_tcb)
  115. {
  116. #if OS_CFG_APP_HOOKS_EN > 0u
  117. if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
  118. (*OS_AppTaskCreateHookPtr)(p_tcb);
  119. }
  120. #else
  121. (void)p_tcb; /* Prevent compiler warning */
  122. #endif
  123. }
  124. /*$PAGE*/
  125. /*
  126. *********************************************************************************************************
  127. * TASK DELETION HOOK
  128. *
  129. * Description: This function is called when a task is deleted.
  130. *
  131. * Arguments : p_tcb Pointer to the task control block of the task being deleted.
  132. *
  133. * Note(s) : None.
  134. *********************************************************************************************************
  135. */
  136. void OSTaskDelHook (OS_TCB *p_tcb)
  137. {
  138. #if OS_CFG_APP_HOOKS_EN > 0u
  139. if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
  140. (*OS_AppTaskDelHookPtr)(p_tcb);
  141. }
  142. #else
  143. (void)p_tcb; /* Prevent compiler warning */
  144. #endif
  145. }
  146. /*$PAGE*/
  147. /*
  148. *********************************************************************************************************
  149. * TASK RETURN HOOK
  150. *
  151. * Description: This function is called if a task accidentally returns. In other words, a task should
  152. * either be an infinite loop or delete itself when done.
  153. *
  154. * Arguments : p_tcb Pointer to the task control block of the task that is returning.
  155. *
  156. * Note(s) : None.
  157. *********************************************************************************************************
  158. */
  159. void OSTaskReturnHook (OS_TCB *p_tcb)
  160. {
  161. #if OS_CFG_APP_HOOKS_EN > 0u
  162. if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
  163. (*OS_AppTaskReturnHookPtr)(p_tcb);
  164. }
  165. #else
  166. (void)p_tcb; /* Prevent compiler warning */
  167. #endif
  168. }
  169. /*$PAGE*/
  170. /*
  171. **********************************************************************************************************
  172. * INITIALIZE A TASK'S STACK
  173. *
  174. * Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
  175. * frame of the task being created. This function is highly processor specific.
  176. *
  177. * Arguments : p_task Pointer to the task entry point address.
  178. *
  179. * p_arg Pointer to a user supplied data area that will be passed to the task
  180. * when the task first executes.
  181. *
  182. * p_stk_base Pointer to the base address of the stack.
  183. *
  184. * stk_size Size of the stack, in number of CPU_STK elements.
  185. *
  186. * opt Options used to alter the behavior of OS_Task_StkInit().
  187. * (see OS.H for OS_TASK_OPT_xxx).
  188. *
  189. * Returns : Always returns the location of the new top-of-stack' once the processor registers have
  190. * been placed on the stack in the proper order.
  191. *
  192. * Note(s) : 1) Interrupts are enabled when task starts executing.
  193. *
  194. * 2) All tasks run in Thread mode, using process stack.
  195. **********************************************************************************************************
  196. */
  197. CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
  198. void *p_arg,
  199. CPU_STK *p_stk_base,
  200. CPU_STK *p_stk_limit,
  201. CPU_STK_SIZE stk_size,
  202. OS_OPT opt)
  203. {
  204. CPU_STK *p_stk;
  205. (void)opt; /* Prevent compiler warning */
  206. p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
  207. /* Registers stacked as if auto-saved on exception */
  208. *--p_stk = (CPU_STK)0x01000000u; /* xPSR */
  209. *--p_stk = (CPU_STK)p_task; /* Entry Point */
  210. *--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
  211. *--p_stk = (CPU_STK)0x12121212u; /* R12 */
  212. *--p_stk = (CPU_STK)0x03030303u; /* R3 */
  213. *--p_stk = (CPU_STK)0x02020202u; /* R2 */
  214. *--p_stk = (CPU_STK)p_stk_limit; /* R1 */
  215. *--p_stk = (CPU_STK)p_arg; /* R0 : argument */
  216. /* Remaining registers saved on process stack */
  217. *--p_stk = (CPU_STK)0x11111111u; /* R11 */
  218. *--p_stk = (CPU_STK)0x10101010u; /* R10 */
  219. *--p_stk = (CPU_STK)0x09090909u; /* R9 */
  220. *--p_stk = (CPU_STK)0x08080808u; /* R8 */
  221. *--p_stk = (CPU_STK)0x07070707u; /* R7 */
  222. *--p_stk = (CPU_STK)0x06060606u; /* R6 */
  223. *--p_stk = (CPU_STK)0x05050505u; /* R5 */
  224. *--p_stk = (CPU_STK)0x04040404u; /* R4 */
  225. return (p_stk);
  226. }
  227. /*$PAGE*/
  228. /*
  229. *********************************************************************************************************
  230. * TASK SWITCH HOOK
  231. *
  232. * Description: This function is called when a task switch is performed. This allows you to perform other
  233. * operations during a context switch.
  234. *
  235. * Arguments : None.
  236. *
  237. * Note(s) : 1) Interrupts are disabled during this call.
  238. * 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
  239. * that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
  240. * to the task being switched out (i.e. the preempted task).
  241. *********************************************************************************************************
  242. */
  243. void OSTaskSwHook (void)
  244. {
  245. #if OS_CFG_TASK_PROFILE_EN > 0u
  246. CPU_TS ts;
  247. #endif
  248. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  249. CPU_TS int_dis_time;
  250. #endif
  251. #if OS_CFG_APP_HOOKS_EN > 0u
  252. if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
  253. (*OS_AppTaskSwHookPtr)();
  254. }
  255. #endif
  256. #if OS_CFG_TASK_PROFILE_EN > 0u
  257. ts = OS_TS_GET();
  258. if (OSTCBCurPtr != OSTCBHighRdyPtr) {
  259. OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
  260. OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
  261. }
  262. OSTCBHighRdyPtr->CyclesStart = ts;
  263. #endif
  264. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  265. int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
  266. if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
  267. OSTCBCurPtr->IntDisTimeMax = int_dis_time;
  268. }
  269. #endif
  270. #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
  271. /* Keep track of per-task scheduler lock time */
  272. if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
  273. OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
  274. }
  275. OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
  276. #endif
  277. }
  278. /*$PAGE*/
  279. /*
  280. *********************************************************************************************************
  281. * TICK HOOK
  282. *
  283. * Description: This function is called every tick.
  284. *
  285. * Arguments : None.
  286. *
  287. * Note(s) : 1) This function is assumed to be called from the Tick ISR.
  288. *********************************************************************************************************
  289. */
  290. void OSTimeTickHook (void)
  291. {
  292. #if OS_CFG_APP_HOOKS_EN > 0u
  293. if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
  294. (*OS_AppTimeTickHookPtr)();
  295. }
  296. #endif
  297. }
  298. /*$PAGE*/
  299. /*
  300. *********************************************************************************************************
  301. * SYS TICK HANDLER
  302. *
  303. * Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
  304. * interrupt.
  305. *
  306. * Arguments : None.
  307. *
  308. * Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
  309. *********************************************************************************************************
  310. */
  311. //void OS_CPU_SysTickHandler (void)
  312. //{
  313. // CPU_SR_ALLOC();
  314. // CPU_CRITICAL_ENTER();
  315. // OSIntNestingCtr++; // Tell uC/OS-III that we are starting an ISR
  316. // CPU_CRITICAL_EXIT();
  317. // OSTimeTick(); // Call uC/OS-III's OSTimeTick()
  318. // OSIntExit(); // Tell uC/OS-III that we are leaving the ISR
  319. //}
  320. /*$PAGE*/
  321. /*
  322. *********************************************************************************************************
  323. * INITIALIZE SYS TICK
  324. *
  325. * Description: Initialize the SysTick.
  326. *
  327. * Arguments : cnts Number of SysTick counts between two OS tick interrupts.
  328. *
  329. * Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
  330. *********************************************************************************************************
  331. */
  332. //void OS_CPU_SysTickInit (CPU_INT32U cnts)
  333. //{
  334. // CPU_INT32U prio;
  335. // CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
  336. // // Set SysTick handler prio.
  337. // prio = CPU_REG_NVIC_SHPRI3;
  338. // prio &= DEF_BIT_FIELD(24, 0);
  339. // prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
  340. // CPU_REG_NVIC_SHPRI3 = prio;
  341. // // Enable timer.
  342. // CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
  343. // CPU_REG_NVIC_ST_CTRL_ENABLE;
  344. // // Enable timer interrupt.
  345. // CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
  346. //}