Hi Folks!
I'm coding a micro web server and I see that certain chunks in my code allocate RAM at all and since it's more than the 328 provides, I'm trying to understand why my code in the related sections consumes RAM. In the code attached, you'll see two commented section. If I uncomment those the RAM allocation causes a crash. I'm using the sprintf command since I'd like to introduce some variable parts in those lines later but it already fails right now.
Can you give a hint why these sections consume that additional RAM (besides the already allocated "transferText") and I'd appreciate some guidance how to improve it?
Thanks a lot in advance!
-tuxuser
#include <EtherCard.h>
#include <Arduino.h>
#include <avr/interrupt.h>
#include <avr/io.h>
boolean secondExpired = 0;
byte Ethernet::buffer[500];
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x35,0x33 };
static byte myip[] = {192,168,1,210};
static byte gwip[] = { 192,168,1,1 };
static byte hisip[] = { 192,168,1,200};
static byte static_dns[] = { 192,168,1,1 };
static byte mymask[] = { 255,255,255,0};
int GetAvailableMemory();
static void response_callback (byte, word, word);
/* ----------------------------------------------------------------------
Setup
---------------------------------------------------------------------- */
void setup() {
Serial.begin (115200);
Serial.println("Test Web Server");
Serial.println();
Serial.print ("Available Memory: ");
Serial.println (GetAvailableMemory ());
if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
Serial.println( "Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
Serial.println();
if (!ether.staticSetup(myip, gwip)) {
Serial.println("Failed to set IP address");
}
ether.copyIp(ether.hisip, hisip);
ether.copyIp(ether.mymask, mymask);
ether.printIp("IP Address:\t", ether.myip);
ether.printIp("Netmask:\t", ether.mymask);
ether.printIp("Gateway:\t", ether.gwip);
ether.printIp("Server IP:\t", ether.hisip);
}
/* ----------------------------------------------------------------------
Main function
---------------------------------------------------------------------- */
void loop() {
static bool prevKey0 = 0;
static bool prevKey1 = 0;
static char transferText [100] = "\0";
static unsigned long driveTimer = 0;
static byte state = 0;
// --- Web Server Part --------------------------------------------------
word pos = ether.packetLoop(ether.packetReceive());
if (pos) {
BufferFiller bfill = ether.tcpOffset();
if(int cntr = strstr((char *)Ethernet::buffer + pos, "?1=Upper") != 0) {
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<meta http-equiv=\"refresh\" content=\"0; URL=192.168.1.210\"></head>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
else if(int cntr = strstr((char *)Ethernet::buffer + pos, "?1=Middle") != 0) {
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<meta http-equiv=\"refresh\" content=\"0; URL=192.168.1.210\"></head>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
else if(int cntr = strstr((char *)Ethernet::buffer + pos, "?1=Lower") != 0) {
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<meta http-equiv=\"refresh\" content=\"0; URL=192.168.1.210\"></head>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
else if(int cntr = strstr((char *)Ethernet::buffer + pos, "ipAdr=") != 0) {
#ifdef DEBUG_ETHERNET
Serial.print ("Set IP Address: ");
Serial.println (cntr);
#endif
}
else if (strstr((char *)Ethernet::buffer + pos, "setup") != 0) {
#ifdef DEBUG_ETHERNET
Serial.println ("Buttons");
#endif
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head><title>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "Server</title></head><body><h3>Server</h3>");
bfill.emit_p(PSTR("$S"), transferText);
/*
// Next line consumes ram - lots of ram!
sprintf (transferText, "<form action=\"input_text.htm\"><p>IP: <input name=\"ipAdr\" type=\"text\" size=\"15\" maxlength=\"15\" value=\"192.168.\"></p></form>");
bfill.emit_p(PSTR("$S"), transferText);
*/
sprintf (transferText, "</body></html>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
/*
// Next lines consume tremendous amount of ram!
else if (strstr((char *)Ethernet::buffer + pos, "two") != 0) {
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head><title>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "Server</title></head><body><h3>Server</h3>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<form action=\"\"><input type=\"submit\" value='Upper' name=2 style=\"height: 60px; width: 100px;\">
");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<input type=\"submit\" value='Middle' name=2 style=\"height: 60px; width: 100px;\">
");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<input type=\"submit\" value='Lower' name=2 style=\"height: 60px; width: 100px;\">");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "</form>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "</body></html>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
*/
else {
sprintf (transferText, "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n<html><head><title>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "Server</title></head><body><h3>Server</h3>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<form action=\"\"><input type=\"submit\" value='Upper' name=1 style=\"height: 60px; width: 100px;\">
");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<input type=\"submit\" value='Middle' name=1 style=\"height: 60px; width: 100px;\">
");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "<input type=\"submit\" value='Lower' name=1 style=\"height: 60px; width: 100px;\">");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "</form>");
bfill.emit_p(PSTR("$S"), transferText);
sprintf (transferText, "</body></html>");
bfill.emit_p(PSTR("$S"), transferText);
ether.httpServerReply(bfill.position());
}
}
}
/* ----------------------------------------------------------------------
Ethernet Response Handling
---------------------------------------------------------------------- */
static void response_callback (byte status, word off, word len) {
}
/* ----------------------------------------------------------------------
Determine Available Memory
---------------------------------------------------------------------- */
int GetAvailableMemory() {
extern int __bss_end;
extern void *__brkval;
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}