Yes — you can run Linux on the Cortex-A53 cores of a TI AM67A and a real-time firmware image on a Cortex-R5F core at the same time. That is what the device is built for, and TI's own framing is that you run the bulk of your application under Linux and offload the timing-critical part to the R5F. The interesting question is not whether it works. It is where the boundary goes, which R5F you use, and what crosses between them — because those three decisions determine whether the real-time domain actually buys you anything. This article works through all three. All device facts come from TI's AM67x datasheet SPRSPA3B and the SPRUJB3D technical reference manual. Spikedge has not independently benchmarked this platform for this article; everything that would require measurement is listed as such.

First, drop the wrong question

"Is Linux real-time?" sends this discussion sideways every time. The useful question is: what happens when your task misses its deadline?

There are three different contracts here, and they are not the same thing:

  • Fast on average. A stock Linux scheduler does this well. Fine for throughput-bound work.
  • Usually on time. PREEMPT_RT, CPU isolation, IRQ affinity and priority tuning move Linux into this band. This is real engineering work and it is validated by measurement, not by configuration.
  • On time every time. If a single missed cycle has a physical consequence — an axis drifts, a safety interlock does not fire, something overheats — the burden of proof changes. You now care about the worst case, not the average, and you can only defend a worst case in a domain where nothing else runs.

The R5F domain on the AM67A exists for the third category. The R5F is not there because it is faster than an A53. It is there because it is predictable: tightly coupled memory, its own interrupt controller, its own clock domain, and — for the MCU-domain core — its own 512 KB of SRAM. No page faults, no demand paging, no competing userspace.

One nuance to keep: an R5F does not sell you a hard real-time guarantee. It gives you the hardware ground on which one can be built. The guarantee comes from your design — interrupt priorities, worst-case execution time analysis, lock-free data structures, and measurement.

How many R5F cores can you actually use?

This is the question that comes up first on every forum thread about this part, and the datasheet answers it indirectly.

TI lists three separate single-core Cortex-R5F cores, each up to 800 MHz:

Datasheet wording Name Who owns it
"integrated as part of MCU Channel with FFI" MCU_R5F — the MCU-R5F your firmware
"integrated to support Run-time Management" R5FSS0 — the MAIN-R5F your firmware
"integrated to support Device Management" WKUP_R5F TI's device management firmware

Two of the three are yours. The third runs TI's power, clock and resource management firmware and arrives inside the boot image; it is not a core you schedule work onto.

Two more things that get assumed and are wrong:

  • There is no lockstep. The TRM lists lockstep under unsupported features for all three R5F subsystems. "FFI" means freedom from interference — an isolation property, not dual execution with result comparison. If your safety concept expects hardware-level redundant execution, this part does not provide it.
  • Which cores the SDK exposes is an SDK question. The datasheet points twice to the Software Build Sheet for that. Settle it before you plan the partitioning, not after.

MAIN-R5F and MCU-R5F are not interchangeable

This deserves its own section because it is the failure mode that costs the most time.

The two application-available R5F cores sit in different domains. The MCU-R5F lives in the MCU channel, described with freedom from interference and backed by its own 512 KB SRAM. The MAIN-R5F sits in the main domain alongside the A53 cluster, the accelerators and the high-speed interconnect. Different domains mean different interconnect paths, different reset and power relationships, and different memory visibility.

The practical consequence shows up in community reports of firmware that initialises cleanly on one core and stalls during inter-core bring-up on the other — same code, different core. We are not going to attribute a single root cause, because that would require reproducing it. The design guidance stands on its own regardless:

Treat "which R5F" as an architectural decision, not a build flag. Choose deliberately:

  • MCU-R5F when the task must be isolated from main-domain activity. This is the core the FFI wording attaches to and the one with dedicated SRAM. Your hard-deadline control loop belongs here.
  • MAIN-R5F when the task needs cheap, high-bandwidth proximity to main-domain peripherals and memory, and its deadlines are firm rather than hard.

And validate bring-up on the specific core you intend to ship on, early. Porting between the two is not a recompile.

Deciding what goes where

Run each task through these four questions in order. The first "yes" decides it.

1. Does a missed deadline have a physical consequence? Motor commands, safety interlocks, trigger timing, synchronous sampling. If yes, the task goes to an R5F. The discussion ends there.

2. Is the task driven by a microsecond-scale interrupt? Encoder pulses, capture inputs, external triggers. The AM67A carries three each of ePWM, eCAP and eQEP; driving those from Linux userspace gives back more in jitter than it saves in effort. R5F.

3. Does the task need a rich library? A TLS stack, a database, ROS 2, a filesystem, a network protocol, a model runtime. If yes, Cortex-A53. Porting those to an R5F is sometimes possible and almost never worth the maintenance cost.

4. Is the task high-volume but soft-deadline? Video, logging, telemetry, inference. A53 and the accelerators. Putting these on an R5F destroys the property you moved there to get.

