I'm going to start this post with something unrelated to the NDK/NSP, but in my mind needs to be fixed ASAP. Please see: https://e2e.ti.com/support/embedded/tirtos/f/355/t/2612
DSP: C6748
Code Composer: 5.5
SYSBIOS: 6.37.05.35
XDCTools: 3.25.06.96
NDK: 2.24.02.31
NSP: 1.10.02.09
The C6748 NSP provided by TI appears to be a SW port from some other C6x part. It is poorly written, poorly commented, and contains bugs. With that said, it is better than starting from scratch, so we should be thankful we have at least something to use. This discussion is meant to help me understand the NSP, and to hopefully have TI release an updated NSP for the C6748.
Layer 1: NIMU. This is the layer that the NDK talks to, so no matter what device you use, the NDK expects certain functions to be implemented. The files for this layer are: nimu_eth.c and nimu_eth.h.
Problem #1. The NDK main stack thread starts the NDK by calling NC_NetStart( ). This is called from a dowhile loop, so as long as NC_NetStart( ) doesn't return with an error, the NDK will just be restarted. Every time NC_NetStart( ) is called, it calls the initialization function provided in the NIMUDeviceTable[ ] array. For the C6748 NSP that init function is EmacInit( ). EmacInit( ) acquires some memory via two mmAlloc( ) calls. That memory is never freed when EmacStop( ) is called. Therefore every time the NDK is restarted, a little bit of memory is lost (memory leak). After many restarts, eventually the NDK stops working. My suggested fix is to implement the memory required as a static variables. For example: static PDINFO PrivateEMACData and static NETIF_DEVICE C6748EMAC.
Problem #2. Too many places where the Ethernet MAC address is defined. EmacInit( ) has a hard coded MAC address, ethdriver.c has a hard coded static MAC address, and finally HwPktInit( ) calls EMAC_getConfig( ) where you're supposed to load up the real Ethernet MAC. Yikes. How about removing the hard coded Ethernet MAC addresses from EmacInit( ) and ethdriver.c, and pass the a pointer to the PrivateEMACData structure into HwPktInit( ). That way once HwPktInit( ) get the "real" Ethernet MAC address, it just loads that right into the PrivateEMACData structure. Finally copy that MAC address into the NETIF_DEVICE structure before calling NIMURegister( ). The NDK knows the MAC address right from the get go, and doesn't have to be overridden during EmacStart( ). Simple, easy, less confusion.
Problem #3. Undocumented configuration option. EmacStart( ) sets the Emac filter. According to the NDK the options are: NOTHING, DIRECT, BROADCAST, MULTICAST, ALLMULTICAST, ALL. The NSP forces this to ETH_PKTFLT_MULTICAST. Our applications never use multicast, so I've set this to ETH_PKTFLT_BROADCAST. I think this will reduce processing time further down in the NSP layers.
Problem #4. EmacStop( ) calls HwPktShutdown( ) which does nothing and returns. Why is it in the code? Remove the call to HwPktShutdown( ). This is a common problem with the NSP. Code that does nothing, code that is commented out, variables created for no reason, etc.
Problem #5. Emacioctl( ) only supports (2) of the (13) defined options in the NDK. The two that are supported are for multicast, which we don't use. In fact we don't use any of the defined options. I wouldn't care if this function was empty, but some people might. The NDK has code defined to use these options, therefore shouldn't the NSP support them?
Problem #6. EmacSend( ) does a min check verification on the packet length. Why here? It looks like EMAC_sendPacket( ) (located in the low level emac driver file) has the logic to handle packets less than the Ethernet minimum.
Problem #7. The C6748 NSP appears to be really old. I've reviewed the NSP for the C6657 and it is pretty different. The biggest difference appears to be how it handles RAW Ethernet packets. The PDINFO structure includes a PBMQ queue for raw received packets, where the C6748 implementation doesn't have this. Not sure if this means the C6748 can't send / receive raw Ethernet. Finally the C6647 NSP has no code for the function EmacPoll( ), it just returns. For the C6748 NSP EmacPoll( ) samples the MDIO layer to see if the Ethernet link is up or down.
I'll continue the rest of the NSP layers in another post. I've attached my re-write of the NIMU layer at the bottom of this post. Please review.
Thanks, Dean
/cfs-file/__key/communityserver-discussions-components-files/355/6457.Ethernet_5F00_NSP_5F00_nimu.c