레이블이 Debug-Info인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Debug-Info인 게시물을 표시합니다. 모든 게시물 표시

9/10/2021

Ecplise CDT 기반의 ESP32 OpenOCD 설정 on Window

1. Ecplise CDT 설치 및 설정 

Ecplise-CDT Oxygen 설치 및 설정 





1.1 Ecplise-CDT 의 ESP-PlugIn 설치 


  • Ecplise CDK 의 ESP PlugIn 설치방법 아래참조 
  1. Java 11 and above : Download and install Java SE from here
  2. Python 3.5 and above : Download and install Python from here
  3. Eclipse IDE for C/C++ Developers 2020-12 and above : Download and install Eclipse CDT package from here
  4. Git : Get the latest git from here
  5. ESP-IDF 4.0 and above : Clone the ESP-IDF repo from here

  • Help > Install New Software > Add
  1. Name: Espressif IDF Plugin for Eclipse
  2. Location: https://dl.espressif.com/dl/idf-eclipse-plugin/updates/latest/



추후 설치시 Keep 말고 Update로 진행 



Manage에서 설치된 것을 확인 



재시작을 해도 상위 Manual 대로 동작되지는 않아서 필수 조건에서 내가 만족을 못시키는가 찾아보았지만, 이상없음 

  • Help -> Ecplise Marketplace 
혹시 몰라서 직접 MaketPlace에서 ESP로 직접 찾아보고 다시 설치진행하는데 두 개의 버전이 있으며 두 개 아래 것으로 다시 재설치 (사실 상위와 동일한 과정임)
왜냐하면, 첫번째 버전은 OpenOCD용으로만 나왔으며, Plugin들이 별로 없음 

  1. 다시 설치진행했으며, 이전에는 Keep했지만, Update로 변경설치 진행 
  


  • 2번째 설치된 후 실행된 모습 
상위에서 안된 이유가 Keep으로 진행해서 안된 것 같으며, 다음에는 Update로 하면 다 될거라고 생각되며, 구지 ESP Manual 처럼 주소 직접 입력할 필요는 없을 것 같다. 
다음에는 그냥 Market에서만 검색해서 설치진행하도록 하자. 



1.2 Ecplise-CDT 의 ESP-PlugIn 환경설정 
 
  • ESP-IDF PlugIn 기본설정 (Espressif -> Downdload and Configure ESP IDF) 
설치진행 후 이미 사용중이 ESP-IDF PATH 설정/Git/ Python (ESP-IDF 내부로 설정) 진행 
  1. ESP-IDF : C:\Users\jhlee\esp\esp-idf
  2. Git:  C:\Program Files\Git\bin\git.exe
  3. Python : C:\Users\jhlee\.espressif\python_env\idf4.2_py3.8_env\Scripts\python.exe


Python은 이미 ESP-IDF에서 venv 형식으로 설치했으므로, VS code 동일하다 


  • Window -> Preference 설정확인 
Git 혹은 ESP-IDF 관련설정들을 확인 

  • Project 생성 후 기본테스트 
  1. File-> New -> Project-> Espressif IDF Project  :  Ecplise Project 생성 

  • ESP Target 설정 
우측 esp32 설정 

ESP32 와 Serial Port 설정 


  • Edit Configuration 확인
좌측 test2 설정 


Build Setting 확인 
이부분이 별도로 존재하지 않는다면 Build가 제대로 진행이 안됨


Main 확인



  • Window -> Show View -> Terminal  
Open a Terminal 진행 

  1. Serial 설정확인 
  2. ESP-IDF Monitor 실행  


  • File -> Properties
CDT Core Builder 설정확인 



  • TEST Program 기본확인 
TEST Program을 만들어서 이제 빌드해보고 화면을 보도록하자.



2. Ecplise CDT  OpenOCD 기반의 GDB 사용  

  • OpenOCD 관련내용
기본 OpenOCD 관련내용

  • VS Code의 OpenOCD 사용 및 설치 
이전에 VS Code에서 쉽게 OpenOCD기반으로 사용 

  • ESP32-Ecplise 환경설정 
Ecplise 기반으로 구성하지만, Visual 적으로 ELF format을 분석하여 Memory상태확인가능



  • ESP사에서 제공하는 JTAG은 FT2232이며, 아래와 같이 사용 
  1. Serial Converter A:  JTAG  (WinUSB 변경)
  2. Serial Converter B:  Serial 

libusb 때문에 발생하는 문제이므로, 이전과 크게 다르지 않으며, Window용으로 변경 
Tool은 본인이 좋아하는 것으로 사용  


VS Code와 별반 다르지 않으므로 크게 어렵지 않다. 

  • Configuration 추가 
OpenOCD를 이용하고자 한다면, Configuratino을 새로 더 생성하여 설정 후 진행
좌측 test2에서 새롭게 Conifguration 추가진행 


Debug 를 ESP-IDF GDB OpenOCD Debugging으로 연결 


  • 설정시  Debugger 관련설정 
  1. GDB/Telnet/TCL 확인: 기본설정값 
  2. OpenOCD 설정파일 확인 : 설정변경방법은 상위 링크 참조 



ELF 파일확인 

Gdb Init Command 및 세부설정 




  • OpenOCD 기반으로 GDB Debug
확실히 사용하기에는 VS Code보다는 Ecplise 기반이 편한 것 같아 보이며, 더 다양한 기능사용가능 
이 부분은 이전 Ecplise 사용부분 참조하시길 


상위와 같이 쉽게 디버깅가능 및 데이타 확인 가능 




8/24/2021

ESP32 OpenOCD 설정 과 VS Code 설정

1. ESP32 OpenOCD 설정 

이전까지 내가 가지고 있던 OpenOCD는 FT2232 기반으로 다른 보드에서 각각 동작되는 것들을 리눅스에서 해왔지만, 
최근 Window 기반으로 이를 해결해야할 것 같아 관련자료들을 정리해본다.

ESP32 OpenOCD 관련내용 과 gdbgui 연결 
바로 이전 ESP32로 구성한 것이며, 반드시 참조 


JTAG과 OpenOCD 이해와 이전 Raspberry Pi 적용사항 (반드시 확인)
A. JTAG의 기본이해 와 OpenOCD관련내용
B. Raspberry PI OpenOCD 관련내용 과 VS Code/ VS Community 연결

OpenOCD User Guide 와 GDB Command
A. OpenOCD User Guide 반드시 확인 
B. OpenOCD에서 처음 gdb 직접연결하여 테스트 할 경우 각 gdb 명령어들 설명 


1.1 ESP Prog Board

기존에 내가 사용하던 FT2232H와 동일하며, 2개 포트를 하나는 Serial 는 다른 하나는 JTAG으로 사용한다.
세부내용은 이전의 FT2232관련 OpenOCD 참조 

https://github.com/espressif/esp-dev-kits/blob/master/docs/_static/esp-prog/block.png




  1. Interface 0 / A: JTAG
  2. interface 1 / B: UART

  • USB Serial Port 설정 
  1. 장치관리자->범용 직렬버스 컨트롤러
  2. USB Serial Converter B 선택 후 속성 
  3. 고급-> VCP 드라이버 설치 


