heap_trace_module.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2018 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <stdint.h>
  14. #include <sdkconfig.h>
  15. #include "SEGGER_SYSVIEW.h"
  16. #include "SEGGER_RTT.h"
  17. #include "esp_app_trace.h"
  18. #include "freertos/FreeRTOS.h"
  19. #include "freertos/task.h"
  20. #include "esp_log.h"
  21. const static char *TAG = "sysview_heap_trace";
  22. #ifdef CONFIG_HEAP_TRACING_STACK_DEPTH
  23. #define CALLSTACK_SIZE CONFIG_HEAP_TRACING_STACK_DEPTH
  24. #else
  25. #define CALLSTACK_SIZE 0
  26. #endif
  27. static SEGGER_SYSVIEW_MODULE s_esp_sysview_heap_module = {
  28. .sModule = "ESP32 SystemView Heap Tracing Module",
  29. .NumEvents = 2,
  30. };
  31. static bool s_mod_registered;
  32. esp_err_t esp_sysview_heap_trace_start(uint32_t tmo)
  33. {
  34. uint32_t tmo_ticks = tmo/(1000*portTICK_PERIOD_MS);
  35. ESP_EARLY_LOGV(TAG, "%s", __func__);
  36. do {
  37. if (tmo != (uint32_t)-1) {
  38. // Currently timeout implementation is simple and has granularity of 1 OS tick,
  39. // so just count down the number of times to call vTaskDelay
  40. if (tmo_ticks-- == 0) {
  41. return ESP_ERR_TIMEOUT;
  42. }
  43. }
  44. vTaskDelay(1);
  45. } while(!SEGGER_SYSVIEW_Started());
  46. SEGGER_SYSVIEW_RegisterModule(&s_esp_sysview_heap_module);
  47. s_mod_registered = true;
  48. return ESP_OK;
  49. }
  50. esp_err_t esp_sysview_heap_trace_stop(void)
  51. {
  52. ESP_EARLY_LOGV(TAG, "%s", __func__);
  53. SEGGER_RTT_ESP32_Flush(0, ESP_APPTRACE_TMO_INFINITE);
  54. return ESP_OK;
  55. }
  56. void esp_sysview_heap_trace_alloc(const void *addr, uint32_t size, const void *callers)
  57. {
  58. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (2+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
  59. U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
  60. U32 *calls = (U32 *)callers;
  61. if (!s_mod_registered) {
  62. return;
  63. }
  64. ESP_EARLY_LOGV(TAG, "%s %p %lu", __func__, addr, size);
  65. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
  66. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, size);
  67. for (int i = 0; i < CALLSTACK_SIZE; i++) {
  68. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
  69. }
  70. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 0);
  71. }
  72. void esp_sysview_heap_trace_free(const void *addr, const void *callers)
  73. {
  74. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (1+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
  75. U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
  76. U32 *calls = (U32 *)callers;
  77. if (!s_mod_registered) {
  78. return;
  79. }
  80. ESP_EARLY_LOGV(TAG, "%s %p", __func__, addr);
  81. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
  82. for (int i = 0; i < CALLSTACK_SIZE; i++) {
  83. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
  84. }
  85. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 1);
  86. }