sysview_tracing.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* Application Trace to Host Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <inttypes.h>
  11. #include "esp_log.h"
  12. #include "freertos/FreeRTOS.h"
  13. #include "freertos/task.h"
  14. #include "driver/gptimer.h"
  15. static const char *TAG = "example";
  16. #if CONFIG_APPTRACE_SV_ENABLE
  17. #if !CONFIG_USE_CUSTOM_EVENT_ID
  18. #define SYSVIEW_EXAMPLE_SEND_EVENT_ID 0
  19. #define SYSVIEW_EXAMPLE_WAIT_EVENT_ID 1
  20. #define SYSVIEW_EXAMPLE_SEND_EVENT_START() SEGGER_SYSVIEW_OnUserStart(SYSVIEW_EXAMPLE_SEND_EVENT_ID)
  21. #define SYSVIEW_EXAMPLE_SEND_EVENT_END(_val_) SEGGER_SYSVIEW_OnUserStop(SYSVIEW_EXAMPLE_SEND_EVENT_ID)
  22. #define SYSVIEW_EXAMPLE_WAIT_EVENT_START() SEGGER_SYSVIEW_OnUserStart(SYSVIEW_EXAMPLE_WAIT_EVENT_ID)
  23. #define SYSVIEW_EXAMPLE_WAIT_EVENT_END(_val_) SEGGER_SYSVIEW_OnUserStop(SYSVIEW_EXAMPLE_WAIT_EVENT_ID)
  24. #else
  25. #define SYSVIEW_EXAMPLE_SEND_EVENT_START_ID 0
  26. #define SYSVIEW_EXAMPLE_SEND_EVENT_END_ID 1
  27. #define SYSVIEW_EXAMPLE_WAIT_EVENT_START_ID 2
  28. #define SYSVIEW_EXAMPLE_WAIT_EVENT_END_ID 3
  29. #define SYSVIEW_EXAMPLE_EVENT_MAX 4
  30. #define SYSVIEW_EXAMPLE_SEND_EVENT_START() example_sysview_event_send(SYSVIEW_EXAMPLE_SEND_EVENT_START_ID, 0)
  31. #define SYSVIEW_EXAMPLE_SEND_EVENT_END(_val_) example_sysview_event_send(SYSVIEW_EXAMPLE_SEND_EVENT_END_ID, _val_)
  32. #define SYSVIEW_EXAMPLE_WAIT_EVENT_START() example_sysview_event_send(SYSVIEW_EXAMPLE_WAIT_EVENT_START_ID, 0)
  33. #define SYSVIEW_EXAMPLE_WAIT_EVENT_END(_val_) example_sysview_event_send(SYSVIEW_EXAMPLE_WAIT_EVENT_END_ID, _val_)
  34. static void example_sysview_module_send_desc(void);
  35. static SEGGER_SYSVIEW_MODULE s_example_sysview_module = {
  36. .sModule = "example_sysview_module",
  37. .NumEvents = SYSVIEW_EXAMPLE_EVENT_MAX,
  38. .pfSendModuleDesc = example_sysview_module_send_desc,
  39. };
  40. static void example_sysview_module_send_desc(void)
  41. {
  42. SEGGER_SYSVIEW_RecordModuleDescription(&s_example_sysview_module, "Example SystemView User Module");
  43. }
  44. static void example_sysview_event_send(uint32_t id, uint32_t val)
  45. {
  46. U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_QUANTA_U32];
  47. U8 *pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
  48. pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, val); // Add the parameter to the packet
  49. SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_example_sysview_module.EventOffset + id);
  50. }
  51. #endif // !CONFIG_USE_CUSTOM_EVENT_ID
  52. #else
  53. #define SYSVIEW_EXAMPLE_SEND_EVENT_START()
  54. #define SYSVIEW_EXAMPLE_SEND_EVENT_END(_val_)
  55. #define SYSVIEW_EXAMPLE_WAIT_EVENT_START()
  56. #define SYSVIEW_EXAMPLE_WAIT_EVENT_END(_val_)
  57. #endif // CONFIG_APPTRACE_SV_ENABLE
  58. typedef struct {
  59. gptimer_handle_t gptimer;
  60. int count;
  61. TaskHandle_t thnd;
  62. uint64_t period;
  63. char task_name[32];
  64. } example_event_data_t;
  65. static bool example_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
  66. {
  67. example_event_data_t *tim_arg = (example_event_data_t *)user_ctx;
  68. bool need_yield = false;
  69. if (tim_arg->thnd != NULL) {
  70. if (tim_arg->count++ < 10) {
  71. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  72. SYSVIEW_EXAMPLE_SEND_EVENT_START();
  73. if (xTaskNotifyFromISR(tim_arg->thnd, tim_arg->count, eSetValueWithOverwrite, &xHigherPriorityTaskWoken) != pdPASS) {
  74. ESP_EARLY_LOGE(TAG, "Failed to notify task %p", tim_arg->thnd);
  75. } else {
  76. SYSVIEW_EXAMPLE_SEND_EVENT_END(tim_arg->count);
  77. if (xHigherPriorityTaskWoken == pdTRUE) {
  78. need_yield = true;
  79. }
  80. }
  81. }
  82. }
  83. return need_yield;
  84. }
  85. static void example_task(void *p)
  86. {
  87. uint32_t event_val;
  88. example_event_data_t *arg = (example_event_data_t *) p;
  89. ESP_LOGI(TAG, "%p: run task", xTaskGetCurrentTaskHandle());
  90. gptimer_alarm_config_t alarm_config = {
  91. .reload_count = 0,
  92. .alarm_count = arg->period,
  93. .flags.auto_reload_on_alarm = true,
  94. };
  95. // This task is pinned to a specific core, to the interrupt will also be install to that core
  96. gptimer_event_callbacks_t cbs = {
  97. .on_alarm = example_timer_alarm_cb,
  98. };
  99. ESP_ERROR_CHECK(gptimer_register_event_callbacks(arg->gptimer, &cbs, arg));
  100. ESP_ERROR_CHECK(gptimer_set_alarm_action(arg->gptimer, &alarm_config));
  101. ESP_ERROR_CHECK(gptimer_enable(arg->gptimer));
  102. ESP_ERROR_CHECK(gptimer_start(arg->gptimer));
  103. while (1) {
  104. SYSVIEW_EXAMPLE_WAIT_EVENT_START();
  105. xTaskNotifyWait(0, 0, &event_val, portMAX_DELAY);
  106. SYSVIEW_EXAMPLE_WAIT_EVENT_END(event_val);
  107. ESP_LOGI(TAG, "Task[%p]: received event %"PRIu32, xTaskGetCurrentTaskHandle(), event_val);
  108. }
  109. }
  110. void app_main(void)
  111. {
  112. static example_event_data_t event_data[portNUM_PROCESSORS];
  113. #if CONFIG_APPTRACE_SV_ENABLE && CONFIG_USE_CUSTOM_EVENT_ID
  114. // Currently OpenOCD does not support requesting module info from target. So do the following...
  115. // Wait untill SystemView module receives START command from host,
  116. // after that data can be sent to the host using onboard API,
  117. // so user module description does not need to be requested by OpenOCD itself.
  118. while (!SEGGER_SYSVIEW_Started()) {
  119. vTaskDelay(1);
  120. }
  121. SEGGER_SYSVIEW_RegisterModule(&s_example_sysview_module);
  122. #endif
  123. for (int i = 0; i < portNUM_PROCESSORS; i++) {
  124. gptimer_config_t timer_config = {
  125. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  126. .direction = GPTIMER_COUNT_UP,
  127. .resolution_hz = 1000000,
  128. };
  129. ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &event_data[i].gptimer));
  130. event_data[i].period = 1000000 * (i + 1);
  131. }
  132. for (int i = 0; i < portNUM_PROCESSORS; i++) {
  133. sprintf(event_data->task_name, "svtrace%d", i);
  134. xTaskCreatePinnedToCore(example_task, event_data->task_name, 4096, &event_data[i], 3, &event_data[i].thnd, i);
  135. ESP_LOGI(TAG, "Created task %p", event_data[i].thnd);
  136. }
  137. }