The grey zone — "important but no physical consequence" — belongs on the A53. Moving a task to an R5F costs you a second build pipeline, a second debug environment, a second lifecycle and a protocol between them. That cost is only justified when question 1 or 2 answers yes.

A note from practice: most partitioning mistakes come from using the R5F too much, not too little. Every extra task on the real-time core widens the scope of your worst-case analysis and erodes the reason the core was chosen. Design the R5F as a device with one job, not as a second CPU.

The bridge: remoteproc and RPMsg

Two Linux frameworks handle the other side.

remoteproc manages the remote core's lifecycle: placing the firmware image in memory, releasing the core from reset, stopping it, recovering it after a crash. The resource table inside the firmware ELF declares which memory carveouts the core needs, which vrings it uses and where the trace buffer sits. That table is where the two sides agree on a memory map, and it is where most silent failures originate.

RPMsg provides messaging over the virtio channels remoteproc sets up — shared-memory ring buffers plus a mailbox interrupt as the doorbell. One side writes, rings, the other wakes.

Knowing the split matters because RPMsg is not the right tool for every kind of traffic. For commands, status, parameter updates and error reports it is the correct abstraction: named channels, flow control and connection management come for free. For a data path carrying a few hundred bytes per cycle with a microsecond budget, its copy and queue semantics are overhead you did not ask for.

The healthy pattern uses both:

Traffic Mechanism Why
Commands, configuration, status RPMsg channel Reliable, ordered, named; low rate
Loop data (setpoints, measurements) Double-buffered or ring structure in shared memory Zero-copy, fixed cost
Wake-up signalling Mailbox interrupt No polling, predictable
Debug trace remoteproc trace buffer Can be disabled in production

Shared memory is where the design actually lives

Treating shared memory as "an array both sides can see" is the most expensive simplification in this architecture. Three separate concerns.

Cache coherency. The A53 side sees the region through caches; the R5F has its own view. If both sides read and write the same region cached, the data will be wrong sometimes — and that class of bug surfaces in the field under load, not on the bench. Two defensible approaches exist: map the region uncached on one side (simple, slower) or perform explicit cache maintenance on every access (fast, requires discipline). There is no middle.

Torn reads. If two 32-bit fields are updated by two separate writes, the reader can observe one old and one new. The standard lock-free fix is a seqlock-style counter: the writer makes the counter odd on entry and even on exit; the reader samples it before and after and retries if it changed. The alternative is double buffering — the writer fills the inactive buffer, then swaps with a single atomic index write.

Ownership. Every shared region should have exactly one writer. A region both sides write will eventually need a lock, and a lock means unbounded waiting on the R5F side, which discards your worst-case analysis. Use two one-way regions instead.

Six anti-patterns

The recurring failures in this architecture, most expensive first.

1. Treating the R5F as a second application processor. Symptom: the firmware grows, and logging, networking and file access creep in. Result: worst-case execution time is no longer computable. The R5F's job should be single and bounded.

2. Putting the critical path across RPMsg. Symptom: the control loop waits for a message from Linux every iteration. Result: the loop's worst case becomes Linux's worst case and the reason for the R5F disappears. The critical loop must keep running safely even if Linux stops entirely.

3. Drawing the boundary by where the code already lives. Symptom: "this function was already in C, let's move it to the R5F." Result: the real-time domain fills with unrelated work. The boundary is drawn by deadline contract, not by language.

4. Assuming a start-up order. Symptom: the R5F firmware expects Linux to have prepared a structure, or the reverse. Result: a system that boots cold correctly deadlocks on a warm reset or a remoteproc restart. Both sides must wait in a defined state when the other is absent, and the handshake must be explicit.

5. Not designing for Linux crashing. Symptom: the A53 side restarts, the R5F's view of shared state goes stale, and nothing notices. Result: an actuator still acting on the last setpoint. Every shared structure needs a freshness indicator — a counter or timestamp — and the R5F needs a timeout behaviour.

6. Saying "deterministic" without measuring. Symptom: the architecture is correct and nobody has looked at the latency distribution. Result: good average, bad tail. What matters here is p99 and worst case, and only measurement shows either.

Building a latency budget

"Latency" in a control loop is not one number. Break it apart before trying to improve it:

  1. Source event — encoder pulse, trigger, timer overflow.
  2. Interrupt latency — from the event to the first instruction of the service routine.
  3. Service time — read, compute, write.
  4. Output to actuator — through the peripheral to the physical world.
  5. (If present) cross-domain transfer — the bridge between R5F and A53.

If steps 1–4 stay inside the R5F domain, the budget is small and tightly distributed. The moment step 5 enters the critical path, the budget contains Linux's worst case. The entire point of this architecture is keeping step 5 off the critical path.

