This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS570LC4357: Possible memory corruption using stack LWIP

Part Number: TMS570LC4357
Other Parts Discussed in Thread: LAUNCHXL2-570LC43

Tool/software: Code Composer Studio

Hello,

I'm trying to implement STACK LWIP 1.4.1 on TM570LC4357 (I'm using LAUNCHXL2-570LC43).

I have done an application in order to test the UDP communication. Here there's the code involved:

void sendUDP(void);
    
    #define UDP_PORT 23
    ip_addr_t srcaddrUDP;
    ip_addr_t dstaddrUDP;
   struct udp_pcb *pcb_u;
    int main(void)
    {
    
             IP4_ADDR(&dstaddrUDP,160,2,168,192); // the bytes are flipped for some reason..
             IP4_ADDR(&srcaddrUDP,44,2,168,192); // the bytes are flipped for some reason..
             pcb_u = udp_new();
             errorCode = udp_bind(pcb_u,&srcaddrUDP,UDP_PORT);
             errorCode = udp_connect(pcb_u,&dstaddrUDP,UDP_PORT);
             while(1)
             {
                if(flag500ms)
                {
                  flag500ms = 0;
                  sendUDP();
                }
        
              }
    }
    void sendUDP(void){
    
        //UDP
        err_t error;

int i; u16_t dst_port; struct pbuf * pb; char str[512];
for(i=0;i<512;i++)
str[i] = i;
pb = pbuf_alloc(PBUF_TRANSPORT, 512, PBUF_REF); pb->payload = str; pb->len = pb->tot_len = 512; error = udp_sendto(pcb_u, pb,&dstaddrUDP,UDP_PORT); pbuf_free(pb); }

The issue is that when I send a packet, the transmission itself works but the final bytes of the frame get corrupted. Only the first time the transmission works fine..

I'm testing the application using wireshark to detect the bytes phisically transmitted. I guess the problem is inside udp_sendto because I checked with debugger that the datas contained in str are good.

I'm not using free RTOS but I read on internet that the send functions must be called inside the interrupt of the "lwip timer" in order to prevent unexpected results. However, I didn't understand where to find this interrupt. Could this be the issue?

The frame is transmitted every 500ms under the flag500ms but for semplicity I'm not attaching this code.

Please give me any hint to solve this problem, or if you need other informations, please ask.

Thanks,

