DEV Community

코딩나우(하늘아래)
코딩나우(하늘아래)

Posted on Edited on Originally published at coding-now.com

Decoding Keil µVision build errors: what each message actually means

Keil µVision tells you a build failed with something like L6218E or #67, and that's about it. No hint about which file to open, no suggestion of what to try. The first few times, you end up pasting the code into a search box and hoping.

In practice the same handful of errors account for most lost afternoons, and each one has a small set of likely causes. Here they are, grouped by the stage that produced them.

First: which stage failed?

Before reading the message itself, look at its prefix. It tells you where to look, which cuts the search space in half.

Prefix Stage What it means
#20, #67 ... Compile C syntax or types — inside that one .c file
L6218E, L6050U ... Link Files compiled fine, combining them failed
A1586E ... Assemble Assembly file, usually the startup code
*** error 65 Simulator Not a build failure at all

One more habit worth forming: fix the first error, then rebuild. Thirty errors rarely means thirty mistakes — usually one early failure cascades.

Link errors

L6050U — "the code size of this image exceeds the maximum"

Error: L6050U: The code size of this image (35128 bytes) exceeds the maximum
allowed for this version of the linker.
Enter fullscreen mode Exit fullscreen mode

Nothing is wrong with your code. The free MDK-Lite edition caps output at 32 KB, and you crossed it. In order of effort:

  1. Raise optimisation to -O2 or higher (Options for Target > C/C++). Often enough on its own.
  2. Drop printf. The full formatter pulls in kilobytes; send debug output over UART directly, or enable MicroLIB (Options for Target > Target).
  3. Remove driver and library files the project doesn't actually use.
  4. Beyond that you need a full licence — the limit is not configurable.

If this is a learning project on STM32, note that ST's own STM32CubeIDE is free with no size limit.

L6218E — Undefined symbol

Error: L6218E: Undefined symbol delay_ms (referred from main.o).
Enter fullscreen mode Exit fullscreen mode

The linker found the call but not the body. Check in this order:

  • Is the .c file that defines the function actually in the project tree? Including the header and forgetting the .c is the most common cause by a wide margin.
  • Do spelling and case match between declaration and definition?
  • Calling C from C++? It needs extern "C".
  • Undefined symbol main means main is missing, or main.c is excluded from the build.

L6236E — No section matches selector

Error: L6236E: No section matches selector - no section to be FIRST/LAST.
Enter fullscreen mode Exit fullscreen mode

The startup file (startup_xxx.s) is missing. Add the one for your device, or tick Device > Startup in Manage Run-Time Environment. Switching target devices and leaving the old startup file behind gives the same error.

Link errors are project-structure problems. Reading source code won't reveal them — start from the file list in the Project pane.

Compile errors

Message Cause Fix
#5: cannot open source input file "stm32f4xx.h" Include path not registered Add the folder under C/C++ > Include Paths
#20: identifier "GPIOA" is undefined Device header missing, or device macro undefined Add the macro (e.g. STM32F407xx) under C/C++ > Define
#67: expected a "}" Missing brace or semicolon Look at the line before the reported one
#513: a value of type ... cannot be assigned Type mismatch Cast explicitly between pointers and integers

If "cannot open source input file" keeps coming back after you move the project, register include paths relative to the project folder instead of absolute paths.

Flashing failures

These are debugger settings, not code.

No Algorithm found for: 08000000H - 080003FFH

No flash algorithm is registered for your device. Options for Target > Debug > Settings > Flash Download > Add, pick your device family, and check the start address and size match the part.

Flash Download failed - "Cortex-M4"

  1. Power and probe first. A charge-only USB cable will not enumerate.
  2. In Debug > Settings, confirm the probe reports an IDCODE. If not, it's wiring.
  3. Previously flashed firmware may have disabled the debug pins — switch to Connect under Reset.
  4. Still stuck: full chip erase with ST-Link Utility or STM32CubeProgrammer, then retry.

If another tool is holding the probe (CubeProgrammer, a serial monitor), µVision can't claim it. Close it first.

Simulator: access violation

*** error 65: access violation at 0x40021000 : no 'read' permission
Enter fullscreen mode Exit fullscreen mode

Your code touched a peripheral register the simulator doesn't model. The code is fine; the simulator simply doesn't know that address. Either switch Debug from the simulator to a real probe, or map the region from the Debug command line:

MAP 0x40000000, 0x40030000 READ WRITE
Enter fullscreen mode Exit fullscreen mode

Peripheral behaviour is never fully reproduced in simulation. Use the simulator for logic, and check hardware behaviour on the board.

A five-minute checklist when nothing makes sense

  1. Project > Clean Target, then rebuild. Stale object files cause phantom errors.
  2. Read only the first error.
  3. Confirm every required .c is in the Project pane — especially the startup file.
  4. Check Options for Target > Device against the actual part, and the define macro with it.
  5. Open Manage Run-Time Environment and look for yellow/red markers — missing packs surface here.
  6. Move the project somewhere without spaces or non-ASCII characters in the path. Older toolchains still trip over those.

I keep the full version of this updated here, along with a register-level embedded C track (8051 and STM32, no HAL) if you're learning this from scratch:

Which Keil error has eaten the most of your time? If it's one I haven't listed, tell me and I'll add it with a proper explanation.

Top comments (0)