Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

Network Developers Kit FAQ

From Texas Instruments Wiki
Jump to: navigation, search

This topic discusses several common questions when trying to debug TI's NDK (Network Developer's Kit) in C64 and C64+ DSP Processors.

Important! With the recent release of NDK 2.0 and its new set of features, this page will be continuously updated. Please stay tuned.


Q: Licensing and availability

Please check this updated page for information on licensing and availability.

Q: How is NDK delivered? Does each board have a specific release? Or is there a common version of NDK for all the boards?

Please check this updated page for information about NDK releases.

Q: Why doesn't my pre-production DM648 EVM work with NDK?

NDK example code works on DM648 production boards with the NDK and drivers provided in the DVSDK.

However pre-production boards have some special requirements:

  • No pre-configured MAC address. Some initial device driver releases did not assign a MAC address properly, preventing the boards from being able to communicate properly. This can be fixed by using DVSDK release and newer, which includes software for MAC configuration. This is configured in file <evmdm648_init.c> at the following line:
 static Uint8 bMacAddr[] = {0x00,0x0e,0x99,0x02,0xaa,0x25};
  • NDK recognizes a valid link but no IP address is assigned by the DHCP server. This can be overcome by using the latest supplied GEL file that allows access to EMAC configuration registers. Note: depending on the PHY, the activity LED blinks even if the NDK is not running.
  • DVSDK release used. Certain boards only work with DVSDK or newer. No matter which release is used, it is imperative that BIOS 5.31.07 should be used, since it fixes the DM648 clock rate.
  • PHY clock frequency setting. Pre-production boards use 125 MHz as the clock frequency for the PHY, but newer DVSDK releases set it to 62.5 MHz used by production boards. This is configured in the EMAC device driver by defining a symbol in the compiler options:

Q: Why does the DHCP client seems to give up after a certain period of time if the Ethernet cable is disconnected when the NDK boots up?

If the Ethernet cable is not connected when the board is booted, the DHCP client service attempts to obtain an address for a certain period of time (around two minutes) and then shuts down. Starting with releases 1.8 and newer, NDK incorporates a DHCP reset function in <client.c> that periodically checks for new servers in case a DHCP is not found right from the start. Basically it creates a task DHCP_reset() in ServiceReport() function that resets the DHCPC service after several minutes if an address is not assigned to the interface.

The output then becomes:

TCP/IP Stack Example Client
Using MAC Address: 00-0e-99-02-70-04
Service Status: DHCPC    : Enabled  :          : 000
Service Status: Telnet   : Enabled  :          : 000
Service Status: HTTP     : Enabled  :          : 000
Service Status: DHCPC    : Enabled  : Running  : 000
Link Status: 10Mb/s Half Duplex on PHY 1
Service Status: DHCPC    : Enabled  : Fault    : 002
Service Status: DHCPC    : Disabled :          : 000
Service Status: DHCPC    : Enabled  :          : 000
Service Status: DHCPC    : Enabled  : Running  : 000

The updated <client.c> is available in the example code supplied with the Network Support Packages. Together with NDK evaluation releases, they can be downloaded from the NDK Update Advisor. Updating the NDK is not mandatory, since <client.c> file can be used by release 1.7.

Q: Why can't I debug the EMAC and PHY device drivers in the NDK example projects?

This is because the hardware initialization routines are inside the HAL libraries. For example, the DM6437 EMAC device driver is the library <hal_eth_dm64lc.lib>. Only assembly step-by-step debugging is allowed (more on this below).

However, all NDK examples have callback routines from the device driver that help verify if it is working properly. In the case of DM6437, the file <evmdm6437init.c> contains two callback functions:

  • DM64LCEMAC_getConfig() reports the MAC address was properly assigned to the EMAC and allows you to configure what interrupt source will be used by the EMAC peripheral: variable *pIntVector;
  • DM64LCEMAC_linkStatus() is used to report that a valid link was detected and at what speed.

If device driver source code debugging is really needed, this is possible by including the HAL and low-level source files into the CCS project (typically installed under %NDK_INSTALL_DIR%/packages/ti/ndk/src/hal/<name_of_the_board>). The build process will overload the device driver function calls when using the libraries. For additional details about the files that comprise the device driver source code please check this page.

Q: What happens during NDK startup? What is the sequence of events?

Taking as an example the NDK for the DM6437, the sequence of events at startup is below:

  • BIOS starts;
  • dm6437_init() in file <evmdm6437init.c> is called by BIOS initialization code (configured in the TCF file under System -> General Settings);
  • main() is called;
  • BIOS finishes initialization and starts running;
  • StackTest() is called (it is a static TSK configured in the TCF file); a message is printed in the stdout:
TCP/IP Stack Example Client
  • Function NC_NetStart() is called by StackTest() and initializes the stack (both device drivers, NDK scheduler and TCP/IP);
  • DM64LCEMAC_getConfig() is called; a message is printed in the stdout:
