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.

RTOS/TM4C1294NCPDT: Setting NDK configuration without xconfig

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: OMAPL138,

Tool/software: TI-RTOS

Hello TI members,

For past couple of days I am struggling to run the TI-NDK without using the XCONFIG configuration setting tool and I want to set the configuration with the c code initialisation method of the TI-NDK as mentioned in the file spru524j , but I am unable to achieve that till now.

what I am doing is here:

First I created an empty project from the TI resource explorer and than I did following changes to it in order to make the TI-NDK gets initialised with the c code.

First of all I took the help from the example code of "ndk_omapl138_arm9_examples" in the nsp package.

So as the project got imported I also have a *.cfg file with minimal amount of xconfig settings in it.

I added following lines of code to the configuration file which are as follow:

// Added the memory configuration of Heap. It is required as without it the system create error.

var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
/* create a HeapMem heap instance "systemHeap" */
var systemHeapParams = new HeapMem.Params;
systemHeapParams.size = 0x00002000;
//systemHeapParams.size = 0x00020000;
var systemHeap = HeapMem.create(systemHeapParams);

/* set "systemHeap" to be the default Heap for the app */
Memory.defaultHeapInstance = systemHeap;


/*There after I added following code section at very last of the configuration file */



var Global = xdc.useModule('ti.ndk.config.Global');
Global.enableCodeGeneration = false;

/* create the NDK stack Task thread */
var Task = xdc.useModule('ti.sysbios.knl.Task');
var ndkTaskParams = new Task.Params();
ndkTaskParams.priority = 5;
ndkTaskParams.stackSize = 8192;
Task.create('&StackTest', ndkTaskParams);

Now In the main.c file I added the following code apart from the minimal code present already for blinking an led in a task.

/* Included following files */

#include <stdio.h>
#include <netmain.h>
#include <_stack.h>
#include <servers.h>


/* Added following line of code in it */


//---------------------------------------------------------------------------
// Title String
//
char *VerStr = "\nTCP/IP Stack 'Hello World!' Application\n\n";

// Our NETCTRL callback functions
static void   NetworkOpen();
static void   NetworkClose();
static void   NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd );

// Fun reporting function
static void   ServiceReport( uint Item, uint Status, uint Report, HANDLE hCfgEntry );

//---------------------------------------------------------------------------
// Configuration
//
char *HostName    = "tidsp";
char *LocalIPAddr = "0.0.0.0";                  // Set to "0.0.0.0" for DHCP
char *LocalIPMask = "255.255.254.0";    // Not used when using DHCP
char *GatewayIP   = "0.0.0.0";                  // Not used when using DHCP
char *DomainName  = "demo.net";         // Not used when using DHCP
char *DNSServer   = "0.0.0.0";          // Used when set to anything but zero


// This callback function is called by the evaluation stack 5 min before the
// evaluation period times out.
void evalCallBack()
{
    printf("The Stack is going to shutdown in 5 min\n");
}

HANDLE            hCfg;