속성에서 고급 과 Power Menagement 탭이 없다면, 다시시작한 후 다시 진행
USB Serial Converter B (Serial)이므로 VCP설정 



  • USB Serial Converter B기반의 Serial Port 설정완료 
  1. 포트-> USB Serial Port (COM6) 확인 후  USB Serial Convert B 연결확인 (Serial 용) 
  2. 포트-> USB Serial Port (COMx) 확인 후  USB Serial Convert A 있을 경우 삭제(JTAG 용)
  3. 포트-> USB Serial Port의 Port를 변경하고자 할 경우 포트설정이용
  4. 장치관리자->보기->숨겨진장치 표시 (설정되어진 Serial 포트 확인가능)
 


FTDI Driver가  반드시 상위 USB Serial Port로 잡혀야하며, 내 두번째 노트북에서는 Serial이 자꾸 Dual RS232 Serial로 잡혀서 동작이 전혀 안됨 
이부분을 아래 Tool 혹은 Driver를 변경하여 해결진행 

  • Window LibUSB 설정 (JTAG 설정)
Download
  1. Download 후 실행
  2. Option->List All Devices 선택 
  3. Dual RS232 HS Interface 0 선택
  4. FTDIBUS -> WinUSB로 변경 


  • USBDriverTool 
상위와 동일한 기능이며, OpenOCD 내부에도 동일한 Tool이 존재 
세부사용은 상위 Raspberry PI OpenOCD 관련내용 과 VS Code/ VS Community 연결 참조
이게 더 편한 것 같음 


1.2 ESP32 OpenOCD 설정 

상위 ESP-IDF를 설치를 진행했다면, esp tool 내에 openocd도 함께 들어있으며, VS Code에서도 쉽게 OpenOCD를 Start/Stop를 진행가능하다.

  1. View->Command Palette 실행 
  2. 창에서 ESP 치면 ESP 관련 Command들이 나오며 그중 OpenOCD 선택
  3. View->Output 선택 후 Output의 우측 메뉴에 "OpenOCD" 현재상태 확인가능   

하지만 나의 경우는 OpenOCD의 세부설정을 위해서 별도로 bat 파일을 만들어서 동작하도록 별도로 또 구성하였다. 


  • esp_openocd.bat
아래와 같이 별도의 TCL script 별도설정을 해주어 동작하며, 아래의 appimage_offset은 본인의 Partition Table에서 참고 
TITLE OpenOCD for ESP32 Prog 
rem Author: Jeonghun Lee
rem TEST OpenOCD
set SCR_PATH=%userprofile%\.espressif\tools\openocd-esp32\v0.10.0-esp32-20200709\openocd-esp32\share\openocd\scripts
set BIN_PATH=%userprofile%\.espressif\tools\openocd-esp32\v0.10.0-esp32-20200709\openocd-esp32\bin
set SET_ESP32_FLASH="init; halt; esp appimage_offset 0x50000"
set SET_ESP32_OS="set ESP32_RTOS \"FreeRTOS\" "
%BIN_PATH%\openocd.exe  -f  %SCR_PATH%\board\esp32-wrover-kit-3.3v.cfg -c %SET_ESP32_FLASH% -c %SET_ESP32_OS%

ESP32 OpenOCD의 관련설정 내용

  • SET_ESP32_FLASH 설정
esp32에서 내부 partition을 사용하고 있다면, 별도의 실행할 offset을 넣어 상위와 같이 설정 
재미있는것은 SPI ROM인데, profile 해보면 이 영역이 NOR Flash처럼 XIP(Execute In Place)도 되는 것으로 나온다. 
SW영역에서 그렇게 표시되어있는데, 이부분은 ESP 내부 Flash만 되는지 외부 Flash도 지원가능한지 반드시 추후에 확인 

현재 MTDI의 설정에 따라 내부 LDO로  FLASH 전원 3.3 or 1.8로 변경되며 관련설정은 별도가능 (ESP32_FLASH_VOLTAGE 값 참조)

ESP32 전용 내부변수들( 이를 이해하려면 아래내용들을 분석하면 쉽게이해)
상위 SET_ESP32_OS 에 설정을 별도로 했으며, 관련내용들 


1.3 ESP32 OpenOCD Configuration 분석 

상위에서 사용하는 esp32-wrover-kit-3.3v.cfg 을 세부적으로 분석 및 수정방법 

  • board/esp32-wrover-kit-3.3v.cfg
Main을 보면 다시 2개를 참조하며, ESP32_FLASH_VOLTAGE를 설정하고 구성됨
# Example OpenOCD configuration file for ESP32-WROVER-KIT board.
#
# For example, OpenOCD can be started for ESP32 debugging on
#
#   openocd -f board/esp32-wrover-kit-3.3v.cfg
#

# Source the JTAG interface configuration file
source [find interface/ftdi/esp32_devkitj_v1.cfg]
set ESP32_FLASH_VOLTAGE 3.3


# Source the ESP32 configuration file
source [find target/esp32.cfg]

  • interface/ftdi/esp32_devkitj_v1.cfg
ESP32 Prog Board의 설정 구성이며, FT2232 설정과 유사하며 이는 FTDI 사용법을 알면 쉽게 설정도 변경가능하다.
#
# Driver for the FT2232H JTAG chip on the Espressif DevkitJ board
# (and most other FT2232H and FT232H based boards)
#
 

interface ftdi
ftdi_vid_pid 0x0403 0x6010 0x0403 0x6014

# interface 1 is the uart
ftdi_channel 0

# TCK, TDI, TDO, TMS: ADBUS0-3
# LEDs: ACBUS4-7

ftdi_layout_init 0x0008 0xf00b
ftdi_layout_signal LED -data 0x1000
ftdi_layout_signal LED2 -data 0x2000
ftdi_layout_signal LED3 -data 0x4000
ftdi_layout_signal LED4 -data 0x8000

# ESP32 series chips do not have a TRST input, and the SRST line is connected
# to the EN pin. 
# The target code doesn't handle SRST reset properly yet, so this is
# commented out:
# ftdi_layout_signal nSRST -oe 0x0020

reset_config none

# The speed of the JTAG interface, in KHz. If you get DSR/DIR errors (and they
# do not relate to OpenOCD trying to read from a memory range without physical
# memory being present there), you can try lowering this.
#
# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
# if CPU frequency is 160MHz or 240MHz.
adapter_khz 20000

ESP32 JTAG Speed
JTAG을 연결하면 간혹 DSR/DIR Error가 발생하는데, 이는 OpenOCD와 관련이 없다고 한다.
처음 이 문제를 JTAG Speed 문제, 즉 JTAG의 속도가 너무 부족하여 동작안되는 줄 알았는데, 알아보니 아니다.
JTAG의 속도는 20Mhz or 26Mhz 설정이며,  존재하지 않은 Memory 영역을 접근했을때 문제가 발생하는 것이라고 한다.  

  • target/esp32.cfg
ESP32의 전반적인 설정이며, TAP으로 얻는 정보들을 확인 및 관련부분 설정과정이며 이전 OpenOCD를 보면 쉽게 이해가능하다.(esp_common 생략)
# The ESP32 only supports JTAG.
transport select jtag

# Source the ESP common configuration file
source [find target/esp_common.cfg]

if { [info exists CHIPNAME] } {
	set _CHIPNAME $CHIPNAME
} else {
	set _CHIPNAME esp32
}

if { [info exists CPUTAPID] } {
	set _CPUTAPID $CPUTAPID
} else {
	set _CPUTAPID 0x120034e5
}