Using MAC Address: 00-01-02-03-04-05 (or whatever number is configured)
  • ServiceReport() in <client.c> is called as many times as the services configured in the StackTest() function; messages are printed in the stdout following the basic format:
Service Status: DHCPC	: Enabled	:		: 000
Service Status: Telnet	: Enabled	:		: 000
Service Status: HTTP	: Enabled	:		: 000
(and so on)
  • NetworkOpen() is called and initializes dynamically all the tasks and daemons needed by your application; by default in client project you will see five daemons configured;
  • ServiceReport() is called once again (if DHCP is enabled) to report that this service is properly running; a message is printed in the stdout:
Service Status: DHCPC	: Enabled	: Running	: 000 
  • DM64LCEMAC_linkStatus() is then called by the device driver after a proper link is detected by the PHY; a message is displayed in the stdout:
Link Status: 100Mb/s Full Duplex on PHY 1  (or whatever speed and PHY you are using)
  • NetworkIPAddr is then called when and IP address is assigned by the DHCP server (or is statically configured in <client.c>); a message is printed in the stdout:
Network Added: If-1: (or whatever interface and IP address are configured)
  • The network stack then starts running.

For additional details please see section 3.3 of the NDK User's Guide (spru523).

Q: Why does the Kernel Object Viewer show a "daemon Stack Full" warning? (fixed in NDK 1.92)

The Kernel Object Viewer performs this verification by checking if the pattern 0xBEBEBEBE exists at the end of each task stack. However, since the memory used by the daemon task is not initialized to this value when the program loads, the KOV reports that the stack is full.

If you want to test if this is happening in your system, before loading your software you can fill the DSP memory: go to menu Edit -> Memory -> Fill. Be careful not to fill the entire memory space, since the process may take a while to complete.

A more efficient workaround is to use the linker command file to fill this memory for you by adding the command fill = 0xBEBEBEBE after the .SDRAM$heap section. First, locate this section in the linker command file generated automatically by the DSP/BIOS; copy its declaration to the <client.cmd> file; add the command fill = 0xBEBEBEBE after its definition; finally, wrap this declaration with the SECTIONS {} command (see below an example extracted from the client project):

        .SDRAM$heap: {
        SDRAM$B = .;
        _SDRAM_base = .;
        SDRAM$L = 0x20000;
        _SDRAM_length = 0x20000;
        . += 0x20000;
        } > SDRAM  fill = 0xBEBEBEBE

You will get some linker warnings about redefining sections, but you can disregard them for this test. Please keep in mind that this is a workaround to make the instrumentation tools work properly with the NDK 1.8.

Q: Does NDK support Jumbo Packets?

New for NDK 2.0!!! Support for Jumbo packets is now available - the only development board that currently supports it the mezzanine card of the C6455 EVM.

Please check the NDK 2.0 Release Notes for additional information on how to enable support.

Legacy releases do not support Jumbo Packets.

Q: C6455 EVM has a Gigabit EMAC. Does the hardware support Jumbo Packets?

The EMAC peripheral in C6455 Mezzanine card supports packets up to 65536 bytes (16-bit). This board has a Broadcom BCM5464 external PHY connected in RGMII mode.

The EMAC on this device has an internal memory buffer that can hold up to 8 kB, but L2 memory can also be used. Please see section 2.2 of the EMAC peripheral User's Guide for C6455 (spru975).

Apart from this, the SW Operation of Gigabit Ethernet Media Access Controller on TMS320C645x DSP (spraa90) describes in detail the support of jumbo packets on the C6455. It has an entire description of the system and sections 6.3 and 6.4 contain considerations about the available buffer sizes and even PHY limitations.

Q: Does DM648 EVM support Gigabit Ethernet? What about Jumbo Packets?

Yes, the DM648 EVM has a PHY device that supports Gigabit Ethernet speeds, and the NDK device driver provides support for Gigabit Ethernet links.

However, the hardware does not support Jumbo Frames (typically around 9000 bytes but can assume any value), since the DM648 EMAC peripheral has a limitation to receive frames up to 2047 bytes (headers included). This is still above the standard value of 1518 bytes.

Even so, all NDK releases can transmit regular sized packets faster than 100 Mbps.

For additional information please refer to the 3 Port Switch Ethernet Subsystem User's Guide (spruf57).

Q: What are the numbers shown in the Service report messages for the DHCP?

The DHCP Client returns a status message at startup. Typically the code 017 is printed at the end of a successful address assignment to NDK. A typical startup sequence is:

 TCP/IP Stack Example Client
 Using MAC Address: 08-00-28-34-10-67
 Service Status: DHCPC    : Enabled  :          : 000
 Service Status: Telnet   : Enabled  :          : 000
 Service Status: HTTP     : Enabled  :          : 000
 Service Status: DHCPC    : Enabled  : Running  : 000
 Link Status: 100Mb/s Full Duplex on PHY 1
 Network Added: If-1:
 Service Status: DHCPC    : Enabled  : Running  : 017