//
// Main Thread
//
int StackTest()
{
    int               rc;

    //
    // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!!
    //
    rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
    if( rc )
    {
        printf("NC_SystemOpen Failed (%d)\n",rc);
        for(;;);
    }

    // Print out our banner
    printf(VerStr);

    //
    // Create and build the system configuration from scratch.
    //

    // Create a new configuration
    hCfg = CfgNew();
    if( !hCfg )
    {
        printf("Unable to create configuration\n");
        goto main_exit;
    }

    // The evaluation version of TCP/IP Stack restricts usage of stack
    // to maximum of 24 Hours. If application wants to be notified 5 min
    // before the timeout, it can register a callback function by using
    // the following configuration code section.
    /*{
        void (*pFxn)() = &evalCallBack;
        CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_SYSINFO_EVALCALLBACK, 0,
                    sizeof(void(*)()), (UINT8*) &pFxn, 0 );
    }*/

    // We better validate the length of the supplied names
    if( strlen( DomainName ) >= CFG_DOMAIN_MAX ||
        strlen( HostName ) >= CFG_HOSTNAME_MAX )
    {
        printf("Names too long\n");
        goto main_exit;
    }

    // Add our global hostname to hCfg (to be claimed in all connected domains)
    CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0,
                 strlen(HostName), (UINT8 *)HostName, 0 );

    // If the IP address is specified, manually configure IP and Gateway
    if( inet_addr(LocalIPAddr) )
    {
        CI_IPNET NA;
        CI_ROUTE RT;
        IPN      IPTmp;

        // Setup manual IP address
        bzero( &NA, sizeof(NA) );
        NA.IPAddr  = inet_addr(LocalIPAddr);
        NA.IPMask  = inet_addr(LocalIPMask);
        strcpy( NA.Domain, DomainName );
        NA.NetType = 0;

        // Add the address to interface 1
        CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0,
                           sizeof(CI_IPNET), (UINT8 *)&NA, 0 );

        // Add the default gateway. Since it is the default, the
        // destination address and mask are both zero (we go ahead
        // and show the assignment for clarity).
        bzero( &RT, sizeof(RT) );
        RT.IPDestAddr = 0;
        RT.IPDestMask = 0;
        RT.IPGateAddr = inet_addr(GatewayIP);

        // Add the route
        CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0,
                           sizeof(CI_ROUTE), (UINT8 *)&RT, 0 );

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
    }
    // Else we specify DHCP
    else
    {
//
    }

    //
    // Configure IPStack/OS Options
    //

    // We don't want to see debug messages less than WARNINGS
    rc = DBG_WARN;
    CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    //
    // This code sets up the TCP and UDP buffer sizes
    // (Note 8192 is actually the default. This code is here to
    // illustrate how the buffer and limit sizes are configured.)
    //

    // UDP Receive limit
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    //
    // Boot the system using this configuration
    //
    // We keep booting until the function returns 0. This allows
    // us to have a "reboot" command.
    //
    do
    {
        rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
    } while( rc > 0 );

    // Delete Configuration
    CfgFree( hCfg );

    // Close the OS
main_exit:
    NC_SystemClose();
    return(0);
}


void DHCPTestTask(void)
{
    HANDLE dhcpService;
    CI_SERVICE_DHCPC dhcpc;

    TaskSleep(3000);

    // Specify DHCP Service on IF-1
    bzero( &dhcpc, sizeof(dhcpc) );
    dhcpc.cisargs.Mode   = CIS_FLG_IFIDXVALID;
    dhcpc.cisargs.IfIdx  = 1;
    dhcpc.cisargs.pCbSrv = &ServiceReport;

    printf("Before adding DCHP");
    //_mmCheck(MMCHECK_MAP, &printf);
    CfgAddEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0, sizeof(dhcpc), (UINT8*)&dhcpc, 0);

    printf("After adding DCHP");
    //_mmCheck(MMCHECK_MAP, &printf);

    TaskSleep(3000);

    if (CfgGetEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 1, &dhcpService) > 0)
    {
        CfgRemoveEntry(hCfg, dhcpService);
    }

    printf("After removing DCHP");
    //_mmCheck(MMCHECK_MAP, &printf);
}

//
// NetworkOpen
//
// This function is called after the configuration has booted
//
static void NetworkOpen()
{
    TaskCreate( DHCPTestTask, "DHCPTest", OS_TASKPRINORM, 0x1400, 0, 0, 0 );
}

//
// NetworkClose
//
// This function is called when the network is shutting down,
// or when it no longer has any IP addresses assigned to it.
//
static void NetworkClose()
{
//    DaemonFree( hHello );
}


//
// NetworkIPAddr
//
// This function is called whenever an IP address binding is
// added or removed from the system.
//
static void NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd )
{
    IPN IPTmp;

    if( fAdd )
        printf("Network Added: ");
    else
        printf("Network Removed: ");

    // Print a message
    IPTmp = ntohl( IPAddr );
    printf("If-%d:%d.%d.%d.%d\n", IfIdx,
            (UINT8)(IPTmp>>24)&0xFF, (UINT8)(IPTmp>>16)&0xFF,
            (UINT8)(IPTmp>>8)&0xFF, (UINT8)IPTmp&0xFF );
}

