← 실용 가이드 목록
임베디드작성 · 9분 읽기

Keil µVision 빌드 오류 해결 — 자주 보는 메시지별 원인과 조치

Keil µVision 은 오류 메시지가 짧고 코드 번호로만 나와서, 처음 보면 무엇을 고쳐야 할지 감이 오지 않습니다. 그런데 실제로 마주치는 오류는 몇 가지로 좁혀지고, 각각 원인이 꽤 정해져 있습니다. 자주 나오는 메시지를 모아 '무엇을 뜻하고 어디를 손대면 되는지' 순서대로 정리했습니다.

오류 메시지 읽는 법

Build Output 창의 메시지는 세 종류로 나뉩니다. 어느 단계에서 멈췄는지 알면 찾아볼 곳이 절반으로 줄어듭니다.

접두사단계
#숫자 (예: #20, #67)컴파일C 문법·타입 문제. 해당 .c 파일 안에서 해결
L6xxx (예: L6218E)링크파일은 컴파일됐지만 합치는 단계에서 실패
A1xxx어셈블어셈블리 파일(.s) 문제. 보통 시작 코드
*** error 65시뮬레이터·디버거빌드가 아니라 실행/디버그 환경 문제
💡

오류가 30개 떴다고 30군데가 잘못된 것이 아닙니다. 첫 번째 오류를 고치고 다시 빌드하면 나머지가 한꺼번에 사라지는 일이 아주 흔합니다. 항상 맨 위부터 보세요.

링크 단계 오류 — 가장 많이 막히는 곳

L6050U — 코드 크기 초과

text
Error: L6050U: The code size of this image (xxxxx bytes) exceeds the maximum allowed for this version of the linker.

무료로 쓰는 MDK-Lite 는 컴파일 결과물이 32KB 를 넘을 수 없습니다. 코드가 틀린 것이 아니라 용량 한도에 걸린 것입니다. 학습용이라면 다음 순서로 줄여 보세요.

  1. 1Options for Target > C/C++ 에서 최적화를 -O2 이상으로 올립니다. 보통 이것만으로 상당히 줄어듭니다.
  2. 2printf 계열을 쓰고 있다면 그 자체로 수 KB 를 먹습니다. 디버그 출력을 UART 직접 전송으로 바꾸거나 MicroLIB 를 켜 보세요 (Options for Target > Target > Use MicroLIB).
  3. 3쓰지 않는 드라이버·라이브러리 파일을 프로젝트에서 제외합니다.
  4. 4그래도 넘으면 정식 라이선스가 필요합니다. 용량 제한은 설정으로 풀 수 없습니다.

L6218E — Undefined symbol

text
Error: L6218E: Undefined symbol delay_ms (referred from main.o).

main.c 에서 부르는 함수의 **본체를 찾지 못했다**는 뜻입니다. 순서대로 확인하세요.

  • 함수를 정의한 .c 파일이 프로젝트 트리에 추가되어 있는지 (헤더만 include 하고 .c 를 안 넣는 실수가 가장 많습니다)
  • 함수 이름 철자와 대소문자가 선언과 정의에서 같은지
  • C++ 파일에서 C 함수를 부른다면 extern "C" 로 감쌌는지
  • Undefined symbol main 이라면 main 함수 자체가 없거나, main.c 가 빌드 대상에서 빠진 것입니다

L6236E — No section matches selector

text
Error: L6236E: No section matches selector - no section to be FIRST/LAST.

시작 코드(startup_xxx.s)가 프로젝트에 없을 때 나옵니다. 칩에 맞는 startup 파일을 추가하거나, Manage Run-Time Environment 에서 Device > Startup 을 체크하세요. 칩 종류를 바꾼 뒤 예전 startup 파일이 남아 있어도 같은 증상이 납니다.

⚠️

링크 오류는 파일 구성 문제라서 소스 코드를 아무리 들여다봐도 답이 안 나옵니다. Project 창의 파일 목록부터 확인하는 습관을 들이세요.

컴파일 단계 오류

메시지원인조치
error: #5: cannot open source input file "stm32f4xx.h"헤더 경로 미등록Options for Target > C/C++ > Include Paths 에 헤더 폴더 추가
error: #20: identifier "GPIOA" is undefined장치 헤더 미포함 또는 디바이스 정의 누락해당 헤더 include 확인, Options > C/C++ > Define 에 칩 매크로(예: STM32F407xx) 추가
error: #67: expected a "}"괄호·세미콜론 누락오류 줄보다 **그 앞줄**을 먼저 확인
warning: #1295-D: Deprecated declaration구형 문법동작에는 문제 없음. 함수 선언에 매개변수 타입 명시
error: #513: a value of type ... cannot be assigned타입 불일치포인터/정수 변환은 명시적 캐스팅

헤더를 못 찾는 오류가 반복된다면 경로를 절대경로로 넣지 말고, 프로젝트 폴더 기준 상대경로로 등록하세요. 프로젝트를 다른 PC 로 옮겼을 때 다시 깨지는 일을 막을 수 있습니다.

