Если вы действительно хотите выполнить рекурсию (и, как сказал @jippie, это плохая идея; подсознательное сообщение: не делайте этого ) и хотите узнать, сколько вы можете рекурсировать, вам придется выполнить некоторые вычисления и эксперименты; Кроме того, вы, как правило, будете иметь только приблизительное значение, так как оно сильно зависит от состояния памяти в момент вызова рекурсивной функции.
Для этого вам следует сначала узнать, как организована SRAM в Arduino на базе AVR (это не относится, например, к Arduino Galileo от Intel). Следующая диаграмма от Adafruit ясно показывает это:
Затем вам нужно знать общий размер вашей SRAM (зависит от микроконтроллера Atmel, следовательно, какая у вас плата Arduino).
На этой диаграмме легко определить размер блока статических данных, так как он известен во время компиляции и не изменится позже.
Размер кучи может быть сложнее узнать, так как он может изменяться во время выполнения, в зависимости от динамического выделения памяти ( 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.