//
// Service Status Reports
//
// Here's a quick example of using service status updates
//
static char *TaskName[]  = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };
static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };
static char *StatusStr[] = { "Disabled","Waiting","IPTerm","Failed","Enabled" };
static void ServiceReport( uint Item, uint Status, uint Report, HANDLE h )
{
    printf( "Service Status: %-9s: %-9s: %-9s: %03d\n",
            TaskName[Item-1], StatusStr[Status],
            ReportStr[Report/256], Report&0xFF );

    //
    // Example of adding to the DHCP configuration space
    //
    // When using the DHCP client, the client has full control over access
    // to the first 256 entries in the CFGTAG_SYSINFO space.
    //
    // Note that the DHCP client will erase all CFGTAG_SYSINFO tags except
    // CFGITEM_DHCP_HOSTNAME. If the application needs to keep manual
    // entries in the DHCP tag range, then the code to maintain them should
    // be placed here.
    //
    // Here, we want to manually add a DNS server to the configuration, but
    // we can only do it once DHCP has finished its programming.
    //
    if( Item == CFGITEM_SERVICE_DHCPCLIENT &&
        Status == CIS_SRV_STATUS_ENABLED &&
        (Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPADD) ||
         Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPRENEW)) )
    {
        IPN IPTmp;

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
    }
}

After adding this code I was having some compiler error related to _mmCheck function which I suppressed by commenting it for now in the entire code.

and now my code is compiling successfully but the problem starts in the linking phase where it says:

<Linking>
"../EK_TM4C1294XL.cmd", line 54: error #10099-D: program will not fit into available memory.  run placement with alignment fails for section ".bss" size 0x5eb50 .  Available memory ranges:
   SRAM         size: 0x40000      unused: 0x3e080      max hole: 0x3e080   
error #10010: errors encountered during linking; "NetworkCfgTest.out" not built

So I want to know that would I be not able to configure the NDK stack through c code method on tiva board which I think is not a case.

Please guide me how should I proceed so that it build successfully and also gets the static IP address during runtime.

