guy8247 1 Posted August 18, 2014 Share Posted August 18, 2014 Hello, I am new on Energia and I am trying to setup a webserver with html pages and images stored on a SD card. The board is the TIVA C EK-TM4C1294XL and the Energia release 0101E0012. The setup was running pretty well with simple pages. However when using larger image (jpeg) files with a size like 20 kB, only an empty box is showed on the client browser. In order to separate the reading flow from the SD and the writing operation to the Ethernet client, I am done a test program using a jpeg file stored into an array of char. Doing a loop which writes each byte from the array and to the ethernet client.write is not working, and the returned image to the browser has every time a size smaller than the array. Therefore, when adding some delay or message output to the console (using Serial.print) into the above loop, then the image is showed correctly every time. Therefore, the performance becomes very slow like 10 sec required to print a 20K jpeg image webserver_test_img.ino Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 Can you zip that .ino file up into a .zip file and attach it here? I have no way of copying & pasting that much data... Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 Ok I found a different tiger picture for my example, ~24KB, and it worked fine... JpegTest.zip Did a sniff too and analyzed with wireshark, I don't see anything wrong. The connection closed as expected, and my browser even requested a /favicon.ico afterward which was met with an immediate close (since the sketch doesn't provide for any request except /tiger.jpg). I had to modify the sketch slightly to remove the SD.h stuff since I don't have that in my install, and the StrContains/StrClear functionally replaced with strncmp and memset. Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 Ah nevermind, I'm comprehending what you've done more now... I removed the 128-byte "catch" delay(10) and I see the resulting output: Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 Ok, found the basic issue... In energia-0101E0012/hardware/lm4f/libraries/Ethernet/EthernetClient.cpp, the EthernetClient::write(const uint8_t *buf, size_t size) function looks like this: size_t EthernetClient::write(const uint8_t *buf, size_t size) { err_t err = tcp_write(cpcb, buf, size, TCP_WRITE_FLAG_COPY); if (err == ERR_MEM) { /* TODO: Need to send smaller chunks if fails */ } if(cs->mode) tcp_output(cpcb); } In this instance, the "if (err == ERR_MEM)" condition evaluates true. I'm guessing @@energia meant to put something in there to catch & handle it but never got around to it. I added some extra code (a volatile catch variable that I printed over Serial from the sketch) to verify that indeed got set: GET /tiger.jpg HTTP/1.1 Host: 192.168.0.230 Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 sizeof(tiger_jpg): 24851 _ethernet_client_err_mem = 1 GET /favicon.ico HTTP/1.1 Host: 192.168.0.230 Connection: keep-alive Accept: */* User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 _ethernet_client_err_mem = 0 As you can see, the _ethernet_client_err_mem catch variable I added to my test did test true for the tiger.jpg, but not for the (dummy, zero-output) favicon.ico. Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 @@guy8247 Can you try replacing your "energia-0101E0012/hardware/lm4f/libraries/Ethernet/EthernetClient.cpp" file with this version (open the zip file attached)? It seems to work for me: EthernetClient_fixed_write.zip Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 With that modified EthernetClient.cpp library file I can do this: Serial.print("sizeof(tiger_jpg): "); Serial.println(sizeof(tiger_jpg), DEC); client.write(tiger_jpg, sizeof(tiger_jpg)); /* for (uint32_t i = 0; i < sizeof(tiger_jpg); i++) { //if ( (i & 0x7f) == 0x40) delay(10); client.write(tiger_jpg[i]); } */ and forget trying to spoon-feed the TCP/IP layer 1 byte at a time, and it works (a bit snappier I might add). Quote Link to post Share on other sites
spirilis 1,265 Posted August 18, 2014 Share Posted August 18, 2014 Pull request #447 issued for the Energia project to merge this change into the master code branch - https://github.com/energia/Energia/pull/447 reaper7 and Automate 2 Quote Link to post Share on other sites
guy8247 1 Posted August 18, 2014 Author Share Posted August 18, 2014 Hello spirilis, WAOOH !!! Many thanks for your very fast and accurate answer. Using your new release of EthernetClient.cpp and the above modification related to the client.write, right now the system is working perfectly and the image display is fast as expected. An other time, thanks a lot for your help. Best regards Guy spirilis 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.