arduino / ArduinoCore-mbed

330 stars 192 forks source link

Question: Is it possible to manually extend the ArduinoCore to support pico_multicore? #217

Open AlexJasonStewart opened 3 years ago

AlexJasonStewart commented 3 years ago

Hello,

I am using the latest ArduinoCore-mbed 2.0.0 on my Raspberry Pi Pico and would like to be able to use the multicore function as is described in the official SDK.

I have tried copying the requisite parts of the SDK to: Arduino15\packages\arduino\hardware\mbed_rp2040\2.0.0\cores\arduino\mbed\targets\TARGET_RASPBERRYPI\TARGET_RP2040\pico-sdk

I have also modified the following file so that the compiler can find all the library files: Arduino15\packages\arduino\hardware\mbed_rp2040\2.0.0\variants\RASPBERRY_PI_PICO\includes.txt

When I go to compile however it fails at the following point: Compiling sketch... "C:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\arm-none-eabi-gcc\\7-2017q4/bin/arm-none-eabi-g++" -c -Wall -Wextra -g3 -nostdlib "@C:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\variants\\RASPBERRY_PI_PICO/defines.txt" "@C:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\variants\\RASPBERRY_PI_PICO/cxxflags.txt" -DARDUINO_ARCH_RP2040 -MMD -mcpu=cortex-m0plus -DARDUINO=10607 -DARDUINO_RASPBERRY_PI_PICO -DARDUINO_ARCH_MBED_RP2040 -DARDUINO_ARCH_MBED -DARDUINO_LIBRARY_DISCOVERY_PHASE=0 "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\cores\\arduino" "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\variants\\RASPBERRY_PI_PICO" "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\libraries\\SPI" "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\libraries\\Wire" "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\cores\\arduino/api/deprecated" "-IC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\cores\\arduino/api/deprecated-avr-comp" "-iprefixC:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\cores\\arduino" "@C:\\Users\\AlexStewart\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\mbed_rp2040\\2.0.0\\variants\\RASPBERRY_PI_PICO/includes.txt" "C:\\Users\\ALEXST~1\\AppData\\Local\\Temp\\arduino-sketch-4087D06F8A8419D4493F714B6F85855D\\sketch\\2021_AURA_Front_Lamp.ino.cpp" -o "C:\\Users\\ALEXST~1\\AppData\\Local\\Temp\\arduino-sketch-4087D06F8A8419D4493F714B6F85855D\\sketch\\2021_AURA_Front_Lamp.ino.cpp.o" arm-none-eabi-g++: error: CreateProcess: No such file or directory

Is there something more I need to do to enable this functionality? I'd like to be able to run code on core1 as described in the SDK documentation linked below whilst staying within the Arduino ecosystem (the rest of my code requires the use of Arduino compatible libraries).

https://datasheets.raspberrypi.org/pico/raspberry-pi-pico-c-sdk.pdf#page=194

Thank you for your help!

fsievers commented 3 years ago

With the latest version (ArduinoCore-mbed 2.1.0) it is possible to use the pico SDK multicore functions. But I've some trouble if I use the Arduino delay() function on one of the core. This is what I've used to send the current millis() return value from core1 to core0 and do some output. It's a boring example, but it works as long as you don't use delay(). You can switch between blocking and none-blocking fifo usage by changing the blocking definition to true or false.

#include "pico/multicore.h"

#define blocking false

void core1_entry() {
  while (1) {
    if (blocking) {
      multicore_fifo_push_blocking(millis());
    } else {
      if (multicore_fifo_wready()) {
        multicore_fifo_push_timeout_us(millis(), 1000 * 1000);
      }
    }

    sleep_ms(800);
    // delay(800); delay does not work on the second core and freezes the output
  }
}

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.print("Hello, multicore!\n");

  multicore_launch_core1(core1_entry);
}

void loop() {
  uint32_t data;

  Serial.println();
  Serial.print("loop - ");

  if (blocking) {
    data = multicore_fifo_pop_blocking();
    Serial.print(data);
  } else {
    if (multicore_fifo_pop_timeout_us(1000 * 1000, &data)) {
      Serial.print(data);
    }
  }

  sleep_ms(1000);
  // delay(1000); delay does not work on the first core and freezes the output
}
MNS26 commented 3 years ago

This is a basic but great example but for some reason it always gets stuck on "Hello, mulicore!" the only way around it that i found was by pulling the RUN pin low and reseting the serial connection. any ideas to solve it?

EDIT: when it auto launches/opens the serial monitor and shows "Hello multicore!" it gets stuck in the setup call if i connect it 1or so seconds after it its fine

facchinm commented 3 years ago

delay() is implemented using ThisThread::sleep_for() but the core1 doesn't have a thread context, thus the failure. I'll provide a workaround but it's a rather complex topic that should be tackled in a structured way (like creating wrappers around multicore_launch_core1)

dlivingstone commented 2 years ago

I have been exploring this over the last week, and have a few other examples..

  1. Very basic multicore blink. Each core blinks a different LED with no interaction between them - and each using a different delay timing. https://create.arduino.cc/editor/dlivingstone/8363965d-6412-4ee7-9bad-a60a5ad728b7/preview
  2. Core 0 blinks a LED, while Core1 calculates square roots. Values are passed between cores using RAM. Delays are added with sleep_ms() to show that problems can occur trying to read numbers before they are ready. https://create.arduino.cc/editor/dlivingstone/2e2701e1-e35c-4950-89fc-bb139282e404/preview
  3. Multicore Runner. This is an example from the Pico C SDK converted to run through Arduino IDE. This one uses blocking FIFO for passing values (and function pointers) between cores. https://create.arduino.cc/editor/dlivingstone/27551f27-45e7-4a98-904e-e22dfedae36d/preview

You should be able to verify/upload these direct from Arduino Cloud

MNS26 commented 2 years ago

@dlivingstone based on the 1st link i made the builtin led (gp25) fade, but it would only run for 1 or (if lucky) 2 times

the code:


#include <Arduino.h>
#include "pico/multicore.h"
#define CORE1_LED 25u
int brightness=0;
int fadevalue = 25;
void core1_loop()
{
  while(true)
  {
  brightness=brightness+fadevalue;
  if(brightness <=0 || brightness >= 2048) {
    fadevalue = -fadevalue;
  }
    digitalWrite(CORE1_LED,HIGH);
    sleep_us(brightness);
    digitalWrite(CORE1_LED,LOW);
    sleep_us(1000);
  }
}

void setup()
{
  pinMode(CORE1_LED,OUTPUT);
  //multicore_reset_core1();
  multicore_launch_core1(core1_loop);
}

void loop()
{
}

Update: running it WITHOUT a usb connection (either 5v on vusb or only usb power) it does keep running. and the moment usb is connected to will freeze

dlivingstone commented 2 years ago

Is it actually crashing? You'll know it has crashed if the builtin LED starts a fast/slow flashing pattern.

You might want to put a sleep_ms or delay in the core0 loop too - the AFAIK mbed OS and bootloader functions all run on Core0 so it is likely a core0 issue. A simple delay in that empty loop might be enough to fix that.

Other than that I'm afraid Im not sure!