Cortex-M4(F) Lazy Stacking and Context Switching (2)

Handling of context switching in a RTOS

Cortex-M4F를 지원하는 RTOS를 설계할 때 컨텍스트 스위칭 코드가 lazy stacking 메커니즘을 인식하는 것이 중요합니다.

응용 프로그램 작업의 부동 소수점 사용에 따라 부동 소수점 컨텍스트 스위칭을 위한 가능한 예시는 세 가지 다른 경우로 나눌 수 있습니다.

  • 모든 애플리케이션 작업에서 부동 소수점 연산 없음
  • 하나의 애플리케이션 작업만 FPU를 사용합니다.
  • 여러 애플리케이션 작업에서 FPU를 사용합니다.

사례 1: 애플리케이션 작업에서 부동 소수점 연산 없음

애플리케이션 작업이 FPU를 사용하지 않은 경우(EXC_RETURN[4]=1로 표시됨) 부동 소수점 컨텍스트 저장을 처리할 필요가 없습니다(그림 7 참조).

일반적으로 OS 작업 스케줄러는 정기적으로 실행됩니다(예: SysTick 타이머에 의해 트리거됨). 컨텍스트 전환 작업은 PendSV 예외(exception) 핸들러에서 수행되는 것이 일반적입니다. 컨텍스트 전환이 필요한 경우 OS는 PendSV 예외의 보류 상태 비트를 설정하여 컨텍스트 전환을 요청할 수 있습니다. PendSV 처리기는 SysTick 처리기 이후와 새 작업 컨텍스트 이전에 실행됩니다.

Note :

  • PendSV는 Cortex-M 프로세서의 표준 예외 유형입니다. 시스템 수준 서비스에 대한 인터럽트 기반 요청입니다. OS 환경에서 다른 예외가 활성화되지 않은 경우 컨텍스트 전환을 위해 PendSV를 사용할 수 있습니다.
  • 특정 OS의 구현에 따라 컨텍스트 전환을 처리하는 다른 방법이 있습니다.

인터럽트 핸들러를 다룰 때:

  • 여러 인터럽트 핸들러가 FPU를 사용하고 이러한 인터럽트가 중첩될 수 있는 경우 이러한 인터럽트 핸들러에 대한 컨텍스트 저장은 lazy stacking 메커니즘에 의해 처리됩니다.
  • 하나의 인터럽트 핸들러가 FPU를 사용하거나 여러 개의 인터럽트 핸들러가 FPU를 사용하지만 이러한 인터럽트의 우선 순위가 중첩이 허용되지 않도록 설정되어 있는 경우, 인터럽트 핸들러가 작업을 완료한 후 부동 소수점 상태를 보존할 필요가 없습니다. 이러한 경우 부동 소수점 레지스터의 자동 저장을 비활성화할 수 있습니다.
  • 인터럽트 핸들러에 FPU가 필요하지 않은 경우 FPU를 비활성화할 수 있으며 FPU가 없는 Cortex-M4 프로세서처럼 작동합니다.

Note : FPU를 비활성화하면 전력소빌흘 줄일 수 있습니다.

ARM은 부동 소수점 연산이 우발적으로 사용되지 않도록 컨텍스트 전환 중에 OS 내의 컨텍스트 전환 코드에서 EXC_RETURN 비트[4]를 확인하도록 권장합니다. 예를 들어 프로젝트로 내보낸 라이브러리 개체는 부동 소수점 명령어로 컴파일되었을 수 있습니다.

사례 2: 하나의 애플리케이션 작업만 FPU를 사용

FPU에 대한 작업을 처리할 때:

  • 하나의 애플리케이션 작업만 FPU를 사용하고 인터럽트 핸들러가 사용하지 않는 것으로 알려진 경우 부동 소수점 컨텍스트 저장 절차를 생략할 수 있습니다.
  • 인터럽트 처리기가 응용 프로그램 작업 중 하나에 추가하여 FPU를 사용하는 경우 ASPEN=1을 설정하여 자동 저장 기능을 활성화해야 합니다. 가능하면 더 짧은 인터럽트 대기 시간을 허용하기 위해 LSPEN=1을 설정하여 lazy stacking 기능을 활성화할 수 있습니다. LSPEN과 ASPEN 모두 기본적으로 1로 설정되기 때문에 중첩된 인터럽트 시나리오 내에서 인터럽트 핸들러에 대한 컨텍스트 저장은 lazy stacking 메커니즘에 의해 자동으로 처리됩니다.
  • FPU를 사용하는 인터럽트 핸들러가 없으면 LSPEN과 ASPEN을 모두 0으로 설정할 수 있습니다. 이러한 방식으로 부동 소수점 컨텍스트를 위한 공간을 예약하지 않아도 되므로 스택 공간을 줄일 수 있습니다.