플래시 다운로드가 안 될 때

No Algorithm found for: 08000000H - 080003FFH

빌드는 성공했는데 보드에 굽는 단계에서 멈춘 경우입니다. 칩에 맞는 플래시 알고리즘이 등록되지 않아서 생깁니다. Options for Target > Debug > Settings > Flash Download 에서 Add 를 눌러 사용하는 칩 계열의 알고리즘을 추가하고, 시작 주소와 크기가 칩 사양과 맞는지 확인하세요.

Flash Download failed - "Cortex-M4"

  1. 1보드 전원과 디버거(ST-Link/J-Link) 연결을 먼저 확인합니다. USB 케이블이 충전 전용이면 인식되지 않습니다.
  2. 2Debug > Settings 에서 디버거가 칩을 인식하는지(IDCODE 표시) 봅니다. 인식이 안 되면 배선 문제입니다.
  3. 3이전에 구운 펌웨어가 디버그 핀을 꺼 버렸을 수 있습니다. Reset 을 누른 채 연결하는 'Connect under Reset' 옵션으로 바꿔 보세요.
  4. 4그래도 안 되면 ST-Link Utility 나 STM32CubeProgrammer 로 전체 지우기(Full chip erase) 후 다시 시도합니다.
ℹ️

디버거를 여러 개 꽂아 두었거나 다른 프로그램(CubeProgrammer 등)이 포트를 쥐고 있으면 µVision 이 접근하지 못합니다. 다른 프로그램을 먼저 닫아 보세요.

시뮬레이터에서 나는 오류

text
*** error 65: access violation at 0x40021000 : no 'read' permission

실제 보드 없이 시뮬레이터로 돌릴 때 주변장치 레지스터 주소를 읽으면 나오는 메시지입니다. 시뮬레이터가 그 주소를 모른다는 뜻이지 코드가 틀린 것이 아닙니다. 해결은 두 가지입니다.

  • Options for Target > Debug 에서 시뮬레이터 대신 실제 디버거를 선택해 보드에서 실행합니다.
  • 시뮬레이터를 계속 쓰려면 Debug 창의 Command 란에 MAP 0x40000000, 0x40030000 READ WRITE 처럼 해당 영역을 매핑해 줍니다.
💡

GPIO·타이머처럼 주변장치를 건드리는 코드는 시뮬레이터에서 동작을 100% 재현하지 못합니다. 로직 확인까지만 시뮬레이터로 하고, 하드웨어 동작은 보드에서 확인하는 편이 시간을 아낍니다.

그래도 안 될 때 — 5분 점검 순서

  1. 1Project > Clean Target 후 Rebuild. 예전 오브젝트 파일이 남아 생기는 유령 오류가 사라집니다.
  2. 2Build Output 의 **첫 번째** 오류만 보고 그것부터 수정.
  3. 3Project 창에서 필요한 .c 파일이 모두 들어 있는지 확인 (특히 startup 파일).
  4. 4Options for Target > Device 가 실제 칩과 같은지 확인. 칩을 바꿨다면 Define 매크로도 함께 바꿔야 합니다.
  5. 5Manage Run-Time Environment 에서 노란색·빨간색 경고가 있는지 확인. 필요한 팩이 빠져 있으면 여기서 드러납니다.
  6. 6프로젝트 경로에 한글이나 공백이 있으면 옮겨 보세요. 오래된 툴체인에서 경로 문제로 엉뚱한 오류가 납니다.

자주 묻는 질문

Q. 무료판 32KB 제한은 설정으로 풀 수 있나요?

없습니다. MDK-Lite 의 제한은 라이선스 조건이라 최적화나 설정으로 우회할 수 없습니다. 다만 STM32 계열이라면 ST 가 제공하는 무료 툴체인(STM32CubeIDE)에는 용량 제한이 없으므로, 학습 목적이라면 그쪽으로 옮기는 것도 방법입니다.

Q. 빌드는 되는데 보드에서 아무 동작도 하지 않습니다.

대부분 클럭 설정이나 주변장치 클럭 활성화(RCC) 누락입니다. GPIO 를 건드리기 전에 해당 포트의 클럭을 켰는지 먼저 확인하세요. 그다음으로는 실제로 최신 펌웨어가 구워졌는지(다운로드 성공 메시지)와 리셋 여부를 확인합니다.

Q. 오류 줄 번호가 실제 코드와 다릅니다.

헤더에서 발생한 오류가 그 헤더를 include 한 줄로 표시되는 경우입니다. 메시지에 나온 파일 이름을 먼저 보고, 매크로를 많이 쓰는 코드라면 매크로 전개 결과를 의심하세요.

Q. 같은 프로젝트가 다른 PC 에서는 빌드됩니다.

절대경로로 등록된 Include Path 나 설치되지 않은 Device Pack 이 원인일 가능성이 큽니다. Pack Installer 에서 필요한 팩 버전을 맞추고, 경로는 프로젝트 기준 상대경로로 바꾸세요.

다른 가이드