Arduinoはコンパイル時にcppに落とされてからコンパイルされるので、基本はコンパイラ言語ですが、学習用にかなり冗長な作りになっているようなので、実行速度が問題になるケースも多そうです
というわけで簡単にベンチマーク
元はLEDブリンクのソースに計測用のコードを追加しています
<mainのinoファイル>
ただし時間測定時には、loop1()のwhile処理(loop0()からのメッセージ受信)はコメントアウト
#include "common.h"
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 500; // interval at which to blink (milliseconds)
uint32_t message_s = 0;
uint32_t message = 999;
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// send message to core1
rp2040.fifo.push(message_s);
message_s += 1;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
void setup1(){
pinMode(0, OUTPUT);
}
void loop1(){
while (rp2040.fifo.available()>0){
message = rp2040.fifo.pop();
message *= 10;
}
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){ if (disp_data[i][j] > 7){
dest_data[i][j] = disp_data[i][j];
}
else{
dest_data[i][j] = 0;
}
}
}
clock_func();
}
<common.hファイル:byte型の二次元配列を2個確保しています>
データの中身に取り立てて意味はありません
// display data
byte disp_data[8][8] = {
{0,1,1,2,3,5,8,13},
{13,8,5,3,2,1,1,0},
{0,1,1,2,3,5,8,13},
{13,8,5,3,2,1,1,0},
{0,1,1,2,3,5,8,13},
{13,8,5,3,2,1,1,0},
{0,1,1,2,3,5,8,13},
{13,8,5,3,2,1,1,0}
};
byte dest_data[8][8] = {
};
<clock.inoファイル>
gpioへの書き込みが極端に遅いので、c++の関数を呼び出せるということなので切り替えた(digitalWrite() -> gpio_put())、パルス幅確保のためにハイレベルを5回書き込んでます
void clock_func(){
//digitalWrite(0, HIGH);
gpio_put(0, 1);
gpio_put(0, 1);
gpio_put(0, 1);
gpio_put(0, 1);
gpio_put(0, 1);
//digitalWrite(0, LOW);
gpio_put(0, 0);
}
実行速度の測定結果
測定はgpio0のポイントをオシロのプローブであたって時間測定
・digitalWrite()使用時
・gpio_put()使用時
考察
ループの外でGPIO書き込みを行っているのに、全体の処理時間を3割程度長くしてしまうArduinoの標準書き込み関数は時間がクリティカルな場所では使えない、配列の処理に関してはcに比較したら遅いだろうけれども許容範囲か、ただしコードの記述には工夫が必要(配列の要素を一度変数に入れてから処理とかはやめた方が良い
やりたいことはLEDアレイ(HUB75で64*32)の点灯をコア1で行うようにしたいから、16階調処理だと一行のループ処理をおよそ69μs以内(50Hz以下になると人の目に見えるから、1000000/(60*15*16) =69.444μs )ぐらいで実行必要だからターゲットはそこだけど、なんとかなりそうな感触
admin