From time to time it is common that code 019 is displayed, after the IP lease time defined by the DHCP server expires and is automatically renewed. NDK then prints the following message at the stdout window:

 Service Status: DHCPC    : Enabled  : Running  : 019

These running codes are defined in the header file <dhcpif.h>:

 // Running Codes (State codes are all less than 0x10)
 #define DHCPCODE_IPADD          0x11    // Client has added an address
 #define DHCPCODE_IPREMOVE       0x12    // IP address removed and CFG erased
 #define DHCPCODE_IPRENEW        0x13    // IP renewed, DHCP config space reset

Sometimes errors occur and NDK prints out the following message:

 TCP/IP Stack Example Client
 Using MAC Address: 00-0e-99-02-71-57
 Service Status: DHCPC    : Enabled  :          : 000
 Service Status: Telnet   : Enabled  :          : 000
 Service Status: HTTP     : Enabled  :          : 000
 Service Status: DHCPC    : Enabled  : Running  : 000
 Link Status: 10Mb/s Half Duplex on PHY 1
 Service Status: DHCPC    : Enabled  : Fault    : 002
 Service Status: DHCPC    : Disabled :          : 000
 Service Status: DHCPC    : Enabled  :          : 000
 Service Status: DHCPC    : Enabled  : Running  : 000

In the case above, the DHCP server is off line and does not acknowledge the IP request.

Please see below the error codes defined for the DHCP client defined in <dhcp.h>:

 // Errors
 enum DhcpErrors

Q: Why does the http server responds with the message "HTTP Error 400 - Bad request" when I try to access it using Internet Explorer? (fixed in release 1.93)

This issue happens if you performed a recent upgrade to Windows Vista, or recently updated your Windows XP with Microsoft .NET 3.0 or with Internet Explorer 7.0.

This issue started to happen because the .NET Frameworks 3.0 added several types of documents that the Internet Explorer browser can accept in a connection. More technically, when the browser sends an http GET command to receive a web page and its contents (like pictures, scripts, etc) it contains some fields that exceed the length of 256 chars. These fields are of type Accept: and are specified in the following registry key: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Accepted Documents] If you look at this registry entry you will see several document types like application/msword, image/jpeg and others. .NET Frameworks 3.0 added other document types like application/xaml+xml that exceed the limit of the embedded web server in the NDK, causing the malfunction. The short-term workaround in this case is to reduce the number of documents in an Accept: line by deleting the new types, the definitive fix is already included in NDK 1.93 Depending on the version, there are patches for previous releases.

Q: I checked the troubleshooting section in the User's Guide but NDK still cannot communicate properly. Is this a priority issue between my application and the NDK?

Could be. Anytime anything is done with the NDK in an infinite (or extended) loop in an application, care is needed. The NDK is designed to operate in one of two different scheduling modes, and with two different corresponding event notification modes. The least intrusive of these is to run the network scheduler (the thread that runs the stack) at the lowest priority, and to poll for network events. As shipped, the NDK runs the scheduler at a low priority, and uses interrupts for events. However, the interrupts only set flags so that the scheduler thread knows there is work to do -- the TCP/IP stack itself will not preempt a higher priority task.

Just to illustrate, if you write an application that just spins on sendto() in a loop, and the scheduler is at a lower priority than the application, then the scheduler never runs. This can cause the stack to eventually fail, simply because work gets backlogged to the point where it starts running out of resources.

In summary, the priority of your application tasks and NDK will influence communications and (maybe) break the stack.

To check if the system is running out of resources due to the application priority, you can experiment the following workaround:

There is a call near the top of the stack initialization function that looks as follows:


Try changing it to


This way you should have communications partially or fully restored in your system.


If your application breaks due to NDK scheduler preemptions, you should then start optimizing your application to meet the real-time goals. In other words, the system must guarantee a precise execution of NDK’s heartbeat. Despite the fact that PRDs operate at some of the highest priority levels in a BIOS system, their operation may be clogged by other PRDs, SWIs or even Hardware Interrupts. Also, they can be starved by asynchronous execution conflicts. This problem comes from the fact that CPU usage is actually an average amount per a given time span, but each thread uses 100% of CPU while running leaving no room for other activities. To illustrate, the picture shows a system with two threads running: one video thread that runs for 10ms every 30ms and the NDK PRD thread that runs every 100ms for, say, 20ms. The two threads will clash at roughly every 300ms. The NDK stack will not necessarily crash, but delays should definitely be expected. This can be solved by reducing the priority of the video processing task - obviously paying attention to other side effects that this may cause.

Q: Does NDK support zero-copy transfers?