if { [info exists ESP32_ONLYCPU] } {
	set _ONLYCPU $ESP32_ONLYCPU
} else {
	set _ONLYCPU 3
}

if { [info exists ESP32_FLASH_VOLTAGE] } {
	set _FLASH_VOLTAGE $ESP32_FLASH_VOLTAGE
} else {
	set _FLASH_VOLTAGE 3.3
}

set _TARGETNAME $_CHIPNAME
set _CPU0NAME cpu0
set _CPU1NAME cpu1
set _TAPNAME $_CHIPNAME.$_CPU0NAME

jtag newtap $_CHIPNAME $_CPU0NAME -irlen 5 -expected-id $_CPUTAPID
if { $_ONLYCPU != 1 } {
	jtag newtap $_CHIPNAME $_CPU1NAME -irlen 5 -expected-id $_CPUTAPID
} else {
	jtag newtap $_CHIPNAME $_CPU1NAME -irlen 5 -disable -expected-id $_CPUTAPID
}

if { $_RTOS == "none" } {
	target create $_TARGETNAME esp32 -endian little -chain-position $_TAPNAME
} else {
	target create $_TARGETNAME esp32 -endian little -chain-position $_TAPNAME -rtos $_RTOS
}

configure_esp_workarea $_TARGETNAME 0x40090000 0x3400 0x3FFC0000 0x6000
configure_esp_flash_bank $_TARGETNAME $_TARGETNAME $_FLASH_SIZE

esp32 flashbootstrap $_FLASH_VOLTAGE
xtensa maskisr on
if { $_SEMIHOST_BASEDIR != "" } {
	esp semihost_basedir $_SEMIHOST_BASEDIR
}
if { $_FLASH_SIZE == 0 } {
	gdb_breakpoint_override hard
}

# special function to program ESP32, it differs from the original 'program' that
# it verifies written image by reading flash directly, instead of reading memory mapped flash regions
proc program_esp32 {filename args} {
	program_esp $filename $args
}

add_help_text program_esp32 "write an image to flash, address is only required for binary images. verify, reset, exit are optional"
add_usage_text program_esp32 "<filename> \[address\] \[verify\] \[reset\] \[exit\]"

1.4 OpenOCD 와 SDKCONFIG 설정 

ESP32의 경우 Linux Kernel 처럼 Kconfig 기반으로 menuconfig로 설정가능하며 이때 나오는 결과 설정값이 sdkconfig 이며, 이를 쉽게 변경가능하다. 
VS Code의 경우 GUI로 멋지게 제공을 해주고 있으므로 쉽게 설정가능하다. 

  • OpenOCD사용시 SDKCONFIG 설정변경값
기본적으로 OpenOCD기반으로 Debugger로 이용시 설정해야하는 설정들 
  1. CONFIG_ESP_DEBUG_OCDAWARE 
  2. CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/tips-and-quirks.html#support-options-for-openocd-at-compile-time


HEAP TRACE와 APP TRACE는 ESP-IDF Extension에서 세부사항을 확인가능 

  • APP TRACE 관련예제
이전에 간단하게 App Trace 테스트 구동 했으며, Heap trace는 추후 테스트 진행

  • HEAP_TRACE 기능제공 (SDKCONFIG 설정변경)
heap tracing 방법은 2가지로 제공해주고 있으며, 각각 sdkconfig 설정기반으로 본인이 선택

  • APP_TRACE  기능제공 (SDKCONFIG 설정변경)
두 개의 Trace가 다 Trace Log기반으로 동작이 되므로 관련부분은 상위 메뉴얼 참조 
APP TRACE의 경우 세부분석은 SYSTEM VIEW가 별도로 필요 (아직사용못해봄) 



2. VS Code 내부 설정 


  • VS Code Setup Manual 
ESP-IDF 설치 방법 (내부에 Git/Python을 비롯하여 전부 포함되어있음)


2.1 VS Code의 MS-CPPTool 기반설정  

상위에서 이미 CPPTool은 이미 설치가 되어있고, 아래와 같이 Run and Debug에서 launch.json만 설정해주면 된다.
OpenOCD와 동작은되는데, 이상하게 Breakpoint가 동작이 안되며, Exception이 발생하여 진행하기 힘들다.
예제프로그램으로 하면 괜찮을 것 같은데, 아직 해보지는 않음 


  • launch.json 설정 
launch.json 생성 후 자동으로 c_cpp_properties.json 자동생성 이게 다시 build/compile_commands.json 관리 
  {
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "ESP32 Debugger",             //launch.json 의 Name 
            "type": "cppdbg",                      //cppdbg 기반으로 작동  
            "request": "launch",
            
             //만약 인식을 못한다면, \\build\\xxxx.elf" 변경을 해보도록 하자 Window에서 매번 PATH문제 발생 
            "program": "${workspaceRoot}/build/xxxxx.elf",

            "miDebuggerServerAddress": "localhost:3333",    // GDB:3333/ TCL:6666/ Telnet:4444 (OpenOCD 참조) 
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:/Users/jhlee/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-gdb.exe",
            
            "setupCommands": [
                {
                     //gdbinit 정보를 넣으려고 했는데, 동작이 제대로 안됨 
                    "description": "gdb에 자동 서식 지정 사용",
                    "text": "symbol-file d:\\project\\mod\\mod610_sw\\build\\xxxxx.elf",
                    "ignoreFailures": true
                }
            ]

        }
    ]
}  

  • 상위 설정기반으로 진행방법 
  1. OpenOCD Start  (상위 batch 파일참조)
  2. VS Code의 Run and Debug->launch.json 설정 (상위참조)
  3. Run and Debug에서 Debug 실행진행 




  • OpenOCD Server 확인 
  1. port 4444 for Telnet communication
  2. port 6666 for TCL communication 
  3. port 3333 for gdb

2.2 ESP-IDF Debug Adapter 기반설정 (이방법 추천) 

View->Output -> ESP-IDF Debug Adapter가 존재하며, 이를 Run and Debug에 연결을하여 launch.json을 생성한다. 
이를 생성을 하게되면, 자동으로 task.json 과 setting.json이 생성이 되어진다. 
이는 예전에 Linux에서 동작하는 것으로 관련설정과 task.json을 쉽게 볼수 있다. 

상위에 내가 별도로 만든 OpenOCD batch 파일 설정도 필요가 없으며, 내부설정해서 모두 해결하면된다.

실행을 해보면 처음 breakpoint는 한번은 동작은하는데, 다음부터 exception 때문에 잘 동작이 되지 않는다. 
이전에 Linux에서도 사용했는데, 그때는 gdbgui로 집중해서 사용했던것 같다. 
 

  • lauch.json 생성
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "espidf",         //espidf 기반으로 작동 (VS Code ESP IDF를 이미 설치)  
      "name": "Launch-name", 
      "request": "launch",
       "gdbinitFile":"${workspaceFolder}/gdbinit",   
    }
  ]
}
  • gdbinit 생성
 //gdbinit 생성 후 elf에서 symbol을 찾도록 연결 
target remote :3333
set remote hardware-watchpoint-limit 2           //ESP32가 2 까지만,   
symbol-file ./build/xxxxx.elf                    //반드시 Symbol Table 연결 
mon reset halt
flushregs
thb app_main
c
  • launch.json 생성 및 관련설정 