Marco.

  • Hi Marco,

    I will look into this and get back to you. Please note that because of the holidays, it may be until Jan 5th that you receive a proper response depending on the depth of the issue. 

    Best Regards,

    Andrei

  • Hi Andrei,

    thanks for the response. I'm aware of holidays and It's not a problem by my side.

    Thanks and have a nice time.

    Marco.

  • Hello Marco,

    I am not an expertise of using UDP. 

    1. Do you need to call lwip_init() before configuring UDP?

    2. If you need interrupt, please call _enable_IRQ() in main()

    3. I think you may need to set a receive callback for the UDP pcb

  • Hi QJ Wang,

    thanks for the reply.

    I already call:

    _enable_IRQ();
    
    lwIPInit(..);


    at the very beginning. Then i call

    pcb_u = udp_new(); // listen to UDP requests
    IP4_ADDR(&srcaddrUDP, 44, 2, 168, 192);
    errorCode = udp_bind(pcb_u, &srcaddrUDP, 23); // bind to port 23
    udp_recv(pcb_u, udpPacketReceivedCallBack, NULL); /* set call back */


    The procedure works fine as I correctly can receive and transmit something. So IRQ and initialization methods work quite well.

    My problem is in the transmitting side. The first frame I'm sending is good and from the second frame seems to me full of junk data.

    Attached the screens of what I mean. BTW I'm sending this data:

    0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 for a total of 10 bytes

    But only the first frame received from wireshark results to me correct. Have you any idea about what's going on?

    Thanks,

    Marco.

  • Ok, so I've made other tests:

    void sendUDP(void)
    {
    	char dataToWrite[512] = {"HELLOOOOOOO"};
    	struct pbuf * pb;
    	err_t error;
    	pb = pbuf_alloc(PBUF_TRANSPORT, strlen(dataToWrite), PBUF_REF);
    	pb->len = pb->tot_len = strlen(dataToWrite);
    	pb->payload = dataToWrite;
    
    	error = udp_sendto(pcb_u, pb, &dstaddrUDP, UDP_PORT);
    
    	pbuf_free(pb);
    
    }
    void sendUDP1(void)
    {
    	char dataToWrite[512] = {"HELLOOOOOOOOOOOOOOOOOO"};
    	struct pbuf * pb;
    	err_t error;
    	pb = pbuf_alloc(PBUF_TRANSPORT, strlen(dataToWrite), PBUF_REF);
    	pb->len = pb->tot_len = strlen(dataToWrite);
    	pb->payload = dataToWrite;
    
    	error = udp_sendto(pcb_u, pb, &dstaddrUDP, UDP_PORT);
    
    	pbuf_free(pb);
    
    }
    

    basically the 2 functions are the same except for the "dataToWrite".

    However, only the sendUDP1(); works as expected. Below a screenshot of sowftware "Packet Sender" that shows me the UDP packets received.

    I'm literally getting crazy. The functions differ only for the amount of bytes transmitted.. any help?

    Thanks,

    Marco.

  • Hi Marco,

    This is just an observation. It looks like the payload located on the "stack" may be the issue. Does not explain why the first send() works ok???

    I did not check lwip source, but if the sendto() call implements a zero-copy method, payload may not have yet transferred into TX memory, only queued, when the call returns!

    You can test this by moving the payload to data or heap.

    Follows an extract from doc/rawAPI.txt

    "--- Zero-copy MACs

    To achieve zero-copy on transmit, the data passed to the raw API must
    remain unchanged until sent. Because the send- (or write-)functions return
    when the packets have been enqueued for sending, data must be kept stable
    after that, too.

    This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions
    must *not* be reused by the application unless their ref-count is 1.

    For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too,
    but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while
    PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change).

    Also, data passed to tcp_write without the copy-flag must not be changed!

    Therefore, be careful which type of PBUF you use and if you copy TCP data
    or not!"

  • Hi Joson,

    thanks for the reply. Actually I'm not understanding too why the first trasmission worked as expected and the others no.

    By the way, I tried to change the third parameter of pbuf_alloc in PBUF_RAM, PBUF_ROM resulting the same behaviour.

    Then I made my dataBuffer a global variable and using these instructions: 

    pb = pbuf_alloc(PBUF_TRANSPORT, strlen(dataToWrite), PBUF_POOL);
    pb->len = pb->tot_len = strlen(dataToWrite);
    pb->payload = dataToWrite;
    
    error = udp_sendto(pcb_u, pb, &dstaddrUDP, UDP_PORT);
    pbuf_free(pb);

    now seems to work as expected, even with a few bytes.

    I'm not an expert on LWIP Stack and really I'm not understanding what's going on, maybe my old local buffer was automatically deallocated by the end of the function causing corrupted data while transmission was ongoing? Why the behaviour was the same regardless of the type of pbuff?

    After the send function I checked pb->ref and was equal to 1 so as stated in rwaApi.txt I believe that data could change without any problems but it's not so.

    Is there a way to use buffer in local function or I have to use the buffer decleared as global? Actually It's not an issue for me but I'd like to understand what's going on.

    Thanks,

    Marco.

  • EDIT: Also with local data (instead of global) declared as static seems to work properly.

  • This indicates an insufficient stack issue. Please increase the size of the stack allocated to the CPU mode when this function is executed.

    All local variables are stored on to the stack by default. Global variables and static local variables are stored in the CPU RAM.

  • Hello Marco,

    Have you solved this issue?

  • Hi QJ Wang,

    sorry for the late reply. For the moment I solved the issue making these variables global or static. I tried increasing stack size as suggested from Project-->Properties but the same thing happens.

    For the moment I leave it as global, than I'll go more in deep :/

    Thanks,

    Marco