训练营PLSR题目
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

521 rader
19 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. * STATISTICS MODULE
  10. *
  11. * File : OS_STAT.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_stat__c = "$Id: $";
  38. #endif
  39. #if OS_CFG_STAT_TASK_EN > 0u
  40. /*
  41. ************************************************************************************************************************
  42. * RESET STATISTICS
  43. *
  44. * Description: This function is called by your application to reset the statistics.
  45. *
  46. * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
  47. *
  48. * OS_ERR_NONE
  49. *
  50. * Returns : none
  51. ************************************************************************************************************************
  52. */
  53. void OSStatReset (OS_ERR *p_err)
  54. {
  55. #if (OS_CFG_DBG_EN > 0u)
  56. OS_TCB *p_tcb;
  57. #if (OS_MSG_EN > 0u)
  58. OS_MSG_Q *p_msg_q;
  59. #endif
  60. #if (OS_CFG_Q_EN > 0u)
  61. OS_Q *p_q;
  62. #endif
  63. #endif
  64. CPU_SR_ALLOC();
  65. #ifdef OS_SAFETY_CRITICAL
  66. if (p_err == (OS_ERR *)0) {
  67. OS_SAFETY_CRITICAL_EXCEPTION();
  68. return;
  69. }
  70. #endif
  71. CPU_CRITICAL_ENTER();
  72. #if OS_CFG_ISR_POST_DEFERRED_EN > 0u
  73. OSIntQTaskTimeMax = (CPU_TS )0; /* Reset the task execution times */
  74. OSIntQNbrEntriesMax = (OS_OBJ_QTY)0; /* Reset the queue maximum number of entries */
  75. #endif
  76. #if OS_CFG_STAT_TASK_EN > 0u
  77. OSStatTaskCPUUsageMax = 0u;
  78. OSStatTaskTimeMax = (CPU_TS)0;
  79. #endif
  80. OSTickTaskTimeMax = (CPU_TS)0;
  81. #if OS_CFG_TMR_EN > 0u
  82. OSTmrTaskTimeMax = (CPU_TS)0;
  83. #endif
  84. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  85. OSIntDisTimeMax = (CPU_TS)0; /* Reset the maximum interrupt disable time */
  86. #endif
  87. #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
  88. OSSchedLockTimeMax = (CPU_TS)0; /* Reset the maximum scheduler lock time */
  89. #endif
  90. #if ((OS_MSG_EN > 0u) && (OS_CFG_DBG_EN > 0u))
  91. OSMsgPool.NbrUsedMax = 0u;
  92. #endif
  93. CPU_CRITICAL_EXIT();
  94. #if OS_CFG_DBG_EN > 0u
  95. CPU_CRITICAL_ENTER();
  96. p_tcb = OSTaskDbgListPtr;
  97. CPU_CRITICAL_EXIT();
  98. while (p_tcb != (OS_TCB *)0) { /* Reset per-Task statistics */
  99. CPU_CRITICAL_ENTER();
  100. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  101. p_tcb->IntDisTimeMax = (CPU_TS )0;
  102. #endif
  103. #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
  104. p_tcb->SchedLockTimeMax = (CPU_TS )0;
  105. #endif
  106. #if OS_CFG_TASK_PROFILE_EN > 0u
  107. #if OS_CFG_TASK_Q_EN > 0u
  108. p_tcb->MsgQPendTimeMax = (CPU_TS )0;
  109. #endif
  110. p_tcb->SemPendTimeMax = (CPU_TS )0;
  111. p_tcb->CtxSwCtr = (OS_CTR )0;
  112. p_tcb->CPUUsage = (OS_CPU_USAGE)0;
  113. p_tcb->CPUUsageMax = (OS_CPU_USAGE)0;
  114. p_tcb->CyclesTotal = (OS_CYCLES )0;
  115. p_tcb->CyclesTotalPrev = (OS_CYCLES )0;
  116. p_tcb->CyclesStart = OS_TS_GET();
  117. #endif
  118. #if OS_CFG_TASK_Q_EN > 0u
  119. p_msg_q = &p_tcb->MsgQ;
  120. p_msg_q->NbrEntriesMax = (OS_MSG_QTY )0;
  121. #endif
  122. p_tcb = p_tcb->DbgNextPtr;
  123. CPU_CRITICAL_EXIT();
  124. }
  125. #endif
  126. #if (OS_CFG_Q_EN > 0u) && (OS_CFG_DBG_EN > 0u)
  127. CPU_CRITICAL_ENTER();
  128. p_q = OSQDbgListPtr;
  129. CPU_CRITICAL_EXIT();
  130. while (p_q != (OS_Q *)0) { /* Reset message queues statistics */
  131. CPU_CRITICAL_ENTER();
  132. p_msg_q = &p_q->MsgQ;
  133. p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
  134. p_q = p_q->DbgNextPtr;
  135. CPU_CRITICAL_EXIT();
  136. }
  137. #endif
  138. OS_TickListResetPeak(); /* Reset tick wheel statistics */
  139. #if OS_CFG_TMR_EN > 0u
  140. OS_TmrResetPeak();
  141. #endif
  142. *p_err = OS_ERR_NONE;
  143. }
  144. /*
  145. ************************************************************************************************************************
  146. * DETERMINE THE CPU CAPACITY
  147. *
  148. * Description: This function is called by your application to establish CPU usage by first determining how high a 32-bit
  149. * counter would count to in 1/10 second if no other tasks were to execute during that time. CPU usage is
  150. * then determined by a low priority task which keeps track of this 32-bit counter every second but this
  151. * time, with other tasks running. CPU usage is determined by:
  152. *
  153. * OS_Stat_IdleCtr
  154. * CPU Usage (%) = 100 * (1 - ------------------)
  155. * OS_Stat_IdleCtrMax
  156. *
  157. * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
  158. *
  159. * OS_ERR_NONE
  160. *
  161. * Returns : none
  162. ************************************************************************************************************************
  163. */
  164. void OSStatTaskCPUUsageInit (OS_ERR *p_err)
  165. {
  166. OS_ERR err;
  167. OS_TICK dly;
  168. CPU_SR_ALLOC();
  169. #ifdef OS_SAFETY_CRITICAL
  170. if (p_err == (OS_ERR *)0) {
  171. OS_SAFETY_CRITICAL_EXCEPTION();
  172. return;
  173. }
  174. #endif
  175. #if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
  176. OSTaskSuspend(&OSTmrTaskTCB, &err);
  177. if (err != OS_ERR_NONE) {
  178. *p_err = err;
  179. return;
  180. }
  181. #endif
  182. OSTimeDly((OS_TICK )2, /* Synchronize with clock tick */
  183. (OS_OPT )OS_OPT_TIME_DLY,
  184. (OS_ERR *)&err);
  185. if (err != OS_ERR_NONE) {
  186. *p_err = err;
  187. return;
  188. }
  189. CPU_CRITICAL_ENTER();
  190. OSStatTaskCtr = (OS_TICK)0; /* Clear idle counter */
  191. CPU_CRITICAL_EXIT();
  192. dly = (OS_TICK)0;
  193. if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
  194. dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
  195. }
  196. if (dly == (OS_TICK)0) {
  197. dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
  198. }
  199. OSTimeDly(dly, /* Determine MAX. idle counter value */
  200. OS_OPT_TIME_DLY,
  201. &err);
  202. #if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
  203. OSTaskResume(&OSTmrTaskTCB, &err);
  204. if (err != OS_ERR_NONE) {
  205. *p_err = err;
  206. return;
  207. }
  208. #endif
  209. CPU_CRITICAL_ENTER();
  210. OSStatTaskTimeMax = (CPU_TS)0;
  211. OSStatTaskCtrMax = OSStatTaskCtr; /* Store maximum idle counter count */
  212. OSStatTaskRdy = OS_STATE_RDY;
  213. CPU_CRITICAL_EXIT();
  214. *p_err = OS_ERR_NONE;
  215. }
  216. /*
  217. ************************************************************************************************************************
  218. * STATISTICS TASK
  219. *
  220. * Description: This task is internal to uC/OS-III and is used to compute some statistics about the multitasking
  221. * environment. Specifically, OS_StatTask() computes the CPU usage. CPU usage is determined by:
  222. *
  223. * OSStatTaskCtr
  224. * OSStatTaskCPUUsage = 100 * (1 - ------------------) (units are in %)
  225. * OSStatTaskCtrMax
  226. *
  227. * Arguments : p_arg this pointer is not used at this time.
  228. *
  229. * Returns : none
  230. *
  231. * Note(s) : 1) This task runs at a priority level higher than the idle task.
  232. *
  233. * 2) You can disable this task by setting the configuration #define OS_CFG_STAT_TASK_EN to 0.
  234. *
  235. * 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the maximum value
  236. * for the idle counter.
  237. *
  238. * 4) This function is INTERNAL to uC/OS-III and your application should not call it.
  239. ************************************************************************************************************************
  240. */
  241. void OS_StatTask (void *p_arg)
  242. {
  243. #if OS_CFG_DBG_EN > 0u
  244. #if OS_CFG_TASK_PROFILE_EN > 0u
  245. OS_CPU_USAGE usage;
  246. OS_CYCLES cycles_total;
  247. OS_CYCLES cycles_div;
  248. OS_CYCLES cycles_mult;
  249. OS_CYCLES cycles_max;
  250. #endif
  251. OS_TCB *p_tcb;
  252. #endif
  253. OS_TICK ctr_max;
  254. OS_TICK ctr_mult;
  255. OS_TICK ctr_div;
  256. OS_ERR err;
  257. OS_TICK dly;
  258. CPU_TS ts_start;
  259. CPU_TS ts_end;
  260. CPU_SR_ALLOC();
  261. (void)&p_arg; /* Prevent compiler warning for not using 'p_arg' */
  262. while (OSStatTaskRdy != DEF_TRUE) {
  263. OSTimeDly(2u * OSCfg_StatTaskRate_Hz, /* Wait until statistic task is ready */
  264. OS_OPT_TIME_DLY,
  265. &err);
  266. }
  267. OSStatReset(&err); /* Reset statistics */
  268. dly = (OS_TICK)0; /* Compute statistic task sleep delay */
  269. if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
  270. dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
  271. }
  272. if (dly == (OS_TICK)0) {
  273. dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
  274. }
  275. while (DEF_ON) {
  276. ts_start = OS_TS_GET();
  277. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  278. OSIntDisTimeMax = CPU_IntDisMeasMaxGet();
  279. #endif
  280. CPU_CRITICAL_ENTER(); /* ----------------- OVERALL CPU USAGE ------------------ */
  281. OSStatTaskCtrRun = OSStatTaskCtr; /* Obtain the of the stat counter for the past .1 second */
  282. OSStatTaskCtr = (OS_TICK)0; /* Reset the stat counter for the next .1 second */
  283. CPU_CRITICAL_EXIT();
  284. if (OSStatTaskCtrMax > OSStatTaskCtrRun) { /* Compute CPU Usage with best resolution */
  285. if (OSStatTaskCtrMax < 400000u) { /* 1 to 400,000 */
  286. ctr_mult = 10000u;
  287. ctr_div = 1u;
  288. } else if (OSStatTaskCtrMax < 4000000u) { /* 400,000 to 4,000,000 */
  289. ctr_mult = 1000u;
  290. ctr_div = 10u;
  291. } else if (OSStatTaskCtrMax < 40000000u) { /* 4,000,000 to 40,000,000 */
  292. ctr_mult = 100u;
  293. ctr_div = 100u;
  294. } else if (OSStatTaskCtrMax < 400000000u) { /* 40,000,000 to 400,000,000 */
  295. ctr_mult = 10u;
  296. ctr_div = 1000u;
  297. } else { /* 400,000,000 and up */
  298. ctr_mult = 1u;
  299. ctr_div = 10000u;
  300. }
  301. ctr_max = OSStatTaskCtrMax / ctr_div;
  302. OSStatTaskCPUUsage = (OS_CPU_USAGE)((OS_TICK)10000u - ctr_mult * OSStatTaskCtrRun / ctr_max);
  303. if (OSStatTaskCPUUsageMax < OSStatTaskCPUUsage) {
  304. OSStatTaskCPUUsageMax = OSStatTaskCPUUsage;
  305. }
  306. } else {
  307. OSStatTaskCPUUsage = (OS_CPU_USAGE)10000u;
  308. }
  309. OSStatTaskHook(); /* Invoke user definable hook */
  310. #if OS_CFG_DBG_EN > 0u
  311. #if OS_CFG_TASK_PROFILE_EN > 0u
  312. cycles_total = (OS_CYCLES)0;
  313. CPU_CRITICAL_ENTER();
  314. p_tcb = OSTaskDbgListPtr;
  315. CPU_CRITICAL_EXIT();
  316. while (p_tcb != (OS_TCB *)0) { /* ----------------- TOTAL CYCLES COUNT ----------------- */
  317. OS_CRITICAL_ENTER();
  318. p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal; /* Save accumulated # cycles into a temp variable */
  319. p_tcb->CyclesTotal = (OS_CYCLES)0; /* Reset total cycles for task for next run */
  320. OS_CRITICAL_EXIT();
  321. cycles_total += p_tcb->CyclesTotalPrev;/* Perform sum of all task # cycles */
  322. CPU_CRITICAL_ENTER();
  323. p_tcb = p_tcb->DbgNextPtr;
  324. CPU_CRITICAL_EXIT();
  325. }
  326. #endif
  327. #if OS_CFG_TASK_PROFILE_EN > 0u
  328. /* ------------- INDIVIDUAL TASK CPU USAGE -------------- */
  329. if (cycles_total > (OS_CYCLES)0u) { /* 'cycles_total' scaling ... */
  330. if (cycles_total < 400000u) { /* 1 to 400,000 */
  331. cycles_mult = 10000u;
  332. cycles_div = 1u;
  333. } else if (cycles_total < 4000000u) { /* 400,000 to 4,000,000 */
  334. cycles_mult = 1000u;
  335. cycles_div = 10u;
  336. } else if (cycles_total < 40000000u) { /* 4,000,000 to 40,000,000 */
  337. cycles_mult = 100u;
  338. cycles_div = 100u;
  339. } else if (cycles_total < 400000000u) { /* 40,000,000 to 400,000,000 */
  340. cycles_mult = 10u;
  341. cycles_div = 1000u;
  342. } else { /* 400,000,000 and up */
  343. cycles_mult = 1u;
  344. cycles_div = 10000u;
  345. }
  346. cycles_max = cycles_total / cycles_div;
  347. } else {
  348. cycles_mult = 0u;
  349. cycles_max = 1u;
  350. }
  351. #endif
  352. CPU_CRITICAL_ENTER();
  353. p_tcb = OSTaskDbgListPtr;
  354. CPU_CRITICAL_EXIT();
  355. while (p_tcb != (OS_TCB *)0) {
  356. #if OS_CFG_TASK_PROFILE_EN > 0u /* Compute execution time of each task */
  357. usage = (OS_CPU_USAGE)(cycles_mult * p_tcb->CyclesTotalPrev / cycles_max);
  358. if (usage > 10000u) {
  359. usage = 10000u;
  360. }
  361. p_tcb->CPUUsage = usage;
  362. if (p_tcb->CPUUsageMax < usage) { /* Detect peak CPU usage */
  363. p_tcb->CPUUsageMax = usage;
  364. }
  365. #endif
  366. #if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
  367. OSTaskStkChk( p_tcb, /* Compute stack usage of active tasks only */
  368. &p_tcb->StkFree,
  369. &p_tcb->StkUsed,
  370. &err);
  371. #endif
  372. CPU_CRITICAL_ENTER();
  373. p_tcb = p_tcb->DbgNextPtr;
  374. CPU_CRITICAL_EXIT();
  375. }
  376. #endif
  377. if (OSStatResetFlag == DEF_TRUE) { /* Check if need to reset statistics */
  378. OSStatResetFlag = DEF_FALSE;
  379. OSStatReset(&err);
  380. }
  381. ts_end = OS_TS_GET() - ts_start; /* Measure execution time of statistic task */
  382. if (OSStatTaskTimeMax < ts_end) {
  383. OSStatTaskTimeMax = ts_end;
  384. }
  385. OSTimeDly(dly,
  386. OS_OPT_TIME_DLY,
  387. &err);
  388. }
  389. }
  390. /*
  391. ************************************************************************************************************************
  392. * INITIALIZE THE STATISTICS
  393. *
  394. * Description: This function is called by OSInit() to initialize the statistic task.
  395. *
  396. * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
  397. *
  398. * OS_ERR_STK_INVALID If you specified a NULL stack pointer during configuration
  399. * OS_ERR_STK_SIZE_INVALID If you didn't specify a large enough stack.
  400. * OS_ERR_PRIO_INVALID If you specified a priority for the statistic task equal to or
  401. * lower (i.e. higher number) than the idle task.
  402. * OS_ERR_xxx An error code returned by OSTaskCreate()
  403. *
  404. * Returns : none
  405. *
  406. * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
  407. ************************************************************************************************************************
  408. */
  409. void OS_StatTaskInit (OS_ERR *p_err)
  410. {
  411. #ifdef OS_SAFETY_CRITICAL
  412. if (p_err == (OS_ERR *)0) {
  413. OS_SAFETY_CRITICAL_EXCEPTION();
  414. return;
  415. }
  416. #endif
  417. OSStatTaskCtr = (OS_TICK)0;
  418. OSStatTaskCtrRun = (OS_TICK)0;
  419. OSStatTaskCtrMax = (OS_TICK)0;
  420. OSStatTaskRdy = OS_STATE_NOT_RDY; /* Statistic task is not ready */
  421. OSStatResetFlag = DEF_FALSE;
  422. /* ---------------- CREATE THE STAT TASK ---------------- */
  423. if (OSCfg_StatTaskStkBasePtr == (CPU_STK *)0) {
  424. *p_err = OS_ERR_STAT_STK_INVALID;
  425. return;
  426. }
  427. if (OSCfg_StatTaskStkSize < OSCfg_StkSizeMin) {
  428. *p_err = OS_ERR_STAT_STK_SIZE_INVALID;
  429. return;
  430. }
  431. if (OSCfg_StatTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) {
  432. *p_err = OS_ERR_STAT_PRIO_INVALID;
  433. return;
  434. }
  435. OSTaskCreate((OS_TCB *)&OSStatTaskTCB,
  436. (CPU_CHAR *)((void *)"uC/OS-III Stat Task"),
  437. (OS_TASK_PTR )OS_StatTask,
  438. (void *)0,
  439. (OS_PRIO )OSCfg_StatTaskPrio,
  440. (CPU_STK *)OSCfg_StatTaskStkBasePtr,
  441. (CPU_STK_SIZE)OSCfg_StatTaskStkLimit,
  442. (CPU_STK_SIZE)OSCfg_StatTaskStkSize,
  443. (OS_MSG_QTY )0,
  444. (OS_TICK )0,
  445. (void *)0,
  446. (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  447. (OS_ERR *)p_err);
  448. }
  449. #endif