상위설정은 기본으로 auto이며, 이외  별도로 세부설정가능 아래 링크참조 

  • 기본동작 및 확인 
본인의 Thread 갯수가 맞는 지 부터 확인 (elf 심볼테이블 매치)



아래사항들 확인 각 로그확인 
  1. View->OUTPUT ESP-IDF Debug adapter 선택 로그확인 
  2. View->OUTPUT 의 OpenOCD 선택 로그확인 (특히 Symbols 부분)
  3. View->DEBUG CONSOLE을 확인

이전과의 다른점은 Call Stack에서 각 Thread의 이름을 알수 있으며, 개별 Thread Control도 가능하며, 제어가 가능하다는 부분이다.

  • 참고
WATCH POINT를 사용하고자 하면 원하는 변수를 넣으면 감시가 된다. (물론 SDKCONFIG설정필요)


  • VSCode의 동작 
아래처럼 동작하지만 PERIPHERALS/REGISTERS/MEMORY/DiSASSEMBLEY는 없음 


  • esp-idf-vscode-generated.gdb 
gdbinit 처럼 생성된 파일로 gdb를 초기설정값 
target remote :3333
mon reset halt
flushregs
thb app_main

gdbinit 처럼 gdb 초기화 부분 
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/tips-and-quirks.html#what-is-the-meaning-of-debugger-s-startup-commands

  • ESP32의 제약사항 
ESP32의 경우 HW-BP(breakpoint)는 2개까지 지원되며, HW-BP기반으로 SW-BP 생성하여 FLASH(32개)와 IRAM (32개) 사용가능하지만
gdb는 SW-BP를 사용하지 못한다고 한다. 


  • Terminal->Run Task 이용하여 각 Task 실행 
기존에 제공해주는 메뉴와 비슷하며, 거의 별도로 사용할 일은 없을 것 같다. 
Linux에서는 별도로 Task를 만들어 내마음대로 구성을 했지만, 현재 ESP-IDF 에서 기본으로 각 메뉴로 제공해주고 있다. 

  • VS Code IDF Setting 
View -> Command Palette -> Preferences: Open Settings (UI))
Extensions->ESP-IDF 세부참조확인 
.vscode/task.json 참조 


상위대로하면, WATCH기능과 BreakPoints기반으로 디버깅이 가능하며 Call Stack도 분석이 가능하며 나름 어느 정도 쓸만한 것으로 보인다.

  • VS Code ESP-IDF 단점 
  1. Disasemble 
  2. Memory Read/Write 
  3. Peripheral 
상위와 같은 정보를 제공을 못해주고 있으며, 다소 불안전한 모습으로 동작한다.
사용하면 사용할 수로 많은 부분이 JTAG 디버거 기능으로 부족하다고 느끼는 바이다.


3. VS Code 기반의 ESP-IDF 의 TIPs

ESP-IDF VS Code Extension 설치 후 하단에 아래 아이콘이 생성되며 각각의 idf.py 의 기능을 손쉽게 사용가능하다.


얼마전에 새로 업데이트가 되어 새로운 기능들이 추가되고 있으며, 약간씩 변경될지도 모른다.



ESP-IDF Monitor 혹은 VS Code에서 제공해주는 기능은 PowerShell 기반으로 동작이 되며 이를 응용하여 간단하게 확장하여 사용가능하다.

  • ESP-IDF Monitor 의 경우 (tee를 이용)

Ctrl+C로 정지 후 아래와 같이 tee를 이용하여 log capture를 하자 PS에서 tee가 될줄은 정말 몰랐는데, PS(Power Shell)이 가만보면 
Linux 환경을 비롯하여 기능들을 최대한 지원해주려고 하는 것으로 보인다.
 C:\Users\jhlee\.espressif\python_env\idf4.2_py3.8_env\Scripts\python.exe C:\Users\jhlee\esp\esp-idf\tools\idf.py -p COM6 monitor | tee debug.log  

  • ESP-IDF Terminal 사용할 경우
기존 리눅스 처럼 idf.py 기반으로 메뉴를 사용가능하지만, menuconfig는 제대로 동작이 안됨
그래서 별도로 VS Code에서 GUI로 제공해줌 

 idf.py --help
......
  add-dependency           Add dependency to the manifest file. For now we only support adding dependencies on the default service.
  all                      Aliases: build. Build the project.
  app                      Build only the app.
  app-flash                Flash the app only.
  bootloader               Build only bootloader.
  bootloader-flash         Flash bootloader only.
  clean                    Delete build output files from the build directory.
  confserver               Run JSON configuration server.
  create-manifest          Create manifest for specified component.
  create-remote-component  Register a new component on the component service.
  delete-version           Delete version in dist directory from the component service.
  efuse_common_table       Generate C-source for IDF's eFuse fields.
  efuse_custom_table       Generate C-source for user's eFuse fields.
  encrypted-app-flash      Flash the encrypted app only.
  encrypted-flash          Flash the encrypted project.
  erase_flash              Erase entire flash chip.
  erase_otadata            Erase otadata partition.
  flash                    Flash the project.
  fullclean                Delete the entire build directory contents.
  gdb                      Run the GDB.
  gdbgui                   GDB UI in default browser.
  gdbtui                   GDB TUI mode.
  menuconfig               Run "menuconfig" project configuration tool.
  monitor                  Display serial output.
  openocd                  Run openocd from current path
  pack-component           Create component archive.
  partition_table          Build only partition table.
  partition_table-flash    Flash partition table only.
  post_debug               Utility target to read the output of async debug action and stop them.
  python-clean             Delete generated Python byte code from the IDF directory
  read_otadata             Read otadata partition.
  reconfigure              Re-run CMake.
  set-target               Set the chip target to build.
  show_efuse_table         Print eFuse table.
  size                     Print basic size information about the app.
  size-components          Print per-component size information.
  size-files               Print per-source-file size information.
  upload-component         Upload component in dist directory to the component service.
  upload-component-status  Check status of component upload


5/02/2021

ESP32 Backtrace 와 addr2line

1. ESP32의 Monitor 기능 

esp32 개발환경에서 제공해주는 idf.py -p /dev/ttyUSBx monitor , 즉 monitor 기능은 기본적으로 gdb option을 포함하고 있다. 
그래서, abort 시 backtrace가 가능한데, 이때 사용하는 기능이 addr2line 기능이며, 이는 각 Stack의 Address를 Code의 위치를 찾는다. 
기본기능으로 아래와 같이 addr2line을 이용하여 위치를 찾아주며, 이 정보는 stderr로 표시해주고 있다. 

  • ESP32가 Exception 이 발생할때 아래와 같이 Dump와 Backtrace 정보출력   
Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90

  • addr2line이용하여 추적가능 
Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
0x400dbf56: still_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:47
0x400dbf5e: dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:42
0x400dbf82: app_main at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:33
0x400d071d: main_task at /home/gus/esp/32/idf/components/esp32/./cpu_start.c:254 

Backtrace는 2개의 Address로 구성되며, PC와 A1, 즉 , Arg라고 짐작 (세부내용은 ABI 참조해야함)

  • addr2line 이용하여 소스위치확인
$ xtensa-esp32-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS  // 상위 Address 입력하면 각 소스위치파악 


  • ESP32 Exception이 발생할 경우 순서도 


GDB-Stub 사용

ESP32 Exception, Fatal Errors

