Do not call tcp_new() or netconn_new() from outside the lwip thread.  As you 
say, things will work most of the time...  Until you hit the race condition and 
something breaks.  But eventually you will hit the race condition.
 
I use DHCP and the socket API.  If you don't have memory limitations, that 
works.  The raw api will save some space, but you have to know more about what 
you are doing.  Yeah, lots of options.  Use existing examples wherever you can.
 
Marty


________________________________

From: [email protected] 
[mailto:[email protected]] On Behalf Of 
furiantes
Sent: Thursday, May 23, 2013 12:38 PM
To: Mailing list for lwIP users
Subject: Re: [lwip-users] LPC1768/9 LAN8720 FreeRTOS 7.4 LWIP 1.4.1


I have some more questions.

1. Can i call tcp_new() in different FreeRTOS threads. So functions to set tcp 
recieve functions, sent handler, errors handler etc. is that ok? 

2. This will be a dumb question but i would like to know.

I will have to make these connections:
- UDP broadcast listener
- do a polling to a server (30 second) intervals
- One file download connection

What is the best/better way to do it:

- Netcon API (which is sequential executing i know)
- TCP/IP as it is
- Socket API

Can i call netcon_new in various threads, so the things like blocking will only 
affect that current
thread and not the others.  So 1 thread call netcon newand send some data and 
wait for recieve, 
other implement or do a listening to some port and wait for data too.

I am a little lost in all that options :) thank you very much for help.


"First, all tcpip thread stuff MUST be done on the tcpip thread, so DO
NOT call it from the timer interrupt.  Option 2 is eventually going to
cause errors."
Funny fact about this, the things just keep working. True is I have only one 
active connection but it's still funny. 
But I definitly agree with you, just a funny fact :)

Danijel


