What's Inside a CAREL c.pCO Controller? Architecture of an HVAC/R PLC
If you work in industrial refrigeration or HVAC, you’ve almost certainly programmed a CAREL controller. But have you ever wondered what’s actually running beneath the surface of that c.pCO board?
We spend our days in c.suite, dragging variables onto displays, configuring Modbus lines, and deploying applications. But the firmware architecture running inside these controllers is a fascinating world of embedded engineering. Let me walk you through what makes the c.pCO tick — focusing on publicly known components and aspects that any engineer working with these controllers can observe.
The Heart: A Real-Time Operating System
At the core of every c.pCO controller runs SEGGER’s embOS — a priority-based, preemptive Real-Time Operating System. Unlike Linux or Windows, an RTOS guarantees deterministic behavior: every task executes within strict time constraints.
Why does this matter? Think about what your controller does in a cold room installation. The regulation loop controlling compressors and expansion valves absolutely cannot wait for a web page to finish loading or a Modbus polling cycle to complete. embOS ensures that high-priority tasks preempt lower-priority ones instantly, through interrupt-driven task switching, semaphores for thread-safe data access, and software timers — all packed into a tiny footprint suitable for a microcontroller.
The Software Stack: Standing on SEGGER’s Shoulders
CAREL didn’t build everything from scratch. The c.pCO leverages a family of proven SEGGER middleware modules that work together seamlessly: embOS for task management, embOS/IP for TCP/IP networking, emFile for filesystem operations, and emUSB for USB connectivity.
Each module follows a clean four-layer architecture: a hardware-independent core, a configuration layer, a Board Support Package (BSP), and a CPU-specific driver layer. This means CAREL can port the same high-level logic to different hardware platforms by adapting only the lower layers — elegant engineering where every byte of RAM counts.
Interestingly, SEGGER’s stack didn’t cover everything CAREL needed. Serial port support (critical for RS485 fieldbus communication) wasn’t included in the SEGGER package, so CAREL developed their own serial communication module from scratch. Similarly, they wrote a custom SPI driver specifically tailored for the built-in display communication. These are the kind of practical adaptations that make a real product out of middleware components.
The Filesystem: More Than Just Storage
You might not think a PLC needs a filesystem, but the c.pCO stores quite a lot on its NAND flash: application binaries, configuration files, logs, web server pages, and upgrade packages. SEGGER’s emFile provides a FAT-based embedded filesystem, which means you can plug in a USB stick and your PC can read the files directly.
What makes this interesting from an engineering perspective is the constraint management. Memory for file handles and buffers is allocated statically at compile time — no dynamic allocation — because in an embedded system running your cold room, a failed memory allocation at runtime could mean a crashed controller and spoiled product. Journaling support ensures filesystem consistency even after unexpected power cuts. For anyone who has lost a controller’s configuration to a power outage on an older platform, this is a significant improvement.
The NAND flash itself adds complexity: limited write/erase cycles require wear leveling, similar to what SSD manufacturers deal with — except CAREL solves it within kilobytes of RAM.
The Application Runtime: Where Your Structured Text Comes to Life
The code you write in Structured Text (or FBD, or Ladder) in c.suite doesn’t run directly on the hardware. It runs inside an IEC 61131-3 compliant runtime — specifically, Rockwell Automation’s ISaGRAF. This runtime supports all five IEC 61131-3 programming languages and executes your application in the classic PLC scan cycle: read inputs, execute the program, write outputs.
Here’s where it gets interesting for those of us who’ve deployed applications to c.pCO controllers: when you compile your project in c.suite, the output is a file with the .ap1 extension. If you’ve ever wondered what this file actually is — it’s essentially a renamed ZIP archive containing the compiled application code, ISAI configuration tables, and a manifest with CRC integrity checks. The manifest lists all components and their checksums, and the controller verifies each file’s CRC16 (plus the ZIP’s own CRC32) before accepting the upgrade. If anything doesn’t match, the controller rejects the package. This is why your application deployment is either fully successful or cleanly fails — there’s no half-deployed state.
The Telnet Console: Your Hidden Debugging Friend
Here’s a detail that many c.pCO programmers don’t know about: the controller runs a telnet server that gives you access to a built-in command-line shell. This isn’t just a simple status display — it’s a full diagnostic console where you can inspect the running state of the controller, check system status, and interact with the firmware in ways the graphical tools don’t expose.
The shell even includes command-line utilities built on top of zlib — the same open-source compression library used for handling the .ap1 upgrade packages. Having access to this console can be invaluable during commissioning or when troubleshooting communication issues in the field, especially when you don’t have c.suite handy.
Communication: Every Protocol Is a Task
Modern c.pCO controllers don’t work in isolation. They communicate via Modbus, BACnet, the proprietary CAREL protocol, and more. What’s elegant about CAREL’s implementation is that every protocol runs as a separate RTOS task, and every protocol instance on a port is its own task instance with its own isolated memory context — no global variables shared between protocols.
The architecture includes a bridging layer that synchronizes the runtime’s variables with communication tasks through carefully timed hooks: external values are injected at the beginning of each scan cycle, and updated outputs are exported at the end. This ensures your application always sees a consistent snapshot of its I/O during execution. It’s also why a Modbus write doesn’t take effect mid-cycle — it waits for the next synchronization point.
The failure management is worth noting too. When communicating with slave devices over a serial line, the master uses a timeout-and-retry mechanism. If a device goes offline, the delay is calculated as timeout multiplied by the number of attempts, and the system supports priority-based polling — high-priority variables from important devices get polled more frequently than low-priority diagnostic data.
The I/O Architecture: A Board Within a Board
One of the more surprising aspects of the c.pCO’s design is how local I/O is managed. The main processor doesn’t directly read temperature probes or drive relay outputs. Instead, the controller board contains multiple STM8 microprocessors (up to 5, depending on the board size) that handle the analog and digital I/O through dedicated ChipIO frontend circuits.
The main CPU communicates with these STM8 processors via a local serial bus at 115200 baud, using a modified Modbus RTU protocol with custom commands for speed optimization. A dedicated task continuously polls the STM8 chips for input data and dispatches output commands through a message queue. A synchronization timer broadcast every 2 seconds keeps all I/O processors coordinated.
The board size determines the I/O topology: a “small” c.pCO has 2 STM8 processors and 1 ChipIO, while an “extralarge” model has 5 STM8s and 2 ChipIOs. This hardware configuration is stored in a write-locked I2C EEPROM on the base board, written during production and then permanently sealed. The firmware reads this topology descriptor at boot to know exactly what I/O capabilities are physically available.
The Watchdog: Because Reliability Is Non-Negotiable
In refrigeration, a hung controller can mean thousands of euros in spoiled product. The c.pCO implements a dual-layer watchdog system. A hardware Independent Watchdog Timer (IWDT) runs from its own clock source and cannot be stopped — even by a software reset. On top of this sits a software watchdog implemented as an array of down-counters, one per critical module. The OS ticks down all counters once per second and only refreshes the hardware watchdog if none have underflowed.
Here’s a practical detail that every c.pCO programmer should know: an application downloaded without configured I/O will trigger the watchdog. The I/O module is one of the critical modules protected by the software watchdog, and if it has nothing to manage, it won’t refresh its counter — leading to a system restart. It’s not a bug, it’s a safety feature.
Retained Variables: EEPROM with a Safety Net
When you declare retained variables in your ISaGRAF application, you might assume they’re simply saved to some memory. The reality is more sophisticated. The c.pCO uses EEPROM with a “safe” module that adds block-level CRC verification and maintains a complete mirror copy of all data. On c.pCO boards with two EEPROM chips, the mirror is stored on the second chip for maximum reliability. On smaller platforms like pCOmini with a single chip, the mirror occupies the upper half of the same chip.
For non-volatile variables requiring frequent writes (where EEPROM wear would be a concern), there’s a separate NVRAM path using battery-backed storage — either from the real-time clock chip or a dedicated FRAM chip.
USB: The Dual-Personality Port
When you connect a c.pCO via USB, the controller presents itself as a composite device with two interfaces: CDC (Communication Device Class) for application download — essentially a virtual serial port — and MSD (Mass Storage Device) for accessing the flash filesystem. It’s a neat trick: the same USB port handles both programming and file transfer.
One important caveat that trips up engineers in the field: when USB mass storage is active, the same flash volume cannot be mounted by both the controller and the PC simultaneously. This means the web server and FTP server stop working while USB is connected. It’s a filesystem-level limitation, not a bug.
Why This Matters
Understanding what’s underneath the c.suite interface makes you a better HVAC/R engineer. When you know that variable synchronization happens only at cycle boundaries, you understand communication timing. When you know there’s no hardware memory protection between tasks, you understand why a careless string operation can crash the entire controller. When you know about the journaling filesystem, you understand why the controller recovers gracefully after a power cut — but might lose the last few seconds of logged data.
The next time you deploy an .ap1 file to a c.pCO, take a moment to appreciate the layers of engineering that make it all work — from the bootloader checking CRC integrity, through the RTOS juggling a dozen concurrent tasks, to the ISaGRAF runtime interpreting your Structured Text. It’s a remarkable stack, purpose-built for reliability in the environments where it matters most.