monitor 관련내용

ESP32용 Backtrace Shell Script 


1.1 backtrace 와 addr2line 기본사용법 

backtrace는 Stack Trace라고도 하며, 기본적으로 함수의 Call Stack을 추적하는 방법을 말하며, 주로 사용되어지는 함수가 backtrace기능이다. 
이때 보조적으로 Code의 위치를 찾아주는 기능이 addr2line tool 이며, 이를 이용하여 쉽게 어디서 호출되어지는 분석이 가능하다. 

  • 기본설정 
GCC 로 Compile 시 반드시 -g 옵션 과 -rdynamic (동적 Library)

  • backtrace 함수와 addr2line 사용법 


1.2 addr2line 이용

ESP32는 기존의 Backtrace처럼 사용하지 않는 구조로 보이며, Backtrace가 아래와 같이 나오면 addr2line을 이용하여 쉽게 Source 위치 파악은 가능하다  

Backtrace:0x40090677:0x3ffe3710 0x40090c89:0x3ffe3730 0x400955fa:0x3ffe3750 0x400da8f2:0x3ffe37c0 0x400da9f0:0x3ffe37e0 0x400ec484:0x3ffe3800 0x400ec516:0x3ffe3840 0x400ec651:0x3ffe3870 0x400ec6e4:0x3ffe38a0 0x400daa13:0x3ffe38c0 0x400db275:0x3ffe38f0 0x400db4fa:0x3ffe3920 0x400d8deb:0x3ffe3a70 0x400d978c:0x3ffe3a90 0x40090cf9:0x3ffe3ac0 

$ xtensa-esp32-elf-addr2line 0x40090677 -e ./build/demos  
$ xtensa-esp32-elf-addr2line 0x40090c89 -e ./build/demos 

1.3 이외 Tool 사용 

  • Linux Kernel 처럼 map 분석 
Symbol Table 과 Linker Script Section 과 Library 비롯하여 모든 기본정보 확인
$ cat ./build/demos.map    
// Discarded input sections     (Linker Scirpt 의 Section 과 상대주소 파악 ) 
// Memory Configuration         (실제 Memory 영역과 Attribute로 x/r/w 확인 ) 
// Linker script and memory map (Linker Scirpt 와 같이 절대주소 파악 )
// Cross Reference Table        (Symbol Table로 Symbol의 사용여부 확인가능)

  • readelf 로 Library 분석 및 ELF 분석 
각 Library 및 ELF Format 관련정보 확인 
$ xtensa-esp32-elf-readelf -a ./build/esp-idf/app_trace/libapp_trace.a    //Build 내에서 사용하는 ESP-IDF Library 분석 (-a 전체정보)  
$ xtensa-esp32-elf-readelf -h ./build/esp-idf/app_trace/libapp_trace.a                           //ELF 기본정보확인 (Endian/Entry Point/Machine)   
$ xtensa-esp32-elf-readelf -s ./build/esp-idf/app_trace/libapp_trace.a | grep function           //library Symbol Table 확인   
$ xtensa-esp32-elf-readelf -S ./build/demo                          //Linker Script Section 확인   

4/24/2021

ESP32 OpenOCD 와 GDB 사용

1. ESP32 개발환경구축 


  • ESP32-OpenOCD
ESP32개발환경을 설치하면, 자동으로 아래의 Openocd가 설치가 되며, 없다면, 직접설치

  • JTAG의 기본이해와 OpenOCD 관련내용 
JTAG을 기본적으로 이해하고 OpenOCD로 어떻게 JTAG을 사용하는지 이해 

  • Raspberry Pi 에 OpenOCD 구성 및 구조이해 
이전의 FTDI 기반으로 Raspberry Pi3  OpenOCD 사용 (반드시 숙지)  

  • /dev/ttyUSBx 권한문제

$ ls -al /dev/ttyUSB*           // 권한문제시 직접확인 
crw-rw---- 1 root dialout 188, 0  4월 20 12:25 /dev/ttyUSB0
crw-rw-r-- 1 root plugdev 188, 1  4월 20 12:25 /dev/ttyUSB1
crw-rw-r-- 1 root plugdev 188, 2  4월 20 12:25 /dev/ttyUSB2

//각 Group 권한 추가 
$ sudo usermod -a -G dialout jhlee  //serial 
$ sudo usermod -a -G plugdev jhlee  //JTAG
or
// 직접 권한변경 
$ sudo chmod a+rw /dev/ttyUSB0

  • libusb 권한문제

Info : Configured 2 cores
  Info : Listening on port 6666 for tcl connections
  Info : Listening on port 4444 for telnet connections
  Error: libusb_open() failed with LIBUSB_ERROR_ACCESS
  Error: no device found
  Error: unable to open ftdi device with vid 0403, pid 6010, description '*', serial '*' at bus location '*'
  
문제 해결방법 (udev 권한 변경)

$ lsusb   // 현재 PID 와 VID (Product ID/ Vendor ID) 확인 
...
Bus 001 Device 011: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC
...

$ sudo vi /etc/udev/rules.d/esp32link.rules
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev"

  • Window 10 (Zadig)
Zadig Download 진행 후 아래와 같이 Libusb/WinUSB 설정 진행 



관련이슈내용



1.1  ESP32 Board 와 FT2232H Board 연결 

  • ESP32 Module과 FT2232 연결 
이전의 OpenOCD와 동일하며, 하나는 JTAG  다른하나는 Serail로 연결 
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-wrover-kit.html




  • ESP32 OpenOCD 와 GDB 동작구조 
OpenOCD를 사용할 경우 GDB로 연결하여 동작하는데, 아래와 같이 연결되어 동작되어진다.

  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html


  • ESP32 Module 과 JTAG 연결 

ESP32 Pin

JTAG Signal

MTDO / GPIO15

TDO

MTDI / GPIO12

TDI

MTCK / GPIO13

TCK

MTMS / GPIO14

TMS

GND

GND


  • 직접 구성한 FT2232H 와 ESP32 Board 
나의 경우 ESP32에서 제공하는 ESP사에 제공해주는 FT2332H Board가 없어서 기존의 FT2232H Board로 구성한 것이지만, 
별도로 ESP에서 전용 Board를 판매하고 있으니,돈이 있다면, 직접 구입을 하면 편하다. 







2.  VS Code의 Espressif IDF 설치 

  • VS Code의 Extension 에서 Espressif IDF 설치 
VS Code에서 Extension에서 찾아서 설치 


VS Code에서 F1을 누르고, ESP로 치면, ESP-IDF 관련 많은 메뉴들이 존재하는 것을 볼 수 있다. 
VS Code의 이 메뉴 없이 직접 python의 idf.py로 직접 Control로 가능하다. 
idf.py는 esptool.py도 control하기 때문에 모두 idf.py command만 알아도 된다. 

  • 많이 사용하는 Menu들 
  1. ESP-IDF: New Project 
  2. ESP-IDF: Build your project
  3. ESP-IDF: Device configuration
  4. ESP-IDF: Flash(UART) your project
  5. ESP-IDF: Monitor your device
  6. ESP-IDF: OpenOCD  Manager

  • Terminal에서 직접 Command 입력 
$ source ~/esp/esp-idf/export.sh 

