We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello!
I'm trying to run HTTP-server on my LPC1788 board. lwip stack works fine. But when I try to run http-server under RL-ARM programm doesn't start at all. I included to my project follow files: EMAC_LPC177x_8x.c, Net_Config.c, TCP_CM3.lib, TCPD_CM3.lib (and corresponding headers Net_Config.h, EMAC_LPC177x_8x.h). Here my program:
include "LPC177x_8x.h" #include "debug_frmwrk.h" #include "RTL.h" int main (void) { SystemInit(); debug_frmwrk_init(); _DBG_("Started!"); init_TcpNet (); while (1) { main_TcpNet(); } }
I want just to try ping my board from my PC Ethernet. Do you mind to explain to me what is wrong?
Regards, Vasilij.
Thank you very much, it works!!! Another one question, do you mind? I need to dynamically create web pages using data from SD card and send large amounts of data by HTTP. Haw can I manually create HTTP responses?
yep, look for example : Keil\ARM\Boards\Keil\MCB1700\EasyWEB
You need to read TCPNet's user manual. Normally this is achieved by callback functions the user implements.
I try to respond to all tcp massages that come to my board by tcp_send (soc, "OLOLO!", 6); (soc - soket that used). I some changed LEDSwitch sample:
U16 tcp_callback (U8 soc, U8 evt, U8 *ptr, U16 par) { /* This function is called by the TCP module on TCP event */ /* Check the 'Net_Config.h' for possible events. */ par = par; if (soc != socket_tcp) { return (0); } switch (evt) { case TCP_EVT_DATA: /* TCP data frame has arrived, data is located at *par1, */ /* data length is par2. Allocate buffer to send reply. */ // procrec(ptr); tcp_send (soc, "OLOLO!", 6); break; case TCP_EVT_CONREQ: /* Remote peer requested connect, accept it */ return (1); case TCP_EVT_CONNECT: tcp_send (soc, "OLOLO!", 6); /* The TCP socket is connected */ return (1); } return (0); }
But answer doesn't come (I'm using Putty). What is wrong?
If I remember well tcp_send cannot be used from inside the callback.
And before invoking the tcp_send you need to get the tcp buffer which is the only one that tcp_send likes so invoking directly tcp_send (soc, "OLOLO!", 6); !!!! WILL NOT WORK.
do something like this:
void send_data (void) { U32 unMax; U8 *ucSendbuf; U32 unIndex; if (tcp_check_send (tcp_soc)) { unMax = your_size; ucSendbuf = tcp_get_buf (unMax); // copy bytes to send buffer. for (unIndex = 0; unIndex < your_size; unIndex++) { ucSendbuf[unIndex] = your_data; } tcp_send (tcp_soc, ucSendbuf, your_size); } }
Finally I did it! Once again thanks a lot for your help! My code follow:
void send_data (U8 tcp_soc) { U32 unMax; U8 *ucSendbuf; U8 data[] = "HTTP/1.0 200 Ok\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n<html><head>Hello!</head><body> <h1>Nothing to see here</h1></body></html>\n";// if (tcp_check_send (tcp_soc)) { unMax = tcp_max_dsize (sizeof(data)); ucSendbuf = tcp_get_buf (unMax); memcpy(ucSendbuf, data, sizeof(data)); tcp_send (tcp_soc, ucSendbuf, sizeof(data)); } } static void timer_poll () { /* System tick timer running in poll mode */ static U32 time; if (SysTick->CTRL & 0x10000) { time++; if (time == 10) { /* Timer tick every 100 ms */ time = 0; timer_tick (); } } } //Opened socket----- static U8 socket_tcp; U16 tcp_callback (U8 soc, U8 evt, U8 *ptr, U16 par) { par = par; if (soc != socket_tcp) { return (0); } switch (evt) { case TCP_EVT_DATA: flag = 1; return (1); case TCP_EVT_CONREQ: return (1); case TCP_EVT_CONNECT: return (1); case TCP_EVT_ACK: return (1); } return (0); } void webServerTsk (void *pvParameters) { init_TcpNet (); socket_tcp = tcp_get_socket (TCP_TYPE_SERVER, 0, 10, tcp_callback); if (socket_tcp != 0) tcp_listen (socket_tcp, 80);//PORT_NUM for(;;) { timer_poll (); main_TcpNet (); if(flag == 1) { //It works and sends data send_data (socket_tcp); //It doesn't work and doesn't send data send_data (socket_tcp); flag = 0; } portYIELD(); } }
But now I can't to send more than one TCP message. What I'm doing wrong?
Not sure, but maybe the main_TcpNet() need to be invoked after each send_data , I suspect only the latest version of what was set on on the tcp buffer is sent when main_TcpNet() is invoked
Well here my programm:
void webServerTsk (void *pvParameters) { init_TcpNet (); socket_tcp = tcp_get_socket (TCP_TYPE_SERVER, 0, 10, tcp_callback); if (socket_tcp != 0) tcp_listen (socket_tcp, 80);//PORT_NUM for(;;) { timer_poll (); main_TcpNet (); if(flag == 1) { send_data (socket_tcp); main_TcpNet (); send_data (socket_tcp); flag = 0; } portYIELD(); } }
It still doesn't work. Any idea?
send_data (socket_tcp); main_TcpNet (); send_data (socket_tcp); flag = 0;
You can't send second data until the first has been acknowledged, which you see with a callback.
Which I guess implies that main_TcpNet() need to be invoked many times before the second send_data can be used.
Quite possibly. But really, communication with TCPnet should be more event driven anyway. I think the call to main_TcpNet() is best done in a loop, the acknowledgement event setting a flag which is picked up and actioned in another part of that loop.
It works! I just added while(wait_ack == __TRUE) main_TcpNet () before second tcpSend. Thanks a lot!
Well I build http_upload, and all works fine. But for some strange reason there is to slow upload speed (only 5kB/s). All web pages are on SD card. Does somebody know what is wrong and what should I to check?
This is not strange at all but a feature of TCPNet - every sent out frame must be acknowledged before the next one is sent. Why don't you bother to read the product's manuals? If you want upload at speeds of up to 230 KB/s, you could use something like lwIP, but honestly I doubt very much you will manage to port it
I manage to get 380 KBytes/second TCPNet when transmiting file from SD card.
Try to use the maximum size for TCP messages to reduce overhead.
I am curious: TCPNet requires the user to prepare the payload for one complete frame and to wait to the ack for that frame. The most optimal payload is 1532 bytes long (I think, or something like that). Are you _sure_ you are uploading data to a server, and not downloading it? I have done exactly that only to get a poor upload rate, slightly better than uIP's which is not surprising given that also uIP requires the program to _wait_ until an ack for that frame is received. The margin is do big that I am inclined to believe we are not talking about the same thing here.