기술나눔

STM32 충돌 문제 해결

2024-07-08

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

머리말

최근에 다른 플랫폼의 일부 코드를 STM32에 병합한 후 충돌 문제가 발생한다는 사실을 발견하여 STM32의 충돌 문제 해결 원칙을 전체적으로 정리하고 싶었습니다.

1. 문제 설명

여기에 이미지 설명을 삽입하세요.
위 내용은 크래시 프린트 정보 중 하나입니다. 조사 결과, FreeRTOS의 타이머 스택 깊이가 너무 작게 설정되어 타이머 실행 기능에서 실행 중인 콘텐츠가 너무 많고, 각 로컬 변수에 적용되는 메모리가 부족한 것으로 나타났습니다. 제 시간에 출시되지 않았고 결국 충돌이 발생했습니다.

FreeRTOS의 타이머에 대해 이야기해 보겠습니다. 이는 실제로 시간을 유지하기 위해 스레드를 만든 다음 현재 타이머 목록을 폴링하고 쿼리하여 어떤 타이머의 실행 시간이 만료되었는지 확인하는 것과 동일한 작업으로 이해될 수 있습니다. 그것.

따라서 타이머가 사용하는 메모리 크기도 구성해야 합니다.

2. STM32 레지스터(Cortex M4 코어)

여기에 이미지 설명을 삽입하세요.
R0~R12는 범용 레지스터입니다.

R13은 스택 포인터이며 물리적으로 두 개의 스택 포인터가 있습니다.메인 스택 포인터(MSP)는 재설정 후 사용하기 위해 선택되는 기본 스택 포인터이며, 프로세서가 처리 모드에 있을 때 다른 스택 포인터는 스레드에서만 사용할 수 있는 프로세스 스택 포인터(PSP)입니다. 모드(RTOS가 있는 경우) )

R14는 함수나 서브루틴이 호출될 때 반환 주소를 저장하는 데 사용되는 링크 레지스터(LR)입니다. 함수 또는 서브루틴이 끝나면 프로그램 제어는 LR 값을 프로그램 카운터(PC)에 로드하여 호출 프로그램으로 돌아갈 수 있으며 예외 처리 중에 LR은 자동으로 특수 EXC_RETURN(예외 반환)으로 업데이트됩니다. ) 값.

예를 들어, a는 b를 호출합니다. 이때 b 하위 함수의 주소는 pc 포인터에 배치되고 a의 주소는 b가 실행된 후 PC 포인터에 배치됩니다. 실행을 위해 LR에서.

3. 충돌 문제 분석

3.1 충돌 정보는 어디에서 나오나요?

Arm 충돌은 실제로 비정상적인 인터럽트입니다. 인터럽트가 발생하면 프로세서는 현재 작업 상태를 스택에 저장합니다.

  • 스택 프레임
    여기에 이미지 설명을 삽입하세요.
    스택 프레임은 함수 호출 중에 함수 매개변수, 지역 변수, 반환 주소 및 기타 정보를 저장하는 데 사용되는 메모리 영역을 나타냅니다.

    함수가 호출되면 STM32는 이에 대한 스택 프레임을 할당합니다. 스택 프레임의 크기는 매개변수 수, 지역 변수 수 및 컴파일러의 최적화 설정과 같은 요소에 따라 달라집니다.

    위의 정보를 결합하면 함수가 충돌했을 때 어떤 함수가 충돌했는지 확인하려면 예외 인터럽트가 트리거되었을 때 스택에 푸시된 스택 프레임을 찾아야 하며 이 스택 프레임은 R13에 있음을 알 수 있습니다. (스택 포인트) 스택 포인터가 저장되었습니다.

    충돌 처리 함수 HardFault_Handler()에서 R13 레지스터의 포인터가 가리키는 내용을 가져온 다음 인쇄하는 방법을 찾았습니다.

3.2 크래시 정보에 포함된 각 키워드의 의미

STM32 마이크로컨트롤러는 두 개의 스택 포인터가 있는 ARM Cortex-M 코어를 사용합니다. 하나는 메인 스택 포인터(MSP)이고 다른 하나는 프로세스 스택 포인터(PSP)입니다.

MSP(메인 스택 포인터): 메인 스택 포인터는 주로 운영체제 커널이나 인터럽트 서비스 루틴에 사용됩니다.

PSP(프로세스 스택 포인터): 프로세스 스택 포인터는 주로 사용자 응용 프로그램에서 사용됩니다.

Cortex-M 코어가 스레드 모드로 돌아가면 CONTROL 레지스터의 설정에 따라 메인 스택 포인터 MSP 또는 프로세스 스택 포인터 PSP로 다시 전환할 수 있습니다.

PSP는 실행 중인 사용자 애플리케이션과 관련된 컨텍스트를 저장합니다. 구체적으로 다음을 포함합니다.

一些或全部的通用寄存器的值,这些寄存器在用户程序运行时会使用。

Program Counter(PC):指向下一条将要执行的指令。

Processor Status Register(PSR)的值:包含标志位状态。

스택 포인터: 이전 스택 프레임의 위치를 ​​저장합니다.

일반적으로 작업 전환(또는 컨텍스트 전환) 시 이 정보는 스택에 저장됩니다. 새 작업이 시작되면 해당 컨텍스트 정보가 스택에서 복원됩니다.

저장되는 특정 콘텐츠는 특정 일정 전략 및 운영 체제 설계에 따라 달라질 수 있습니다.

3.3 충돌 정보를 활용해 충돌 원인 파악

LR/PC 포인터 값 결정
여기에 이미지 설명을 삽입하세요.
먼저 RTOS가 사용되는지 확인해야 합니다. 그렇다면 충돌 정보를 PSP에 저장해야 합니다.
이 정보를 먼저 읽어야 하고, 그 다음 LR과 PC의 값을 알고 나면 keil5의 Debug를 통해 크래시 지점을 찾거나 컴파일 과정에서 생성된 맵 파일을 통해 해당 크래시 지점을 찾을 수 있습니다.
여기에 이미지 설명을 삽입하세요.

3.4 keil5의 주소를 기반으로 문제 지점을 찾는 방법

디스어셈블리 창을 마우스 오른쪽 버튼으로 클릭합니다.