$ idf.py --help   //상위에서 제공되는 메뉴기능을 Command로 실행하면된다. 
.......
Commands:
  all                    Aliases: build. Build the project.
  app                    Build only the app.
  app-flash              Flash the app only.
  bootloader             Build only bootloader.
  bootloader-flash       Flash bootloader only.
  build-system-targets   Print list of build system targets.
  clean                  Delete build output files from the build directory.
  confserver             Run JSON configuration server.
  create-component       Create a new component.
  create-project         Create a new project.
  efuse_common_table     Generate C-source for IDF's eFuse fields.
  efuse_custom_table     Generate C-source for user's eFuse fields.
  encrypted-app-flash    Flash the encrypted app only.
  encrypted-flash        Flash the encrypted project.
  erase_flash            Erase entire flash chip.
  erase_otadata          Erase otadata partition.
  flash                  Flash the project.
  fullclean              Delete the entire build directory contents.
  gdb                    Run the GDB.
  gdbgui                 GDB UI in default browser.
  gdbtui                 GDB TUI mode.
  menuconfig             Run "menuconfig" project configuration tool.
  monitor                Display serial output.
  openocd                Run openocd from current path
  partition_table        Build only partition table.
  partition_table-flash  Flash partition table only.
  post_debug             Utility target to read the output of async debug action and stop them.
  python-clean           Delete generated Python byte code from the IDF directory
  read_otadata           Read otadata partition.
  reconfigure            Re-run CMake.
  set-target             Set the chip target to build.
  show_efuse_table       Print eFuse table.
  size                   Print basic size information about the app.
  size-components        Print per-component size information.
  size-files             Print per-source-file size information.
  uf2                    Generate the UF2 binary with all the binaries included
  uf2-app                Generate an UF2 binary for the application only


  • Monitor의 경우 별도의 Command
기본적으로 Exception이 나오면, add2line으로 분석을 해주며, bootloader에서 elf로 올려 분석을 해주는 것으로 보인다. 
Ctrl + ] 는 모니터에서 Exit 


2.1  VSCode의  Espressif IDF 설정  

  • 설치후 Espressif IDF 설정 확인 
Flash 방법도 UART/JTAG으로 두가지 다 가능 



  • 별도의 OpenOCD 세부설정 존재
중요한 것은 이거의 주내용은 Flash Type 관련설정이며, ESP OpenOCD의 위치파악 가능 및 설정확인가능 
  1. UART이면, 해당 Port로 연결
  2. JTAG이면, 해당 Port로 연결


ESP32-OpenOCD에서 확인
$ ls ~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32*     //OpenOCD Board 설정 (Interface/Target 분석)
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-ethernet-kit-3.3v.cfg
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-solo-1.cfg
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-wrover-kit-1.8v.cfg
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-wrover-kit-3.3v.cfg
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-wrover.cfg
/home/jhlee/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32s2-kaluga-1.cfg

$ vi ~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/board/esp32-wrover-kit-3.3v.cfg //현재 사용중인 config (Target/Inferface)


2.2  OpenOCD 연결 및 에러사항 

상위 ESP-IDF 메뉴 중 OpenOCD Manager를 이용하여 간단하게 실행가능하며, 직접 idf.py를 이용하여 실행해도 상관없다. 

  • OpenOCD 기본 동작확인
Open On-Chip Debugger  v0.10.0-esp32-20200709 (2020-07-09-08:54)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 20000 kHz

Info : Configured 2 cores
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : esp32: Debug controller 0 was reset.
Info : esp32: Core 0 was reset.
Info : esp32: Debug controller 1 was reset.
Info : esp32: Core 1 was reset.
Info : Listening on port 3333 for gdb connections

  • OpenOCD 에러 
아래  에러는 대부분 제대로 연결이 안되거나,  FT2332H는 Channel이 두개인데, Channel 설정오류 즉 연결(Interface)에서 잘되지 않은 것이므로, 
HW으로는 연결사항을 확인하고, SW는 Channel 설정사항을 세부적으로 살펴 보자.  

open On-Chip Debugger  v0.10.0-esp32-20200709 (2020-07-09-08:54)
  Licensed under GNU GPL v2
  For bug reports, read
      http://openocd.org/doc/doxygen/bugs.html
  adapter speed: 20000 kHz

  Info : Configured 2 cores
  Info : Listening on port 6666 for tcl connections
  Info : Listening on port 4444 for telnet connections
  Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
  Info : clock speed 20000 kHz
  Error: JTAG scan chain interrogation failed: all ones
  Error: Check JTAG interface, timings, target power, etc.
  Error: Trying to use configured scan chain anyway...
  Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
  Warn : Bypassing JTAG setup events due to errors
  Info : Listening on port 3333 for gdb connections
  • OpenOCD 세부설정 확인 
나의 경우 Channel A가 동작이되지 않아 아래와 같이 Channel B로 소스 수정하여 동작가능 
$ vi ~/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/share/openocd/scripts/interface/ftdi/esp32_devkitj_v1.cfg 
#
# Driver for the FT2232H JTAG chip on the Espressif DevkitJ board
# (and most other FT2232H and FT232H based boards)
#
 

interface ftdi
ftdi_vid_pid 0x0403 0x6010 0x0403 0x6014

#
# interface 0 channle A 
# interface 1 channel B (나의 경우 현재 Channel B로 사용)
ftdi_channel 1

#
# ftdi_layout_init 0x0008 0xf00b 
#
# 0x0008 0x000b  JTAG 설정 
# TCK, TDI, TDO, TMS: ADBUS0-3
#
# 0x0000 0xf000 LED 설정 
# LEDs: ACBUS4-7

ftdi_layout_init 0x0008 0xf00b
ftdi_layout_signal LED -data 0x1000
ftdi_layout_signal LED2 -data 0x2000
ftdi_layout_signal LED3 -data 0x4000
ftdi_layout_signal LED4 -data 0x8000
.... 

이외 VS Code로 사용할 경우 중복 실행되는 경우 및 설정이 잘못되는 경우가 많으므로, 관련부분을 확인하자. 



2.3 App Tracer 사용 

상위 상태에서 IDF App Tracer -> Start App Trace를 실행해보면 동작되는 것을 확인가능하며, 관련 설정은 아래를 참고해서 미리 해두자. 

APP Trace

Heap Trace

  • VSCode 기반으로 OpenOCD 사용예제 
일반예제로는 좌측의 Tracer 이용하여 사용하지만 제대로 동작되지는 않는 것을 확인 


  • App tracer의 사용법 
Application Level의 JTAG을 사용하고자 한다면, 반드시 sdkdefault에 설정을 추가하고 아래의 Manaul대로 설정하자. 

  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html



  • ESP32의 App Trace 사용예제
ESP32의 Example에 App Trace를 사용하여 Debug하는 예제가 존재하는데, 이 기반으로 테스트 진행 
반드시 sdkconfig의 설정과 별도의 esp함수가 필요하므로, 세부사항은 상위를 참조 

아래의 App Trace 예제를 보면, ADC Sampling을 하는데, 한번은 app trace를 이용하고 한번은 UART로 보여주는 방식으로 아주 기초적으로 사용하는 방식같다. 

  • Trace Log 분석 


3.  GDB 기반의 Visual Display 도구들 

JTAG을 사용하면, GDB는 사용해야 하며, 이 기반으로 손쉽게 디버깅할 수 있도록 하는 것이 중요한데, 예전것들 부터 보면 아래와 같다. 

  • gdbtui
