Якщо ви дійсно хочете повторити (а як @jippie сказав, що це погана ідея; підсумкове повідомлення: не робіть цього ) і хочете знати, скільки ви можете повторити, то вам доведеться виконати деякі розрахунки та експерименти; також, як правило, ви матимете лише його наближення, оскільки це багато залежить від стану пам'яті під час виклику вашої рекурсивної функції.
Для цього спершу слід знати, як організовано SRAM всередині Arduino на базі AVR (це не стосується, наприклад, Arduino Galileo від Intel). Наведена нижче діаграма Adafruit чітко показує:
Тоді вам потрібно знати загальний розмір вашої SRAM (залежить від Atmel MCU, отже, яка у вас Arduino плата).
На цій діаграмі легко з’ясувати розмір блоку статичних даних, оскільки він відомий під час компіляції і згодом не змінюватиметься.
Розмір Heap може бути важче пізнати, оскільки він може змінюватися під час виконання, залежно від динамічного розподілу пам'яті ( malloc
або new
), виконаного вашим ескізом або бібліотеками, які він використовує. Використання динамічної пам'яті в Arduino досить рідко, але деякі стандартні функції роблять це ( String
я думаю, що тип використовує її).
Для розміру стека він також буде змінюватися під час виконання, залежно від поточної глибини викликів функції (кожен виклик функції займає 2 байти в Стек для зберігання адреси абонента) та кількість та розмір локальних змінних, включаючи передані аргументи ( які також зберігаються у стеку ) для всіх функцій, які до цього часу викликаються.
Отже, припустимо, що ваша recurse()
функція використовує 12 байт для своїх локальних змінних та аргументів, тоді кожен виклик цієї функції (перший із зовнішнього абонента та рекурсивний) буде використовувати 12+2
байти.
Якщо припустити, що:
- ви перебуваєте на Arduino UNO (SRAM = 2K)
- ваш ескіз не використовує динамічний розподіл пам'яті (немає купи )
- ви знаєте розмір своїх статистичних даних (скажімо, 132 байти)
- коли ваша
recurse()
функція викликається з вашого ескізу, поточний стек має 128 байт
Тоді вам залишаються 2048 - 132 - 128 = 1788
доступні байти в стеці . Таким чином, кількість рекурсивних викликів до вашої функції 1788 / 14 = 127
, включаючи початковий виклик (який не є рекурсивним).
Як бачите, це дуже важко, але не неможливо знайти те, що ви хочете.
Більш простим способом отримати доступний розмір стека, який раніше recurse()
був названий, було б використовувати наступну функцію (знайдена в навчальному центрі Adafruit; я сама не перевіряла її):
int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
Я настійно рекомендую вам прочитати цю статтю в навчальному центрі Adafruit.