Dne 23.5.2013 17:20, piše Pomeroy, Marty:


        If I'm seeing this right, you are polling for link status, and want to
        figure out which is the better way to poll.
        
        First, all tcpip thread stuff MUST be done on the tcpip thread, so DO
        NOT call it from the timer interrupt.  Option 2 is eventually going to
        cause errors.
        
        But better still, most phy chips will generate an interrupt when a cable
        is inserted or pulled.  In that interrupt, send a message to update
        status.  My interrupt is basically:
           tcpip_callback_with_block( s_HandlePhyInterrupt, NULL, 0);
        This passes a static function to be called from the tcpip thread.
        
        That's my preference - use the interrupt, let the phy chip notify your
        code when there is a change, have the interrupt pass a task-time
        interrupt handler to the tcpip thread.
        
        Marty
         
        
        -----Original Message-----
        From: [email protected]
        [mailto:[email protected]] On
        Behalf Of furiantes
        Sent: Wednesday, May 22, 2013 9:56 AM
        To: [email protected]
        Subject: [lwip-users] LPC1768/9 LAN8720 FreeRTOS 7.4 LWIP 1.4.1
        
        Hello,
        
        first sorry for my english.
        
        I have a bit of problem don't to do this properly, what is a correct way
        (both ways are working). I want to make a lwip cable ON/OFF bulletproof.
        
        First my HW config is:
        
        - LPC1768 (i do with LPC1769 too)
        - LAN8720
        
        SW:
        - FreeRTOS 7.4
        - LWIP 1.4.1
             - DHCP
             - TCP
        
        I execute a TCP connection to some adress like www.example.com/file.txt 
        -> download that file (this is working at is looking)
        
        My code for init part is like:
        
             setupHardware();
             static struct s_network_config net;
             net.use_dhcp = 1; // set to 1 to enable DHCP. Or set to 0 and fill
        the struct manually
             tcpip_init(network_init, &net);
             InitDelayTimer();
             xTaskCreate(hc_task, ( signed portCHAR * ) "send hc",1536u, NULL,
        TCPIP_THREAD_PRIO, NULL);
             vTaskStartScheduler();
        
        So main lwip thread is in seperate thread, my connection is started in
        hc_task so it's seperated thread.
        
        I have a 2second timer too. From which i am checking my PHY and i am
        want to do a procedure now to handle cable disconetion/connection.
        
        I am guessing the right way:
        
        1. send a "special" message box to main lwip thread  so add a case and
        call a netif_set_link_down(pxNetIfInUse);,
        netif_set_link_up(pxNetIfInUse); 2. or in timer interrupt call
        netif_set_link_down(pxNetIfInUse);,
        netif_set_link_up(pxNetIfInUse);
        
        I want to restart DHCP and KILL TCP connection to start it again.
        
        So what is "more" right:
        
        - call in interrupt
        - or send a message box to mainlwip thread
        
        
        (code is simplified, for cable off i actual call function only once no
        matter this is actually a timer interrupt called in 2 sec intervalls)
        if(cableState == 0)
                 {
                     //link off
                     iface_up = 0;
                     netif_set_link_down(pxNetIfInUse); //method 2
        
                     /*method 1
                     msg.type= 165;
                     msg.msg.inp.netif = pxNetIfInUse;
                     res = sys_mbox_trypost(toOutput, &msg);*/
        
                 }
                 else
                 {
                     //link on
                     netif_set_link_up(pxNetIfInUse); //method 2
        
                     /*Method 1
                     msg.type= 165;
                     msg.msg.inp.netif = pxNetIfInUse;
                     res = sys_mbox_trypost(toOutput, &msg);
                     */
                 }
        
        
        
        Code:
        static void hc_task(void *parameters)
        {
             struct hc_message mes;
             mes.client_port_number = 4839;
             mes.host_addres = "192.168.1.183\0";
             mes.host_add[0] = 192;
             mes.host_add[1] = 168;
             mes.host_add[2] = 1;
             mes.host_add[3] = 183;
             mes.host_file = "test/data.php\0";
             mes.host_port_number = 80;
             mes.target = "http://192.168.1.183/test/data.php\0"; 
<http://192.168.1.183/test/data.php\0> ;
             transferEnd = 0;
             numberOfPacketsProc = 0;
             totalRecievedSize = 0;
             hc_send(&mes, 0);
             vTaskDelete(NULL);
        }
        
        
        The hc_send thread:
        uint_fast8_t hc_send(const struct hc_message *mes, int8_t addParam) {
        
             while(!is_netiface_up())
             {
                 vTaskDelay(500);
             }
        
             if(bufferTmp == NULL)
             {
                 bufferTmp = (char *) pvPortMalloc((PBUF_POOL_BUFSIZE +
        1)*sizeof(*bufferTmp));
             }
        
             if(bigDataBuffer == NULL)
             {
                 bigDataBuffer = (char
        *)pvPortMalloc((256*12)*sizeof(*bigDataBuffer));
             }
        
        
             bufferCounterWriter = 0;
             numberOfPacketsProc = 0;
             totalRecievedSize = 0;
             recieveTimer = 0;
             stateFlag = 0;
             transferEnd = 0;
        
             struct ip_addr remote_ipaddr;
             err_t ret_code = ERR_OK;
        
             pcbHolder = tcp_new();
             if(NULL == pcbHolder)
             {
                 printf("tcp_new(): echec PCBHOLDER IS NULLLL.\n\r");
                 return -1;
             }
        
             tcp_err(pcbHolder, err_hc_tcp);
        
             //for reconnect detection
             if(addParam == 1)
             {
                 //tcp_close(pcbHolder);
                 //pcbHolder = tcp_new();
                 if(NULL == pcbHolder)
                 {
                     printf("tcp_new(): echec. PCB HOLDER RETURN\n\r");
                     return -1;
                 }
             }
        
        
             //int portRead = mes->client_port_number;
             IP4_ADDR(&remote_ipaddr, mes->host_add[0], mes->host_add[1], 
        mes->host_add[2], mes->host_add[3]);
        
              ret_code = tcp_connect(pcbHolder, &remote_ipaddr, 
        mes->host_port_number, client_connected_my);
              if(ERR_OK != ret_code)
              {
                      printf("tcp_connect(): error RETURN -1\n\r");
                      return -1;
              }
        
        
              sprintf(request_my_c, "GET /%s HTTP/1.1\r\nAccept: 
        */*\r\nAccept-Language: sl\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 
        5.01; Windows NT 5.0)\r\nHost: %s:%d\r\nConnection: Close\r\n\r\n", 
        mes->host_file, mes->host_addres, mes->host_port_number);
              printf("%s", request_my_c);//
        
              nsend_my_c = 0;
              totalsend_my_c = 0;
              nbytes_my_c=strlen(request_my_c);
        
             return 0;
        }
        
        
        
        _______________________________________________
        lwip-users mailing list
        [email protected]
        https://lists.nongnu.org/mailman/listinfo/lwip-users
        
        _______________________________________________
        lwip-users mailing list
        [email protected]
        https://lists.nongnu.org/mailman/listinfo/lwip-users
        .
        


_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to