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.
Tool/software: Code Composer Studio
I've followed the instructions in a related post for successfully establishing a static IP for the device based on the udpecho example code. Now I would like to implement a simple telnet service as well. Is anyone able to point me in the right direction for setting this up, I'm not finding a lot of documentation on the net or in the forums.
To be clear, I just want an idea of the necessary framework for a telnet service that I can build upon for displaying basic serial output to a (Putty) terminal as opposed to using the TI boards UART.
Thanks
Hello Sai,
so I did some review, and some digging. I decided to try using XGCONF to configure a telnet operation.
I opened the graphical interface and enabled the NDK Global Network Settings, along with IP, TCP, and TELNET layers. I then went in and added some custom code to power a couple PWMs and ADCs as well as push some terminal output to a UART display. Everything compiles nicely, but I can't get a telnet terminal to open.
I look back into XGCONF and see that there's the "Instance" tab, where I assume you can add a new telnet instance, however when I go to the tab all options and dialogs are disabled. How do I add a telnet instance?
I found this older thread (/support/embedded/tirtos/f/355/t/327369) which nicely covers the topic but for an older version of CCS and the NDK, still, everything looks reasonably unchanged. It seems to imply that I should be able to use the Instance tab of the .cfg file telnet layer to create an instance and callback function. But obviously something is wrong on my end as I don't have that ability. Are there some additional steps I should be taking?
I've used the 'empty_MSP_EXP432E401Y_tirtos_ccs' example as my starting point. I've made some changes to the board.h files to add in features, but nothing substantive. The main program I have running now is in empty.c
/* * ======== empty.c ======== */ /* For usleep() */ #include <unistd.h> #include <stdint.h> #include <stddef.h> /* Driver Header files */ #include <ti/drivers/GPIO.h> #include <ti/drivers/ADC.h> #include <ti/display/Display.h> #include <ti/drivers/PWM.h> // #include <ti/drivers/I2C.h> // #include <ti/drivers/SDSPI.h> // #include <ti/drivers/SPI.h> // #include <ti/drivers/UART.h> // #include <ti/drivers/Watchdog.h> /* Board Header file */ #include "Board.h" //#include <ti/devices/msp432e4/driverlib/driverlib.h> /* global variableS FOR GUI COMPOSER */ uint16_t adcValue = 0; uint16_t threshold = 2048; uint16_t trigger = 0; uint8_t cycleCount = 0; /* * ======== mainThread ======== */ void *mainThread(void *arg0) { /* 1 second delay */ uint32_t time = 100; // update 8/sec uint16_t statusTimer = 100; // number of cycles per status LED toggle //[ PWM variables uint16_t pwm1Period = 3000; uint16_t pwm1duty = 0; uint16_t pwm1dutyInc = 100; uint16_t pwm2Period = 3000; uint16_t pwm2duty = 0; uint16_t pwm2dutyInc = 100; uint16_t pwmtimer = statusTimer; //] /* Call driver init functions */ GPIO_init(); ADC_init(); Display_init(); PWM_init(); // I2C_init(); // SDSPI_init(); // SPI_init(); // UART_init(); // Watchdog_init(); //[ LEDs /* Configure the LED pin */ GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); // status LED GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); // ADC threshold LED /* Turn on status LED */ GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON); //] //[ Open the PWM Driver PWM_Handle pwm1 = NULL; PWM_Params pwm1params; PWM_Handle pwm2 = NULL; PWM_Params pwm2params; PWM_Params_init(&pwm1params); pwm1params.dutyUnits = PWM_DUTY_US; pwm1params.dutyValue = 0; pwm1params.periodUnits = PWM_PERIOD_US; pwm1params.periodValue = pwm1Period; pwm1 = PWM_open(Board_PWM0, &pwm1params); if (pwm1 == NULL) { /* Board_PWM0 did not open */ while (1); } PWM_Params_init(&pwm2params); pwm2params.dutyUnits = PWM_DUTY_US; pwm2params.dutyValue = 0; pwm2params.periodUnits = PWM_PERIOD_US; pwm2params.periodValue = pwm2Period; pwm2 = PWM_open(Board_PWM1, &pwm2params); if (pwm2 == NULL) { /* Board_PWM1 did not open */ while (1); } PWM_start(pwm1); PWM_start(pwm2); //] //[ Open the ADC Driver ADC_Handle adc0; ADC_Params adc0Params; ADC_Params_init(&adc0Params); adc0 = ADC_open(Board_ADC0, &adc0Params); if (adc0 == NULL) { // Error initializing ADC channel 0 while(1); } //] //[ Open the display Driver Display_Handle displayHandle; Display_Params displayParams; Display_Params_init(&displayParams); displayHandle = Display_open(Display_Type_UART, NULL); //] /* Run the main routine */ while(1) { int_fast16_t res; uint16_t adc0Value; //Display_printf(displayHandle, 1, 0, "In main"); res = ADC_convert(adc0, &adc0Value); if(res == ADC_STATUS_SUCCESS) { Display_printf(displayHandle, 1, 0, "ADC Reading %d", adc0Value); if(adc0Value >= threshold) { // arbitrary threshold GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON); trigger = 1; } else { GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF); trigger = 0; } } cycleCount++; if(cycleCount == pwmtimer) { PWM_setDuty(pwm1, pwm1duty); pwm1duty = (pwm1duty + pwm1dutyInc); if (pwm1duty == pwm1Period || (!pwm1duty)) { pwm1dutyInc = - pwm1dutyInc; } PWM_setDuty(pwm2, pwm2duty); pwm2duty = (pwm2duty + pwm2dutyInc); if (pwm2duty == pwm2Period || (!pwm2duty)) { pwm2dutyInc = - pwm2dutyInc; } } if(cycleCount == statusTimer) { GPIO_toggle(Board_GPIO_LED0); cycleCount = 0; } usleep(time); } }
Okay, well I figured out how to create the telnet instance, so that's no longer the problem. But now I'm having trouble understanding how to define the callback function. Is there a good demo or example somewhere on how to define this for a telnet service? I don't have a lot of experience with this, so any help is appreciated.\
Patrick.
Steve,
Thank you very much for your help with this, but I'm seemingly still running into problems getting the telnet service to run consistently. Using the stock udpecho example I defined a telnet instance but when I initialize the program I get a "failed" status for the telnet.
Here is what the UART display terminal displays:
the main changes I've made to the udpecho sample code are to define an initTelnet function which I call in the ndkStackThread along with the other initialization functions for IP, TCP and UDP. I also created a second serviceReport function to have the telnet service call which is exactly identical to the existing serviceReport function in the example code.
Here is the initTelnet function:
/* * ===== initTelnet ===== * Configure a telnet instance * see spru524k_ndk_api_ref p.96 */ static void initTelnet(void *hCfg) { CI_SERVICE_TELNET telnet; //bzero(&telnet, sizeof(telnet)); memset(&telnet, NULL, sizeof(telnet)); telnet.cisargs.Mode = CIS_FLG_CALLBYIP | CIS_FLG_RESTARTIPTERM; telnet.cisargs.IfIdx = 2; telnet.cisargs.IPAddr = INADDR_ANY; telnet.cisargs.pCbSrv = &serviceReportTelnet; telnet.param.MaxCon = 2; telnet.param.Port = 23; telnet.param.Callback = &ConsoleOpen; CfgAddEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_TELNET, 0, sizeof(telnet), (unsigned char *)&telnet, NULL); }
here is the serviceReportTelnet function:
/* * ======== serviceReportTelnet ======== * Function for reporting service status updates. */ static char *taskNameTelnet[] = {"Telnet", "HTTP", "NAT", "DHCPS", "DHCPC", "DNS"}; static char *reportStrTelnet[] = {"", "Running", "Updated", "Complete", "Fault"}; static char *statusStrTelnet[] = {"Disabled", "Waiting", "IPTerm", "Failed","Enabled"}; static void serviceReportTelnet(uint32_t item, uint32_t status, uint32_t report, void *h) { Display_printf(display, 0, 0, "Service Status: %-9s: %-9s: %-9s: %03d\n", taskNameTelnet[item - 1], statusStrTelnet[status], reportStrTelnet[report / 256], report & 0xFF); }
and here is the modified ndkStackThread function:
/* * ======== ndkStackThread ======== * NDK stack's main thread function */ static void ndkStackThread(uintptr_t arg0, uintptr_t arg1) { void *hCfg; int rc; timer_t ndkHeartBeat; struct sigevent sev; struct itimerspec its; struct itimerspec oldIts; int ndkHeartBeatCount = 0; /* create the NDK timer tick */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_value.sival_ptr = &ndkHeartBeatCount; sev.sigev_notify_attributes = NULL; sev.sigev_notify_function = &llTimerTick; rc = timer_create(CLOCK_MONOTONIC, &sev, &ndkHeartBeat); if (rc != 0) { Display_printf(display, 0, 0, "ndkStackThread: failed to create timer (%d)\n"); } /* start the NDK 100ms timer */ its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 100000000; its.it_value.tv_sec = 0; its.it_value.tv_nsec = 100000000; rc = timer_settime(ndkHeartBeat, 0, &its, NULL); if (rc != 0) { Display_printf(display, 0, 0, "ndkStackThread: failed to set time (%d)\n"); } rc = NC_SystemOpen(NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT); if (rc) { Display_printf(display, 0, 0, "ndkStackThread: NC_SystemOpen Failed (%d)\n"); } /* create and build the system configuration from scratch. */ hCfg = CfgNew(); if (!hCfg) { Display_printf(display, 0, 0, "ndkStackThread: Unable to create configuration\n"); goto main_exit; } /* IP, TCP, UDP, and Telnet config */ initIp(hCfg); initTcp(hCfg); initUdp(hCfg); initTelnet(hCfg); /* config low priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKLOW, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); /* config norm priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKNORM, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); /* config high priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKHIGH, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); do { rc = NC_NetStart(hCfg, networkOpen, networkClose, networkIPAddr); } while(rc > 0); /* Shut down the stack */ CfgFree(hCfg); main_exit: NC_SystemClose(); /* stop and delete the NDK heartbeat */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 0; rc = timer_settime(ndkHeartBeat, 0, &its, &oldIts); rc = timer_delete(ndkHeartBeat); Display_printf(display, 0, 0, "ndkStackThread: exiting ...\n"); }
The remainder of the udpecho example code is unchanged.
I'm assuming that I'm doing something wrong in either the way I've defined the telnet instance, or maybe in how I call the init routine, but I can't seem to figure it out.
Just in case it helps, I've attached the complete ndk_tirtos.c file.
/* * Copyright (c) 2017-2018, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== ndk_tirtos.c ======== */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/ndk/inc/netmain.h> #include <ti/ndk/inc/os/oskern.h> #include <signal.h> #include <time.h> #include <ti\ndk\inc\tools\console.h> #include <ti/display/Display.h> /* Socket file descriptor table */ #define MAXSOCKETS 10 uint32_t ti_ndk_socket_max_fd = MAXSOCKETS; void *ti_ndk_socket_fdtable[MAXSOCKETS]; extern Display_Handle display; /* NDK memory manager page size and number of pages [used by mmAlloc()] */ #define RAW_PAGE_SIZE 3072 #define RAW_PAGE_COUNT 6 const int ti_ndk_config_Global_rawPageSize = RAW_PAGE_SIZE; const int ti_ndk_config_Global_rawPageCount = RAW_PAGE_COUNT; /* P.I.T. (page information table) */ #ifdef __ti__ #pragma DATA_SECTION(ti_ndk_config_Global_pit, ".bss:NDK_MMBUFFER"); #pragma DATA_SECTION(ti_ndk_config_Global_pitBuffer, ".bss:NDK_MMBUFFER"); PITENTRY ti_ndk_config_Global_pit[RAW_PAGE_COUNT]; unsigned char ti_ndk_config_Global_pitBuffer[RAW_PAGE_SIZE * RAW_PAGE_COUNT]; #elif defined (__IAR_SYSTEMS_ICC__) PITENTRY ti_ndk_config_Global_pit[RAW_PAGE_COUNT]; unsigned char ti_ndk_config_Global_pitBuffer[RAW_PAGE_SIZE * RAW_PAGE_COUNT]; #else PITENTRY ti_ndk_config_Global_pit[RAW_PAGE_COUNT] __attribute__ ((section(".bss:NDK_MMBUFFER"))); unsigned char ti_ndk_config_Global_pitBuffer[RAW_PAGE_SIZE * RAW_PAGE_COUNT] __attribute__ ((section(".bss:NDK_MMBUFFER"))); #endif /* Memory bucket sizes */ #define SMALLEST 48 #define LARGEST (RAW_PAGE_SIZE) const int ti_ndk_config_Global_smallest = SMALLEST; const int ti_ndk_config_Global_largest = LARGEST; /* define the opening console string for the telnet instance */ char *VerStr = "\nNDK Telnet Console\n"; /* Memory Slot Tracking */ uint32_t ti_ndk_config_Global_Id2Size[] = {SMALLEST, 96, 128, 256, 512, 1536, LARGEST}; /* * Local Packet Buffer Pool Definitions * * The below variables/defines are used to override the defaults that are set * in the Packet Buffer Manager (PBM) file src/stack/pbm/pbm_data.c */ /* * Number of buffers in PBM packet buffer free pool * * The number of buffers in the free pool can have a significant effect * on performance, especially in UDP packet loss. Increasing this number * will increase the size of the static packet pool use for both sending * and receiving packets. */ #define PKT_NUM_FRAMEBUF 10 /* Size of Ethernet frame buffer */ #define PKT_SIZE_FRAMEBUF 1536 const int ti_ndk_config_Global_numFrameBuf = PKT_NUM_FRAMEBUF; const int ti_ndk_config_Global_sizeFrameBuf = PKT_SIZE_FRAMEBUF; /* Data space for packet buffers */ #ifdef __ti__ #pragma DATA_ALIGN(ti_ndk_config_Global_pBufMem, 128); #pragma DATA_SECTION(ti_ndk_config_Global_pBufMem, ".bss:NDK_PACKETMEM"); unsigned char ti_ndk_config_Global_pBufMem[PKT_NUM_FRAMEBUF * PKT_SIZE_FRAMEBUF]; #elif defined (__IAR_SYSTEMS_ICC__) #pragma data_alignment = 128 unsigned char ti_ndk_config_Global_pBufMem[PKT_NUM_FRAMEBUF * PKT_SIZE_FRAMEBUF]; #else unsigned char ti_ndk_config_Global_pBufMem[PKT_NUM_FRAMEBUF * PKT_SIZE_FRAMEBUF] __attribute__ ((aligned(128), section(".bss:NDK_PACKETMEM"))); #endif #ifdef __ti__ #pragma DATA_ALIGN(ti_ndk_config_Global_pHdrMem, 128); #pragma DATA_SECTION(ti_ndk_config_Global_pHdrMem, ".bss:NDK_PACKETMEM"); unsigned char ti_ndk_config_Global_pHdrMem[PKT_NUM_FRAMEBUF * sizeof(PBM_Pkt)]; #elif defined (__IAR_SYSTEMS_ICC__) #pragma data_alignment = 128 unsigned char ti_ndk_config_Global_pHdrMem[PKT_NUM_FRAMEBUF * sizeof(PBM_Pkt)]; #else unsigned char ti_ndk_config_Global_pHdrMem[PKT_NUM_FRAMEBUF * sizeof(PBM_Pkt)] __attribute__ ((aligned(128), section(".bss:NDK_PACKETMEM"))); #endif /* Our NETCTRL callback functions */ static void networkOpen(); static void networkClose(); static void networkIPAddr(uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd); static char *hostName = "tisoc"; extern void llTimerTick(); /* * ======== networkOpen ======== * This function is called after the configuration has booted */ static void networkOpen() { extern void netOpenHook(); /* call user defined network open hook */ netOpenHook(); } /* * ======== 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() { /* call user defined network close hook */ } /* * ======== networkIPAddr ======== * This function is called whenever an IP address binding is * added or removed from the system. */ static void networkIPAddr(uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd) { uint32_t IPTmp; if (fAdd) { Display_printf(display, 0, 0, "Network Added: "); } else { Display_printf(display, 0, 0, "Network Removed: "); } /* print the IP address that was added/removed */ IPTmp = NDK_ntohl(IPAddr); Display_printf(display, 0, 0, "If-%d:%d.%d.%d.%d\n", IfIdx, (uint8_t)(IPTmp>>24)&0xFF, (uint8_t)(IPTmp>>16)&0xFF, (uint8_t)(IPTmp>>8)&0xFF, (uint8_t)IPTmp&0xFF); extern void netIPAddrHook(); /* call user defined network IP address hook */ netIPAddrHook(IPAddr, IfIdx, fAdd); } /* * ======== serviceReport ======== * Function for reporting 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(uint32_t item, uint32_t status, uint32_t report, void *h) { Display_printf(display, 0, 0, "Service Status: %-9s: %-9s: %-9s: %03d\n", taskName[item - 1], statusStr[status], reportStr[report / 256], report & 0xFF); } /* * ======== serviceReportTelnet ======== * Function for reporting service status updates. */ static char *taskNameTelnet[] = {"Telnet", "HTTP", "NAT", "DHCPS", "DHCPC", "DNS"}; static char *reportStrTelnet[] = {"", "Running", "Updated", "Complete", "Fault"}; static char *statusStrTelnet[] = {"Disabled", "Waiting", "IPTerm", "Failed","Enabled"}; static void serviceReportTelnet(uint32_t item, uint32_t status, uint32_t report, void *h) { Display_printf(display, 0, 0, "Service Status: %-9s: %-9s: %-9s: %03d\n", taskNameTelnet[item - 1], statusStrTelnet[status], reportStrTelnet[report / 256], report & 0xFF); } /* * ======== initTcp ======== * Configure the stack's TCP settings */ static void initTcp(void *hCfg) { int transmitBufSize = 1024; int receiveBufSize = 1024; int receiveBufLimit = 2048; CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&transmitBufSize, NULL); CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&receiveBufSize, NULL); CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&receiveBufLimit, NULL); } /* * ======== initIp ======== * Configure the stack's IP settings */ static void initIp(void *hCfg) { CI_SERVICE_DHCPC dhcpc; unsigned char DHCP_OPTIONS[] = { DHCPOPT_SUBNET_MASK }; /* Add global hostname to hCfg (to be claimed in all connected domains) */ CfgAddEntry(hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0, strlen(hostName), (unsigned char *)hostName, NULL); /* Use DHCP to obtain IP address on interface 1 */ memset(&dhcpc, 0, sizeof(dhcpc)); dhcpc.cisargs.Mode = CIS_FLG_IFIDXVALID; dhcpc.cisargs.IfIdx = 1; dhcpc.cisargs.pCbSrv = &serviceReport; dhcpc.param.pOptions = DHCP_OPTIONS; dhcpc.param.len = 1; CfgAddEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0, sizeof(dhcpc), (unsigned char *)&dhcpc, NULL); } /* * ===== initTelnet ===== * Configure a telnet instance * see spru524k_ndk_api_ref p.96 */ static void initTelnet(void *hCfg) { CI_SERVICE_TELNET telnet; //bzero(&telnet, sizeof(telnet)); memset(&telnet, NULL, sizeof(telnet)); telnet.cisargs.Mode = CIS_FLG_CALLBYIP | CIS_FLG_RESTARTIPTERM; telnet.cisargs.IfIdx = 2; telnet.cisargs.IPAddr = INADDR_ANY; telnet.cisargs.pCbSrv = &serviceReportTelnet; telnet.param.MaxCon = 2; telnet.param.Port = 23; telnet.param.Callback = &ConsoleOpen; CfgAddEntry(hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_TELNET, 0, sizeof(telnet), (unsigned char *)&telnet, NULL); } /* * ======== initUdp ======== * Configure the stack's UDP settings */ void initUdp(void *hCfg) { int receiveBufSize = 2048; CfgAddEntry(hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&receiveBufSize, NULL); } /* * ======== ndkStackThread ======== * NDK stack's main thread function */ static void ndkStackThread(uintptr_t arg0, uintptr_t arg1) { void *hCfg; int rc; timer_t ndkHeartBeat; struct sigevent sev; struct itimerspec its; struct itimerspec oldIts; int ndkHeartBeatCount = 0; /* create the NDK timer tick */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_value.sival_ptr = &ndkHeartBeatCount; sev.sigev_notify_attributes = NULL; sev.sigev_notify_function = &llTimerTick; rc = timer_create(CLOCK_MONOTONIC, &sev, &ndkHeartBeat); if (rc != 0) { Display_printf(display, 0, 0, "ndkStackThread: failed to create timer (%d)\n"); } /* start the NDK 100ms timer */ its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 100000000; its.it_value.tv_sec = 0; its.it_value.tv_nsec = 100000000; rc = timer_settime(ndkHeartBeat, 0, &its, NULL); if (rc != 0) { Display_printf(display, 0, 0, "ndkStackThread: failed to set time (%d)\n"); } rc = NC_SystemOpen(NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT); if (rc) { Display_printf(display, 0, 0, "ndkStackThread: NC_SystemOpen Failed (%d)\n"); } /* create and build the system configuration from scratch. */ hCfg = CfgNew(); if (!hCfg) { Display_printf(display, 0, 0, "ndkStackThread: Unable to create configuration\n"); goto main_exit; } /* IP, TCP, UDP, and Telnet config */ initIp(hCfg); initTcp(hCfg); initUdp(hCfg); initTelnet(hCfg); /* config low priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKLOW, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); /* config norm priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKNORM, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); /* config high priority tasks stack size */ rc = 2048; CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_TASKSTKHIGH, CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (unsigned char *)&rc, NULL); do { rc = NC_NetStart(hCfg, networkOpen, networkClose, networkIPAddr); } while(rc > 0); /* Shut down the stack */ CfgFree(hCfg); main_exit: NC_SystemClose(); /* stop and delete the NDK heartbeat */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 0; rc = timer_settime(ndkHeartBeat, 0, &its, &oldIts); rc = timer_delete(ndkHeartBeat); Display_printf(display, 0, 0, "ndkStackThread: exiting ...\n"); } /* * ======== ti_ndk_config_Global_startupFxn ======== * Called to start up the NDK. In BIOS, this can be called as a BIOS startup * function, or from main(). In FreeRTOS, this should be called from main(). */ void ti_ndk_config_Global_startupFxn() { Task_Params params; Task_Handle ndkThread; Task_Params_init(¶ms); params.instance->name = "ndkStackThread"; params.priority = 5; params.stackSize = 2048; ndkThread = Task_create((Task_FuncPtr)ndkStackThread, ¶ms, NULL); if (!ndkThread) { /* Error: could not create NDK stack thread */ while(1); } }
I hope you can point me to whatever it is I'm still doing wrong.
Thank you
Patrick
Well,
I never got the telnet service to operate reliably. I worked around the issue by defining my own connection socket and interface console.
**Attention** This is a public forum