OS가 Cortex-M3 프로세서에서 포팅되는 경우 EXC_RETURN 값의 비트[4]를 올바르게 처리하도록 컨텍스트 스위칭 코드를 업데이트해야 합니다. 또한 각 컨텍스트 스위칭에서 EXC_RETURN 비트[4]를 확인하여 다른 작업이 예기치 않게 FPU를 사용하지 않았는지 확인해야 합니다.

사례 3: FPU를 사용하는 여러 애플리케이션 Task

컨텍스트 스위칭을 처리하는 간단한 방법은 17페이지의 그림 8과 같이 모든 부동 소수점 레지스터를 항상 저장하고 복원하는 것입니다.

일반적으로 PendSV 예외 내에서 발생하는 컨텍스트 전환 중에 프로세서는 VSTM 명령(Floating-point Store Multiple 명령이라고도 함)을 실행합니다. 그림 8과 같이 OS 구현에 따라 여러 부동 소수점 레지스터를 메모리에 저장하여 S16 ~ S31 레지스터를 프로세스 스택 또는 작업 제어 블록(TCB)의 컨텍스트 데이터에 저장합니다.

VSTM 명령이 실행되기 전에 프로세서는 이전 컨텍스트의 S0-S15 레지스터 및 FPSCR이 아직 스택에 저장되지 않은 동안 새 컨텍스트에서 FPU의 사용을 감지합니다(FPCCR의 LSPACT 비트로 표시됨). 이렇게 하면 보류 중인 lazy stacking 이 트리거되어 부동 소수점 레지스터 S0-S15 및 FPSCR이 FPCAR에서 지정한 메모리 위치로 푸시됩니다.

그런 다음 컨텍스트 전환 스위칭는 FPU의 레지스터 S16에서 S31에 대한 다음 작업의 컨텍스트를 복원할 수 있습니다. 레지스터 S0 S15의 복원 및 FPSCR은 PendSV 예외가 종료될 때 예외 반환에서 처리될 수 있습니다. EXC_RETURN[4] 및 LSPACT를 모두 0으로 설정하면 레지스터 S0-S15 및 FPSCR의 복원이 자동으로 수행됩니다.

이 일련의 처리들에서 FPU가 필요한 작업에 대한 각 컨텍스트 스위치는 부동 소수점 레지스터의 저장 및 복원을 처리하기 위해 레지스터 S0-S31 및 FPSCR을 사용하는 최소 2 x 34 = 68 사이클과 컨텍스트 스위칭 소프트웨어의 추가 사이클을 필요로 합니다. EXC_RETURN에서 비트[4]의 상태를 확인하십시오. EXC_RETURN[4] 비트의 검사는 컨텍스트 스위칭 소프트웨어 내에서 수행되어야 합니다.

기타 고려 사항

새 애플리케이션 작업을 생성할 때 부동 소수점 레지스터 없이 리턴 스택을 사용하려면 EXC_RETURN[4]를 1로 설정해야 합니다.

Note

  • CONTROL.FPCA 비트, 즉 CONTROL 레지스터의 비트[2]가 부동 소수점 연산의 결과로 설정되면 해당 응용 작업에 대해 HIGH로 유지됩니다. 이 애플리케이션 작업이 일시 중단되면 이 정보는 EXC_RETURN[4]에 저장됩니다.

— EXC_RETURN의 비트[4]는 CONTROL.FPCA가 1인 경우 LOW입니다.

  • 작업에서 더 이상 FPU가 필요하지 않다고 판단하면 CONTROL.FPCA 비트를 지울 수 있습니다. 저장된 EXC_RETURN[4]은 작업이 마지막으로 선점되었을 때 이 비트가 스택 프레임의 크기를 나타내기 때문에 프로세스가 일시 중단될 때 작업 스케줄러에 의해 변경되지 않아야 합니다.

