Getting multicore example to work (Pico C SDK multicore_runner.c)

I have been learning about the new multicore functionality using the examples found in the official Raspberry Pi Pico C SDK.

There is one example called multicore_runner.c which uses a function pointer.

I was having great problems getting it to work because of this line in the code:

int32_t (*func)() = (int32_t(*)()) multicore_fifo_pop_blocking();

The Arduino compiler did not like it.

Well with a bit of thought and some trial and error I figured out that this needs to be:

int32_t (*func)(int32_t) = (int32_t(*)(int32_t)) multicore_fifo_pop_blocking();

Now the code example works.

I created a fun example which includes blinking LED's (see below). Note this example was developed and tested on a Raspberry Pi Pico board rather than the RP2040 Connect.

Apologies to the purists as I tend to use a mix of Arduino and Mbed code. I also prefer to use Serial1 for my serial output as this avoids the hassle of the virtual serial USB port (Serial).

#include <stdio.h>
#include <mbed.h>
#include "pico/multicore.h"

mbed::DigitalOut led1(LED1, 0);
mbed::DigitalOut led2(p2, 0);

#define TEST_NUM 10

void core1_entry() {
    
  uint32_t t_int = millis();
  while (1) {
    // Function pointer is passed to us via the FIFO
    // We have one incoming int32_t as a parameter, and will provide an
    // int32_t return value by simply pushing it back on the FIFO
    // which also indicates the result is ready.

    int32_t (*func)(int32_t) = (int32_t(*)(int32_t)) multicore_fifo_pop_blocking();
    int32_t p = (int32_t)multicore_fifo_pop_blocking();
    led2 = !led2;    
    int32_t result = (*func)(p);
    multicore_fifo_push_blocking(result);
    
  } 
}


int32_t factorial(int32_t n) {
    int32_t f = 1;
    for (int i = 2; i <= n; i++) {
        f *= i;
    }
    return f;
}

int32_t fibonacci(int32_t n) {
    if (n == 0) return 0;
    if (n == 1) return 1;

    int n1 = 0, n2 = 1, n3;

    for (int i = 2; i <= n; i++) {
        n3 = n1 + n2;
        n1 = n2;
        n2 = n3;
    }
    return n3;
}

void setup() {

  Serial1.begin(115200);
  sleep_ms(100);
  Serial1.println("\r\nHello, multicore_runner!");
  
  // This example dispatches arbitrary functions to run on the second core
  // To do this we run a dispatcher on the second core that accepts a function
  // pointer and runs it
  multicore_launch_core1(core1_entry);
  
}

void loop() {
  int32_t res;
  led1 = !led1;
  sleep_ms(500);
  multicore_fifo_push_blocking((int32_t) &factorial);
  multicore_fifo_push_blocking((int32_t)TEST_NUM);

  // We could now do a load of stuff on core 0 and get our result later

  res = multicore_fifo_pop_blocking();

  Serial1.println("Factorial " + String(TEST_NUM,DEC) + " is " + String(res, DEC));

  // Now try a different function
  led1 = !led1;
  sleep_ms(500);
  multicore_fifo_push_blocking((int32_t) &fibonacci);
  multicore_fifo_push_blocking((int32_t)TEST_NUM);

  res = multicore_fifo_pop_blocking();

  Serial1.println("Fibonacci " + String(TEST_NUM,DEC) + " is " + String(res, DEC));
}

What if 'n' is negative?

You're welcome to insert your own negative number into the code to then crash the pico if you want... :slightly_smiling_face:

This code snippet is an extraction (copy n paste) from the Pico C SDK example set, with an amendment to the function pointer and with LED state changes added in to demonstrate how "pop_blocking" works in core1 when you add in a delay in core0.