heap_trace_module.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include <sdkconfig.h>
  8. #include "SEGGER_SYSVIEW.h"
  9. #include "SEGGER_RTT.h"
  10. #include "esp_app_trace.h"
  11. #include "freertos/FreeRTOS.h"
  12. #include "freertos/task.h"
  13. #include "esp_log.h"
  14. const static char *TAG = "sysview_heap_trace";
  15. #ifdef CONFIG_HEAP_TRACING_STACK_DEPTH
  16. #define CALLSTACK_SIZE CONFIG_HEAP_TRACING_STACK_DEPTH
  17. #else
  18. #define CALLSTACK_SIZE 0
  19. #endif
  20. static SEGGER_SYSVIEW_MODULE s_esp_sysview_heap_module = {
  21. .sModule = "ESP32 SystemView Heap Tracing Module",
  22. .NumEvents = 2,
  23. };
  24. static bool s_mod_registered;
  25. esp_err_t esp_sysview_heap_trace_start(uint32_t tmo)
  26. {
  27. uint32_t tmo_ticks = tmo/(1000*portTICK_PERIOD_MS);
  28. ESP_EARLY_LOGV(TAG, "%s", __func__);
  29. do {
  30. if (tmo != (uint32_t)-1) {
  31. // Currently timeout implementation is simple and has granularity of 1 OS tick,
  32. // so just count down the number of times to call vTaskDelay
  33. if (tmo_ticks-- == 0) {
  34. return ESP_ERR_TIMEOUT;
  35. }
  36. }
  37. vTaskDelay(1);
  38. } while(!SEGGER_SYSVIEW_Started());
  39. SEGGER_SYSVIEW_RegisterModule(&s_esp_sysview_heap_module);
  40. s_mod_registered = true;
  41. return ESP_OK;
  42. }
  43. esp_err_t esp_sysview_heap_trace_stop(void)
  44. {
  45. ESP_EARLY_LOGV(TAG, "%s", __func__);
  46. SEGGER_RTT_ESP_Flush(0, ESP_APPTRACE_TMO_INFINITE);
  47. return ESP_OK;
  48. }
  49. void esp_sysview_heap_trace_alloc(const void *addr, uint32_t size, const void *callers)
  50. {
  51. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (2+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
  52. U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
  53. U32 *calls = (U32 *)callers;
  54. if (!s_mod_registered) {
  55. return;
  56. }
  57. ESP_EARLY_LOGV(TAG, "%s %p %lu", __func__, addr, size);
  58. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
  59. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, size);
  60. for (int i = 0; i < CALLSTACK_SIZE; i++) {
  61. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
  62. }
  63. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 0);
  64. }
  65. void esp_sysview_heap_trace_free(const void *addr, const void *callers)
  66. {
  67. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (1+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
  68. U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
  69. U32 *calls = (U32 *)callers;
  70. if (!s_mod_registered) {
  71. return;
  72. }
  73. ESP_EARLY_LOGV(TAG, "%s %p", __func__, addr);
  74. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
  75. for (int i = 0; i < CALLSTACK_SIZE; i++) {
  76. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
  77. }
  78. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 1);
  79. }