]> granicus.if.org Git - esp-idf/commitdiff
sys_view: Adds heap & log tracing example
authorAlexey Gerenkov <alexey@espressif.com>
Wed, 12 Dec 2018 17:44:32 +0000 (20:44 +0300)
committerAlexey Gerenkov <alexey@espressif.com>
Mon, 1 Apr 2019 16:31:45 +0000 (19:31 +0300)
examples/system/sysview_tracing/sdkconfig.defaults
examples/system/sysview_tracing_heap_log/CMakeLists.txt [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/Makefile [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/README.md [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/SYSVIEW_FreeRTOS.txt [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/gdbinit [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/main/CMakeLists.txt [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/main/component.mk [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c [new file with mode: 0644]
examples/system/sysview_tracing_heap_log/sdkconfig.defaults [new file with mode: 0644]

index d27d2611cdddb4d81d95ad183758afd4ae592cb4..21dd3c78f277a42b58421d30739eb5123cc75408 100644 (file)
@@ -1,5 +1,7 @@
+# Enable single core mode by default
 CONFIG_MEMMAP_SMP=n
 CONFIG_FREERTOS_UNICORE=y
+# 1ms tick period
 CONFIG_FREERTOS_HZ=1000
 # Enable application tracing by default
 CONFIG_ESP32_APPTRACE_DEST_TRAX=y
diff --git a/examples/system/sysview_tracing_heap_log/CMakeLists.txt b/examples/system/sysview_tracing_heap_log/CMakeLists.txt
new file mode 100644 (file)
index 0000000..39a10b5
--- /dev/null
@@ -0,0 +1,6 @@
+# The following lines of boilerplate have to be in your project's CMakeLists
+# in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(sysview_tracing_heap_log)
diff --git a/examples/system/sysview_tracing_heap_log/Makefile b/examples/system/sysview_tracing_heap_log/Makefile
new file mode 100644 (file)
index 0000000..d14ffd8
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := sysview_tracing_heap_log
+
+include $(IDF_PATH)/make/project.mk
+
diff --git a/examples/system/sysview_tracing_heap_log/README.md b/examples/system/sysview_tracing_heap_log/README.md
new file mode 100644 (file)
index 0000000..8d39311
--- /dev/null
@@ -0,0 +1,164 @@
+# SystemView Heap and Log Tracing Example
+
+Heap memory leaking is quite widespread software bug. IDF provides [heap tracing feature](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/heap_debug.html#heap-tracing) which allows to collect information related to heap operations (allocations/deallocations) and detect potential memory leaks. This feature can be used in two modes: standalone and host-based. In standalone mode collected data are kept on-board, so this mode is limited by avaialable memory in the system. Host-based mode does not have such limitation because collected data are sent to the host and can be analysed there using special tools. One of such tool is SEGGER SystemView. For description of [SystemView tracing feature](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/app_trace.html#system-behaviour-analysis-with-segger-systemview) please refer to **ESP32 Programming Guide**, section **Application Level Tracing library**. SystemView is also can be useful to show log message sent from the target.
+This example shows how to use this tool and IDF's scripts for host-based heap and log tracing analysis.
+
+Consider the following situation. User program have two tasks. One task allocates memory and puts obtained addresses into the queue. Another task waits on that queue, reads sent pointers and frees memory. The first task queues only part of the pointers so some of the allocated blocks are not freed and become leaked. Both tasks uses IDF's logging API to report their actions. This example uses IDF's heap tracing module to record allocations and deallocations to detect memory leaks. Both heap tracing records and log mesages are redirected to the host.
+
+## How to use example
+
+### Hardware and tools required
+
+This example does not require any special hardware, and can be run on any common development board.
+This example requires the following tools:
+1. [OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#run-openocd).
+NOTE: In order to run this example you need OpenOCD version `v0.10.0-esp32-20190313` or later.
+
+2. [GDB](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#setup-toolchain) can be used to start and/or stop tracing automatically. To do this you need to prepare special GDB command file. Having provided with `gdbinit` file from the example project directory GDB will connect to the target, reset it, start and stop tracing automatically.
+when program hits breakpoint at `heap_trace_start`. Trace data will be saved to `/tmp/hesp_log.svdat`. Tracing will be stopped when program hits breakpoint at `heap_trace_stop`.
+
+3. [SEGGER SystemView tool](https://www.segger.com/products/development-tools/systemview/). By default SystemView shows only numeric values of IDs and parameters for IDF's heap messages in `Events` view. To make them pretty-looking you need to copy `SYSVIEW_FreeRTOS.txt` from the project's root directory to SystemView installation one.
+
+### Configure the project
+
+If using Make based build system, run `make menuconfig` and set serial port under Serial Flasher Options.
+
+If using CMake based build system, no configuration is required.
+
+### Build and flash
+
+Build the project and flash it to the board, then run monitor tool to view serial output:
+
+```
+make -j4 flash monitor
+```
+
+Or, for CMake based build system (replace PORT with serial port name):
+
+```
+idf.py -p PORT flash monitor
+```
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+### Collect And View Trace Data
+
+To run the example and collect trace data:
+
+1. Run GDB using the following command from the project root directory:
+
+    ```
+    xtensa-esp32-elf-gdb -x gdbinit build/sysview_tracing_heap_log.elf
+    ```
+2. When program stops at `heap_trace_stop`  quit GDB.
+
+3. Open trace data file in SystemView tool.
+
+4. Now you can inspect all collected events. Log messages are shown in `Terminal` view.
+
+5. You can filter out API related and heap events by right-clicking on any item in `Events` view and select `Show APIs only`.
+
+### Auto-detect Heap Leaks
+
+Since SystemView tool is mostly intended for OS level analysis. It allows just to inspect custom events' timestamps and parameters. So it can require some efforts to analyse heap operations flow. IDF provides special script to make the life a bit more easy. This script parses SystemView trace file sand reports detected memory leaks. The script also prints found log messages. To run it type the following from the project root directory:
+
+```
+$IDF_PATH/tools/esp_app_trace/sysviewtrace_proc.py -p /tmp/heap_log.svdat build/sysview_tracing_heap_log.elf
+```
+
+Below is the sample scripts output.
+
+```
+Parse trace from '/tmp/heap_log.svdat'...
+Stop parsing trace. (Timeout 0.000000 sec while reading 1 bytes!)
+Process events from '['/tmp/heap_log.svdat']'...
+[0.002244575] HEAP: Allocated 1 bytes @ 0x3ffaffd8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.002258425] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.002405000] LOG: I (264) example: Task[0x3ffb6cf4]: allocated 2 bytes @ 0x3ffaffe0
+[0.002553425] LOG: I (265) example: Task[0x3ffb7660]: free memory @ 0x3ffaffe0
+[0.002563725] HEAP: Freed bytes @ 0x3ffaffe0 from task "free" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.002782950] HEAP: Freed bytes @ 0x3ffb40b8 from task "main" on core 0 by:
+/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
+/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
+
+[0.002798700] HEAP: Freed bytes @ 0x3ffb50bc from task "main" on core 0 by:
+/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
+/home/user/projects/esp/esp-idf/components/freertos/tasks.c:4590
+
+[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.102449800] HEAP: Allocated 4 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.102536400] LOG: I (365) example: Task[0x3ffb6cf4]: allocated 4 bytes @ 0x3ffaffe8
+[0.102655625] LOG: I (365) example: Task[0x3ffb7660]: free memory @ 0x3ffaffe8
+[0.102666150] HEAP: Freed bytes @ 0x3ffaffe8 from task "free" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.202451725] HEAP: Allocated 6 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.202538225] LOG: I (465) example: Task[0x3ffb6cf4]: allocated 6 bytes @ 0x3ffafff0
+[0.202654475] LOG: I (465) example: Task[0x3ffb7660]: free memory @ 0x3ffafff0
+[0.202667075] HEAP: Freed bytes @ 0x3ffafff0 from task "free" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.302451475] HEAP: Allocated 8 bytes @ 0x3ffb40b8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:48
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.302540900] LOG: I (565) example: Task[0x3ffb6cf4]: allocated 8 bytes @ 0x3ffb40b8
+[0.302657050] LOG: I (565) example: Task[0x3ffb7660]: free memory @ 0x3ffb40b8
+[0.302667500] HEAP: Freed bytes @ 0x3ffb40b8 from task "free" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:31 (discriminator 9)
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+Processing completed.
+Processed 1027 events
+=============== LOG TRACE REPORT ===============
+Processed 8 log messages.
+=============== HEAP TRACE REPORT ===============
+Processed 14 heap events.
+[0.002244575] HEAP: Allocated 1 bytes @ 0x3ffaffd8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.102436025] HEAP: Allocated 2 bytes @ 0x3ffaffe0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.202436200] HEAP: Allocated 3 bytes @ 0x3ffaffe8 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+[0.302436000] HEAP: Allocated 4 bytes @ 0x3ffafff0 from task "alloc" on core 0 by:
+/home/user/projects/esp/esp-idf/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c:47
+/home/user/projects/esp/esp-idf/components/freertos/port.c:355 (discriminator 1)
+
+Found 10 leaked bytes in 4 blocks.
+```
\ No newline at end of file
diff --git a/examples/system/sysview_tracing_heap_log/SYSVIEW_FreeRTOS.txt b/examples/system/sysview_tracing_heap_log/SYSVIEW_FreeRTOS.txt
new file mode 100644 (file)
index 0000000..8162a5d
--- /dev/null
@@ -0,0 +1,107 @@
+128        vTaskAllocateMPURegions             xTask=%t pxRegions=%u
+33        vTaskDelete                         xTaskToDelete=%t
+34        vTaskDelay                          xTicksToDelay=%u
+35        vTaskDelayUntil                     
+129        uxTaskPriorityGet                   xTask=%t
+56        uxTaskPriorityGetFromISR            xTask=%t
+130        eTaskGetState                       xTask=%t
+55        vTaskPrioritySet                    xTask=%t uxNewPriority=%u
+36        vTaskSuspend                        xTaskToSuspend=%t
+40        vTaskResume                         xTaskToResume=%t
+43        xTaskResumeFromISR                  xTaskToResume=%t
+131        vTaskStartScheduler                  
+132        vTaskEndScheduler                    
+133        vTaskSuspendAll                      
+134        xTaskResumeAll                       
+135        xTaskGetTickCount                    
+57        xTaskGetTickCountFromISR             
+136        uxTaskGetNumberOfTasks               
+137        pcTaskGetTaskName                   xTaskToQuery=%t
+138        uxTaskGetStackHighWaterMark         xTask=%t
+139        vTaskSetApplicationTaskTag          xTask=%t pxHookFunction=%u
+140        xTaskGetApplicationTaskTag          xTask=%t
+141        vTaskSetThreadLocalStoragePointer   xTaskToSet=%T xIndex=%u pvValue=%u
+142        pvTaskGetThreadLocalStoragePointer  xTaskToQuery=%T xIndex=%u
+143        xTaskCallApplicationTaskHook        xTask=%T pvParameter=%u
+144        xTaskGetIdleTaskHandle               
+145        uxTaskGetSystemState                pxTaskStatusArray=%u uxArraySize=%u pulTotalRunTime=%u
+146        vTaskList                           pcWriteBuffer=%u
+147        vTaskGetRunTimeStats                pcWriteBuffer=%u
+44        xTaskGenericNotify                  xTaskToNotify=%t ulValue=%u eAction=%u pulPreviousNotificationValue=%u
+45        xTaskGenericNotifyFromISR           xTaskToNotify=%t ulValue=%u eAction=%u pulPreviousNotificationValue=%u pxHigherPriorityTaskWoken=%u
+46        xTaskNotifyWait                     ulBitsToClearOnEntry=%u ulBitsToClearOnExit=%u pulNotificationValue=%u xTicksToWait=%u
+38        vTaskNotifyGiveFromISR              xTaskToNotify=%t pxHigherPriorityTaskWoken=%u
+37        ulTaskNotifyTake                    xClearCountOnExit=%u xTicksToWait=%u
+148        xTaskNotifyStateClear               xTask=%t
+149        xTaskGetCurrentTaskHandle            
+150        vTaskSetTimeOutState                pxTimeOut=%u
+151        xTaskCheckForTimeOut                pxTimeOut=%u pxTicksToWait=%u
+152        vTaskMissedYield                     
+153        xTaskGetSchedulerState               
+39        vTaskPriorityInherit                pxMutexHolder=%p
+42        xTaskPriorityDisinherit             pxMutexHolder=%p
+154        xTaskGenericCreate                  pxTaskCode=%u pcName=%u usStackDepth=%u pvParameters=%u uxPriority=%u pxCreatedTask=%u puxStackBuffer=%u xRegions=%u
+155        uxTaskGetTaskNumber                 xTask=%u
+156        vTaskSetTaskNumber                  xTask=%u uxHandle=%u
+41        vTaskStepTick                       xTicksToJump=%u
+157        eTaskConfirmSleepModeStatus          
+158        xTimerCreate                        pcTimerName=%u xTimerPeriodInTicks=%u uxAutoReload=%u pvTimerID=%u pxCallbackFunction=%u
+159        pvTimerGetTimerID                   xTimer=%u
+160        vTimerSetTimerID                    xTimer=%u pvNewID=%u
+161        xTimerIsTimerActive                 xTimer=%u
+162        xTimerGetTimerDaemonTaskHandle       
+163        xTimerPendFunctionCallFromISR       xFunctionToPend=%u pvParameter1=%u ulParameter2=%u pxHigherPriorityTaskWoken=%u
+164        xTimerPendFunctionCall              xFunctionToPend=%u pvParameter1=%u ulParameter2=%u xTicksToWait=%u
+165        pcTimerGetTimerName                 xTimer=%u
+166        xTimerCreateTimerTask                
+167        xTimerGenericCommand                xTimer=%u xCommandID=%u xOptionalValue=%u pxHigherPriorityTaskWoken=%u xTicksToWait=%u
+53        xQueueGenericSend                   xQueue=%I pvItemToQueue=%p xTicksToWait=%u xCopyPosition=%u
+50        xQueuePeekFromISR                   xQueue=%I pvBuffer=%p
+49        xQueueGenericReceive                xQueue=%I pvBuffer=%p xTicksToWait=%u xJustPeek=%u
+168        uxQueueMessagesWaiting              xQueue=%I
+169        uxQueueSpacesAvailable              xQueue=%I
+48        vQueueDelete                        xQueue=%I
+54        xQueueGenericSendFromISR            xQueue=%I pvItemToQueue=%p pxHigherPriorityTaskWoken=%u xCopyPosition=%u
+61        xQueueGiveFromISR                   xQueue=%I pxHigherPriorityTaskWoken=%u
+51        xQueueReceiveFromISR                xQueue=%I pvBuffer=%p pxHigherPriorityTaskWoken=%u
+62        xQueueIsQueueEmptyFromISR           xQueue=%I
+63       xQueueIsQueueFullFromISR            xQueue=%I
+170       uxQueueMessagesWaitingFromISR       xQueue=%I
+171       xQueueAltGenericSend                xQueue=%I pvItemToQueue=%p xTicksToWait=%u xCopyPosition=%u
+172       xQueueAltGenericReceive             xQueue=%I pvBuffer=%p xTicksToWait=%u xJustPeeking=%u
+173       xQueueCRSendFromISR                 xQueue=%I pvItemToQueue=%p xCoRoutinePreviouslyWoken=%u
+174       xQueueCRReceiveFromISR              xQueue=%I pvBuffer=%p pxTaskWoken=%u
+175       xQueueCRSend                        xQueue=%I pvItemToQueue=%p xTicksToWait=%u
+176       xQueueCRReceive                     xQueue=%I pvBuffer=%p xTicksToWait=%u
+177       xQueueCreateMutex                   ucQueueType=%u
+178       xQueueCreateCountingSemaphore       uxMaxCount=%u uxInitialCount=%u
+179       xQueueGetMutexHolder                xSemaphore=%u
+180       xQueueTakeMutexRecursive            xMutex=%u xTicksToWait=%u
+181       xQueueGiveMutexRecursive            pxMutex=%u
+52       vQueueAddToRegistry                 xQueue=%I pcName=%u
+182       vQueueUnregisterQueue               xQueue=%I
+47       xQueueGenericCreate                 uxQueueLength=%u uxItemSize=%u ucQueueType=%u
+183       xQueueCreateSet                     uxEventQueueLength=%u
+184       xQueueAddToSet                      xQueueOrSemaphore=%u xQueueSet=%u
+185       xQueueRemoveFromSet                 xQueueOrSemaphore=%u xQueueSet=%u
+186       xQueueSelectFromSet                 xQueueSet=%u xTicksToWait=%u
+187       xQueueSelectFromSetFromISR          xQueueSet=%u
+188       xQueueGenericReset                  xQueue=%I xNewQueue=%u
+189       vListInitialise                     pxList=%u
+190       vListInitialiseItem                 pxItem=%u
+191       vListInsert                         pxList=%u pxNewListItem=%u
+192       vListInsertEnd                      pxList=%u pxNewListItem=%u
+193       uxListRemove                        pxItemToRemove=%u
+194       xEventGroupCreate                    
+195       xEventGroupWaitBits                 xEventGroup=%u uxBitsToWaitFor=%u xClearOnExit=%u xWaitForAllBits=%u xTicksToWait=%u
+196       xEventGroupClearBits                xEventGroup=%u uxBitsToClear=%u
+58       xEventGroupClearBitsFromISR         xEventGroup=%u uxBitsToSet=%u
+197       xEventGroupSetBits                  xEventGroup=%u uxBitsToSet=%u
+59       xEventGroupSetBitsFromISR           xEventGroup=%u uxBitsToSet=%u pxHigherPriorityTaskWoken=%u
+198       xEventGroupSync                     xEventGroup=%u uxBitsToSet=%u uxBitsToWaitFor=%u xTicksToWait=%u
+60       xEventGroupGetBitsFromISR           xEventGroup=%u
+199       vEventGroupDelete                   xEventGroup=%u
+200       uxEventGroupGetNumber               xEventGroup=%u
+
+512       esp_sysview_heap_trace_alloc        addr=%p size=%u callers=%x
+513       esp_sysview_heap_trace_free        addr=%p callers=%x
diff --git a/examples/system/sysview_tracing_heap_log/gdbinit b/examples/system/sysview_tracing_heap_log/gdbinit
new file mode 100644 (file)
index 0000000..f68ad18
--- /dev/null
@@ -0,0 +1,17 @@
+target remote :3333
+
+mon reset halt
+flushregs
+
+tb heap_trace_start
+commands
+mon esp32 sysview start file:///tmp/heap_log.svdat
+c
+end
+
+tb heap_trace_stop
+commands
+mon esp32 sysview stop
+end
+
+c
diff --git a/examples/system/sysview_tracing_heap_log/main/CMakeLists.txt b/examples/system/sysview_tracing_heap_log/main/CMakeLists.txt
new file mode 100644 (file)
index 0000000..58d592c
--- /dev/null
@@ -0,0 +1,4 @@
+set(COMPONENT_SRCS "sysview_heap_log.c")
+set(COMPONENT_ADD_INCLUDEDIRS ".")
+
+register_component()
diff --git a/examples/system/sysview_tracing_heap_log/main/component.mk b/examples/system/sysview_tracing_heap_log/main/component.mk
new file mode 100644 (file)
index 0000000..44bd2b5
--- /dev/null
@@ -0,0 +1,3 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
diff --git a/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c b/examples/system/sysview_tracing_heap_log/main/sysview_heap_log.c
new file mode 100644 (file)
index 0000000..d34c93d
--- /dev/null
@@ -0,0 +1,75 @@
+/* Application Trace to Host Example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include "esp_sysview_trace.h"
+#include "esp_heap_trace.h"
+#include "esp_log.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+
+
+static const char *TAG = "example";
+
+// waits on queue for memory addresses and frees memory allocated by 'alloc_task'
+static void free_task(void *p)
+{
+    QueueHandle_t queue = (QueueHandle_t)p;
+    while (1) {
+        void *p = NULL;
+        if (xQueueReceive(queue, ( void * )&p, portMAX_DELAY) != pdPASS) {
+            ESP_LOGE(TAG, "Failed to send to queue!");
+        } else {
+            ESP_LOGI(TAG, "Task[%p]: free memory @ %p", xTaskGetCurrentTaskHandle(), p);
+            free(p);
+        }
+    }
+}
+
+// allocates memory and puts addresses to the queue
+static void alloc_task(void *p)
+{
+    QueueHandle_t queue = (QueueHandle_t)p;
+
+    xTaskCreatePinnedToCore(free_task, "free", 2048, queue, 5, NULL, portNUM_PROCESSORS-1);
+
+    // here GDB will stop at brekpoint and execute OpenOCD command to start tracing
+    heap_trace_start(HEAP_TRACE_ALL);
+    for(int i = 1; i < 5; i++) {
+        uint32_t sz = 2*i;
+        void *p = malloc(sz/2);
+        // WARNING: the previous allocated memory is intentionally not deallocated in order to cause memory leak!
+        p = malloc(sz);
+        ESP_LOGI(TAG, "Task[%p]: allocated %d bytes @ %p", xTaskGetCurrentTaskHandle(), sz, p);
+        if (xQueueSend(queue, ( void * )&p, portMAX_DELAY) != pdPASS) {
+            ESP_LOGE(TAG, "Failed to send to queue!");
+        }
+        vTaskDelay(100/portTICK_PERIOD_MS);
+    }
+    // here GDB will stop at brekpoint and execute OpenOCD command to stop tracing
+    heap_trace_stop();
+    while(1);
+}
+
+void app_main()
+{
+    // redirect log messages to the host using SystemView tracing module
+    esp_log_set_vprintf(&esp_sysview_vprintf);
+    QueueHandle_t queue = xQueueCreate(10, sizeof(void *));
+    if(queue == 0) {
+        ESP_LOGE(TAG, "Failed to create queue!");
+        return;
+    }
+    // init host-based heap tracing
+    if(heap_trace_init_tohost() != ESP_OK) {
+        ESP_LOGE(TAG, "Failed to init heap trace!");
+        return;
+    }
+    xTaskCreatePinnedToCore(alloc_task, "alloc", 2048, queue, 5, NULL, 0);
+}
diff --git a/examples/system/sysview_tracing_heap_log/sdkconfig.defaults b/examples/system/sysview_tracing_heap_log/sdkconfig.defaults
new file mode 100644 (file)
index 0000000..26ca10d
--- /dev/null
@@ -0,0 +1,28 @@
+# Enable single core mode by default
+CONFIG_MEMMAP_SMP=n
+CONFIG_FREERTOS_UNICORE=y
+# 1ms tick period
+CONFIG_FREERTOS_HZ=1000
+# Enable application tracing by default
+CONFIG_ESP32_APPTRACE_DEST_TRAX=y
+CONFIG_ESP32_APPTRACE_ENABLE=y
+# Enable FreeRTOS SystemView Tracing by default
+CONFIG_SYSVIEW_ENABLE=y
+CONFIG_SYSVIEW_TS_SOURCE_TIMER_00=y
+CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE=y
+CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE=y
+CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE=y
+CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE=y
+CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE=y
+CONFIG_SYSVIEW_EVT_IDLE_ENABLE=y
+CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE=y
+CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE=y
+# Disable color output in logs
+CONFIG_LOG_COLORS=
+# Enable heap tracing to host
+CONFIG_HEAP_TRACING_TOHOST=y