2 ******************************************************************************
3 * @addtogroup OpenPilotSystem OpenPilot System
5 * @addtogroup OpenPilotLibraries OpenPilot System Libraries
7 * @file pios_task_monitor.h
8 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
9 * @brief Task monitoring functions
10 * @see The GNU Public License (GPL) Version 3
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #ifdef PIOS_INCLUDE_TASK_MONITOR
33 static xSemaphoreHandle mLock
;
34 static xTaskHandle
*mTaskHandles
;
35 static uint32_t mLastMonitorTime
;
36 static uint32_t mLastIdleMonitorTime
;
37 static uint16_t mMaxTasks
;
40 * Initialize the Task Monitor
42 int32_t PIOS_TASK_MONITOR_Initialize(uint16_t max_tasks
)
44 mLock
= xSemaphoreCreateRecursiveMutex();
49 mTaskHandles
= (xTaskHandle
*)pios_malloc(max_tasks
* sizeof(xTaskHandle
));
53 memset(mTaskHandles
, 0, max_tasks
* sizeof(xTaskHandle
));
55 mMaxTasks
= max_tasks
;
56 #if (configGENERATE_RUN_TIME_STATS == 1)
57 mLastMonitorTime
= portGET_RUN_TIME_COUNTER_VALUE();
58 mLastIdleMonitorTime
= portGET_RUN_TIME_COUNTER_VALUE();
61 mLastIdleMonitorTime
= 0;
67 * Register a task handle
69 int32_t PIOS_TASK_MONITOR_RegisterTask(uint16_t task_id
, xTaskHandle handle
)
71 if (mTaskHandles
&& task_id
< mMaxTasks
) {
72 xSemaphoreTakeRecursive(mLock
, portMAX_DELAY
);
73 mTaskHandles
[task_id
] = handle
;
74 xSemaphoreGiveRecursive(mLock
);
82 * Unregister a task handle
84 int32_t PIOS_TASK_MONITOR_UnregisterTask(uint16_t task_id
)
86 if (mTaskHandles
&& task_id
< mMaxTasks
) {
87 xSemaphoreTakeRecursive(mLock
, portMAX_DELAY
);
88 mTaskHandles
[task_id
] = 0;
89 xSemaphoreGiveRecursive(mLock
);
97 * Query if a task is running
99 bool PIOS_TASK_MONITOR_IsRunning(uint16_t task_id
)
101 return mTaskHandles
&& task_id
<= mMaxTasks
&& mTaskHandles
[task_id
];
105 * Tell the caller the status of all tasks via a task-by-task callback
107 void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback
, void *context
)
113 xSemaphoreTakeRecursive(mLock
, portMAX_DELAY
);
115 #if (configGENERATE_RUN_TIME_STATS == 1)
116 /* Calculate the amount of elapsed run time between the last time we
117 * measured and now. Scale so that we can convert task run times
118 * directly to percentages. */
119 uint32_t currentTime
= portGET_RUN_TIME_COUNTER_VALUE();
120 /* avoid divide-by-zero if the interval is too small */
121 uint32_t deltaTime
= ((currentTime
- mLastMonitorTime
) / 100) ? : 1;
122 mLastMonitorTime
= currentTime
;
124 /* Update all task information */
125 for (uint16_t n
= 0; n
< mMaxTasks
; ++n
) {
126 struct pios_task_info info
;
127 if (mTaskHandles
[n
]) {
128 info
.is_running
= true;
129 #if defined(ARCH_POSIX) || defined(ARCH_WIN32)
130 info
.stack_remaining
= 10000;
132 info
.stack_remaining
= uxTaskGetStackHighWaterMark(mTaskHandles
[n
]) * 4;
134 #if (configGENERATE_RUN_TIME_STATS == 1)
135 /* Generate run time percentage stats */
136 info
.running_time_percentage
= uxTaskGetRunTime(mTaskHandles
[n
]) / deltaTime
;
138 info
.running_time_percentage
= 0;
141 info
.is_running
= false;
142 info
.stack_remaining
= 0;
143 info
.running_time_percentage
= 0;
145 /* Pass the information for this task back to the caller */
146 callback(n
, &info
, context
);
149 xSemaphoreGiveRecursive(mLock
);
152 uint8_t PIOS_TASK_MONITOR_GetIdlePercentage()
154 #if defined(ARCH_POSIX) || defined(ARCH_WIN32)
157 #elif (configGENERATE_RUN_TIME_STATS == 1)
158 xSemaphoreTakeRecursive(mLock
, portMAX_DELAY
);
160 uint32_t currentTime
= portGET_RUN_TIME_COUNTER_VALUE();
162 /* avoid divide-by-zero if the interval is too small */
163 uint32_t deltaTime
= ((currentTime
- mLastIdleMonitorTime
) / 100) ? : 1;
164 mLastIdleMonitorTime
= currentTime
;
165 uint8_t running_time_percentage
= 0;
167 /* Generate idle time percentage stats */
168 running_time_percentage
= uxTaskGetRunTime(xTaskGetIdleTaskHandle()) / deltaTime
;
169 xSemaphoreGiveRecursive(mLock
);
170 return running_time_percentage
;
179 #endif // PIOS_INCLUDE_TASK_MONITOR