Portenta : Sharing variable bigger than 8-bit makes the M7 crashes

Hi,
I am trying to share variables between the 2 cores using the RPC.call interface but it seems to be limited to int(8-bit) variable. When trying to share bigger variable the arduino crashes (red led starts blinking 4 shorts, 4 longs).

The shared variables can be declared as something bigger than 8-bit int but as soon as the value being passed is greater than 255 the M7 crashes.

This problem seems to only appear when the M7 core calls function on the M4.

#include "Arduino.h"
#include "RPC_internal.h"


#ifndef CORE_CM7
//this is just for CM4
int32_t add(int32_t a, int32_t b){
  RPC1.println(" M4: calling add\n");
  return a+b;
}
#endif

void setup() {
  //for both cores using RPC
  RPC1.begin();
#ifdef CORE_CM7
  Serial.begin(115200);
  while (!Serial) {}
  pinMode(LEDG, OUTPUT); //CM7 configures LED GPIO
  Serial.println("CM7: release and boot CM4");
  //boot CM4
  //-->it has to be done in order to release CM4 !!
  LL_RCC_ForceCM4Boot();
#else
  RPC1.bind("add",add);
#endif
}

void loop() {
  // put your main code here, to run repeatedly:
#ifdef CORE_CM7
  //this is the CM7 main thread
  digitalWrite(LEDG, HIGH); //CM7 toggles the LED (GPIO)
  delay(1000);
  digitalWrite(LEDG, LOW);
  delay(1000);

  Serial.print(" M7: Calling add | ");
  auto res = RPC1.call("add", (int32_t)155,(int32_t) 100).as<int32_t>();
  Serial.println(res);
  while (RPC1.available()) {
    Serial.write(RPC1.read());
  }
#else
  //The CM4 does nothing
#endif
}

This exemple should work, but if you increase the value of the variables passed with the RPC call to something greater than 255 (or the value returned) then the arduino crashes.

Do anyone knows why this happens, and why does it seem to work when the M4 is doing the RPC call ? I guess a simple work around would be to split the int32_t into 4 int8_t, but do you guys have better idea?

Works fine for me though :


Here the code :

#include "Arduino.h"
#include "RPC.h"

int c=0;
#ifdef CORE_CM4
//this is just for CM4
int32_t add(int32_t a, int32_t b){
  int val=a+b;
  String st=" M4: calling add"+(String)val;
  RPC.println(st);
  return a+b;
}
#endif

void setup() {
  //for both cores using RPC
  RPC.begin();
#ifdef CORE_CM7
  Serial.begin(115200);
  while (!Serial) {}
  pinMode(LEDG, OUTPUT); //CM7 configures LED GPIO
  Serial.println("CM7: release and boot CM4");
  //boot CM4
  //-->it has to be done in order to release CM4 !!
  LL_RCC_ForceCM4Boot();
#else
  RPC.bind("add",add);
#endif
}

void loop() {
  // put your main code here, to run repeatedly:
#ifdef CORE_CM7
  //this is the CM7 main thread
  digitalWrite(LEDG, HIGH); //CM7 toggles the LED (GPIO)
  delay(1000);
  digitalWrite(LEDG, LOW);
  delay(1000);
  
  Serial.print(" M7: Calling add | ");
  auto res = RPC.call("add", (int32_t)c,(int32_t) 100).as<int32_t>();
  Serial.println(res);
  while (RPC.available()) {
    Serial.write(RPC.read());
  }
  c++;
#else
  //The CM4 does nothing
#endif
}

I modified close to nothing. As to what I use I use shared memory and HSEM to prevent both cores to access the variable at the same time.
For HSEM use:

#ifdef CORE_M7
#define HSEM_ID_INIT 0
#define HSEM_PROCESS_INIT 0
void loop(){
   while (HAL_HSEM_Take(HSEM_ID_INIT, HSEM_PROCESS_INIT) != HAL_OK) {};
   SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
   //your data management on CORE M7(NAME->data)
   SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
   HAL_HSEM_Release(HSEM_ID_INIT, HSEM_PROCESS_INIT);
}
#endif

#ifdef CORE_M4
#define HSEM_ID_INIT 0
#define HSEM_PROCESS_INIT 0
void loop(){
   while (HAL_HSEM_Take(HSEM_ID_INIT, HSEM_PROCESS_INIT) != HAL_OK) {};
   //your data management on CORE M4(NAME->data)
   HAL_HSEM_Release(HSEM_ID_INIT, HSEM_PROCESS_INIT);
}
#endif

Shared memory :

struct shared_data
{
  type data;
};
volatile struct shared_data * const NAME = (struct shared_data *)FREE_SHARED_MEMORY_ADRESS;

To find shared memory refer to :
image
and
image
Not sure you need that code, I use it because I need a process way faster than RPC.
Best of luck.

Hey thanks for the info. The problem probably comes from the fact that I'm not using the most recent version of mbed-core ( I'm on 2.5.2).
Are you on the latest release ? Have you tested this code for way bigger values, let's say 200000 ?
I've seen other thread talking about using other means to share variables but in my case I'm really just calling functions on the other core and passing arguments. So I don't really need a faster process.


Still work.
And yes I use the latest one also I am not familiar with RPC but the way you defined add in CM4 only print the fact that M4 is working but will never give you the a+b value to be read on M7 it will only be calculated and thrown away since not stored anywhere or used.
Step 1 M7 transfer data to M4
Step 2 M4 calls add (obeying the bind)
Step 3 It sends " M4: calling add\n"
Step 4 it adds a to b
END of the loop, so a+b is always calculated but never shown or stored. Here take a look at the difference when defined on M7 and M4, since M7 has access to serial port you don't need to transfer data but you need to for M4.

Yes I know, the code I showed was just an example to provide some context to explain when my board was crashing.

Thank you for testing it with bigger values.
I guess I will try to update my code for it to be compatible with the latest releases of mbed-core.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.