Skip to content
Parallax Learn

Parallax Learn

  • Welcome
  • Tutorials
        • Tutorial Series head tag

          Tutorial Series
        • Tutorial Series

          The special, classroom-ready series pages are organized collections of tutorials for our most popular hardware and/or languages. The tutorials for each topic are conveniently accessible from a single page, shown in the order it is recommended that they be completed.
        • Robotics Series Head tag

          Robotics Series
        • Robotics Series

          • Artificial Intelligence
          • Cybersecurity: Radio Data tutorialCybersecurity
          • cyber:bot + Python
          • cyber:bot + MakeCode
          • Boe-Bot Tutorial SeriesBoe-Bot
          • Arduino Shield-Bot
          • ActivityBot with C TutorialsActivityBot + C
          • ActivityBot with BlocklyProp Tutorial SeriesActivityBot + BlocklyProp
          • Scribbler 3 Tutorial SeriesScribbler 3
        • Electronics & Programming Series Head tag

          Electronics & Programming Series
          • BS2 Board of Education Tutorial SeriesBS2 Board of Education
          • Propeller C-Language BasicsPropeller C Basics
          • FLiP Try-It Kit C Tutorial SeriesFLiP Try-It Kit + C
          • FLiP Try-It Kit BlocklyProp TutorialsFLiP Try-It Kit + BlocklyProp
          • Badge WX Tutorial SeriesBadge WX
          • Propeller BlocklyProp Basics and ProjectsPropeller BlocklyProp Basics
          • View All Tutorial Series »
        • Browse Tutorials
        • Browse Tutorials

          Individual tutorials sorted by robot or kit, and language.
        • By Robot or Kit
          • ActivityBot
          • SumoBot WX
          • Boe-Bot
          • Shield-Bot
          • cyber:bot
          • Badge WX
          • ELEV-8
          • ARLO
        • By Language
        • By Language

          • Propeller C
          • Arduino
          • BlocklyProp
          • PBASIC
          • Python
          • MakeCode
          • View All Tutorials »
  • Educators
  • Reference
  • Downloads
  • Home
  • All Courses
  • Multicore Approaches

Multicore Approaches

Stopping Cores

The last lesson showed you how to launch a function in another core with cog_run.  Now, let’s use its counterpart cog_end to stop the launched function.

 

Circuit

We’ll keep using the Activity Board’s (original or WX version) built-in LEDs on P26 and P27.  See the Blink a Light tutorial for a schematic if you are using a different board. 

 

Test Code

  • Click SimpleIDE’s Open Project button.
  • Open Cog End Example.spin from …DocumentsSimpleIDELearnExamplesMulticore. 
  • Click the Load RAM & Run button.
  • Verify that the P26 LED blinks for 3 seconds, then stops.

 

How it Works

First, the simpletools library is included to give us access to cog_run and cog_end, along with other functions. Next is the forward declaration for the blink function, which is defined below the main routine.

/*
  Cog End Example.c
*/

#include "simpletools.h"                      // Library include

void blink();                                 // Forward declaration

The cog_run function provides a return value. In this example, a local variable is declared with int *cog  = in front of cog_run(&blink, 128); to capture it.  The asterisk *  indicates cog is a pointer, meaning that the value it holds is actually the address of a memory location. This is the place where the cog_run function call set aside stack space and recorded the ID number of the core it launched. 

int main()                                    // Main function
{
  int *cog = cog_run(blink, 128);             // Run blink in other cog

Next, pause(3000) makes the main routine idle for 3 seconds. Meanwhile, the P26 LED is blinking since the blink function is being executed by another core.  Next comes the function call cog_end(cog);   The cog_end function’s parameter uses the cog_run’s return value cog. Remember that cog is the memory address that stores the ID number of the core that was launched.  So, cog_end can use the address get the ID number and shut the cog down.

  pause(3000);                                // Wait while other cog blinks LED
  cog_end(cog);                               // Stop other cog
}

The blink function itself is below the main routine. Even though its code block is inside a while(1) loop, it is not executed infinitely.  That is because the core running blink was shut down by the cog_end function call made by the core running the main routine.

void blink()                                  // Blink function for other cog
{
  while(1)                                    // Endless loop for other cog
  {
    high(26);                                 // P26 LED on
    pause(100);                               // ...for 0.1 seconds
    low(26);                                  // P26 LED off
    pause(100);                               // ...for 0.1 seconds
  }
}

 


Did You Know?

Always Recycle your Cores! — Always use cog_end to shut down a function that is no longer needed, whether or not it is using a while(1) loop. This frees up the core and stack space for re-use by another cog_run function call later in the program, and prevents unexpected results. 

Keep it local, save a few bytes — The technique above, where *cog is declared locally and used by cog_end within the same function (in this case the main function), uses fewer bytes than declaring *cog globally.

Go global and delegate — Delcaring *cog globally allows it to be used with cog_end by any function in the application, including those running in other cores. It costs a few bytes more of code size, but frees the main routine from the task (a great advantage of multiprocessing).


 

Try This

As mentioned above, the *cog pointer can be declared globally, allowing it to be used with cog_end by any function in the application.  You can put cog_end right inside the blink function, so the core running that code can shut itself down. 

  • Click Save Project As, rename the project, and save it to …DocumentsSimpleIDEMy Projects.
  • Add a line to declare *cog globally, above the main routine.
  • In main, modify the cog_run call so that it stores its return value in the cog variable.. Be sure to comment out or delete the pause and cog_end function calls in the main routine.
  • In the blink function, change the while(1) loop to a for loop, as shown below.
  • Add the cog_end function call to blink, so the core can shut itself down when the for loop is done.

 

Your Turn

So far, we have tried shutting down a core from the main routine, and having a core shut itself down. Now, let’s launch two cores, and have one shut down both itself and the other.

  • Write a blink2 function that blinks the P27 LED on/off every 53 ms in an endless while(1) loop.
  • Above the main routine, add a forward declaration for blink2, and declare a global pointer *cog2 to use with it.
  • In the main routine, launch the blink2 function in a new core, and store the cog_run function’s return value in cog2.
  • In the blink function, add another cog_end function call to shut down the core runing the blink2 function.
  • Run your code and see if it works: both the P26 and P27 LEDs should blink for about 3 seconds, and then shut down at almost the same time.

Did it work?  Hint: if your P27 LED didn’t stop blinking, take a look at the two cog_end calls in your blink function.  Which one is executed first?


Printer-friendly version
Simple Multicore
Prev
Cores Sharing Data
Next

DISCUSSION FORUMS | PARALLAX INC. STORE

About | Terms of Use | Feedback: [email protected] | Copyright©Parallax Inc. 2024

© 2025 Parallax Learn • Built with GeneratePress