How I Proved My Code Was Actually Running on Additional Propeller Cogs | by Maryclareok | Jul, 2026
Using the linker map, worker-reported cog IDs, an LED runtime test, simulation and oscilloscope measurements
By Maryclare
My question was simple: How could I prove that code assigned to additional Propeller cogs was actually executing there, rather than merely existing somewhere in the compiled binary?
I was working with a Propeller 1 Demo Board, an older but unusual microcontroller built around multiple independent processors called cogs. Parallax lists the P8X32A as having eight 32-bit cores, 32 KB of shared hub RAM, and 512 32-bit words of local memory in each cog. This provides approximately 2 KB of local memory per cog.
The part that initially confused me was the relationship between the hub and the cogs. The hub stores shared program data and the compressed instruction stream. However, the hub does not execute instructions by itself. A cog still performs the processing. In my main program, Cog 0 ran the CMM kernel, which fetched and decompressed code stored in hub memory. The remaining cogs were available for worker code.
The PropGCC memory-model documentation explains that CMM stores code and data in hub memory and decompresses instructions through a runtime kernel. The mixed-mode documentation also explains that files ending in .cogc are compiled in the native COG memory model, even when the main project uses CMM. When a cog starts, it loads image it copied from hub memory into that cog’s local memory and execution begins there.
While working through the proofs, I realized that I needed evidence for these four claims:
· The worker cog images were included inside the hub.
· The main program successfully launched additional cogs other than cog 0.
· The worker code identified the cog it was running on (cog id or processor id).
· The worker paths continued executing at runtime on both the simulator and physical hardware.
1. Build evidence: the cog images existed in the linked program
I started with the linker map. The project contained two native worker modules: dummy.cogc and provecmm.cogc. The map file showed separate loadable sections for both images, including their sizes and hub load addresses.
This was necessary evidence, but it was not evidence that this file was running in a separate cog. The map only showed that the compiler and linker placed the worker images into the final program. A load image can exist without ever being launched on a cog because every instruction in the cmm memory model compiles the instructions to the hub but we want the cog instructions to run on other cogs like cog 1 and 2 while the main code runs on cog 0 to take advantage of the multiple cogs or processors . I therefore treated the map as the first layer of the proof, not the conclusion.
2. Launch evidence: the main cog started two workers
The GCC (PROPGCC) for propeller 1 generates external arrays that point to each. cogc image. The main program passed those arrays to cognew() along with pointers to the struct which holds variables :
extern unsigned int _load_start_dummy_cog[];
extern unsigned int _load_start_provecmm_cog[];dummy_cog = cognew(_load_start_dummy_cog,
&dummy_data.mailbox);
monitor_cog = cognew(_load_start_provecmm_cog,
&monitor_data.mailbox);
In my terminal output, the main program reported Cog 0, then cognew() returned Cog 1 for the dummy worker and Cog 2 for the monitor worker. This showed that two additional cog slots had been allocated.
Worker code:
In the worker code the cog id was passed into the mailbox and called during run time, The main program then read and printed those mailbox values.
The dummy worker reported Cog 1, while the monitor worker reported Cog 2. Because cogid() was called inside the worker code, these values provided worker-side evidence of which cogs were executing the two worker images.
3. LED runtime evidence: the monitor worker toggled the Pin 20 LED
I performed a simpler physical runtime check with the Demo Board LED connected to Pin 20. This test used the provecmm.cogc monitor worker. Inside that worker, Pin 20 was configured as an output and toggled repeatedly. Because the Pin 20 output instruction was located inside the worker loop, the visible LED activity showed that the monitor worker had reached and continued executing that runtime path.
Get Maryclareok’s stories in your inbox
Join Medium for free to get updates from this writer.
The code screenshot and board photograph below belong to this Pin 20 LED test.