In the Propeller chip, a cog is a processor; the Propeller P8X32A has eight of them.
Each cog is identical (except for their unique numerical IDs) and runs independently, so it is possible to have eight different processes executing simultaneously. Each cog has its own internal memory, its own configurable counter module hardware, its own video generation hardware, access to all the I/O Pins and the System Clock, and shared access to main memory (RAM and ROM). The cogs can communicate with each other through Main RAM, can synchronize with each other through the System Clock and Locks (Semaphores), and can even silently monitor each other through the I/O Pins if necessary.
Cog RAM is a block of 512 longs (32-bits) of read/write memory inside the cog itself; it is used to hold Propeller Assembly programs and related data for exclusive use by that cog.
Cog RAM is divided into two sections: general purpose registers and special purpose registers. Each location within Cog RAM is long-addressable only and is usually referred to as a "register."
General purpose registers make up the first 496 longs (32-bits each) of Cog RAM. To execute Propeller Assembly code, the general purpose registers are first loaded with code and data from main memory, then execution starts at register 0. When executing Spin code, this portion of Cog RAM is first loaded with a copy of the Spin Interpreter.
Special purpose registers live in the last 16 longs of Cog RAM. The first four of them are read-only and return the values of the boot parameter, system counter, and input states for the I/O pins. The remaining 12 registers facilitate output state, pin direction, and interaction with the cog's counter modules, and video generator hardware.
Cog 0 is sometimes called the Application Cog because it's the one that starts the Propeller Application and often manages the application during its lifetime. Depending on how the application is written, the actual cog performing the role of the Application Cog can change over time, thus the term "Application Cog" more specifically means that which is managing the overall application.
Not much, all cogs are physically identical. Cog 0 just happens to be the first cog started when the Propeller chip boots up. For this reason, it is sometimes called the "Application Cog." All applications begin with Cog 0 executing the first public method in the top object. After that, the programmer can determine which cog will execute which portions of the application.
Yes, Cog 0 can stop (terminate) itself or can be stopped by another cog. At startup, Cog 0 is the only cog that is running until the Propeller Application (which the cog is executing) starts other cogs. If Cog 0 runs out of code to execute (in the top object's first public method, for example) or it executes a COGSTOP(0) command, then Cog 0 will terminate. While shutting down Cog 0 may seem like it would stop the Propeller Application, that's not necessarily the case since the application may have already started other cogs to carry out application tasks.
Yes. A cog can start any other cog using the COGNEW or COGINIT command, and can stop or restart any cog (including itself) using the COGSTOP or COGINIT command. COGNEW starts a new cog, if one is available; the lowest-numbered cog that is not running. COGINIT starts, or restarts, a specific cog by ID number. COGSTOP stops a specific cog by ID number. A common strategy when starting another cog is to use COGNEW and store the returned ID (the ID of the cog that actually started) for use in a future COGSTOP command when it is time to stop it.
The terms "starting" and "launching" are often used interchangeably but starting is more general in context, referring just to a cog, whereas launching usually refers to specific code being started in a cog.
Yes, using the COGNEW or COGINIT command. This is the most practical and recommended way to start a cog.
Yes, using the assembly version of COGINIT and specifying a Main RAM target address of the code to launch. You can optionally specify a target cog by ID, or use the lowest-numbered available cog by default. The most practical and recommended way to start a cog is through Spin, however.
It depends on the type of code that is starting the cog and what type of code it is launching into the cog. By nature of design, the most common case is running Spin code that launches other Spin or Assembly code.
Yes. In Spin, any cog can simply use the statement COGSTOP(COGID) in a method.
In Assembly, it may look something like this (assuming MyID is an available register):
cogid MyID 'get the ID of the cog I'm running in
cogstop MyID 'use the ID to terminate myself
No. There is no direct relationship between objects and cogs. Applications are limited by the size of the Propeller chip’s Main RAM, which is 32 KB (kilobytes) and not by the number of object files that make up the application. An application may consist of a single object, or many objects, as long as the total size of the application is less than 32 KB. An application, whether made from one object or many objects, may execute with one, two, or up to eight cogs depending only on the collective objects' "requests" to launch cogs.
Objects describe how to get tasks done and cogs perform those tasks. Since an object encapsulates all the knowledge necessary to achieve the given task, it is up to the object to decide when and how many other cogs should perform the task. In this way, objects are the natural manager of their own cogs, starting and stopping one or more other cogs as necessary for the given task.
It is possible for any cog to start and stop any other cog, but in practice it is not done outside of the logical object except in extreme cases.
Yes, the COGINIT command is used to do this (and COGID can be used first to identify the cog if it's ID is unknown). Note that care must be taken to provide unique stack space for the new Spin code; stack space that is not currently in use by any currently running Spin code. Failure to provide dormant stack space for the new Spin code will likely cause the new stack frame image to be clobbered before the cog is restarted.
Yes, using the COGINIT command and the current cog ID (or the COGID command to identify itself). If the cog was initially running Spin code, the Spin Interpreter in Cog RAM will be overwritten with 496 longs from Main Memory, starting with the address where the desired assembly code begins.
Yes, but on the Propeller it is called waiting and it functions differently than sleep does on most other devices. An active cog is always in one of two states: executing or waiting. The waiting mechanism is an integral feature of the Propeller design; it puts the cog into a very-low-power state while it waits for a specific synchronous or asynchronous event. When the event occurs, the cog can "wake up" in less the 10 millionths of a second to respond to it. The commands WAITPEQ, WAITPNE, WAITCNT, and WAITVID trigger a cog's waiting state until an event with the I/O Pins, System Counter, or Video Generator occurs.
In Propeller Assembly, once a WAIT instruction's condition is met, the instruction following it is completely processed 6 cycles later (if it's not a Hub or WAIT instruction).
It really depends on which launch command is used, COGNEW or COGINIT.
In Spin, the COGNEW command will simply return -1 if no cogs are available; otherwise, it would actually launch a cog and return its ID number. In contrast, Spin's COGINIT command targets a specific cog by its ID; it will stop the indicated cog if it was currently executing and re-launch it with the new code.
In Propeller Assembly, COGINIT does the combined job of Spin's COGNEW and COGINIT commands. It can also be configured to indicate which cog was launched, if any.
Use a loop that continues to call COGNEW until it returns a value other than -1.
In Spin, it would look something like this:
repeat while cognew(method_or_asm, @address) == -1
Propeller P8X32A Questions & Answers
Copyright © Parallax Inc., dba Parallax Semiconductor
Version 1.3.1
10/23/2013