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.

TSK_Sleep necessary for sending UDP data?

Hello,

I'm trying to do a simple test to have the DSP transmit UDP packets as fast as possible. The transmit task is a P4 and the network process is a P8 (setup as high priority interrupt driven).


The transmit task opens up a socket and inside a loop calls "sendto", followed by a task sleep. I was modifying to the sleep time to adjust the throughput and to allow the network process to run. However, when I remove the task sleep all together, I don't get any data out - though the udps.SndTotal continually increments as in all other cases with task sleep being called. My understanding is that the "sendto" command is a blocking call and therefore will allow the network process to run - as it is higher priority than the transmit task.

Is there something fundamental that I'm missing?

Thanks,
Rajan

  • Can you clarify what is the DSP chip, MCSDK and NDK packages you are running? What test program you modified? hello world or client?

    Regards, Eric

     

  • Hi Eric,

    I'm running the 6670 (EVM) with the following:
    MCSDK 1.1.2.6
    NDK 2.21.2.43

    The code was based on hello world as the example.

  • I think the sendto function works non-blocking, and queues up packets to send. If it was blocking, the throughput would plummet since there’s other threads/processes/code/etc working in the background.

    It sounds like udps.SndTotal is increasing because the NDK acknowledges the send command, but it doesn't send because when NDK calls C6670 hardware layer (via NIMU’s EmacSend), it queues up the hardware buffer too fast and the CPSW gets locked up.

    Regards, Eric

  • Well - I didn't think it would block all the time - only when it had enough data to trigger the NDK to send it out.

    OK - so if the sendto doesn't block, isn't there an NDK clock (i.e. heartbeat) that periodically checks if the NDK has data to process? At that point, shouldn't my lower priority task get blocked to allow the higher priority network task to run?

  • Can you clarify the relationship between sendto task and data processing task? You mentioned there is no data out although udps stats is incremental. Which task is driving the data out?

    The issue is sendto task get called too fast (without any task_sleep in between), so the EMAC/CPSW get locked so there is no data out? Or, the issue is that data processing task (higher priority) didn't get called somehow, so no data is processed and no data out?

    Regards, Eric

     

  • To clarify the tasks:

    NetworkTask (priority of 8) - this task is creating the network (NC_SystemOpen, NC_NetStart, etc).
    TxDataTask (priority of 4) - this task is opening up a UDP socket, and has the sendto and task_sleep calls inside a while(1) loop. In this task I'm also printing out some debug information to the console.

    So far - I've determined the with task_sleep(1) in the code
    - the EMAC Send function gets executed regularly. I put a counter in there and saw it going at about 30000 times a sec
    - I get an output data rate of about 360 Mb/s.
    - CPU load is at about 28% utilization.

    When the don't have the task_sleep(1) in the code
    - the EMAC Send counter gets stuck at 2
    - I get 0 data out.
    - the CPU load returns 0 percent utilized.


    The CPU load returning 0 seems strange as I'm getting the regular printouts from the TxDataTask.

    Is the lack of a task sleep preventing the EMAC Send from executing?

  • That is when NDK calls C6670 hardware layer (via NIMU’s EmacSend), it queues up the hardware buffer too fast and the CPSW gets locked up. You have to insert some time delay between each calls to the EmacSend, you can use bigger packets to improve the throughput.

    Regards, Eric

     

  • I see. If I replace the task_sleep with a dummy for-loop just spinning cycles away, I get the same behavior as if I didn't have the task_sleep. I'm going as slow as 2 sendto calls every second inside the TxDataTask and the EMAC Send counter is still stuck at 2. Replacing the 1 second for loop delay with a task_sleep(1000) generates the same data rate, but the EMAC Send Counter updates regularly.

    It seems to me that there is something more that just too much data involved. The task_sleep is forcing a context switch that I believe should be occurring without the need for a task_sleep.

  • If I make the TxDataTask a priority 1 task, then I don't need a task sleep. The dummy for-loop to control the data rate seems to work just fine and I can pump out data at the same rates as I was when I did have the Task_sleep in there. Raising the priority to anything above 1 results in the same behavior (EMAC_Send not being called and no data output).

    What I don't understand is what is running at the priority 2 level. When I look in the ROV - it's showing the NetworkTask as a priority 8. I know it's supposed to be a priority 2 if it's configured for NC_PRIORITY_LOW, but I have it at NC_PRIORITY_HIGH.

  • >> A few things to check:
    >> 1.  What Tasks are in your system and what are their priorities relative to each other?  A ROV screen shot when >> >> the failure occurs would be nice!

    >> 2.  Make sure the dummy for-loop does not get optimized out.  You can do this by having a function call in the >> >> for-loop or a volatile variable.  Basically, make sure that you are actually spending some cycles spinning.


    I do have code in the for loop so it's not optimized out. I also have a printf statement after each message is sent so I can see the delay loop is taking effect.

    I've attached the ROV screenshots in both the working case (TxDataTask is priority 1) and not working (TxDataTask is priority 2). I can see that the NetworkTask priority has dropped to 1. Does the task normally change priorities on the fly like that?

    Working Case ROV - Tasks snapshot

    Not-Working Case ROV - Tasks Snapshot: