|
@@ -0,0 +1,183 @@
|
|
|
+#include "profiler.h"
|
|
|
+#include "profiler_port.h"
|
|
|
+#include <stdint.h>
|
|
|
+
|
|
|
+typedef struct
|
|
|
+{
|
|
|
+ uint8_t level;
|
|
|
+ uint32_t counter;
|
|
|
+} ProfilerEvent;
|
|
|
+
|
|
|
+uint32_t ProfilerDurationTicks;
|
|
|
+
|
|
|
+#if PROFILER_TYPE == PROFILER_TYPE_STATISTICS
|
|
|
+
|
|
|
+uint32_t ProfilerTime[PROFILER_MAX_LEVEL + 1];
|
|
|
+
|
|
|
+uint32_t ProfilerCounts[PROFILER_MAX_LEVEL + 1];
|
|
|
+
|
|
|
+uint8_t ProfilerStack[PROFILER_MAX_LEVEL + 1];
|
|
|
+
|
|
|
+uint8_t ProfilerSp;
|
|
|
+
|
|
|
+ProfilerEvent ProfilerBuffer;
|
|
|
+
|
|
|
+uint32_t ProfilerStartTicks = 0;
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+uint8_t ProfilerEnable = 0;
|
|
|
+
|
|
|
+uint8_t ProfilerRunning = 0;
|
|
|
+
|
|
|
+int8_t ProfilerError = 0;
|
|
|
+
|
|
|
+void profiler_init()
|
|
|
+{
|
|
|
+ ProfilerEnable = 0;
|
|
|
+ ProfilerError = 0;
|
|
|
+
|
|
|
+ ProfilerDurationTicks = PROFILER_CLOCK * (float)PROFILER_DURATION;
|
|
|
+
|
|
|
+#if PROFILER_TYPE == PROFILER_TYPE_STATISTICS
|
|
|
+ for (int i = 0; i < PROFILER_MAX_LEVEL; i++)
|
|
|
+ {
|
|
|
+ ProfilerTime[i] = 0;
|
|
|
+ ProfilerCounts[i] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ ProfilerSp = 0;
|
|
|
+#elif PROFILER_TYPE == PROFILER_TYPE_TRACE
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+ profiler_init_hw();
|
|
|
+}
|
|
|
+
|
|
|
+void profiler_enable()
|
|
|
+{
|
|
|
+ ProfilerEnable = 1;
|
|
|
+
|
|
|
+ profiler_enable_hw();
|
|
|
+}
|
|
|
+
|
|
|
+void profiler_bg()
|
|
|
+{
|
|
|
+#if PROFILER_TYPE == PROFILER_TYPE_STATISTICS
|
|
|
+ if (!ProfilerEnable)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ PROFILER_DISABLE_IRQ();
|
|
|
+ uint32_t ticks = profiler_getTicks();
|
|
|
+ if (!ProfilerRunning)
|
|
|
+ {
|
|
|
+ /* If counter overflow, return directly */
|
|
|
+ if (ticks + 2 * ProfilerDurationTicks > ticks)
|
|
|
+ {
|
|
|
+ ProfilerSp = 0;
|
|
|
+ ProfilerStack[ProfilerSp] = 0;
|
|
|
+ ProfilerSp += 1;
|
|
|
+ ProfilerCounts[0] += 1;
|
|
|
+ ProfilerBuffer.counter = ticks;
|
|
|
+ ProfilerBuffer.level = 0;
|
|
|
+ ProfilerStartTicks = ticks;
|
|
|
+ ProfilerRunning = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ uint32_t ticks = profiler_getTicks();
|
|
|
+ int32_t delta = ticks - ProfilerBuffer.counter;
|
|
|
+ if(delta<0)
|
|
|
+ {
|
|
|
+ delta+=72000;
|
|
|
+ }
|
|
|
+ ProfilerTime[0] += delta;
|
|
|
+ ProfilerBuffer.counter = ticks;
|
|
|
+ ProfilerBuffer.level = 0;
|
|
|
+ if (ticks > ProfilerStartTicks + ProfilerDurationTicks)
|
|
|
+ {
|
|
|
+ ProfilerRunning = 0;
|
|
|
+ ProfilerEnable = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ProfilerCounts[0] += 1;
|
|
|
+ ProfilerBuffer.counter = ticks;
|
|
|
+ ProfilerBuffer.level = 0;
|
|
|
+ }
|
|
|
+ if (ProfilerSp != 1)
|
|
|
+ {
|
|
|
+ ProfilerError = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ PROFILER_ENABLE_IRQ();
|
|
|
+ }
|
|
|
+#elif PROFILER_TYPE == PROFILER_TYPE_TRACE
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void profiler_start(uint8_t lv)
|
|
|
+{
|
|
|
+#if PROFILER_TYPE == PROFILER_TYPE_STATISTICS
|
|
|
+ if (!ProfilerRunning)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (lv <= 0 || lv > PROFILER_MAX_LEVEL)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ PROFILER_DISABLE_IRQ();
|
|
|
+ uint32_t ticks = profiler_getTicks();
|
|
|
+ int32_t delta = ticks - ProfilerBuffer.counter;
|
|
|
+ if(delta<0)
|
|
|
+ {
|
|
|
+ delta+=72000;
|
|
|
+ }
|
|
|
+ ProfilerTime[ProfilerStack[ProfilerSp - 1]] += delta;
|
|
|
+ ProfilerCounts[lv] += 1;
|
|
|
+ ProfilerStack[ProfilerSp] = lv;
|
|
|
+ ProfilerSp += 1;
|
|
|
+ ProfilerBuffer.counter = ticks;
|
|
|
+ ProfilerBuffer.level = lv;
|
|
|
+ PROFILER_ENABLE_IRQ();
|
|
|
+
|
|
|
+#elif PROFILER_TYPE == PROFILER_TYPE_TRACE
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void profiler_end(uint8_t lv)
|
|
|
+{
|
|
|
+#if PROFILER_TYPE == PROFILER_TYPE_STATISTICS
|
|
|
+ if (!ProfilerRunning)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (lv <= 0 || lv > PROFILER_MAX_LEVEL)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ PROFILER_DISABLE_IRQ();
|
|
|
+ uint32_t ticks = profiler_getTicks();
|
|
|
+ int32_t delta = ticks - ProfilerBuffer.counter;
|
|
|
+ if(delta<0)
|
|
|
+ {
|
|
|
+ delta+=72000;
|
|
|
+ }
|
|
|
+ ProfilerTime[ProfilerStack[ProfilerSp - 1]] += delta;
|
|
|
+ ProfilerSp -= 1;
|
|
|
+ ProfilerBuffer.counter = ticks;
|
|
|
+ ProfilerBuffer.level = lv;
|
|
|
+ PROFILER_ENABLE_IRQ();
|
|
|
+#elif PROFILER_TYPE == PROFILER_TYPE_TRACE
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|