Category: Development tools

How to Use Zephyr RTOS with Arm Keil MDK

Zephyr RTOS gives you a modern, permissively-licensed real-time operating system with a huge board and driver ecosystem, built and configured through its own west/CMake toolchain. Arm Keil MDK gives you µVision’s source-level debugger, RTX-class breakpoints and watch windows, and — through ULINK2, ULINKplus, ULINKpro and DSTREAM-ST — instruction trace, code coverage and execution profiling that Zephyr’s own command-line debug tooling does not provide. The two are not mutually exclusive: you can build a Zephyr application entirely with Zephyr’s own build system, then hand the resulting ELF straight to µVision for debugging, without ever creating a Keil build project. This guide walks through exactly how.

What Is Zephyr RTOS?

Zephyr is an open-source, real-time operating system hosted by the Linux Foundation, designed for resource-constrained and embedded devices. It supports a very wide range of Arm Cortex-M, Cortex-A/R and other architectures, and is built with west (Zephyr’s meta-tool) driving a CMake + Ninja/Make build.

What Is Keil MDK?

Arm Keil MDK is Arm’s own microcontroller development kit — the µVision IDE, Arm Compiler, and CMSIS software packs — paired with Arm Keil ULINK and DSTREAM-ST debug probes. MDK is not tied to any single RTOS or build system: µVision can debug any ELF/AXF image that carries standard debug information, regardless of which toolchain produced it.

Why Debug a Zephyr Application with Keil MDK?

Zephyr’s own west debug and west debugserver commands drive GDB through runners such as pyOCD, J-Link or OpenOCD — Arm’s own ULINK and DSTREAM-ST probes are not among the supported runners. If your team already owns Arm debug hardware, or needs capabilities Zephyr’s default debug flow does not offer — instruction trace, code coverage, execution profiling, or Arm Development Studio/µVision’s debug UI — the practical path is to build with Zephyr as usual, then load the resulting image directly into µVision as a “debug-only” session.

Prerequisites

  • A working Zephyr development environment (Zephyr SDK, west, and Python dependencies installed per the official Getting Started Guide)
  • Keil MDK (µVision 5) installed, with the CMSIS device pack for your target microcontroller
  • An Arm Keil ULINK2, ULINKplus, ULINKpro or DSTREAM-ST probe, or a CMSIS-DAP adapter, wired to your board’s JTAG/SWD header

Step 1 — Build Your Zephyr Application

Build normally with west, targeting your board:

west build -b <your_board> path/to/your/app

By default Zephyr’s CMake build compiles with debug information enabled, which is what makes source-level debugging in µVision possible afterwards. The resulting debug image is written to build/zephyr/zephyr.elf (Zephyr also produces zephyr.hex and zephyr.bin, but only the ELF carries the symbol and line-number information µVision needs for source-level debug).

Step 2 (Optional) — Build with the Arm Compiler 6 Toolchain

Zephyr defaults to the GNU Arm Embedded toolchain, but it also supports Arm Compiler 6 (armclang) — the same compiler used by Keil MDK — as a third-party toolchain. To use it, set before building:

export ZEPHYR_TOOLCHAIN_VARIANT=armclang
export ARMCLANG_TOOLCHAIN_PATH=/path/to/your/arm/compiler
export ARMLMD_LICENSE_FILE=/path/to/license_armds.dat

This requires a valid Arm Compiler license (e.g. from an MDK-Professional or Arm Development Studio installation). It is not required to debug in µVision — a GNU-built ELF debugs in µVision perfectly well — but keeping build and debug on the same compiler family avoids any codegen differences between what you build and what you step through.

Step 3 — Create a Debug-Only µVision Project

Rather than trying to recreate Zephyr’s build inside µVision, create a minimal project whose only job is to load and debug the Zephyr-built ELF:

  1. In µVision, Project › New µVision Project and select the exact microcontroller your Zephyr board targets (matching device is what supplies the correct memory map and flash algorithm).
  2. When prompted for startup/runtime files, you can decline adding them — this project will not compile any source, it only hosts debug settings.
  3. Open Project › Options for Target › Debug, select your debug adapter (ULINK2 / ULINKplus / ULINKpro / DSTREAM-ST / CMSIS-DAP) from the dropdown, and configure it under Settings (port SW, correct clock speed for your target).
  4. Still on the Debug tab, tick Load Application at Startup and Run to main(), and untick Update Target before Debugging under the Utilities tab if present, so µVision does not try to (re)build anything before launching the debug session.

Step 4 — Point µVision at the Zephyr ELF

