Nếu bạn thực sự muốn tái diễn (và như @jippie nói rằng đó là một ý tưởng tồi; thông điệp cao siêu: đừng làm điều đó ) và muốn biết bạn có thể tái diễn bao nhiêu, thì bạn sẽ phải thực hiện một số tính toán và thử nghiệm; ngoài ra, bạn thường chỉ có một xấp xỉ của nó vì nó phụ thuộc rất nhiều vào trạng thái bộ nhớ tại thời điểm hàm đệ quy của bạn sẽ được gọi.
Đối với điều này, trước tiên bạn nên biết SRAM được tổ chức bên trong Arduino dựa trên AVR (nó sẽ không áp dụng cho ví dụ Arduino Galileo của Intel). Sơ đồ sau đây từ Adaf nhung cho thấy rõ:
Sau đó, bạn cần phải biết tổng kích thước của SRAM của bạn (phụ thuộc vào Atmel MCU, do đó bạn có loại bo mạch Arduino nào).
Trên sơ đồ này, có thể dễ dàng tìm ra kích thước của khối Dữ liệu tĩnh vì nó được biết đến vào thời gian biên dịch và sẽ không thay đổi sau này.
Các Heap kích thước có thể khó khăn hơn để biết vì nó có thể thay đổi trong thời gian chạy, tùy theo cấp phát bộ nhớ động ( malloc
hoặc new
) được thực hiện bởi phác thảo của bạn hoặc các thư viện nó sử dụng. Sử dụng bộ nhớ động là khá hiếm trên Arduino, nhưng một số chức năng tiêu chuẩn làm điều đó (loại String
sử dụng nó, tôi nghĩ vậy).
Đối với kích thước Stack , nó cũng sẽ thay đổi trong thời gian chạy, dựa trên độ sâu hiện tại của các lệnh gọi hàm (mỗi lệnh gọi hàm lấy 2 byte trên Stack để lưu địa chỉ của người gọi) và số lượng và kích thước của các biến cục bộ bao gồm các đối số được truyền ( cũng được lưu trữ trên Stack ) cho tất cả các hàm được gọi cho đến bây giờ.
Vì vậy, giả sử recurse()
hàm của bạn sử dụng 12 byte cho các biến và đối số cục bộ của nó, sau đó mỗi lệnh gọi hàm này (lần đầu tiên từ một người gọi bên ngoài và các hàm đệ quy) sẽ sử dụng 12+2
byte.
Nếu chúng ta cho rằng:
- bạn đang dùng Arduino UNO (SRAM = 2K)
- bản phác thảo của bạn không sử dụng cấp phát bộ nhớ động (không có Heap )
- bạn biết kích thước của Dữ liệu tĩnh của mình (giả sử là 132 byte)
- khi
recurse()
hàm của bạn được gọi từ bản phác thảo của bạn, Stack hiện tại dài 128 byte
Sau đó, bạn còn lại với các 2048 - 132 - 128 = 1788
byte có sẵn trên Stack . Do đó, số lượng các cuộc gọi đệ quy đến chức năng của bạn 1788 / 14 = 127
, bao gồm cả cuộc gọi ban đầu (không phải là cuộc gọi đệ quy).
Như bạn có thể thấy, điều này rất khó, nhưng không phải là không thể tìm thấy những gì bạn muốn.
Một cách đơn giản hơn để có được kích thước ngăn xếp có sẵn trước đó recurse()
được gọi là sử dụng chức năng sau (được tìm thấy trên trung tâm học tập Adafbean; tôi chưa tự mình kiểm tra nó):
int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
Tôi đặc biệt khuyến khích bạn đọc bài viết này tại trung tâm học tập Adafbean.