여러 작업에서 FPU를 사용하는 시스템을 처리할 때 컨텍스트 스위칭 코드는 다음 방법 중 하나로 설계할 수 있습니다.

  1. FPU의 컨텍스트는 항상 저장되고 복원됩니다.
  2. 관련 EXC_RETURN[4] 값이 0인 경우에만 FPU의 컨텍스트가 저장되고 복원됩니다. 이는 태스크가 실행 중일 때 컨텍스트 스위칭 코드를 입력하기 전에 CONTROL.FPCA의 값이 1이었다는 것을 의미합니다.

첫 번째 방법은 더 간단하지만 각 컨텍스트 전환에 더 오래 걸리고 더 많은 메모리 공간이 필요합니다.

ARM의 권장사항은 다음과 같습니다.

  • C 컴파일러는 부동 소수점 연산이 없을 때 부동 소수점 명령을 생성하지 않습니다.
  • 런타임 라이브러리의 함수는 부동 소수점 연산을 포함하지 않는 경우 부동 소수점 명령을 포함하지 않습니다.

이러한 권장 사항을 따르지 않으면 인터럽트 대기 시간, 스택 메모리 크기 및 컨텍스트 스위칭 시간이 늘어납니다. 자세한 내용은 26페이지의 도구 지원 고려 사항을 참조하십시오.

Alternative context switching scheme

Concept of the lazy stacking context switching strategy

lazy stacking을 기반으로 하는 대체 컨텍스트 스위칭 메커니즘을 개발할 수 있습니다. 이는 클래식 ARM 프로세서용 Linux 커널에 구현된 지연 FPU 스택과 유사합니다.

이 방법은 필요한 경우에만 FP 레지스터의 저장 및 복원을 수행하도록 Cortex-M4F에서 지연 컨텍스트 저장 메커니즘을 활용하려고 시도합니다. 예를 들어 FPU를 사용하는 애플리케이션 프로세스가 하나만 있는 경우 그림 9와 같이 부동 소수점 레지스터의 컨텍스트 저장을 수행할 필요가 없습니다.

컨텍스트 스위칭 중에 다른 애플리케이션 작업으로 전환하면 FPU가 비활성화됩니다. OS가 컨텍스트를 FPU를 사용한 마지막 프로세스로 다시 전환하면 컨텍스트 스위칭 코드에 의해 장치가 다시 활성화됩니다. FPU가 비활성화되더라도 내부 컨텍스트 정보는 유지됩니다. FPU의 비활성화 또는 활성화는 주소 0xE000ED88에서 CPACR(Co-Processor Access Control Register)을 사용하여 처리할 수 있습니다.

다른 애플리케이션 작업이 FPU를 사용하고 FPU가 비활성화된 경우 결함 예외가 트리거됩니다.

  • 사용 오류 예외가 활성화되고 우선 순위가 허용하는 경우 사용 오류 처리기가 실행되고 그렇지 않으면
  • HardFault 예외 처리기가 실행됩니다.

이 경우 오류 예외 처리기는 FPU를 활성화하고 PendSV 보류 상태를 설정하여 컨텍스트 스위칭 프로세스를 트리거할 수 있습니다(20페이지의 그림 10 참조).

PendSV를 실행하는 동안 첫 번째 부동 소수점 명령을 실행할 때 lazy stacking 작업을 트리거하여 태스크 A가 선점되었을 때 레지스터 S0-S15 및 FPSCR을 예약된 스택 공간에 저장합니다.

컨텍스트 스위칭, 즉 PendSV의 프로세스를 보다 철저하게 살펴보려면 21페이지의 그림 11을 참조하십시오.

오류 예외(fault exception)는 다른 오류 조건에 의해 트리거될 수 있으므로 오류 예외 처리기 HardFault 또는 Usage Fault는 먼저 다양한 오류 상태 레지스터와 CPACR 레지스터의 상태를 확인해야 합니다.

  • FPU가 꺼진 경우, 즉 CPACR의 CP10 및 CP11 필드가 0이고 사용 오류 상태 레지스터의 NOCP(No Coprocessor Usage Fault) 비트[3]가 1인 경우

OS는 다음을 충족해야 합니다.

— NOCP 비트를 지웁니다.

— FPU 활성화(CP10 및 CP11)

— PendSV 보류 상태 설정

— 컨텍스트 전환 제어를 위해 OS에서 사용하는 소프트웨어 변수를 업데이트합니다.

  • FPU가 이미 켜져 있고 NOCP 비트가 1이면 Falut은 다른 보조 프로세서에 대한 액세스 거부와 관련이 있습니다.
  • NOCP 비트가 0이면 fault는 보조 프로세서에 대한 액세스 거부로 인해 발생하지 않습니다.