In Options for Target › Debug, browse to your build output as the image to load: build/zephyr/zephyr.elf. µVision’s debugger reads the ELF’s DWARF debug information directly, so source files, line numbers, function names, global and static variables all resolve normally — you can also drive this via the LOAD command from the command window, e.g. LOAD build\zephyr\zephyr.elf, if you prefer to load images ad hoc without changing project settings.

Step 5 — Start Debugging

Click Debug › Start/Stop Debug Session. µVision resets the target, downloads the Zephyr image over your probe, and stops at main() (or wherever your entry breakpoint is set). From here you have full source-level debugging of your Zephyr application: breakpoints, step/step-over/step-into, local and global variable watch, memory and register views, and — if you’re using ULINKpro or DSTREAM-ST — instruction trace, code coverage and execution profiling against the running Zephyr image, the same as any other Cortex-M target.

Tips for a Clean Debug Session

  • Keep optimization at -O0 or -Og in your Zephyr build (via your application’s CMakeLists.txt or a debug build type) for reliable source-line stepping — higher optimization levels reorder and inline code in ways that make step-by-step debugging confusing regardless of which debugger you use.
  • Double-check the device selected in your µVision project matches your Zephyr board’s exact part number, so the flash algorithm and memory map line up.
  • µVision does not ship a dedicated Zephyr thread-awareness view the way it does for Keil RTX — you get full Cortex-M/CoreSight-level debugging (registers, memory, call stack, trace), but not a built-in “list of Zephyr threads” panel. Zephyr’s thread structures can still be inspected manually via the Watch/Memory windows if needed.
  • Re-run west build and reload the ELF (or restart the debug session) after every source change — this workflow does not auto-rebuild from µVision.

Frequently Asked Questions

Can ‘west debug’ drive a Keil ULINK or DSTREAM-ST probe directly?

No. Zephyr’s west debug/west debugserver commands support runners such as pyOCD, J-Link and OpenOCD, not Arm’s ULINK/DSTREAM-ST family. To use those probes, build with west as usual and load the resulting ELF into a µVision debug session instead, as described above.

Do I need an Arm Compiler license to debug a Zephyr build in µVision?

No. µVision can debug an ELF built with the default GNU Arm Embedded toolchain with no extra license — an Arm Compiler 6 (armclang) license is only needed if you choose to build with ZEPHYR_TOOLCHAIN_VARIANT=armclang instead.

Does this give me Zephyr thread-aware debugging in µVision?

Not out of the box. µVision provides full Cortex-M source-level debugging, memory/register access, and — with ULINKpro or DSTREAM-ST — instruction trace and code coverage against the Zephyr image, but it does not include a built-in Zephyr-specific thread-list view the way it does for Keil RTX.

Pertech supplies the full Arm Keil MDK toolchain and the ULINK2, ULINKplus, ULINKpro and DSTREAM-ST debug probes used in this workflow, with local stock and technical support in Israel. Contact us if you need help wiring up Zephyr and Keil MDK for your project.


Getting Started With Keil MDK UBL

Microchip icon with a padlock and checkmark, representing an activated Keil MDK license

Development Tools — Pertech Knowledge Center

How to Install a Keil MDK User‑Based License (UBL)

A User‑Based License (UBL) is the license type Arm/Keil uses for MDK today. Instead of locking your license to one PC's hardware ID, UBL ties it to your Arm account — so once it's activated, you can use the same license on any computer you personally work from. Below is the simple, first‑time setup, followed by what to do when you already have one or more licenses installed and need to add another.

Part 1Installing Your First MDK UBL License

1 Install MDK µVision 5.37+ or MDK6 / VS Code 2 Find your Serial Number Certificate of Authenticity 3 Activate on the UBL Portal Arm account → generate code 4 Enter code in License Mgmt ✓ Licensed
  1. Install Keil MDK. Install µVision (version 5.37 or later) or the MDK6 extension for VS Code, if you haven't already.
  2. Locate your Serial Number. When you purchase MDK, Arm/Keil (or your distributor) provides a Certificate of Authenticity containing a product Serial Number and a link to the UBL activation portal.
  3. Log in to the UBL portal. Open the link from your certificate and sign in with your Arm account — or create one if this is your first purchase.
  4. Add your product. On the portal, choose Add a product and enter the Serial Number from your certificate to register it to your account.
  5. Generate an activation code. The portal will generate a unique activation code for that product — copy it.
  6. Enter the code in µVision. Open File → License Management, select the UBL tab, click Activate/Deactivate, and paste in your activation code.
  7. Done. The tool now shows as licensed. Because the license belongs to your Arm account rather than one specific PC, you can use the same activation code to activate MDK on any other computer you personally work from.
