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.

Adding Ethernet TCP to a project

I have created a project (actually, a set of them) that uses IPC to send messages between programs running on different cores of the 6678. Now I want to add TCP communications using ethernet to one of the cores. I am using the hua_evmc6678l demo program as a model. I'm having lots of problems.

The code to support the NDK and the ethernet driver is distributed all over the place in the demo program. The config file has lines in it with little explanation and no presence in the GUI that seem to be involved in the NDK/ethernet support, but I'm not really sure. The source code has stuff scattered all over that are also not explained very well. For example, of the items QMSS, CPPI, and Packet Accelerator, I can guess that I need the later, but there is no explanation that I can find for what the first two do and why I might want them.

And then there are the nasty surprises. The files platform_osal.c and resourcemgr.c have functions that are called from the TI libraries! Why are they not part of the library? Can I use them as-is or is there something I need to change for for my application?

Is there a simple cookbook explanation somewhere that can guide someone through adding networking code to a 6678 program to do TCP communication with an outside system? I have looked and haven't found anything.

In my case, the DSP doesn't need http or telnet or any server protocol built into NDK. It needs to make a TCP connection to another processor and exchange messages.

Thanks,
Fred

  • Fred,

     

    Let me see if I can answer your questions. There is a lot here.

     

    In the users guide, also available online you can find a bit about what the osal and resourcemgr,c files are doing:

     

    http://processors.wiki.ti.com/index.php/BIOS_MCSDK_2.0_User_Guide

     

    Essentially the osal files implement the callbacks from the drivers that allow you to map various system calls for memory allocation, spin locking, etc  to your environment.  In the case of our demos we have done a simple mapping to BIOS heap management calls for memory and hardware spin locks. This will likey work for most applications. If that works for you I don’t see that you need to change them but you may need to look at filling out the multi-core access routines. I suggest looking at the multi-core demos as HUA as you have noticed is a fairly simple single core application,

     

    The resource management file is a bit more complicated. They are the high level routines needed to configure and start up the various hardware devices QMSS, CPPI and PA. PA is the packet accelerator which sits between you, the switch and the outside world. You  communicate with that it uses the queueing facilities provided by QMSS/CPPI. For NDK there is a transport driver in the PDK  transport directory that interfaces NDK to the  PA. There is some sharing between the resourcemgr.c file, the definitions in resource.h  to access these facilities. Beyond this driver creating a queue to the PA it also does some of the switch initialization.

     

    I suspect you can start with those two files from a demo and then once you have a good understanding of using QMSS/PA then you can decide if you need to alter them for your application. To learn more about these devices you can access their design documents that came with the software in the PDK_xxx/docs directory.  In particular I would read the NetCPDevelopersGuide first  and then branch out.  I suspect it will take some amount of time to get your head around them so maybe its best to start with your example projects and dig into these in parallel.

     

    Now for what you want to do. I am a little confused. I get the IPC between the cores.  Your first paragraph says you want to have a TCP connection over Ethernet on one core. Sounds like you may wish to talk with that core via IPC from others to send and receive data?  Your last paragraph however says you want to use TCP between cores?  Does this mean you want to run the NDK stack on multiple cores? If you an clarify that would be great as they are different problems to solve.

     

    Assuming you want to run NDK on once core as a source ad sink of TCP data then this should be fairly straightforward. I urge you to study the image processing demo as this is closer to what you want to do and how you will need to set up your multicore app to load and run. That said, you can look at the main for Image Processing or HUA (ignore everything in HUA in the webpages directory). The main is basically configuring the NDK stack and telling it to use DHCP or a static IP. Ignore the telnet stuff its ifddefd anyways and you can ignore starting up the http service if you don’t need it. I would read the ndk docs that come with the NDK stack.

     

    Once you have the stack starting up and are getting an IP address then you can open a tcp socket to send and receive data. Again I would read the NDK documents but you can see an example of a TCP socket in the HUA in the benchmarks/ndkloopback.c file. Look at the tcp_perform_xxxx functions.

     

    Hopefully this gets you started down the right path.

    Jack

     

     

     

     

  • Hi Jack,

    Thanks for the quick reply.

    First, about that last paragraph. I'm sorry if I was unclear about the requirements. A single DSP core connects to an external processor (a PC) via Ethernet. It gets video frames (using TCP) and metadata from the external processor. The frames are processed in a pipeline using IPC to send frames metadata between cores. The final processed data arrives back at the DSP with the external connection where the data is sent back to the external processor. Traditionally we have done the video processing with dedicated hardware, but now the 6678 seems to be just barely fast enough to accomplish most of the processing with software.

    The project goal is to prove the viability of the software-based design. I thought that adding Ethernet I/O to the mix wouldn't be much harder than doing the same thing with VxWorks on an ARM. Unfortunately, this seems to have turned into a lifetime job. You alluded to this problem when you said "I suspect it will take some amount of time to get your head around them..."

    I have looked at the image processing demo. That's how I got as far has I have with IPC.

    From what you said about QMSS, CPPI, and PA, it seems that I really do need them. I hope that one of the documents you referenced has a simple checklist for how to build them into code. I'll be back with more questions if I can't figure out what's going on.

    Here's a suggestion for the people who write the sample and demo code: Add references back to source documents in the comments of the code. Also, it's important note the RTSC configuration items that are needed by the code. The TI documentation is so fractured and difficult to navigate that it's hard to figure out what the code is doing and why it's written that way.

    Fred

  • Fred,

    Thanks for the feedback. I am forwarding it to the development folks. Anything we can do to improve the documents is something we want to look at. In terms of fractured documents, do you mean fractured in there bits and pieces everywhere or fractured in that they are scattered about in directories or both?

    For the PA, yes I recommend using it. Like i said, you can start with the default configuration of it that we have. I believe it will be suitable for what you need to do. As a heads up I do see some things you will need to further tweak. One will likely be the TCP receive buffer size to get better performance. There should already be a CFG call for that in the demos but the demos currently just set the stack default which I think is too low.

    Jack

  • Jack,

    Fractured means both. Clearly they are scattered all over installation directories and also on the TI web site. Also, most of the documents I have tried to use don't tell the whole story, nor do they tell what else you need to figure out the whole story. An example is the networking code I am struggling with right now.

    The documents tend to focus on describing each individual piece but leave out how to put all of the pieces together in a real program. There's sample code for that, but the sample code never refers to the documentation. The documentation, if it refers to the sample code at all, gives a very superficial overview of what it does. One of the biggest pieces that's missing from the puzzle is the way that the RTSC configuration interacts with everything else to make it all work.

    The final straw is that the development environment doesn't give early warnings or errors that things are not right. I have a program that builds, links, and starts to run with no apparent error but then behaves strangely. The calls to CfgAddEntry() seem to be correct and do not return any error or print anything to the log when CFGITEM_OS_DBGPRINTLEVEL is defined. But socket() returns INVALID_SOCKET and then fdError() returns -1, an undocumented value. This is probably due to errors in setting up the PA, QMSS, etc., but I shouldn't have gotten this far without some indication that something is wrong.

    I'll be happy to get to the point where I can work on increasing the performance!

    Fred

  • Jack,

    Well, I got somewhere. I blindly added all of the code from the demo that had to do with the QMSS, CPPI and PA. I also carefully inspected the evm.cfg and added everything that was missing from my cfg. [This was time consuming and quite painful because the configuration entries seem to be randomly ordered.] I don't know if all of it is necessary, but it's all there.

    Even with this I was getting the bogus error return from socket(). But, I noticed that ping worked! So I added a telent server just to see if something else could call socket() without error. Telnet worked!

    So, on the theory that there was something wrong in the socket() call, I looked at the code before the call. Note that I have a Semaphore_post(semNetworkUp); statement in NetworkOpen() so socket() doesn't get called too early. Here's my original code.

        fdOpenSession(TaskSelf());
        Semaphore_pend(semNetworkUp, BIOS_WAIT_FOREVER);
        SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    That looks just fine to me, but it was time to try random perturbations (i.e., a Hail Mary pass) to see what would happen.

        Semaphore_pend(semNetworkUp, BIOS_WAIT_FOREVER);
        fdOpenSession(TaskSelf());

        SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);


    And, that worked! Or, at least socket() returned a socket. Now I need to add the rest of the code for my server.

    It would be nice if there were some kind of error message or return code that would have led me to the solution sooner. Maybe there' s a bug in the fdOpenSession() call. I'll let you work that out with the right people.

    Fred