gdb에서 제공하는 가장 기본적인 Dispaly로 문자 중심으로 표시를 해주는데, 사용한 일이 거의 없다.

  • ddd 
예전에 내가 많이 사용했던 GDB기반의 Display 이지만, Eclipse기반의 Tool들이 나오면서 거의 사용할일이 사실 없다.

  • Eclipse기반의 Tool들 
요즘 대부분의 유명 Chip Vendor사들은 회사마다 자신만의 Eclipse기반의 Tool을 가지고 있어 이 기반으로 손쉽게 gdb 를 사용가능하다.

  • gdbgui
이것은 이번에 나도 처음알게된 것인데 Web broswser 기반으로 동작하는데, 괜찮은 Tool 같은데, 처음 설정이 꼬이면, 제대로 동작이 안되는 것 같다.  

  • visualgdb
VisualStudio기반의 유료로 30일만 사용가능 (이전 OpenOCD에 자세히 설명)


3.1  ESP32 OpenOCD 기반의 GDB 사용법 

  • ESP32의 OpenOCD Ecplise 연결 방법 
ESP Manual을 보면 쉽게 Ecplise에 연결하고 gdbgui를 사용을 언급을 하고 있다. 
Ecplise 기반은 많이 해보았기에, gdbgui로 해보기로 하자. 

  • ESP32 TEST Program 기반 현재 상태 확인 
이전에 만들었던, exaplme로 간단하게 현재 상태를 간단히 분석해보고 gdb 명령과 gdb를 실행해보자.
$ source ~/esp/esp-idf/export.sh    // Ubuntu 20.04기반으로 해서 기본 Python 3으로 됨
Setting IDF_PATH to '/home/jhlee/esp/esp-idf'
Detecting the Python interpreter
Checking "python" ...
Command 'python' not found, did you mean:
  command 'python3' from deb python3
  command 'python' from deb python-is-python3
Checking "python3" ...
Python 3.8.5
"python3" has been detected
Adding ESP-IDF tools to PATH...
Using Python interpreter in /home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/python    // python3기반으로 virtulenv 설정
Checking if Python packages are up to date...
The following Python requirements are not satisfied:        // 다음과 같은 문제가 발생 , 다시 설치해도 동일 
gdbgui==0.13.2.0
pygdbmi<=0.9.0.2
To install the missing packages, please run "/home/jhlee/esp/esp-idf/install.sh"
Diagnostic information:
    IDF_PYTHON_ENV_PATH: /home/jhlee/.espressif/python_env/idf4.4_py3.8_env
    Python interpreter used: /home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/python


$ cat build/gdbinit  //gdb init 명령어확인
file /home/jhlee/project-name/build/app_trace_to_host.elf
target remote :3333
mon reset halt
flushregs
thb app_main
c


$ xtensa-esp32-elf-gdb -x build/gdbinit build/app_trace_to_host.elf   //gdb test 진행시 에러 발생 python 2.7필요  
xtensa-esp32-elf-gdb: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

$ ll /usr/bin/py*  //Ubuntu 20.04에는 python2 가 없음

$ which python
/home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/python

$ sudo apt-get install libpython2.7           //설치 진행 

$ xtensa-esp32-elf-gdb -x build/gdbinit build/app_trace_to_host.elf   //재진행
....
Type "apropos word" to search for commands related to "word"...
Reading symbols from build/app_trace_to_host.elf...done.
build/gdbinit:2: Error in sourced command file:
:3333: 연결 시간 초과.

  • OpenOCD와 GDB 기본 테스트 진행 
 $ idf.py openocd    //openocd 만 TEST 및 tcl/gdb/telnet server 동작확인 
Executing action: openocd
Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)
OpenOCD arguments default to: "-f board/esp32-wrover-kit-3.3v.cfg"
OpenOCD started as a background task 43585
Executing action: post_debug
Open On-Chip Debugger  v0.10.0-esp32-20200709 (2020-07-09-08:54)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : Configured 2 cores
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : Target halted. CPU0: PC=0x400D55BC (active)
Info : Target halted. CPU1: PC=0x400E4926
Info : Listening on port 3333 for gdb connections


$ idf.py openocd gdb                  // openocd 와 gdb TEST 진행 문제없음 
or 
$ idf.py openocd gdb   build/app_trace_to_host.elf   
........
esp32: Core 1 was reset.
Target halted. CPU0: PC=0x40000400 (active)
Target halted. CPU1: PC=0x40000400 
Hardware assisted breakpoint 1 at 0x400d55bc: file ../main/app_trace_to_host_example_main.c, line 92.
Target halted. CPU0: PC=0x400D55BC (active)
Target halted. CPU1: PC=0x400E4926 
[New Thread 1073446776]
[New Thread 1073444120]
[New Thread 1073430168]
[New Thread 1073434616]
[New Thread 1073413208]
[New Thread 1073437016]
[Switching to Thread 1073441464]