인터럽트 서비스 루틴 중 FPU를 사용해야 하는 경우 PendSV 작업이 약간 다릅니다. 결과적으로 NOCP fault 조건을 처리하기 위한 fault 핸들러는 FPU가 애플리케이션 태스크 또는 인터럽트 서비스 루틴에서 호출되는지 여부를 결정하기 위해 스택된 IPSR을 확인해야 합니다. 이 정보를 얻은 후 fault 핸들러는 그에 따라 PendSV에서 사용하는 소프트웨어 변수를 설정할 수 있습니다. 이러한 방식으로 PendSV 예외는 부동 소수점이 인터럽트 서비스 루틴에 의해 사용될 때 부동 소수점 레지스터 저장을 다르게 처리할 수 있습니다.

hard fault 핸들러가 실행된 후 FPU를 사용하고 NOCP 오류를 트리거한 인터럽트 서비스 루틴이 재개되고 첫 번째 부동 소수점 명령의 실행을 시작합니다. 이렇게 하면 lazy stacking이 트리거되어 레지스터 S0-S15 및 FPSCR이 FPCAR가 가리키는 스택 공간으로 푸시됩니다. 나머지 부동 소수점 레지스터 S16-S31은 인터럽트 서비스 루틴에 의해 수정되는 경우 AAPCS 요구 사항인 ISR 자체에 의해 저장되어야 합니다.

23페이지의 그림 12 및 그림 13에서는 ISR에서 지연 스택 컨텍스트 전환 체계와 함께 부동 소수점 명령을 사용하는 방법을 보여줍니다.

23페이지의 그림 13에서는 ISR에서 lazy stacking 컨텍스트 스위칭 체계를 사용하여 부동 소수점 명령어를 사용하는 방법을 보여줍니다.

ISR이 완료된 후 PendSV 예외가 실행됩니다. 그러면 PendSV는 다음을 수행할 수 있습니다.

  • FPU 비활성화
  • 작업 제어 블록(TCB)에 S16-S31의 값을 저장하고 작업 A에 대한 부동 소수점 레지스터 내용이 저장되었음을 나타내도록 OS의 소프트웨어 변수를 업데이트합니다.
  • 다음에 작업 A가 재개되면 스택과 TCB에서 모든 부동 소수점 레지스터를 다시 로드합니다.

장치가 활성화될 때 FPU를 사용하는 ISR이 트리거되는 경우 인터럽트 서비스 루틴이 FPU를 사용할 때 트리거되는 오류 예외는 없습니다. 이러한 경우 부동 소수점 레지스터 저장은 OS가 없는 소프트웨어에서 일반 부동 소수점 컨텍스트 저장과 동일합니다.

FPU를 사용하는 ISR이 컨텍스트 스위칭 중, 즉 PendSV 예외 중에 트리거되고 FPU가 비활성화된 후 인터럽트 트리거링이 발생하면 fault handler는 PendSV 보류 상태를 설정하고 이후에 PendSV 예외로 다시 진입합니다. 그리고 현재 PendSV가 프로세스를 완료합니다. 이 경우 PendSV 예외가 연속으로 두 번 실행됩니다.

PendSV 핸들러의 두 번째 실행은 FPU를 다시 비활성화합니다. 이 lazy stacking 컨텍스트 전환 체계를 사용하려면 FPCCR의 ASPEN 및 LSPEN 비트가 모두 기본 설정인 1로 설정되어야 합니다.

Comparison of the two approaches

표 3은 두 접근 방식 모두 고유한 이점이 있음을 보여줍니다.

대부분의 경우 실제 벤치마킹을 수행하지 않는 한 lazy stacking 방식을 사용하여 실제 성능 이득 또는 잠재적 손실을 예측하기 어려울 수 있습니다.

Additional considerations

