训练营PLSR题目
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

396 líneas
16 KiB

  1. /*
  2. ************************************************************************************************************************
  3. * uC/OS-III
  4. * The Real-Time Kernel
  5. *
  6. * (c) Copyright 2009-2014; Micrium, Inc.; Weston, FL
  7. * All rights reserved. Protected by international copyright laws.
  8. *
  9. * ISR QUEUE MANAGEMENT
  10. *
  11. * File : OS_INT.C
  12. * By : JJL
  13. * Version : V3.04.04
  14. *
  15. * LICENSING TERMS:
  16. * ---------------
  17. * uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
  18. * for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
  19. * product then, you need to contact Micrium to properly license uC/OS-III for its use in your
  20. * application/product. We provide ALL the source code for your convenience and to help you
  21. * experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
  22. * it commercially without paying a licensing fee.
  23. *
  24. * Knowledge of the source code may NOT be used to develop a similar product.
  25. *
  26. * Please help us continue to provide the embedded community with the finest software available.
  27. * Your honesty is greatly appreciated.
  28. *
  29. * You can find our product's user manual, API reference, release notes and
  30. * more information at https://doc.micrium.com.
  31. * You can contact us at www.micrium.com.
  32. ************************************************************************************************************************
  33. */
  34. #define MICRIUM_SOURCE
  35. #include "os.h"
  36. #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
  37. const CPU_CHAR *os_int__c = "$Id: $";
  38. #endif
  39. #if OS_CFG_ISR_POST_DEFERRED_EN > 0u
  40. /*
  41. ************************************************************************************************************************
  42. * POST TO ISR QUEUE
  43. *
  44. * Description: This function places contents of posts into an intermediate queue to help defer processing of interrupts
  45. * at the task level.
  46. *
  47. * Arguments : type is the type of kernel object the post is destined to:
  48. *
  49. * OS_OBJ_TYPE_SEM
  50. * OS_OBJ_TYPE_Q
  51. * OS_OBJ_TYPE_FLAG
  52. * OS_OBJ_TYPE_TASK_MSG
  53. * OS_OBJ_TYPE_TASK_SIGNAL
  54. *
  55. * p_obj is a pointer to the kernel object to post to. This can be a pointer to a semaphore,
  56. * ----- a message queue or a task control clock.
  57. *
  58. * p_void is a pointer to a message that is being posted. This is used when posting to a message
  59. * queue or directly to a task.
  60. *
  61. * msg_size is the size of the message being posted
  62. *
  63. * flags if the post is done to an event flag group then this corresponds to the flags being
  64. * posted
  65. *
  66. * ts is a timestamp as to when the post was done
  67. *
  68. * opt this corresponds to post options and applies to:
  69. *
  70. * OSFlagPost()
  71. * OSSemPost()
  72. * OSQPost()
  73. * OSTaskQPost()
  74. *
  75. * p_err is a pointer to a variable that will contain an error code returned by this function.
  76. *
  77. * OS_ERR_NONE if the post to the ISR queue was successful
  78. * OS_ERR_INT_Q_FULL if the ISR queue is full and cannot accepts any further posts. This
  79. * generally indicates that you are receiving interrupts faster than you
  80. * can process them or, that you didn't make the ISR queue large enough.
  81. *
  82. * Returns : none
  83. *
  84. * Note(s) : none
  85. ************************************************************************************************************************
  86. */
  87. void OS_IntQPost (OS_OBJ_TYPE type,
  88. void *p_obj,
  89. void *p_void,
  90. OS_MSG_SIZE msg_size,
  91. OS_FLAGS flags,
  92. OS_OPT opt,
  93. CPU_TS ts,
  94. OS_ERR *p_err)
  95. {
  96. CPU_SR_ALLOC();
  97. CPU_CRITICAL_ENTER();
  98. if (OSIntQNbrEntries < OSCfg_IntQSize) { /* Make sure we haven't already filled the ISR queue */
  99. OSIntQNbrEntries++;
  100. if (OSIntQNbrEntriesMax < OSIntQNbrEntries) {
  101. OSIntQNbrEntriesMax = OSIntQNbrEntries;
  102. }
  103. OSIntQInPtr->Type = type; /* Save object type being posted */
  104. OSIntQInPtr->ObjPtr = p_obj; /* Save pointer to object being posted */
  105. OSIntQInPtr->MsgPtr = p_void; /* Save pointer to message if posting to a message queue */
  106. OSIntQInPtr->MsgSize = msg_size; /* Save the message size if posting to a message queue */
  107. OSIntQInPtr->Flags = flags; /* Save the flags if posting to an event flag group */
  108. OSIntQInPtr->Opt = opt; /* Save post options */
  109. OSIntQInPtr->TS = ts; /* Save time stamp */
  110. OSIntQInPtr = OSIntQInPtr->NextPtr; /* Point to the next interrupt handler queue entry */
  111. OSRdyList[0].NbrEntries = (OS_OBJ_QTY)1; /* Make the interrupt handler task ready to run */
  112. OSRdyList[0].HeadPtr = &OSIntQTaskTCB;
  113. OSRdyList[0].TailPtr = &OSIntQTaskTCB;
  114. OS_PrioInsert(0u); /* Add task priority 0 in the priority table */
  115. if (OSPrioCur != 0) { /* Chk if OSIntQTask is not running */
  116. OSPrioSaved = OSPrioCur; /* Save current priority */
  117. }
  118. *p_err = OS_ERR_NONE;
  119. } else {
  120. OSIntQOvfCtr++; /* Count the number of ISR queue overflows */
  121. *p_err = OS_ERR_INT_Q_FULL;
  122. }
  123. CPU_CRITICAL_EXIT();
  124. }
  125. /*
  126. ************************************************************************************************************************
  127. * RE-POST FROM ISR QUEUE
  128. *
  129. * Description: This function takes contents of posts from an intermediate queue to help defer processing of interrupts
  130. * at the task level.
  131. *
  132. * Arguments : none
  133. *
  134. * Returns : none
  135. ************************************************************************************************************************
  136. */
  137. void OS_IntQRePost (void)
  138. {
  139. #if OS_CFG_TMR_EN > 0u
  140. CPU_TS ts;
  141. #endif
  142. OS_ERR err;
  143. switch (OSIntQOutPtr->Type) { /* Re-post to task */
  144. case OS_OBJ_TYPE_FLAG:
  145. #if OS_CFG_FLAG_EN > 0u
  146. (void)OS_FlagPost((OS_FLAG_GRP *) OSIntQOutPtr->ObjPtr,
  147. (OS_FLAGS ) OSIntQOutPtr->Flags,
  148. (OS_OPT ) OSIntQOutPtr->Opt,
  149. (CPU_TS ) OSIntQOutPtr->TS,
  150. (OS_ERR *)&err);
  151. #endif
  152. break;
  153. case OS_OBJ_TYPE_Q:
  154. #if OS_CFG_Q_EN > 0u
  155. OS_QPost((OS_Q *) OSIntQOutPtr->ObjPtr,
  156. (void *) OSIntQOutPtr->MsgPtr,
  157. (OS_MSG_SIZE) OSIntQOutPtr->MsgSize,
  158. (OS_OPT ) OSIntQOutPtr->Opt,
  159. (CPU_TS ) OSIntQOutPtr->TS,
  160. (OS_ERR *)&err);
  161. #endif
  162. break;
  163. case OS_OBJ_TYPE_SEM:
  164. #if OS_CFG_SEM_EN > 0u
  165. (void)OS_SemPost((OS_SEM *) OSIntQOutPtr->ObjPtr,
  166. (OS_OPT ) OSIntQOutPtr->Opt,
  167. (CPU_TS ) OSIntQOutPtr->TS,
  168. (OS_ERR *)&err);
  169. #endif
  170. break;
  171. case OS_OBJ_TYPE_TASK_MSG:
  172. #if OS_CFG_TASK_Q_EN > 0u
  173. OS_TaskQPost((OS_TCB *) OSIntQOutPtr->ObjPtr,
  174. (void *) OSIntQOutPtr->MsgPtr,
  175. (OS_MSG_SIZE) OSIntQOutPtr->MsgSize,
  176. (OS_OPT ) OSIntQOutPtr->Opt,
  177. (CPU_TS ) OSIntQOutPtr->TS,
  178. (OS_ERR *)&err);
  179. #endif
  180. break;
  181. case OS_OBJ_TYPE_TASK_RESUME:
  182. #if OS_CFG_TASK_SUSPEND_EN > 0u
  183. (void)OS_TaskResume((OS_TCB *) OSIntQOutPtr->ObjPtr,
  184. (OS_ERR *)&err);
  185. #endif
  186. break;
  187. case OS_OBJ_TYPE_TASK_SIGNAL:
  188. (void)OS_TaskSemPost((OS_TCB *) OSIntQOutPtr->ObjPtr,
  189. (OS_OPT ) OSIntQOutPtr->Opt,
  190. (CPU_TS ) OSIntQOutPtr->TS,
  191. (OS_ERR *)&err);
  192. break;
  193. case OS_OBJ_TYPE_TASK_SUSPEND:
  194. #if OS_CFG_TASK_SUSPEND_EN > 0u
  195. (void)OS_TaskSuspend((OS_TCB *) OSIntQOutPtr->ObjPtr,
  196. (OS_ERR *)&err);
  197. #endif
  198. break;
  199. case OS_OBJ_TYPE_TICK:
  200. #if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
  201. OS_SchedRoundRobin(&OSRdyList[OSPrioSaved]);
  202. #endif
  203. (void)OS_TaskSemPost((OS_TCB *)&OSTickTaskTCB, /* Signal tick task */
  204. (OS_OPT ) OS_OPT_POST_NONE,
  205. (CPU_TS ) OSIntQOutPtr->TS,
  206. (OS_ERR *)&err);
  207. #if OS_CFG_TMR_EN > 0u
  208. OSTmrUpdateCtr--;
  209. if (OSTmrUpdateCtr == (OS_CTR)0u) {
  210. OSTmrUpdateCtr = OSTmrUpdateCnt;
  211. ts = OS_TS_GET(); /* Get timestamp */
  212. (void)OS_TaskSemPost((OS_TCB *)&OSTmrTaskTCB, /* Signal timer task */
  213. (OS_OPT ) OS_OPT_POST_NONE,
  214. (CPU_TS ) ts,
  215. (OS_ERR *)&err);
  216. }
  217. #endif
  218. break;
  219. default:
  220. break;
  221. }
  222. }
  223. /*
  224. ************************************************************************************************************************
  225. * INTERRUPT QUEUE MANAGEMENT TASK
  226. *
  227. * Description: This task is internal to uC/OS-III and is used to process the queue of deffered interrupts.
  228. *
  229. * Arguments : p_arg is a pointer to an optional argument that is passed during task creation. For this function
  230. * the argument is not used and will be a NULL pointer.
  231. *
  232. * Returns : none
  233. ************************************************************************************************************************
  234. */
  235. void OS_IntQTask (void *p_arg)
  236. {
  237. CPU_BOOLEAN done;
  238. CPU_TS ts_start;
  239. CPU_TS ts_end;
  240. CPU_SR_ALLOC();
  241. (void)&p_arg; /* Not using 'p_arg', prevent compiler warning */
  242. while (DEF_ON) {
  243. done = DEF_FALSE;
  244. while (done == DEF_FALSE) {
  245. CPU_CRITICAL_ENTER();
  246. if (OSIntQNbrEntries == (OS_OBJ_QTY)0u) {
  247. OSRdyList[0].NbrEntries = (OS_OBJ_QTY)0u; /* Remove from ready list */
  248. OSRdyList[0].HeadPtr = (OS_TCB *)0;
  249. OSRdyList[0].TailPtr = (OS_TCB *)0;
  250. OS_PrioRemove(0u); /* Remove from the priority table */
  251. CPU_CRITICAL_EXIT();
  252. OSSched();
  253. done = DEF_TRUE; /* No more entries in the queue, we are done */
  254. } else {
  255. CPU_CRITICAL_EXIT();
  256. ts_start = OS_TS_GET();
  257. OS_IntQRePost();
  258. ts_end = OS_TS_GET() - ts_start; /* Measure execution time of tick task */
  259. if (OSIntQTaskTimeMax < ts_end) {
  260. OSIntQTaskTimeMax = ts_end;
  261. }
  262. CPU_CRITICAL_ENTER();
  263. OSIntQOutPtr = OSIntQOutPtr->NextPtr; /* Point to next item in the ISR queue */
  264. OSIntQNbrEntries--;
  265. CPU_CRITICAL_EXIT();
  266. }
  267. }
  268. }
  269. }
  270. /*
  271. ************************************************************************************************************************
  272. * INITIALIZE THE ISR QUEUE
  273. *
  274. * Description: This function is called by OSInit() to initialize the ISR queue.
  275. *
  276. * Arguments : p_err is a pointer to a variable that will contain an error code returned by this function.
  277. *
  278. * OS_ERR_INT_Q If you didn't provide an ISR queue in OS_CFG.C
  279. * OS_ERR_INT_Q_SIZE If you didn't specify a large enough ISR queue.
  280. * OS_ERR_STK_INVALID If you specified a NULL pointer for the task of the ISR task
  281. * handler
  282. * OS_ERR_STK_SIZE_INVALID If you didn't specify a stack size greater than the minimum
  283. * specified by OS_CFG_STK_SIZE_MIN
  284. * OS_ERR_??? An error code returned by OSTaskCreate().
  285. *
  286. * Returns : none
  287. *
  288. * Note(s) : none
  289. ************************************************************************************************************************
  290. */
  291. void OS_IntQTaskInit (OS_ERR *p_err)
  292. {
  293. OS_INT_Q *p_int_q;
  294. OS_INT_Q *p_int_q_next;
  295. OS_OBJ_QTY i;
  296. OSIntQOvfCtr = (OS_QTY)0u; /* Clear the ISR queue overflow counter */
  297. if (OSCfg_IntQBasePtr == (OS_INT_Q *)0) {
  298. *p_err = OS_ERR_INT_Q;
  299. return;
  300. }
  301. if (OSCfg_IntQSize < (OS_OBJ_QTY)2u) {
  302. *p_err = OS_ERR_INT_Q_SIZE;
  303. return;
  304. }
  305. OSIntQTaskTimeMax = (CPU_TS)0;
  306. p_int_q = OSCfg_IntQBasePtr; /* Initialize the circular ISR queue */
  307. p_int_q_next = p_int_q;
  308. p_int_q_next++;
  309. for (i = 0u; i < OSCfg_IntQSize; i++) {
  310. p_int_q->Type = OS_OBJ_TYPE_NONE;
  311. p_int_q->ObjPtr = (void *)0;
  312. p_int_q->MsgPtr = (void *)0;
  313. p_int_q->MsgSize = (OS_MSG_SIZE)0u;
  314. p_int_q->Flags = (OS_FLAGS )0u;
  315. p_int_q->Opt = (OS_OPT )0u;
  316. p_int_q->NextPtr = p_int_q_next;
  317. p_int_q++;
  318. p_int_q_next++;
  319. }
  320. p_int_q--;
  321. p_int_q_next = OSCfg_IntQBasePtr;
  322. p_int_q->NextPtr = p_int_q_next;
  323. OSIntQInPtr = p_int_q_next;
  324. OSIntQOutPtr = p_int_q_next;
  325. OSIntQNbrEntries = (OS_OBJ_QTY)0u;
  326. OSIntQNbrEntriesMax = (OS_OBJ_QTY)0u;
  327. /* -------------- CREATE THE ISR QUEUE TASK ------------- */
  328. if (OSCfg_IntQTaskStkBasePtr == (CPU_STK *)0) {
  329. *p_err = OS_ERR_INT_Q_STK_INVALID;
  330. return;
  331. }
  332. if (OSCfg_IntQTaskStkSize < OSCfg_StkSizeMin) {
  333. *p_err = OS_ERR_INT_Q_STK_SIZE_INVALID;
  334. return;
  335. }
  336. OSTaskCreate((OS_TCB *)&OSIntQTaskTCB,
  337. (CPU_CHAR *)((void *)"uC/OS-III ISR Queue Task"),
  338. (OS_TASK_PTR )OS_IntQTask,
  339. (void *)0,
  340. (OS_PRIO )0u, /* This task is ALWAYS at priority '0' (i.e. highest) */
  341. (CPU_STK *)OSCfg_IntQTaskStkBasePtr,
  342. (CPU_STK_SIZE)OSCfg_IntQTaskStkLimit,
  343. (CPU_STK_SIZE)OSCfg_IntQTaskStkSize,
  344. (OS_MSG_QTY )0u,
  345. (OS_TICK )0u,
  346. (void *)0,
  347. (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  348. (OS_ERR *)p_err);
  349. }
  350. #endif