Zero-copy receive transfers are supported in NDK through the functions recvnc() and recvncfrom(). However, this mechanism is not yet implemented in NDK for sending packets (but it is in the product's roadmap).

For additional information, please check section 3.3.2 of NDK Programmer's Guide (SPRU524).

Q: Does the NDK only support Ethernet connections? What about the serial port of my DM642 EVM?

The NDK supports the DM642 serial port through the examples provided by its NSP. Please check the directory %NDK_INSTALL_DIR%\packages\ti\ndk\example\serial that contains a Serial Client Project and a Router Project. The Serial Client Project is very similar to the Ethernet version of Client Project. The Router Project is a bridge that links between the Ethernet and the serial ports of the DM642 EVM.

The serial device driver source code is provided in the NSP and is configured by default to 115200 8N1 with no handshake. In order to make it work with hardware handshake, please see question 18 below.

These settings are enabled in line the function void sctrl(void) of the file <sctrl.c>:

 // Setup the serial port driver
 llSerialConfig( 1, 115200,

Please see additional details in sections 2.4 and 2.5 of the NDK User's Guide (spru523).

Q: I want to sniff the network traffic using RAW packets just like Ethereal or Wireshark. Is this possible?

No. However, the RAW packet interface changed.

Updated for NDK 2.00! For NDK 2.00 there is a new API as part of the Raw Ethernet Module that communicates directly to the Ethernet driver, skipping the TCP and IP protocol layers. Please see section A.17 of the NDK Programmer's Guide spru524. However its functionality is very similar to the previous RAW interface.

After NC_Netstart() is called at the end of StackTest(), the core TCP stack starts to run and only relevant network traffic is sent to the upper layers. Therefore receiving packets like ARP and others are processed internally by the stack. For additional details check Stevens, W. Richard; Fenner, B; Rudoff, A. UNIX Network Programming vol 1. 3rd ed. page 739

RAW sockets can still send and receive ICMP packets, though. For an example on how to do it please check the file <conping.c> that is part of the client example project. Its location is usually at:


The main reason this was done is due to the memory and processing constraints of an embedded system. Whenever you capture raw traffic using a network sniffer, the incoming data quickly mounts to several MB. A typical load (30%) on a 100Mbps network can yield 1MB of data in just a few seconds!

Q: Does the NDK have a hard limitation on the number of sockets?

No, the NDK does not have a hard limit on the number of sockets. However, memory is the main constraint when designing an application. To allow deterministic behavior, sockets allocate and deallocate fixed-size buffers dynamically from the packet buffer manager (PBM). The PBM has a limited size that depends on the number of buffers configured in the file <pbm.c>. That, in turn depends on the amount of heap memory available.

Therefore, if the application has a fairly large amount of sockets open and communicating at a given time, any attempts to communicate may return the error code 55 (ENOBUFS or No buffer space available).

The solution is to increase the buffer manager.

For additional details on how to do this please see section 5.3 of NDK User's Guide (spru523). You will have to rebuild <os.lib> using the <makelib.bat> script provided with NDK.

Lastly, the error above may also appear due to scheduler starvation caused by real-time constraints. Please see question 13 above.

Q: I want to use the serial port on my DM642 EVM but the hardware handshake does not seem to work. Is this a driver issue?

Yes. The serial and router examples included in the NSP for DM642 EVM provide support for hardware handshake in the serial port. By default this feature is disabled, but it can be controlled via the flags HAL_SERIAL_FLOWCTRL_NONE and HAL_SERIAL_FLOWCTRL_HARDWARE used by the function sctrl() of the source file <sctrl.c>.

However, when using the HAL_SERIAL_FLOWCTRL_HARDWARE flag, the board fails to communicate with the host PC via serial port.

The programming sequence Set Xoff1, Xon1 to VALUE1, VALUE2 at page 32 of the TL16C752B USART datasheet shows exactly how the sequence should be performed.

A footnote at page 23 of the same datasheet mentions that, in order to write to the configuration bits of the automatic hardware handshake (Xon/Xoff), the register LCR must be set to 0xBF.

This was overlooked by the current implementation of the device driver source file <ti752.c> located in the folder %NDK_INSTALL_PATH%\packages\ti\ndk\src\hal\evmdm642\ser_ti752\.

Therefore the changes should be:

static void spInitialize( SDINFO *pi )
    uint        baudsetting;
    uint        temp;                  // added to enable hardware handshake functionality
    if( pi->FlowCtrl == HAL_SERIAL_FLOWCTRL_HARDWARE )
	temp = SREG(pi,UART_LCR);      // added to enable hardware handshake functionality
	SREG(pi, UART_LCR) = 0xBF;     // added to enable hardware handshake functionality
        SREG(pi,UART_EFR) = TL16C752_EFR_ENHANCE |
                            TL16C752_EFR_RTSFLOW |
        SREG(pi,UART_LCR) = temp;     // added to enable hardware handshake functionality
        SREG(pi,UART_MCR) = TL16C752_MCR_IRQEN   |

Once modified, the device driver can be rebuilt using the script <makehal_evmdm642.bat> provided in the NDK installation.

Q: Is C672x family of devices supported?

For a list of all devices and boards supported by NDK please see question 5 of the NDK licensing page.

But the C672x was never supported by any NDK release; therefore, any attempts to do the porting are totally up to you. Please read on for some useful advice:

  • The latest NDK release that supports the C67x family of devices is 1.8, therefore this is a good release to be used as a baseline.
  • This NDK release was built and tested with DSP/BIOS 5.20.01 and CGT 5.1.0. Since CGT 5.1.x releases do not support C672x, you must use CGT 5.3.0 instead. No testing was performed with CGT 6.x releases;
  • Similarly, the device drivers used by this NDK release were built and tested with CSL release 2, but C672x devices use CSL release 3. The differences are not that significant, but again no testing was performed using this release of CSL.
  • These device drivers were designed to support specific external MAC/PHY devices connected to the McBSP of C6711 and C6713 DSPs, therefore the porting to C672x will require changes to their source code.
  • At last, NDK 1.8 was NOT designed to be used with the BIOS in ROM that C672x devices have. It causes linking problems due to long calls between the core stack and the inner BIOS calls.

Again, please keep in mind these are only suggestions to start the porting.

Q: Does the NDK store network statistics that I could use?

Yes, the NDK stores a full set of statistics that can be helpful to debug network traffic and other conditions.

The telnet console command test shows several statistics for IP, TCP, UDP, ICMP and NAT by accessing specific global variables contained in the NDK core stack. Therefore these variables can also be used in other parts of your code, and usage examples can be found in the file <constat.c> typically located at the directory: C:\CCStudio_v3.3\ndk_1_92\packages\ti\ndk\example\tools\common\console

If needed, statistics for IGMP can also be obtained by using the following internal global variables:

_IGMPOutResponse - any IGMP join/leave/renew (timeout) packets sent to the router

_IGMPInResponse - any membership reports (0x12 or 0x16) sent from NDK

_IGMPInQuery - any valid query (type 0x11) sent to all hosts (

_IGMPInQueryGroup - any valid query (type 0x11) sent to the group

_IGMPInDiscard - discarded IGMP packets due to errors

To use these variables you must declared in your source file as:

extern UINT32 _IGMPOutResponse, _IGMPInResponse, _IGMPInQuery, _IGMPInQueryGroup, _IGMPInDiscard;

Note: The internal variables above are valid up to NDK 1.94 but you should be aware they may change without notice.

Q: I copied the device drivers supplied in my DM648 EVM board to NDK 1.93 or 1.94. Why am I getting build errors?

If the errors you are seeing are similar to:

"C:/CCStudio_v3.3/ndk_1_93/packages/ti/ndk/src/hal/evmdm648/ethss_dm648/cpsw3g_ioctl.h", line 250: error:
declaration is incompatible with "uint llPacketIoctl(uint, uint, void *)" (declared at line 52 of

1 error detected in the compilation of "conSwitchCtl.c".

>> Compilation failure

NDK releases 1.93 and newer contain a definition for the function llPacketIoctl() located at line 52 of the include file <hal.h> (see below). However, the example NDK device driver supplied with the DM648 DVDP contains a preliminary definition of the same function at line 250 of the include file <cpsw3g_ioctl.h>, therefore the conflict.

At <hal.h>:

_extern uint   llPacketIoctl( uint dev, uint cmd, void *arg);

At <cpsw3g_ioctl.h>:

extern void llPacketIoctl(Uint32 dev, Uint32 cmd, void *param);

To fix this you can comment out the second definition above without any loss of functionality.

Q: I migrated from a previous version of NDK to 1.94. Why I am getting a relocation error when I try to use the multicast APIs?

If the errors you are seeing are similar to:

[Linking...] "C:\CCStudio_v3.3\C6000\cgt6018\bin\cl6x" -@"Custom.lkf"

undefined                        first referenced
 symbol                              in file
---------                        ----------------
_IGMPJoinHostGroup               C:\\CCStudio_v3.3\\ndk_1_94\\packages\\ti\\ndk\\example\\network\\multicast\\host\\dsk6455\\debug\\host-multicast.obj
>>   error: relocation overflow occurred at address 0x00000050 in
>> section
            '.text' of input file
            'C:\\CCStudio_v3.3\\ndk_1_94\\packages\\ti\\ndk\\example\\network\\multicast\\host\\dsk6455\\debug\\host-multicast.obj'.  The 32-bit PC-relative displacement -2203960 at this location is too large to fit into the 21-bit PC-Relative field; the destination address is too far away from the instruction. You may need to add a mask to the assembly instruction or use other target specific assembly features if you really only need the lowest 21 bits of this symbol. Please see the section on Relocation in the Assembly User's Guide.

>>   error: symbol referencing errors -
            'C:/CCStudio_v3.3/ndk_1_94/packages/ti/ndk/example/network/multicast/host/dsk6455/bin/host-multicast.out' not built

>> Compilation failure

Build Complete,
  3 Errors, 0 Warnings, 0 Remarks.

As stated in section 3.5 (page 68) the NDK 1.94 Programmer's Guide (SPRU524E), the APIs IGMPJoinHostGroup() and IGMPLeaveHostGroup() are deprecated. The reason is that these APIs did not properly follow the BSD recommendations for joining multicast groups, therefore being replaced by the socket options IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.

Please see the usage example below:

char *MulticastAddr = "";   // Multicast group address
struct ip_mreq	mc_group;            // Socket configuration structure for the multicast group membership
SOCKET   recv = INVALID_SOCKET;      // Receiver socket
mc_group.imr_multiaddr.s_addr = inet_addr(MulticastAddr);
mc_group.imr_interface.s_addr = NA.IPAddr;
setsockopt (recv, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mc_group, sizeof(mc_group));

Note: you only need to join the multicast group on the receiving sockets.

The APIs could not be maintained in NDK 1.94 since they replicated the incoming multicast packets to all sockets in the system, clogging bandwidth.

Q: How to properly use the SMA connectors on my DM648EVM board?

If you intend to use the SMA connectors without a PHY then you must perform the two modifications below:

  • In the file <evmdm648init.c> lines 102-103, enable the SMA connectors by setting the two variables below to true:
use_SMA_on_port0 = TRUE;
use_SMA_on_port1 = TRUE;
This is the same as setting the parameter CPSW3G_INITPARAM_SPEED0 to 9999u in the device driver include file <cspw3g_init_cfg.h> line 160.
  • In the device driver source file <cpsw3g_core.c> line 500, prevent the flag pi->TxOn to be reset by commenting out its line:
pi->TxOn = 0;


  1. This last modification requires a rebuild of the device driver using the script <makehal_evmdm648.bat> provided in the NDK installation.
  2. NDK 2.0 does not support the use of the SMA connectors on the DM648 EVM.

Q: The NDK User's Guide (SPRU523) talks about example projects inside the example directory, but I can only find C source files. Are there any ready-to-run examples supplied with NDK?

The example directory supplied with NDK core stack contains only the source files common to all boards and platforms. The directory looks similar to:

Example directory of NDK only

The complete examples tailored for each board (including a CCS pjt and the BIOS configuration file) are supplied with the NSP or PSP. Once installed, the example directory then becomes:

Example directory of NSP for DSK6455

Note: Additional details are mentioned in question 5 of the NDK Licensing and Availability page at this wiki.

Q: I just started development using the NDK. Is there a document to help me?

The NDK Starter Guide (spraax4) and its companion labs covers the basics of NDK and includes a step-by-step tutorial on how to develop an application using NDK.

Q: I downloaded the NDK 1.94 NSP but there are missing libraries and build errors right from the start!

If you are opening any of the example projects and sees a message box that mentions missing either <hal_eth_c6455.lib> or <hal_eth_dm642.lib> libraries, you must convert the project to use NIMU device driver architecture. Additional information on how to do this is provided in the device driver's documentation: please see section 1.2 of the NSP User's Guide for your platform: C6455 or DM642.

See below if you want to keep using the legacy llPacket device driver architecture.

Q: The NDK I am using is release 1.92 and was included in the CD that came with my board. What do I need to update it to NDK 1.94?

This applies to the SDKs supplied with the development boards for DM6437, DM648, C6424 and C6452. The device drivers for NDK 1.92 provided in the SDK or DVSDK are compatible with NDK 1.94 and use the legacy llPacket device driver architecture. Therefore you can simply copy the HAL libraries from the previous version (typically located at %NDK_INSTALL_DIR%\packages\ti\ndk\lib\hal\) or download the PSP package.

Please check question 6 of the NDK Licensing and Availability page for additional details on how to download and install the device drivers included in the PSP package.

Q: How do I improve the security of my network application?

Some of the default settings of the NDK stack do allow for easy detection of the system on the network, for example using ping commands. This is often used in TI EVM applications to detect the presence of an EVM from the host application. However in real applications it might not be desirable to have the network stack answer such messages. It may also protect the stack from security attacks using a flood of messages as it can be configured to ignore messages and not respond at all. That causes less stack process loading too.

configuration struct element configuration macro

See sections 4.4.10 and A 12.2 of the NDK 1.94 Programmer's Guide for more details.

Q: How can I reduce the amount of memory used by the NDK?

See TI-RTOS Networking Stack Memory Usage.

Q: I wonder if I could extract some additional performance from NDK. Are there any tips to make sure my system is performing at top notch?

Despite the difficulty in answering this general question, performance improvements can frequently be obtained by doing simple things in the general configuration:

  • Enable L2 cache and configure the MAR bits to map it to external memory regions. Please check this page for additional details
  • Place the memory sections for buffers in fast memory. For example, the file <client.cmd> contains the following information:
// Specify below whether you want these NDK special memory sections to be
// placed in a specific memory section. By default they are placed in the .far space.
//   .far:NDK_PACKETMEM - Packet buffer memory (defined in HAL/OS libs)
//   .far:NDK_MMBUFFER   - Scatchpad memory used by mmAlloc()
//   .far:NDK_OBJMEM       - Large arrays (defined by example code only)

You can create a memory section for any of them and point to a specific memory region:

	.far:NDK_OBJMEM		{}	> IRAM

For details on size requirements please see section 3.1.3 of NDK User's Guide.

Q: I am using the big endian libraries of NDK 1.94 and I am having trouble in communicating with the network. This does not seem to happen with the little endian versions.

Yes, this is a known issue of NDK 1.94. Please download NDK 1.94.01 from the Update Advisor page.

Q: I would like to know benchmark results for my boards; where can I find them?

Please check the NDK benchmarks page.

Pay special attention to the note in red at that page.

Q: Can a processor handle multiple PHY ?

Generally it is possible to have several PHYs connected to the EMAC peripheral.

Still, you need to check that: a) the specific sw TCP/IP stack supports it b) the specific processor EMAC peripheral does not mention differently

For connecting multiple phys it is possible to leverage the usage of the MDIO interface; the MDIO module is used for initialization, management and query of the phy status, thus provides also a better way to configure the phy(s) instead of having them configured (statically) in hardware. So for this to work you will need to have an MDIO interface connected to both (all) phys from the processor side. Also make sure that the MDIO IDs are different for each phy.

On the hardware side, all the signals for the N phys will have to be connected together.

If a PHY is not active it should be in tri-state on the output and disregard input. This should be something enforced by the specification (i.e. to disconnect the the data signals once the phy is not active), but it should be also verified in the PHY datasheet

On the software side, the TI NDK stack should check to see which one is the active one, turning the other phy off; this will ensure that there will be an isolation of the signals of that phy to the MAC. If instead you do not plan to use the TI stack then you will need to do this function implementation by yourself.

Additional notes:

1. The EMAC peripheral contains the MAC address (which of course is not the same as the IP address), but this as for the specifications is not dependent on which phy you use at the moment. So, provided you have one active phy (alive, linked, and configured properly), any packets intended for that EMAC will reach it.

2. Up to 32 PHYs can be connected to the MII bus, and have cables plugged in. The driver can then choose to use one at a certain time, and "turn off" the other ones, which means to isolate them from the MII bus (by using MDIO to configure the PHY registers).

3. However please note that only one PHY can be active at a given time. Also, only two PHYs can be monitored at the same time by the EMAC layer (because of NDK SW implementation).

For more details about the features of the peripheral and the implementation, please refer to the specific processor EMAC reference guide, and to the device datasheets for more details of supported features on a specific device.

Q: Is there any information that can help if I want to port NDK to my custom hardware that uses a different PHY?

Yes. The page below contains several guidelines and "things to look for" when modifying the NDK device drivers to support PHYs not currently supported out-of-the-box.


Q: How do I test the serial example (PPP over uart) on the DM642 evm ?

This was tested on NDK 1.94 but applies also to NDK 2.x

Since the user guide is not very thorough in describing the host / target setup, below are some more detailed instructions:

Gather a null modem uart cable and connect the evm to the Pc. In the default factory settings, no additional hw configuration should be needed on the DM642 board

1 - Network settings on the PC side: On the Pc, go in windows, and choose start > network > network connections

select the wizard 'create new connection'

then select: setup an advanced connection > accept incoming connections

check the box communication between two computers using com1

- choose the properties and select

  • general: port speed 115200 / flow control none
  • advanced: 8 bits / none parity / 1 stop bit

do not allow virtual private connections

- in the 'user' tab create a new user called 'username' and with password 'password' (without the quotes)

note: if your pc settings are more restrictive for security reasons, and do not allow to use 'password' as password you can also go into srctl.c at line 172 and manually change the password to a more complicated one

as networking software protocol, make sure tcp /ip is checked

- in the tcp /ip properties, you can use dhcp or for simplicity also assign tcp ip addresses (you can also specify a range)

make sure to have at least two addresses if you specify the Ip address ranges manually so that the server (pc) also can get one

A screenshot of the Windows/Network connections settings described above can be found in this file File:PC-side-config for ppp over uart NDK client example.pdf.

2 - On the CCS side: open the example\serial\client\dm642\client.pjt application, rebuild, load and run it

(if it complains about missing hal_eth_dm642.lib see


you can get it from NDK 1.92 NSP package and copy it inside ndk\lib\hal\evmdm642. On NDK 2.x the NSP is already included)

when you run the client application, you should see something like this in the CCS output

TCP/IP Stack Example HDLC Serial Client
Service Status: Telnet   : Enabled  :          : 000
EchoSrv Initialized
DataSrv Initialized
NullSrv Initialized
OobSrv Initialized
SCtrl: Ready, Ports=2
SCtrl: Disconnected (129)

after some time, it should print also

Network Added: If-1:
SCtrl: Connected

3 - Communication status on the PC side: on the windows side, in the network connections you should see that the "incoming connections" network adapter says "1 client connected" (the evm)

at the same time you should see a new entry called "username" type " incoming" status connected type "communications cable between two computers"

note: in the example above the pc (server) was configured to be assigning IP via DHCP addresses which include

4 - Using Hyper-terminal: at this point you can start the windows remote terminal: start > programs > accessories > communication > hyper terminal


  • a connection name (as desired, like DM642 evm)
  • the type should be using tcp/ip (winsock)
  • the host address is the one printed on the ccs terminal window after the evm has connected to the pc, see above (in this example,
  • the port is default 23 for telnet

the DM642 evm answers with:

TCP/IP Stack Example HDLC Serial Client
Welcome connection :
Welcome to the console program.
Enter '?' or 'help' for a list of commands.

(In this case the pc took the address

now you should see the NDK console output redirected to the windows terminal, be able to send commands to it, and receive the output of the commands.

at this point (one a connection is established and the DM642 has an ip address) you can also use the windows test applications in ndk_1_94\packages\ti\ndk\winapps, like calling


Q: On the C647x evm the NDK was working properly. Now on my own board, I can't get it to work, even though the hardware is the same. What should I do?

See section about the EMAC layer at Guidelines_when_porting_NDK_to_different_PHYs

Q: It seems that the NSP for OMAPL137 EVM is incompatible with the EDMA3 LLD. How can I fix it?

The Ethernet driver of the NDK Support Package (NSP) 2.0 for EVM6747 / EVMOMAPL-137 uses the BIOS Interrupt vectors 6, and 7 to setup EMAC Rx, and Tx interrupts. The EDMA3 LLD released for this EVM also happens to use the interrupt vector 7 for its interrupt. If using both NDK 2.0 NSP and EDMA3 LLD in your application please ensure that the interrupt vector numbers used in these two drivers do not overlap each other. Otherwise this could lead to unexpected results.

The interrupt assignment in EMAC driver can be quickly changed by modifying the intVectId parameters in Interrupt_init() function of the driver. Also, the definitions for Disable_DSP_Interrupts() and Enable_DSP_Interrupts() used to enable/disable the EMAC CPU interrupts globally need to be modified to reflect the changed interrupt vector ids.

For example, to modify the Ethernet driver in NDK to use, say, interrupt vector 5 for EMAC Rx interrrupt and interrupt vector 6 for EMAC Tx interrupt, the following changes would be needed:

Step 1: Modify the Ethernet driver’s Interrupt setup code to use the new interrupt vector ids as below:

void Interrupt_init(void)
    IntSetup    hwi_intSetup;
    Uint32      retVal;
    /* Setup the Rx Int using NDK's Interrupt Manager */
    hwi_intSetup.intVectId = 5;    // ==> Inserted the new Rx Interrupt vector id 5 here
    hwi_intSetup.sysEvtCount = 1;
    hwi_intSetup.sysEvtId[0] = 31;
    hwi_intSetup.pCallbackFxn = &HwRxInt;
    hwi_intSetup.pCallbackArg = 0;
    hwi_intSetup.bEnable = 1;
    retVal = Interrupt_add(&hwi_intSetup);
    if(retVal != 0)
        printf("Error setting up Rx Interrupts \n");
    /* Setup the Tx Int using NDK's Interrupt Manager */
    hwi_intSetup.intVectId = 6;    // ==> Inserted the new Tx Interrupt vector id 6 here
    hwi_intSetup.sysEvtCount = 1;
    hwi_intSetup.sysEvtId[0] = 32;
    hwi_intSetup.pCallbackFxn = &HwTxInt;
    hwi_intSetup.pCallbackArg = 0;
    hwi_intSetup.bEnable = 1;
    retVal = Interrupt_add(&hwi_intSetup);
    if(retVal != 0)
        printf("Error setting up Tx Interrupts \n");

Step 2: Modify the Enable_DSP_Interrupts() and Disable_DSP_Interrupts() macros to reflect the new CPU interrupt vector ids as shown below:

#define     Disable_DSP_Interrupts()    IER &= ~0x60     // ==> 0x60 = ((1 << 5) | (1 << 6))
#define     Enable_DSP_Interrupts()     IER |= 0x60      // ==> 0x60 = ((1 << 5) | (1 << 6))

Q: DM6437 users - check the project settings for the network client example

see example\network\client\evmdm6437\client.pjt

It seems that the chip type is wrong (currently setup at -D"DM_643", in NDK rel.2.0). It should be changed to -D"DM_6437"

Q: Is it possible to use NDK with CCSv4?

Yes, it is possible to use CCSv4 with NDK. Just install NDK to any directory of choice and make sure all installation instructions are followed (including setting the environment variable NDK_INSTALL_DIR). Since the existing example NDK projects were designed for CCSv3.3, it is required to import them to CCSv4 by going to menu Project -> Import Legacy CCSv3.3 Project. Just make sure to leave the option Copy projects to workspace unchecked at the Import Legacy CCS Project box, since this will avoid any issues with relative paths. After importing, a message box will alert you to check the file <migration.log> for details that require attention. This file contains the following instruction:

!WARNING: File 'client.cmd' explicitly references a TConf-generated linker-command file (line 9). Please remove this reference when migration completes - CCS now automatically handles generated files during project-build.

Simply edit the linker command file <client.cmd> accordingly.

For additional details, please check the page below:


Q: Why the DM648 does not work at 10/100Mbps, only at 1Gbps?

This is a known bug introduced in NDK 2.0. Please check the forum post below: