我试图存储和检索TensorflowMicro缓冲数组作为Arduino MBED SDRAM指针



Arduino core在github上为ArduinoCore-mbed

我已经成功地将相机缓冲区存储到Arduino MBED SDRAM中,但这相当容易,因为代码在使用相机时期望一个指针。参见下面的代码:

SDRAMClass mySDRAM;
uint8_t *sdram_frame_buffer;
//uint8_t frame_buffer[320*320];
void setup() {  

mySDRAM.begin();
sdram_frame_buffer = (uint8_t *)mySDRAM.malloc(320 * 320 * sizeof(uint8_t));

then in the main loop I did
if (cam.grab(sdram_frame_buffer) == 0){...

注意:我还对上面的代码做了一些帧对齐,但它仍然工作得很好。

现在我想存储整个TensorflowMicro c++数组


const unsigned char model_tflite[] = {  0x74, 0x69, 0x74, ...}; 
unsigned int model_tflite_len = 2640;

//which is later called as an array
model = tflite::GetModel(model_tflite);  // name from the tflite converter model.h file

这里的问题是Portenta的最大阵列大小<= 1MB,远小于SDRAM的最大阵列大小8MB。最好的方法是将机器学习模型的数据直接放入SDRAM中,而根本不使用阵列。我不确定是否有简单的方法来做到这一点。

谁有什么建议?下面是一个在Arduino Portenta上运行的例子

// Needed for SDRAM assignment on Arduino Portenta
#include <SDRAM.h>
#define ALIGN_PTR(p,a)   ((p & (a-1)) ?(((uintptr_t)p + a) & ~(uintptr_t)(a-1)) : p)
SDRAMClass mySDRAM;

// assign values to a regular array
unsigned char model_tflite[] = {0x54, 0x46, 0x4c, 0x33};
unsigned int model_tflite_len = 4;

// define SDRAM pointer
unsigned char *sdram_mem;
unsigned char *sdram_tflite; // 32-byte aligned

void setup() {
Serial.begin(115200);
mySDRAM.begin(SDRAM_START_ADDRESS);   
// setup SDRAM memory block
sdram_mem = (unsigned char *) SDRAM.malloc(4 + 32 /*alignment*/);
sdram_tflite = (unsigned char *)ALIGN_PTR((uintptr_t)sdram_mem, 32);
// THE PROBLEM
// How to assign the data directly to the allocated pointer memory
// without having to make an array as well
// The following traditional line works
// sdram_tflite = model_tflite;
// This line doesn't work
// sdram_tflite =  {0x54, 0x46, 0x4c, 0x33};

// The following works, but is very clumsy 
*(sdram_tflite + 0) =  0x54;
*(sdram_tflite + 1) =  0x46;
*(sdram_tflite + 2) =  0x4c;
*(sdram_tflite + 3) =  0x33;

}

void myShowArray( unsigned char b[], int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(b[k], HEX);
}
Serial.println();
}

void myShowPointer( unsigned char *b, int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(*(b + k), HEX);
}
Serial.println();
}

void loop() {
Serial.println("Regular array");
for (int i=0; i < model_tflite_len; i++){
Serial.println(model_tflite[i], HEX);
}   
Serial.println();

Serial.println("SDRAM pointer as an array");
for (int i=0; i < model_tflite_len; i++){
Serial.println( *(sdram_tflite + i), HEX );
}
Serial.println();

Serial.println("Regular array passed as an array to the receiving function");
myShowArray(model_tflite, model_tflite_len);
Serial.println("Pointer passed as a pointer to the receiving function");
myShowPointer(sdram_tflite, model_tflite_len);

Serial.println("Pointer passed as an array to the receiving function");
myShowArray(*&sdram_tflite, model_tflite_len);

Serial.println("--------------------");
Serial.println();  
delay(4000);
}

输出:

Regular array
54
46
4C
33
SDRAM pointer as an array
54
46
4C
33
Regular array passed as an array to the receiving function
54
46
4C
33
Pointer passed as a pointer to the receiving function
54
46
4C
33
Pointer passed as an array to the receiving function
54
46
4C
33
--------------------

// Needed for SDRAM assignment on Arduino Portenta
#include <SDRAM.h>
#define ALIGN_PTR(p,a)   ((p & (a-1)) ?(((uintptr_t)p + a) & ~(uintptr_t)(a-1)) : p)
SDRAMClass mySDRAM;

// assign values to a regular array
unsigned char model_tflite[] = {0x54, 0x46, 0x4c, 0x33};
unsigned int model_tflite_len = 4;

// define SDRAM pointer
unsigned char *sdram_mem;
unsigned char *sdram_tflite; // 32-byte aligned

void setup() {
Serial.begin(115200);
mySDRAM.begin(SDRAM_START_ADDRESS);  
// setup SDRAM memory block
sdram_mem = (unsigned char *) SDRAM.malloc(4 + 32 /*alignment*/);
sdram_tflite = (unsigned char *)ALIGN_PTR((uintptr_t)sdram_mem, 32);
// THE PROBLEM
// How to assign the data directly to the allocated pointer memory
// without having to make an array as well
// The following traditional line works
// sdram_tflite = model_tflite;
// This line doesn't work
// sdram_tflite =  {0x54, 0x46, 0x4c, 0x33};


// The following works, but is very clumsy
// *(sdram_tflite + 0) =  0x54;
// *(sdram_tflite + 1) =  0x46;
// *(sdram_tflite + 2) =  0x4c;
// *(sdram_tflite + 3) =  0x33;

// Try this
// unsigned char buffer[8];
// memcpy(buffer,"x20x38x00x00x0Ex82x00x06",8);
// yes this works fine!
memcpy(sdram_tflite, "x54x46x4cx33", model_tflite_len);



}

void myShowArray( unsigned char b[], int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(b[k], HEX);
}
Serial.println();
}

void myShowPointer( unsigned char *b, int sizeOfArray ) {
for ( int k = 0 ; k < sizeOfArray ; k++ ){
Serial.println(*(b + k), HEX);
}
Serial.println();
}

void loop() {
Serial.println("Regular array");
for (int i=0; i < model_tflite_len; i++){
Serial.println(model_tflite[i], HEX);
}  
Serial.println();

Serial.println("SDRAM pointer as an array");
for (int i=0; i < model_tflite_len; i++){
Serial.println( *(sdram_tflite + i), HEX );
}
Serial.println();

Serial.println("Regular array passed as an array to the receiving function");
myShowArray(model_tflite, model_tflite_len);
Serial.println("Pointer passed as a pointer to the receiving function");
myShowPointer(sdram_tflite, model_tflite_len);

Serial.println("Pointer passed as an array to the receiving function");
// myShowArray(*&sdram_tflite, model_tflite_len);
myShowArray(sdram_tflite, model_tflite_len);

Serial.println("--------------------");
Serial.println();  
delay(4000);
}

最新更新