Thread 1 hit Temporary breakpoint 1, app_main () at ../main/app_trace_to_host_example_main.c:92
---Type return to continue, or q return to quit---
92      {
(gdb)  


$ idf.py openocd gdbtui   // 엔터를  몇번 치면 소스 가 보임 
or
$ idf.py openocd gdbtui  build/app_trace_to_host.elf   

   ┌──../main/app_trace_to_host_example_main.c────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
   │88       * and logging results with application tracing to the host                                                                                                                                                                           │
   │89       * as well as for comparison printing out sampling result to UART                                                                                                                                                                     │
   │90       */                                                                                                                                                                                                                                   │
   │91      void app_main(void)                                                                                                                                                                                                                   │
H+>│92      {                                                                                                                                                                                                                                     │
   │93          ESP_LOGI(TAG, "Enabling ADC1 on channel 6 / GPIO%d.", ADC1_CHANNEL_6_GPIO_NUM);                                                                                                                                                   │
   │94      #if CONFIG_IDF_TARGET_ESP32                                                                                                                                                                                                           │
   │95          adc1_config_width(ADC_WIDTH_BIT_12);                                                                                                                                                                                              │
   │96      #elif CONFIG_IDF_TARGET_ESP32S2                                                                                                                                                                                                       │
   │97          adc1_config_width(ADC_WIDTH_BIT_13);                                                                                                                                                                                              │
   │98      #endif                                                                                                                                                                                                                                │
   └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
remote Remote target In: app_main                                                                                                                                                                                             L92   PC: 0x400d55bc 
[New Thread 1073413208]
[New Thread 1073437016]
[Switching to Thread 1073441464]

---Type return to continue, or q return to quit---
Thread 1 hit Temporary breakpoint 1, app_main () at ../main/app_trace_to_host_example_main.c:92
(gdb)  quit 

3.2  OpenOCD 기반의 gdbgui  1차 TEST 진행 

결론적으로 제대로 사용해보지 못했으며, 원인은 Version 간의 문제로 보이며, 시간이 없어 이부분 추후에 다시 해보도록 하며, 관련내용을 아래에 기술한다. 
아래내용을 이해하기위해서는 python의 virtual env를 이해해야한다. 

  • gdbgui 만 별도 테스트 
gdbgui 의 경우만 제대로 동작이 되지 않아 이에 관련하여 별도로 테스트를 진행 

$ idf.py openocd gdbgui   // 제대로 실행은 되지만 Webbrowser 에서 제대로 동작되지 않음 
or
$ idf.py  openocd gdbgui monitor -p /dev/ttyUSB0  
Executing action: openocd
Note: OpenOCD cfg not found (via env variable OPENOCD_COMMANDS nor as a --openocd-commands argument)
OpenOCD arguments default to: "-f board/esp32-wrover-kit-3.3v.cfg"
OpenOCD started as a background task 33824
Executing action: gdbgui
gdbgui started as a background task 33825
Executing action: post_debug
Open On-Chip Debugger  v0.10.0-esp32-20200709 (2020-07-09-08:54)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : Configured 2 cores
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : Listening on port 3333 for gdb connections 

$ which gdbgui      
/home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/gdbgui

$ gdbgui   // idf에 기본설치된 gdbgui 만 테스트 진행 
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
Opening gdbgui with default browser at http://127.0.0.1:5000
exit gdbgui by pressing CTRL+C
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
frozen importlib._bootstrap:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
세그멘테이션 오류 (core dumped)   //idf에 기본설치된 gdbgui는 제대로 동작이 안됨

$ pip freeze | grep greenlet   //greenlet 문제로 보고 관련 version 확인 
greenlet==1.0.0

$ pip freeze | grep gdb*   //gdbgui version 확인 
gdbgui==0.13.2.0
pygdbmi==0.9.0.2

  • 일반 gdbgui 테스트 진행 (python3)
esp의 python  virtual env를 사용하지 않고 테스트진행 해야해서 상위 설정하지 않고 별도 설치 후 바로 테스트진행하니 문제없음  
$ which gdbgui        //pip3 install gdbgui 별도 설치 
/home/jhlee/.local/bin/gdbgui

$ gdbgui --version
0.14.0.2

$ pip3 freeze | grep greenlet
greenlet==0.4.16

$ gdbgui   //제대로 동작되는 것을 확인
Opening gdbgui with default browser at http://127.0.0.1:5000
View gdbgui dashboard at http://127.0.0.1:5000/dashboard
exit gdbgui by pressing CTRL+C 



  • esp  gdbgui upgrade 하기로 결정
esp 개발환경을 보면, python virtual env를 사용하는데, 내부에 gdbgui가 존재하며, 이를 upgrade를 진행하기로 결정함 
외부 python3.8  package가 아니며, virtual env 안에서만 upgrade 진행 
//source ~/esp/esp-idf/export.sh 진행했기때문에 esp virtual env 사용 
$ which gdbgui      //esp 개발안정버전 4.4 의 python virtual env에 gdbgui 가 설치됨 
/home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/gdbgui   //문제는 python3.8기반으로 구성되었으며, 나또한 python3으로 하고싶지만, 동작되지 않음 

$ gdbgui --version
0.13.2.0

$ pip install --upgrade gdbgui     //esp virtual env의 gdbgui upgrade 진행 

$ gdbgui --version
0.14.0.2

$ gdbgui //esp virtual env 에서도 gdbgui 기본동작되는 것확인완료 (역시 version문제)
Opening gdbgui with default browser at http://127.0.0.1:5000
View gdbgui dashboard at http://127.0.0.1:5000/dashboard
exit gdbgui by pressing CTRL+C

$ idf.py openocd gdbgui  // esp openocd 와 gdbgui 기본테스트 진행했지만, Version 문제발생 
The following Python requirements are not satisfied:
gdbgui==0.13.2.0
pygdbmi<=0.9.0.2
To install the missing packages, please run "/home/jhlee/esp/esp-idf/install.sh"
Diagnostic information:
    IDF_PYTHON_ENV_PATH: /home/jhlee/.espressif/python_env/idf4.4_py3.8_env
    Python interpreter used: /home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/python
....

$ vi ~/esp/esp-idf/requirements.txt  // version check 하는 부분 수정 (에러는 없어지지만, 제대로 동작되지 않음)

현재 나의 local에 설치하여 gdbgui 별도로 설치하여 동작되는 것을 확인 했지만, idf.py는 python virutal env기반으로 동작되기 때문에  version이 다르다. 
그래서 이를 업그레이드 했지만, idf.py의 내부에서 gdbgui 0.13.2.0 version check하는 부분이 있어 제대로 실행되지 않는다. 

version 체크 하는 부분까지도  다 고쳐서 사용할까도 생각했지만, 나중에 다시 테스트도 해야하니, 이 부분은 다시 원상복귀 하기도 결정했다.

상위와 유사한 상황

  • OpenOCD GDBGUI 1차 TEST 결론
OpenOCD와 TCL/GDB는 잘동작하지만, GDBGUI는 버그로 보인다. 
현재 아래 Manual (최신 Version 4.4) 로 보더라도, Python3으로 설치를 진행하라고 되어있는데, Python2가 필요한 거 보면, 현재도 개발중인 것으로 보이며, 
추후 시간이 된다면, Python2로 변경 후 다시 시도를 해보아도 괜찮을 것 같은데, 다른 부작용이 왠지 있을 것 같다. 


3.3  OpenOCD 기반의 gdbgui  2차 TEST 진행 

기존에 Python3만 동작되었기에, Python2 설치 후  virtual env도 Python2로 바꾸려고 했는데, 실패했다. 
현재 python2 설치되었으며, ESP32는 python3의 virtualenv를 그대로 사용함

$ sudo apt install python2 

$ sudo ln -s /usr/bin/python2 /usr/bin/python 

$ ~/esp/esp-idf/install.sh

일주일 후 다시 시도 후  갑자기 작동되는데, 이전에 왜 동작이 안되었는지 모르겠지만, 다음에 다시 시도 할 경우 다시 해봐야겠음 
며칠사이에 다른 것이 변경이 되었는지, 모르겠음 

$ cd ~/project-name   // 이전과 동일한 Project 
CMakeLists.txt  Makefile  README.md  build  debug.log  example_test.py  main  sdkconfig  sdkconfig.ci  sdkconfig.defaults  trace

$ . esp/esp-idf/export.sh 

$ which gdbgui
/home/jhlee/.espressif/python_env/idf4.4_py3.8_env/bin/gdbgui

$ gdbgui --version
0.13.2.0

$ idf.py openocd gdbgui 
or 
$ idf.py openocd gdbgui monitor -p /dev/ttyUSB1 

Web browser 기반으로 쉽게 Break Point를 쉽게 설정하고, 실행하니 편하다.

우측 정보기반으로 Ecplise 처럼 쉽게 Trace도 가능하다 

Web Browser에서 실행해서 좋은데, Ecplise 처럼 안정적이지는 못한것으로 보이는데, 잘 사용하면 괜찮을 것 같다.  

  • OpenOCD GDBGUI 2차 TEST 결론 
현재 잘 동작하며, 1차 TEST 때 왜 동작이 안되었는지가 다음에 다시 설치할 기회가 있다면, 다시 해보도록하자. 


3.4  Raspberry 를 이용한 OpenOCD 방법 


  • Raspberry Pi 와 ESP32 연결 
FTDI가 아닌 Raspberry를이용하여 OpenOCD 기반으로 JTAG으로  ESP32를 연결하는 방법인데, 새로운 방법이라 아직 시도는 안해봤지만, 추후 해보도록하자. 
상위와 거의 동일하며, FTDI 대신 Raspberry 로 변경된 것으로 보면된다. 추후 VS Code와 연결하여 Debug해보도록 해보자.