컨텍스트 전환을 위한 지연 쌓임 접근 방식에는 다음과 같은 추가 고려 사항도 있습니다.

  • NMI(Non-Maskable Interrupts) 및 HardFault 핸들러는 부동 소수점 연산을 사용하지 않아야 합니다.
  • 사용 fault가 FPU 활성화를 처리하는 데 사용되는 경우 FPU를 필요로 하는 모든 인터럽트 서비스는 사용 fault 핸들러보다 우선 순위가 낮아야 합니다.
  • 프로그램 코드에 부동 소수점 연산이 포함되어 있지 않으면 컴파일러에서 생성한 코드와 런타임 라이브러리가 부동 소수점 명령을 생성하지 않아야 합니다. 26페이지의 도구 지원 고려 사항을 참조하십시오.
  • 작업 중인 응용 프로그램에서도 오류 처리기를 사용해야 하는 경우 OS fault 핸들러를 먼저 실행한 다음 오류가 FPU 트래핑으로 인해 발생하지 않은 경우 fault 핸들러로 분기해야 합니다.
  • 애플리케이션 작업은 FPU 자체를 활성화해서는 안 됩니다. 따라서 CPACR에서 CP10과 CP11을 설정해야 합니다. 그렇지 않으면 다른 작업의 컨텍스트가 저장되지 않고 결과적으로 손실됩니다.

Note

— CPACR은 32비트 레지스터입니다. CP10과 CP11은 모두 2비트 길이를 가집니다. CP10은 비트[21:20]를 커버하고 CP11은 비트[23:22]를 커버합니다. 레지스터의 나머지 부분은 비트[19:0] 및 비트[31:24]를 포함하여 예약됩니다.

— CP10, CP11 및 CMSIS(Cortex Microcontroller Software Interface Standard) 호환 드라이버를 설정하려면 다음을 사용할 수 있습니다.

SCB->CPACR = (0x3 << (10*2)) | (0x3 << (11*2))

Tool support considerations

Compilers and runtime library implications

Lazy stacking 전략으로 설계된 OS 콘텐츠 스위칭은 도구 체인, 즉 컴파일러와 런타임 라이브러리가 특정 방식으로 작동해야 합니다. 그렇지 않으면 이러한 OS가 작동하지 않거나 성능이 매우 저하될 수 있습니다. 이러한 요구 사항의 대부분은 요구 사항 1과 2에 나열되어 있습니다. 부동 소수점 컨텍스트 항상 저장 전략을 사용하는 OS 컨텍스트 전환도 이러한 요구 사항을 활용할 수 있습니다.

Requirement 1

컴파일러는 부동 소수점 자체를 사용하지 않는 코드에 대해 부동 소수점 명령어를 생성해서는 안 됩니다.

Note : 부동 소수점 사용에는 부동 소수점 인수가 있는 함수 호출이 포함됩니다.

requirement 1이 충족되지 않으면 많은 작업 및 프로세스에서 부동 소수점 명령이 생성될 수 있습니다. 이는 인터럽트 처리의 대기 시간에 영향을 미칠 뿐만 아니라 컨텍스트 스위칭의 오버헤드를 증가시킬 수 있습니다. OS 코드가 애플리케이션과 함께 컴파일되는 상황은 최악일 수 있습니다. 이러한 경우 OS 코드에 부동 소수점 명령어가 포함될 수 있습니다. 이 문제는 EABI(Embedded Application Binary Interface) 표준이 비부동 소수점 연산에 FPU 사용을 허용한다는 사실로 인해 더욱 복잡해집니다. 예를 들어 코드가 FPU를 사용할 수 있음을 지정하는 컴파일 옵션으로 컴파일되고 컴파일되는 함수가 데이터 처리를 위해 많은 레지스터를 필요로 하고 결국 일반 레지스터 뱅크의 레지스터를 완전히 활용하는 경우 C 컴파일러는 일부를 사용할 수 있습니다. FPU의 레지스터를 임시 데이터 저장소로 사용합니다.

Note : 이러한 일련의 작업은 캐시 누락이 있는 경우 메모리 액세스에 매우 오랜 시간이 걸릴 수 있는 애플리케이션 프로세서에 적합하기 때문에 EABI에서 허용됩니다. 그러나 Cortex-M4F를 대상으로 하는 임베디드 애플리케이션에서는 인터럽트 속도가 훨씬 더 높을 수 있으며 부동 소수점 컨텍스트 전환 오버헤드로 인해 시스템 성능이 저하될 수 있습니다.

다른 컴파일러 옵션을 사용하여 소프트웨어 파일을 개별적으로 컴파일하고 부동 소수점 기능을 사용하는 응용 프로그램 프로세스만 부동 소수점 옵션으로 컴파일되도록 나중에 개체 파일을 함께 연결할 수 있습니다.

