add dump_threads diagnostics function

This commit is contained in:
Samuel Sadok
2020-11-03 19:42:32 +01:00
parent 80f648fa5c
commit a1ac01e430
6 changed files with 84 additions and 32 deletions
+17 -11
View File
@@ -177,20 +177,26 @@ void vApplicationIdleHook(void) {
if (odrv.system_stats_.fully_booted) {
odrv.system_stats_.uptime = xTaskGetTickCount();
odrv.system_stats_.min_heap_space = xPortGetMinimumEverFreeHeapSize();
uint32_t min_stack_space[AXIS_COUNT];
std::transform(axes.begin(), axes.end(), std::begin(min_stack_space), [](auto& axis) { return uxTaskGetStackHighWaterMark(axis.thread_id_) * sizeof(StackType_t); });
odrv.system_stats_.min_stack_space_axis = *std::min_element(std::begin(min_stack_space), std::end(min_stack_space));
odrv.system_stats_.min_stack_space_usb = uxTaskGetStackHighWaterMark(usb_thread) * sizeof(StackType_t);
odrv.system_stats_.min_stack_space_uart = uxTaskGetStackHighWaterMark(uart_thread) * sizeof(StackType_t);
odrv.system_stats_.min_stack_space_startup = uxTaskGetStackHighWaterMark(defaultTaskHandle) * sizeof(StackType_t);
odrv.system_stats_.min_stack_space_can = uxTaskGetStackHighWaterMark(odCAN->thread_id_) * sizeof(StackType_t);
odrv.system_stats_.max_stack_usage_axis = axes[0].stack_size_ - *std::min_element(std::begin(min_stack_space), std::end(min_stack_space));
odrv.system_stats_.max_stack_usage_usb = stack_size_usb_thread - uxTaskGetStackHighWaterMark(usb_thread) * sizeof(StackType_t);
odrv.system_stats_.max_stack_usage_uart = stack_size_uart_thread - uxTaskGetStackHighWaterMark(uart_thread) * sizeof(StackType_t);
odrv.system_stats_.max_stack_usage_startup = stack_size_default_task - uxTaskGetStackHighWaterMark(defaultTaskHandle) * sizeof(StackType_t);
odrv.system_stats_.max_stack_usage_can = odCAN->stack_size_ - uxTaskGetStackHighWaterMark(odCAN->thread_id_) * sizeof(StackType_t);
// Actual usage, in bytes, so we don't have to math
odrv.system_stats_.stack_usage_axis = axes[0].stack_size_ - odrv.system_stats_.min_stack_space_axis;
odrv.system_stats_.stack_usage_usb = stack_size_usb_thread - odrv.system_stats_.min_stack_space_usb;
odrv.system_stats_.stack_usage_uart = stack_size_uart_thread - odrv.system_stats_.min_stack_space_uart;
odrv.system_stats_.stack_usage_startup = stack_size_default_task - odrv.system_stats_.min_stack_space_startup;
odrv.system_stats_.stack_usage_can = odCAN->stack_size_ - odrv.system_stats_.min_stack_space_can;
odrv.system_stats_.stack_size_axis = axes[0].stack_size_;
odrv.system_stats_.stack_size_usb = stack_size_usb_thread;
odrv.system_stats_.stack_size_uart = stack_size_uart_thread;
odrv.system_stats_.stack_size_startup = stack_size_default_task;
odrv.system_stats_.stack_size_can = odCAN->stack_size_;
odrv.system_stats_.prio_axis = osThreadGetPriority(axes[0].thread_id_);
odrv.system_stats_.prio_usb = osThreadGetPriority(usb_thread);
odrv.system_stats_.prio_uart = osThreadGetPriority(uart_thread);
odrv.system_stats_.prio_startup = osThreadGetPriority(defaultTaskHandle);
odrv.system_stats_.prio_can = osThreadGetPriority(odCAN->thread_id_);
}
}
+16 -10
View File
@@ -29,17 +29,23 @@ typedef struct {
bool fully_booted;
uint32_t uptime; // [ms]
uint32_t min_heap_space; // FreeRTOS heap [Bytes]
uint32_t min_stack_space_axis; // minimum remaining space since startup [Bytes]
uint32_t min_stack_space_usb;
uint32_t min_stack_space_uart;
uint32_t min_stack_space_startup;
uint32_t min_stack_space_can;
uint32_t max_stack_usage_axis; // minimum remaining space since startup [Bytes]
uint32_t max_stack_usage_usb;
uint32_t max_stack_usage_uart;
uint32_t max_stack_usage_startup;
uint32_t max_stack_usage_can;
uint32_t stack_usage_axis;
uint32_t stack_usage_usb;
uint32_t stack_usage_uart;
uint32_t stack_usage_startup;
uint32_t stack_usage_can;
uint32_t stack_size_axis;
uint32_t stack_size_usb;
uint32_t stack_size_uart;
uint32_t stack_size_startup;
uint32_t stack_size_can;
int32_t prio_axis;
int32_t prio_usb;
int32_t prio_uart;
int32_t prio_startup;
int32_t prio_can;
USBStats_t& usb = usb_stats_;
I2CStats_t& i2c = i2c_stats_;
+15 -10
View File
@@ -126,16 +126,21 @@ interfaces:
attributes:
uptime: readonly uint32
min_heap_space: readonly uint32
min_stack_space_axis: readonly uint32
min_stack_space_usb: readonly uint32
min_stack_space_uart: readonly uint32
min_stack_space_can: readonly uint32
min_stack_space_startup: readonly uint32
stack_usage_axis: readonly uint32
stack_usage_usb: readonly uint32
stack_usage_uart: readonly uint32
stack_usage_startup: readonly uint32
stack_usage_can: readonly uint32
max_stack_usage_axis: readonly uint32
max_stack_usage_usb: readonly uint32
max_stack_usage_uart: readonly uint32
max_stack_usage_can: readonly uint32
max_stack_usage_startup: readonly uint32
stack_size_axis: readonly uint32
stack_size_usb: readonly uint32
stack_size_uart: readonly uint32
stack_size_startup: readonly uint32
stack_size_can: readonly uint32
prio_axis: readonly int32
prio_usb: readonly int32
prio_uart: readonly int32
prio_startup: readonly int32
prio_can: readonly int32
usb:
c_is_class: False
attributes:
+16 -1
View File
@@ -1,5 +1,5 @@
Most information in this file can be reproduced by running `dump_interrupts(odrv0)` and `dump_dma(odrv0)` in `odrivetool`.
Most information in this file can be reproduced by running `dump_interrupts(odrv0)`, `dump_dma(odrv0)` and `dump_threads(odrv0)` in `odrivetool` (minor manual postprocessing was applied to the output of those functions).
Take this info with a grain of salt as we might forget to update it from time to time. When in doubt check the file history.
@@ -55,3 +55,18 @@ Take this info with a grain of salt as we might forget to update it from time to
| DMA1_Stream5 | 2 | 0 (SPI3_TX) | SPI |
| DMA2_Stream0 | 0 | 0 (ADC1) | freerunning ADC |
## Threads
- lowest priority: -3
- highest priority: 3
| Name | Stack Size [B] | Prio |
|---------|----------------|------|
| axis0 | 2048 | 3 |
| axis1 | 2048 | 2 |
| can | 1024 | 0 |
| startup | 2048 | 0 |
| uart | 4096 | 0 |
| usb | 4096 | 0 |
+1
View File
@@ -86,6 +86,7 @@ def launch_shell(args, logger, app_shutdown_token):
'dump_errors': dump_errors,
'oscilloscope_dump': oscilloscope_dump,
'dump_interrupts': dump_interrupts,
'dump_threads': dump_threads,
'dump_dma': dump_dma,
'dump_timing': dump_timing,
'BulkCapture': BulkCapture,
+19
View File
@@ -487,6 +487,25 @@ def dump_interrupts(odrv):
" *" if (status & 0x80000000) else " ",
str((status >> 8) & 0x7fffff).rjust(7)))
def dump_threads(odrv):
prefixes = ["max_stack_usage_", "stack_size_", "prio_"]
keys = [k[len(prefix):] for k in dir(odrv.system_stats) for prefix in prefixes if k.startswith(prefix)]
good_keys = set([k for k in set(keys) if keys.count(k) == len(prefixes)])
if len(good_keys) > len(set(keys)):
print("Warning: incomplete thread information for threads {}".format(set(keys) - good_keys))
print("| Name | Stack Size [B] | Max Ever Stack Usage [B] | Prio |")
print("|---------|----------------|--------------------------|------|")
for k in sorted(good_keys):
sz = getattr(odrv.system_stats, "stack_size_" + k)
use = getattr(odrv.system_stats, "max_stack_usage_" + k)
print("| {} | {} | {} | {} |".format(
k.ljust(7),
str(sz).rjust(14),
"{} ({:.1f}%)".format(use, use / sz * 100).rjust(24),
str(getattr(odrv.system_stats, "prio_" + k)).rjust(4)
))
def dump_dma(odrv):
if odrv.hw_version_major == 3: