Electrical Study

STM32CubeIDE로 UART Interrupt Debugging 하기

Torrance 2025. 2. 26. 11:01

STM32CubeIDE로 Debugging을 해보겠습니다.

Debugging이란 프로그램의 버그(오류)를 찾아 수정하는 과정입니다.
컴퓨터 초창기에는 진짜 벌레가 들어가 오류가 발생했고 그래서 디버그라는 이름이 붙었습니다.

이미 환경이 구성되어 있다는 가정하에 시작하겠습니다.

제가 참고한 자료들의 링크를 첨부하니 참고하시길 바랍니다.

 

목차

  • 하드웨어 및 개발 환경
  • Interrupt Debugging 과정
  • Interrupt Debugging 분석

하드웨어 및 개발 환경

2025.02.18 - [Electrical Study] - STM Project 사용된 하드웨어 및 개발 환경

 

STM Project 사용된 하드웨어 및 개발 환경

개발 보드 : NUCLEO-F103RB (내돈내산)https://smartstore.naver.com/muwonkorea/products/10807059000?nl-query=stm32+nucleo-64&nl-ts-pid=iI2r6wqVN8oss6q76kGssssstUw-516721&NaPm=ct%3Dm732kqqo%7Cci%3Dd457cba2010db1ab1f95e32278f0c7d6b24d79ad%7Ctr%3Dsls%7C

semiconwide.tistory.com

Debugging 할 프로젝트

2025.02.18 - [Electrical Study] - STM32CubeIDE UART 사용해 printf 출력하기


Interrupt Debugging 과정

참고 자료 : 3. [STM32] 디버깅

단축키는 6개만 주로 씁니다.

Ctrl F2 : 디버깅 중지

Ctrl Shift b : Break Point Toggle

F5 : Step Into(call 된 함수 안으로 계속 들어가면서 진행)
F6 : Step Over(main 함수에서만 1줄씩 진행)
F8 : 실행 재개(Resume)
F11 : 디버그 모드로 실행


Interrupt 하는 부분을 디버깅할 것이기 때문에 if 문 앞에서 커서를 놓은 후 Break Point Toggle(Ctrl Shift b)을 걸어줍니다.


main에서 F11로 디버그 모드로 실행합니다. Switch를 눌러 Debug 화면으로 전환해 줍니다.

 

F8을 누르면 HAL_Init();을 빠져나옵니다.

여기에 putty를 연결 후 키보드 interrupt를 유발할 수 있도록 아무 키나 누르면 이렇게 line 238에 설정한 Break Point Toggle에 의해 멈추게 됩니다.


이제 디버깅 화면에 나온 것들을 분석해보겠습니다.


Interrupt Debugging 분석


1️⃣ Instance (USART_TypeDef *)

  • 0x40004400 → USART2의 메모리 주소로, USART2를 사용 중

2️⃣ 송신 관련 (Tx - Transmit)

  • pTxBuffPtr = 0x0 → 송신할 데이터가 없음
  • TxXferSize = 0 → 현재 송신할 데이터 크기가 0
  • TxXferCount = 0 → 송신할 데이터 개수도 0

3️⃣ 수신 관련 (Rx - Receive)

  • pRxBuffPtr = 0x20000239 → 수신 버퍼가 설정됨 (데이터가 들어올 공간 있음)
  • RxXferSize = 1 → 수신할 데이터 크기 1바이트 (즉, 1바이트씩 인터럽트 수신 중)
  • RxXferCount = 0 → 현재 남아있는 수신할 데이터 개수

4️⃣ UART 상태 (gState & RxState)

  • gState = HAL_UART_STATE_READY → UART 송신 가능 상태
  • RxState = HAL_UART_STATE_READY → UART 수신도 준비됨

5️⃣ DMA (hdmarx)

  • hdmarx = 0x0 → DMA를 사용하지 않고 있음.
  • 즉, HAL_UART_Receive_DMA()가 아니라 HAL_UART_Receive_IT() 기반으로 동작

6️⃣ ReceptionType & RxEventType   

  • ReceptionType과 RxEventType이 있음 → 인터럽트 기반 수신을 사용 중

Memory Brower 분석


Instance(0x200001F0) = 0x40004400 → USART2

Init.BaudRate(0x2000001F4) = 0x2580 (9600)


pTxBuffPtr(0x200001F8)= 0x00000000 → TX 버퍼 없음

TxXferSize (0x200001FC)= 0x00000000 → TX 데이터 크기 0

TxXferCount (0x20000200)= 0x00000000 → TX 남은 데이터 0

 

pRxBuffPtr(0x20000204)= 0x00000000 → RX 버퍼 없음

RxXferSize (0x20000208)= 0x20000239 → RX 버퍼 크기

RxXferCount (0x2000020C)= 0x00000000 → RX 남은 데이터 0


다른 글에는 없지만 Debugging 글에서는 제 이야기를 바탕으로 중요성을 이야기 하겠습니다.

제가 가장 처음 배운 언어는 C언어입니다. 반복문을 배울 때 값들의 변화를 머릿 속으로만 생각하는 것이 참 어려웠습니다. 지금에야 당연히 중간에 printf를 써서 중간 결과 값을 확인하면 됐지만 저는 코딩에 재능이 딱히 없기 때문에 그런 생각은 하지 못한 것 같습니다.

그 때 C 언어를 하면서 코딩에 흥미를 잃었고 코드는 만지지 않고 싶었습니다. 하기 싫은 일을 업으로 삼는다고 하죠. 역시 다 코드를 만지고, 현재는 코드를 엄청 만지고 있습니다. 이래서 뭐 싫어하면 안됩니다. 결국은 가장 가까이 하게 됩니다.

그 이후 뭔가 어려울 때마다 이렇게 차례로 중간 결과를 출력해주는 것이 해당 문제를 해결해줬습니다. 이제는 개발을 시작할 때 디버깅 환경을 먼저 구성해야 겠습니다. 긴 글 읽어주셔서 감사합니다. 


2025/02/26 ver 0