Note : 이 방법은 gcc 도구 체인 사용자에게 적합하지 않을 수 있습니다. gcc 기반 도구 체인을 제공하는 대부분의 C 컴파일러 공급업체는 gcc를 사용하면 컴파일 및 연결 단계를 분리하면 오류가 발생하기 쉬울 수 있기 때문에 고객이 한 단계로 애플리케이션을 컴파일하고 연결하도록 권장합니다.

Requirement 2

런타임 라이브러리 함수는 부동 소수점 함수가 아닌 한 FPU를 사용해서는 안 됩니다.

유일한 특수 사례는 다음과 같습니다.

1. print() 또는 printf() 함수 계열

2. setjmp() 및 longjmp() 함수.

이는 requirement 1과 유사하며 부동 소수점 명령을 사용하면 컨텍스트 스위칭 및 인터럽트 서비스에서 오버헤드가 증가할 수 있습니다.

이상적으로는 도구 체인이 다음을 수행할 수도 있습니다.

1. 애플리케이션 코드에서 부동 소수점 데이터를 직접 사용한 결과로 부동 소수점 사용이 발견되면 오류를 보고하도록 소스를 컴파일할 수 있는 컴파일 스위치(and/or pragma)를 제공합니다. 이렇게 하면 예를 들어 매크로 또는 인라인 어셈블리 코드를 통해 또는 자동 캐스팅된 인수에서 실수로 부동 소수점 연산을 사용하는 것을 감지하는 데 도움이 됩니다.

추가적으로,

a. 런타임 함수를 통한 부동 소수점 사용은 인수 또는 반환 값에 의해서만 감지되는 것으로 가정합니다.

b. 컴파일러는 부동 소수점 연산을 포함하지만 부동 소수점 인수나 반환 값을 사용하지 않는 함수에 대한 호출을 감지할 수 없음을 이해합니다.

2. 상위 16개 단정밀도 FPU 레지스터를 사용하지 않도록 지정하는 컴파일 스위치를 제공합니다. 예를 들어 최소 레지스터 압력이 있고 상위 16개 레지스터를 사용하지 않는 경우와 같이 부동 소수점이 많이 사용되지 않는 경우 컨텍스트 스위칭 시간이 단축됩니다.

3. lazy stacking 컨텍스트 저장 전략이 사용될 때 디버거가 NOCP에 대한 벡터 포착을 활성화하지 않도록 합니다. 그렇지 않으면 NOCP 오류가 발생할 때 프로세서가 자동으로 정지됩니다. 디버거는 부동 소수점 레지스터에 대한 액세스도 허용해야 합니다.

Current tool status

표 4는 이미 Cortex-MF4를 지원하는 개발 도구 체인의 수를 보여줍니다.

Runtime library

다음으로 구성됩니다.

• 현재 Cortex-M용 memcpy() 및 printf() 함수는 부동 소수점 명령을 사용하지 않습니다.

• mathlib의 일부 함수에는 부동 소수점이 아닌 데이터에 대한 부동 소수점 명령이 포함될 수 있습니다.

Keil MDK-ARM 4.21(armcc v4.1.0.713) 또는 armcc 버전 4.1을 기반으로 하는 이후 버전에서 --no_allow_fpreg_for_nonfpdata 옵션을 C/C++ 옵션의 Misc Controls 필드에 추가하여 비부동 소수점 코드에서 부동 소수점 명령어 사용을 비활성화해야 합니다.

GNUC C 컴파일러(gcc)

프로그램이 FPU 옵션으로 컴파일되는 경우 gcc는 레지스터 압력이 높고 데이터 처리를 위해 사용 가능한 레지스터가 부족할 경우 부동 소수점 레지스터를 사용할 수 있습니다. 경우에 따라 메모리 복사는 부동 소수점 레지스터를 사용하여 데이터를 보유할 수도 있습니다. -mfloat-abi=soft를 사용하여 부동 소수점이 아닌 코드에서 부동 소수점 명령의 사용을 피할 수 있습니다.

기본적으로 라이브러리는 –mfloat-abi=soft로 빌드됩니다. 따라서 부동 소수점 명령어를 포함해서는 안 됩니다. 그러나 빌드 옵션이 다른 다양한 gcc 벤더가 있기 때문에 gcc 도구 체인 공급업체에 문의하여 라이브러리 상태를 확인해야 할 수도 있습니다.

IAR Embedded Workbench for ARM

표 5는 IAR C 컴파일러가 다음 두 가지 경우에 부동 소수점 레지스터를 사용하지 않음을 보여줍니다.