Layer Owner Typical improvement How it is validated
Interrupt latency R5F firmware Priority assignment, nesting policy GPIO pulse + oscilloscope
Service time R5F firmware Placement in TCM, bounded floating-point use Cycle counter
Cross-domain transfer Joint design Zero-copy structure, mailbox signalling Timestamps at both ends
Linux-side scheduling A53 / kernel Isolation, affinity, priority Cyclic latency test under load

What to measure

Every number worth publishing in this architecture carries three things with it: which setup, which method, measured by whom. If one is missing, the number is not published. The minimum set:

  • R5F interrupt latency. GPIO pulse against an external trigger, on an oscilloscope, over at least one overnight run. A histogram, not an average.
  • Missed-cycle counter. Inside the firmware, readable from outside. Any non-zero value is a finding.
  • Cross-domain round trip. Synchronised timestamps at both ends, measured idle and at full load separately.
  • Degradation under load. How the three above change while inference, NVMe writes and network traffic run on the A53 side. The idle number tells you nothing.
  • Cold boot to control-ready. When the R5F firmware comes up, measured independently of when Linux is ready.
  • Recovery behaviour. Stop and restart the R5F through remoteproc while the system runs. Does it land in a defined state or an undefined one?

When not to build this

Splitting across domains is not free. Staying in one domain is the better call when:

  • There is no hard-deadline task. If soft deadlines are met with PREEMPT_RT, a second build pipeline and a protocol layer buy you nothing.
  • Nobody on the team owns firmware. The R5F side is a separate toolchain, a separate debug method and a separate release lifecycle. Unowned firmware is an unowned risk.
  • The critical task already runs on a separate MCU. Migrating a validated external controller into the SoC produces revalidation cost, not savings. Do it only for a concrete gain in board cost, latency or synchronisation.
  • You cannot update both firmware images together in the field. The two domains' versions are coupled; if the OTA plan cannot carry that coupling, the architecture comes apart in deployment.

Frequently asked questions

Can the AM67A run Linux and an RTOS at the same time? Yes. The Cortex-A53 cores run Linux; the Cortex-R5F cores run bare-metal or an RTOS image, loaded and managed from Linux through remoteproc. This is asymmetric multiprocessing, and it is the intended usage model for the device.

How do I run code on the R5F cores from Linux? The firmware image is placed where remoteproc expects it, and Linux loads and starts the core. Messaging then runs over RPMsg. Firmware can alternatively be started earlier by the bootloader when the real-time domain must be up before Linux.

Which R5F should I target, MAIN-R5F or MCU-R5F? The MCU-R5F for tasks that must be isolated from main-domain activity — it is the core the freedom-from-interference wording attaches to and it has dedicated SRAM. The MAIN-R5F for firm-deadline work that benefits from proximity to main-domain peripherals. They are in different domains and are not drop-in replacements for each other.

Does the AM67A support lockstep on the R5F cores? No. The technical reference manual lists lockstep as unsupported for all three R5F subsystems.

Is RPMsg fast enough for a control loop? For commands and status, yes. For a per-cycle data path with a microsecond budget, its copy and queue semantics add avoidable overhead — pair it with a plain shared-memory structure and a mailbox doorbell for the loop data.

What happens to the R5F if Linux crashes? Nothing automatically. That is the point of the design, and also its trap: unless you build a freshness indicator and a timeout into the shared structures, the R5F will keep acting on stale data. Design the failure case explicitly.

Summary

The value of running Linux and an R5F together on the AM67A does not come from having two processors. It comes from hosting two different timing contracts on one board. Preserving that value means drawing the boundary with discipline: the critical path closes inside the R5F domain, Linux is the helper, the bridge stays off the critical path, and every shared structure has exactly one writer.

The rest is measurement. In this architecture the word "deterministic" is not a claim until there is a histogram behind it.

If you are evaluating this partitioning on your own platform, the fastest route is to produce the workload map and the measurement plan together — which is where our hard real-time and RTOS work starts. The device-level context for these cores is covered in our AM67A architecture deep dive; to see how much of it a given board exposes, see our T3 Gemstone O1 analysis. To scope a review, we run an embedded architecture audit.

Sources

  1. Texas Instruments — AM67x Processors datasheet, SPRSPA3B, March 2024, revised June 2026 — https://www.ti.com/lit/ds/symlink/am67a.pdf
  2. Texas Instruments — J722S/TDA4VEN/TDA4AEN/AM67 Processor Silicon Revision 1.0 Technical Reference Manual, SPRUJB3D, August 2026 — https://www.ti.com/lit/zip/sprujb3
  3. Texas Instruments — PROCESSOR-SDK-AM67Ahttps://www.ti.com/tool/PROCESSOR-SDK-AM67A
  4. Linux kernel documentation — Remoteproc Frameworkhttps://docs.kernel.org/staging/remoteproc.html
  5. Linux kernel documentation — RPMsg Messaging Frameworkhttps://docs.kernel.org/staging/rpmsg.html

Documents accessed 5 September 2026. SDK and kernel documentation are versioned; questions such as which cores an SDK exposes should always be confirmed against the release you are using.