regards

  • Hi Piyush,

    For the MSP432E4 device, we have moved away from .cfg configuration for the NDK. The main reason is that the MSP432E3 SDK provides NDK support on both TI-RTOS and FreeRTOS.  I attached the ndk.c file used to setup the stack in the SimpleLink MSP432E4 SDK networking examples. I highly recommend you look at that SDK for examples. I'd even install it () and import the example to see all the project settings.

    I expect the size issue is because you are not specifying the size of the NDK buffers and they are defaulting to large sizes. Again the SimpleLink SDK example shows how to set those up in the runtime code. Here is a discussion of the memory usage in the NDK: 

    Granted, it is more focused on the  .cfg configuration, but the gist and names are similar enough that you can connect the dots.

    Todd

  • Dear Todd,

    Actually I am not using any msp432 based controller. My controller is TM4C1294NCPDT which is arm cortex M4F based microcontroller.

    So , please tell me which will be the proper reference to look upon for setting the TI-NDK settings via c coding and not through XCONFIG.

    regards

  • Sorry for the confusion, I meant to say to look at the MSP432E4 SDK for examples. I know it's a different part (but still a cortex M4F MCU), but the NDK portion is the same. The NDK User Guide and Reference Guide does cover it also.

    Todd
  • Todd,

    if you don't mind , could you please provide me the link to the sdk to download.
    It will be quite helpful and I would not get confused as you know there are lot of documents and software packages from TI which could make anybody confused.

    regards
  • The link is in my first reply.
  • Hi Piyush,

    Are you still working with your original app (the one you mention in your originating post in this thread)?

    If so, I think I know why it's not working.

    Can you add a couple of break points into that app and then restart/run to see in which order they hit?

    break points:

    1. ti_ndk_config_Global_stackThread()
    2. StackTest()

    Which of the above 2 functions is run first? You might be seeing issues due to the order these functions are running at.

    A few other things:

    A general comment - I think that OMAPL138 NSP you copied code from is very outdated and was meant to be used in an old version of the NDK (compared to the NDK version you're using). So, some of the below comments are due to that, not due to anything you are doing in particular.

    Piyush Pandey22 said:
    char *LocalIPAddr = "0.0.0.0";

    If you want a static IP address, then you should update this to be the IP address you want to use.

    This might be the reason you cannot get the app to work with a static IP address.

    But, the code you currently have is configured as a DHCP client, and so will attempt to get the IP address from a DHCP server ...see the next comment.

    Piyush Pandey22 said:
    static void NetworkOpen()
    {
        TaskCreate( DHCPTestTask, "DHCPTest", OS_TASKPRINORM, 0x1400, 0, 0, 0 );
    }

    Piyush Pandey22 said:
    void DHCPTestTask(void)
    {
        HANDLE dhcpService;
        CI_SERVICE_DHCPC dhcpc;
        TaskSleep(3000);
        // Specify DHCP Service on IF-1
        bzero( &dhcpc, sizeof(dhcpc) );
        dhcpc.cisargs.Mode   = CIS_FLG_IFIDXVALID;
        dhcpc.cisargs.IfIdx  = 1;
        dhcpc.cisargs.pCbSrv = &ServiceReport;
        printf("Before adding DCHP");
        //_mmCheck(MMCHECK_MAP, &printf);
        CfgAddEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0, sizeof(dhcpc), (UINT8*)&dhcpc, 0);
        printf("After adding DCHP");
        //_mmCheck(MMCHECK_MAP, &printf);
        TaskSleep(3000);
        if (CfgGetEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 1, &dhcpService) > 0)
        {
            CfgRemoveEntry(hCfg, dhcpService);
        }
        printf("After removing DCHP");
        //_mmCheck(MMCHECK_MAP, &printf);
    }

    If your goal is to get the app working with a static IP address (as you stated) then this code is not helping you. I think you should delete it.


    Piyush Pandey22 said:
    // This callback function is called by the evaluation stack 5 min before the // evaluation period times out. void evalCallBack() { printf("The Stack is going to shutdown in 5 min\n"); }

    Piyush Pandey22 said:
        // The evaluation version of TCP/IP Stack restricts usage of stack
        // to maximum of 24 Hours. If application wants to be notified 5 min
        // before the timeout, it can register a callback function by using
        // the following configuration code section.
        /*{
            void (*pFxn)() = &evalCallBack;
            CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_SYSINFO_EVALCALLBACK, 0,
                        sizeof(void(*)()), (UINT8*) &pFxn, 0 );
        }*/

    You can delete this code. There is no evaluation version of the NDK stack any more. This is from the closed source days of old ...

    Piyush Pandey22 said:
    printf()

    You should update that C code you copied to use another print function. 'printf' will degrade performance drastically. The NDK used to have its own implementation of 'printf()' that had better performance, but it's since been removed.

    I would recommend using System_printf() instead. Note that you will need to configure SysMin in your *.cfg file, too, and then use ROV to check the SysMin buffer for the output.

    You can configure SysMin as follows (paste into the end of your *cfg file):

    /* ================ System configuration ================ */
    var System = xdc.useModule('xdc.runtime.System');
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    SysMin.bufSize = 4096;
    System.SupportProxy = SysMin;


    You can use System_printf() in your C code like this:

    #include <xdc/std.h>
    #include <xdc/runtime/System.h>

    void someFxn()
    {
        System_printf("hello!\n");
    }

    Piyush Pandey22 said:
    HANDLE            hCfg;

    I wouldn't make this a global ... I would move it into your StackTest() function.




  • Hi Piyush,

    Did this get resolved?

    Todd

    [Update 6/11: I'm marking this as "TI Thinks Resolved". If you disagree, please post a response.]