9 years, 4 months ago.

web application not working on K64F

Hi all, I made a web server on mbed. I tested this application on WI-GO (KL25Z based platform) LPC1768 and K64F. I have observed that server works fine on lpc1768 and wi-go, but it crashes on K64F. The reason behind crash is K64F is giving some memory limitation, declaration of large global arrays (char array[10][10]) is letting the program to crash.

I have seen some similar questions in this forum as well, where people has said that K64F crashes when we declare multiple threads or declare big arrays or when program consumes more than 60KB of ram.

It is kinda weird because this board has 256KB of ram.

Can developers report this issue, and kindly fix it as this board is relatively cheap and has more potential to do bigger tasks

1 Answer

9 years, 4 months ago.

I have seen previous questions from you about this, but are they are there any simple example programs you can show to crash? Since for example a 10x10 char array is not large. A 100x100 array is large, but reserving 100 bytes should even on the smallest mbed not be an issue.

I modified the following program to create my web server: http://developer.mbed.org/users/frankvnk/code/Wi-Go_IOT_Demo_MKII/

it has one file which got the html code for web page view, and one file which control the functionality of web page, well my app is quite simple as compare to the above app, and I deleted many files from it which i didnt require. The above mentioned codes runs on KL25Z which has just 16 KB of ram. I modified its main, avnet.html file and demo.cpp file. to create my app

int demo_wifi_main(void)
{
    server_running = 1;
    while(1)
    {
   
        (htmlHandlers.dynHtmlFunc[0]) = getViewsNum;
        memcpy(htmlHandlers.dynHtmlParamName[0],"IP Address...   ",strlen("IP Address...  "));
        htmlHandlers.dynHtmlParamName[0][strlen("IP Address...  ")] ='\0';
        
        
        
  (htmlHandlers.dynHtmlFunc[1]) = getTSI_sliderStr;  
        memcpy(htmlHandlers.dynHtmlParamName[1],"Received Bits   ",strlen("Received Bits   "));
        htmlHandlers.dynHtmlParamName[1][strlen("Received Bits   ")] ='\0';

     
        // Configure CGI Handler
        (pHandlers.cgiHandlerFunc[0]) = testFunc;

        serverMain(HTTP_PORT,(char *)index, &pHandlers, &htmlHandlers);
    }
}


void testFunc(char * str)
{  
char *htt;
char *htt1="http://";
char *pch=NULL; //use for tokenizing the string

char *b=NULL; //bits to be stored from the user

 char *ur="/cgi-bin/ext; 
   char *ht="://";
   char *sl="-";
 char *ip;
    //memcpy(testString,str,strlen(str));

if(strstr(str,"trigger") != NULL)
    { 
 RED_ON; GREEN_OFF; BLUE_OFF; 
    
 pch = strtok (str,"&=");
ip=pch;
ip[strlen(ip)]='\0';
 pch = strtok (NULL, "&=");
 
 pch = strtok (NULL, "&=");
         b=pch;
     
b[strlen(b)]='\0';
  pch = strtok (NULL, "=");
         htt=pch;
             
htt[strlen(htt)]='\0'; 

   strcat(htt1,ht);
   strcat(htt1,ip);
   strcat(htt1,ur);
strcat(ip,sl);
strcat(ip,b);

printf("htt is %s \n",htt1);




     printf("status is %d \n",status);
         memcpy(ipaddr[counter],ip,strlen(ip));
     ipaddr[counter][strlen(ip)] ='\0';
     
 counter++;
  printf("\n"); 
 printf("\n"); 


  
    }
    else if(strstr(str,"trigger") == NULL)
    {

        RED_OFF; GREEN_ON; BLUE_OFF;
    }
    else if (strcmp(str, "Blue-") == 0) 
    {
        RED_OFF; GREEN_OFF; BLUE_ON;
    }      
}

here test function is corresponding to cgi function, it works fine when arrays are small, but it crashes if I increase the size of globally declare array ipaddr. I managed to increase the size from 3*10 to 20*22, by reducing the size of some other arrays.

html handlers are defined in the following chunk of code

void handleHTTPRequest(TCPSocketConnection *client)
{
    char * reqline[1];
    char * cgiTok;

    int i = 0;         
    char paramBuf[80];
    int bytesRecvd;
    char tempStr[80]; //PF was 26

    memset(requestBuffer,0,sizeof (requestBuffer));
    bytesRecvd = client->receive(requestBuffer, sizeof(requestBuffer));

    printf("handleHTTPRequest\r\n");
 
    if(bytesRecvd > 0)
    {
        // Received some data, check it and send data back
        reqline[0] = strstr(requestBuffer, "GET");
        if ( reqline[0] != NULL )
        {
            if (strstr (requestBuffer, "HTTP/1.0") != NULL && strstr (requestBuffer, "HTTP/1.1") != NULL )
            {
                client->send_all("HTTP/1.0 400 Bad Request\n", 25);
            }
            else
            {

#ifdef HTTP_CGI_ENABLED
                // Do we have CGI parameters we need to parse?
                if(strchr(requestBuffer, '?') != NULL)
                {
                    // Decode URL and handle each parameter sequentially
                    // according to table previously setup.
                    cgiTok = strstr(requestBuffer,"=");
                    if(cgiTok != NULL)
                    {
                        memset(paramBuf,0,sizeof(paramBuf));
                        memcpy(paramBuf,cgiTok+1,35);     // hard-coded for demo: 5 character parameter (-Red-/Green/Blue-)
                        chList->cgiHandlerFunc[0](paramBuf);

                    }
                }
#endif

#ifdef HTTP_DYN_HTML_ENABLED
                // The code below replaces data in the HTML page
                // with that generated by the specified functions.
                for(i = 0; i < 2; i++)  // change the range here for more dynamic fields on webpage
                {
                    memset(tempStr,0,sizeof(tempStr));
                    htmlList->dynHtmlFunc[i](tempStr);
                    tempStr[strlen(tempStr)]= ' ';
                    pageReplace((char *)indexPage,
                                (char *)htmlList->dynHtmlParamName[i],
                                (char *)tempStr);
                }
#endif
                viewCounter++;
            
                sendHTTPData(HTTP_RESP, strlen(HTTP_RESP), client);
                                
                for(i = 0; i < strlen(indexPage); i += HTTP_TX_BLOCK_SIZE)
                {
                    if(strlen(indexPage) - i < HTTP_TX_BLOCK_SIZE)
                    {
                        sendHTTPData(&indexPage[i], strlen(indexPage) - i, client);
                    }
                    else
                    {
                        sendHTTPData(&indexPage[i], HTTP_TX_BLOCK_SIZE, client);
                    }
                }
            }
        }
    }
}


posted by zain aftab 03 Dec 2014

However web servers are quite large programs (which is most likely also why they are notoriously unstable compared to other MCU programs). Have you also observed the behavior with simple programs? And do you have any idea where it stops?

posted by Erik - 03 Dec 2014

I made a simple webapplication as well, it worked fine on frdm-k64f, even this application works fine if i declare my global array as local array (which implies it will consumes less ram). There is some issue with a ram, most probably stack and heap collusion occurs in frdm-k64F, because the same web server works fine on lpc1768.

K64F has 256KB of ram, and my webserver consumes 22% of ram and 7% of flash. The following link will give you some more idea.

https://developer.mbed.org/questions/3329/Internal-Size-Limit-K64F-mbed-mbed-rtos-/

posted by zain aftab 03 Dec 2014