Tip: Keep your Arm account credentials safe — every license you activate, now and in the future, lives under that one account.

Part 2Installing an Additional License

Already have one or more MDK licenses activated and just purchased another seat or product? You don't need to remove or redo anything — just add the new one alongside what's already there.

You already have 1+ licenses active same Arm account 1 New Serial Number from new purchase 2 Same UBL Portal, Add a Product generate new code 3 Enter new code in License Mgmt ✓ Both active
  1. Get the new Serial Number. Your new purchase (an additional seat, or a different product/tool) comes with its own Certificate of Authenticity and Serial Number.
  2. Return to the same UBL portal. Log in with the same Arm account that already holds your existing license(s) — don't create a second account.
  3. Add the product again. Choose Add a product and enter the new Serial Number.
  4. Generate a new activation code for this newly added product.
  5. Enter it in µVision. Open File → License Management → UBL tab, click Activate/Deactivate, and paste in the new activation code.
  6. Result: your original license stays exactly as it was, and the new one now appears alongside it — both active under the same account, ready to use.
Note: Generating and activating a code requires an internet connection. If your target machine has no internet access at all, see Part 3: Proxy Activation below.

Part 3Proxy Activation (No Internet on the Target PC)

Some development or lab machines — an isolated test bench, a secure network, a CI build machine — never get direct internet access. Proxy activation lets you generate the license on a different, internet-connected PC, then carry it over to the offline one as a file.

1 Networked PC armlm activate --code ... --to-file transfer.armlm generates a transfer file 2 Copy the File Over USB drive, shared folder, or internal network 3 Offline PC armlm import --file transfer.armlm ✓ Licensed (7–365 days)
  1. On the networked PC, open a terminal in the product's bin folder and run armlm activate --code <activation_code> --as-user <your_username> --to-file <transfer_filename> (use --server <server_URL> --product <product_code> instead of --code if your organization activates through a License Server rather than individual codes).
  2. Optional — extend how long it lasts. By default the license is only valid for 7 days. Add --borrow-period <days> to the same command (any value from 7 up to 365) to make it last up to a full year before you need to repeat this process — handy for a lab bench or CI machine you don't want to touch every week.
  3. Copy the generated transfer file to the offline machine — a USB drive or an internal network share both work, since this step needs no internet access.
  4. On the offline PC, run armlm import --file <transfer_filename> to activate the license locally.
  5. Renewal is off by default. A proxy-activated license won't try to reach the network on its own. If the target machine does get occasional network access and you'd rather it try to auto-renew every 24 hours, add --enable-renewal to the import command — just note that each successful renewal resets validity back down to 7 days, overriding whatever --borrow-period you set.
  6. Repeat before it expires. Whether that's every 7 days (default) or up to 365 days (with --borrow-period), generate a fresh transfer file and import it again before the current one runs out.
Tip: Proxy activation is also useful for activating the same product for the same user across many machines at once — for example, provisioning a batch of CI build machines.
Based on Arm/Keil's official MDK Licensing documentation. Reference: Keil Licensing User's Guide, Arm User-Based Licensing Administration Guide, Arm Proxy Activation Guide.

Total Phase announced A²B Bus Monitor solution

Total Phase announced A²B Bus Monitor solution.

The A²B Bus Monitor provides access to the A²B system. By attaching the A²B Adapter Board in-line between nodes, the A²B monitor can non-intrusively sniff A²B data in real time. A²B superframes are decoded into I2C control data for easy debugging with Interrupts and GPIO handshakes correlated into the data capture, while an I2S/TDM audio data analysis is available in a visual and audio formats.

WHAT IS A2B

Today’s drivers don’t only want a sleek car with sporty handling. Drivers want style, better gas mileage and an infotainment center comparable to the best theaters.

Analog Devices, Inc. has developed Automotive Audio Bus (A2B) digital audio bus technology specifically to deliver high fidelity audio in automobiles while significantly reducing the weight of existing cable harnesses (by upwards of 75% in key applications) – resulting in improved vehicle fuel efficiency and audio capabilities.

More information

NXP’s MCUXpresso IDE now Integrated with PEmicro GDB Server

NXP’s has launched the MCUXpresso Integrated Development Environment for LPC and Kinetis microcontrollers with PEmicro’s GDB Server fully integrated.

This provides advanced debug capabilities via PEmicro’s Multilink, Cyclone, and embedded OpenSDA debug interfaces including: hardware breakpoints, watchpoints, real-time variables, semihosting, FreeRTOS awareness, the ability to attach to a running target, the ability to provide target power, remote debug, and more. More information

upbtn
Skip to content