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.

LAUNCHXL-CC3235S: transmission speed and continuous execution of a task

Part Number: LAUNCHXL-CC3235S

Hello TI Team,

I'm developing an application that intends to do the following:

  • configure one LaunchXL-CC3235S as an Access Point and another one as Station. 
  • transmit data between AP and STA (full duplex, bidirectional) on continuous basis.

for these two requirements, I've developed attached applications. With the same, I facing following issues:

  1. Transmission speeds seems to be very slow. I'm getting almost one message per second. Can something be done for that? My minimum requirements is of 4 Mbps. How do I increase the data rate and how do I verify the same? 
  2. My socket_task in the program has random execution. Sometimes is sends 577 messages, sometimes 5444 sometimes 389. (I've tried three iterations) This shall be continuous. As I've written two counters, it should run 50000 x 50000 times without stopping or switching. I'm not able to understand why does the program stops current execution and switches back to main_thread task?

AP_28Feb2023_main_FreeRTOS.c
/*
 *  ======== main_freertos.c ========
 */
#include <stdint.h>

/* POSIX Header files */
#include <pthread.h>

/* RTOS header files */
#include "FreeRTOS.h"
#include "task.h"

/* TI-DRIVERS Header files */
#include "ti_drivers_config.h"

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>

extern void * mainThread(void *arg0);

/* Stack size in bytes */
#define THREADSTACKSIZE   1024



/*
 *  ======== main ========
 */
int main(void)
{
    pthread_t thread;
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int retc = 0;
    int detachState;

    /* Call board init functions */
    Board_init();

    retc = xTaskCreate( mainThread, /* Pointer to the function that implements the task. */
                        "mainThread 1",/* Text name for the task. This is to facilitate debugging only. */
                        THREADSTACKSIZE, /* Stack depth - small microcontrollers will use much less stack than this. */
                        NULL, /* This example does not use the task parameter. */
                        3, /* This task will run at Maximum priority. */
                        NULL ); /* This example does not use the task handle. */

    if(retc != pdPASS)
    {
        printf("\n\n");
        printf("Main Task Creation failed!!!");
        printf("\n\n");
        while(1)
        {
            ;
        }
    }

    if(retc == pdPASS)
    {
        printf("\n\n");
        printf("Main Task Creation Succeeded !!!");
        printf("\n\n");
    }


    /* Start the FreeRTOS scheduler */
    vTaskStartScheduler();

    return (0);
}

void vApplicationMallocFailedHook()
{
    /* Handle Memory Allocation Errors */
    while(1)
    {
    }
}


void vApplicationStackOverflowHook(TaskHandle_t pxTask,
                                   char *pcTaskName)
{
    //Handle FreeRTOS Stack Overflow
    while(1)
    {
    }
}

void vApplicationTickHook(void)
{

}

void vPreSleepProcessing(uint32_t ulExpectedIdleTime)
{
}


void
vApplicationIdleHook(void)
{
    /* Handle Idle Hook for Profiling, Power Management etc */
}

#if defined (__GNUC__)
void * _sbrk(uint32_t delta)
{
    extern char _end;     /* Defined by the linker */
    extern char __HeapLimit;
    static char *heap_end;
    static char *heap_limit;
    char *prev_heap_end;

    if(heap_end == 0)
    {
        heap_end = &_end;
        heap_limit = &__HeapLimit;
    }

    prev_heap_end = heap_end;
    if(prev_heap_end + delta > heap_limit)
    {
        return((void *) -1L);
    }
    heap_end += delta;
    return((void *) prev_heap_end);
}

#endif

AP_28Feb2023_platform.c
#include <ti/drivers/net/wifi/simplelink.h>
#include <ti/drivers/net/wifi/slnetifwifi.h>

#include <ti/display/Display.h>

#include <ti/drivers/SPI.h>

#include "FreeRTOS.h"
#include "task.h"

// TI-Driver includes
#include "ti_drivers_config.h"
#include "pthread.h"


#include <string.h>
#include <stdint.h>


/* BSD support */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <ti/net/slnetutils.h>




#define DEVICE_ERROR                          ("Device error, please refer \"DEVICE ERRORS CODES\" section in errors.h")
#define WLAN_ERROR                            ("WLAN error, please refer \"WLAN ERRORS CODES\" section in errors.h")
#define SL_STOP_TIMEOUT                       (200)

#define UDPPORT                               (1000)
#define SPAWN_TASK_PRIORITY                   (9)
#define TASK_STACK_SIZE                       (2048)
#define SLNET_IF_WIFI_PRIO                    (5)
#define SLNET_IF_WIFI_NAME                    "CC32xx"
#define UDPPACKETSIZE                           256
#define THREADSTACKSIZE                         4096

#define SSID_NAME                               "HCTRIVEDI_AP1"                                            // AP SSID
// #define SECURITY_TYPE                           SL_WLAN_SEC_TYPE_WPA_WPA2                                   // Security type could be SL_WLAN_SEC_TYPE_OPEN
_u8  SECURITY_TYPE = SL_WLAN_SEC_TYPE_WPA_WPA2;
#define SECURITY_KEY                            "HarshAPConnect"                                                  // Password of the secured AP
#define device_name                             "Trivedi"                                                   // set new name of the device
#define country_code                            "US"                                                        // setting country code...
#define ApPower                                 15                                                          // set Tx power level

_u8 status = 0;
_u8 flag_second_ping = 0;
static _u32 retc = 0;

pthread_t udpThread = (pthread_t)NULL;
pthread_t spawn_thread = (pthread_t)NULL;
int32_t             mode;
Display_Handle display;

char msg1[26], msg2[6], msg3[6];


/*
 *  ======== printError ========
 */
void printError(char *errString, int code)
{
    Display_printf(display, 0, 0, "Error! code = %d, Description = %s\n", code, errString);
    while(1);
}

void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
{
    // unused in this application...
}

void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent)
{
    /* Unused in this application */
}

void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
{
    /* Unused in this application */
}

void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest, SlNetAppResponse_t *pNetAppResponse)
{
    /* Unused in this application */
}

void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *pHttpEvent, SlNetAppHttpServerResponse_t *pHttpResponse)
{
    /* Unused in this application */
}

void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
{
    if(pWlanEvent == NULL)
    {
        return;
    }

    switch(pWlanEvent->Id)
    {
    case SL_WLAN_EVENT_STA_ADDED:
        printf("\n\n A station with following parameters has got connected to the AP: %s", (signed char*)SSID_NAME);
        printf("\n\n %02x:%02x:%02x:%02x:%02x:%02x \n\n",
               pWlanEvent->Data.STAAdded.Mac[0],
               pWlanEvent->Data.STAAdded.Mac[1],
               pWlanEvent->Data.STAAdded.Mac[2],
               pWlanEvent->Data.STAAdded.Mac[3],
               pWlanEvent->Data.STAAdded.Mac[4],
               pWlanEvent->Data.STAAdded.Mac[5]);

        // code to get the number of connected stations...

        _u8 num_ap_connected_sta;
        _u16 len = sizeof(num_ap_connected_sta);
        status = sl_NetCfgGet(SL_NETCFG_AP_STATIONS_NUM_CONNECTED, NULL, &len, &num_ap_connected_sta);
        printf("Revised number of connected stations = %d\n", num_ap_connected_sta);

        // code to get the list of stations...

        SlNetCfgStaInfo_t ApStaList[4];
        _u8 sta_info_len = sizeof(ApStaList);
        _u8 start_sta_index = 0;
        _u8 actual_num_sta, ii;
        sl_NetCfgGet(SL_NETCFG_AP_STATIONS_INFO_LIST, &start_sta_index, &sta_info_len, (_u8 *)ApStaList);
        actual_num_sta = sta_info_len / sizeof(SlNetCfgStaInfo_t);
        printf("\n \n Actual num_stations = %d", actual_num_sta);
        printf("\n \n upon sta_info_len = %d", sta_info_len);
        for (ii=0; ii<actual_num_sta; ii++)
        {
            SlNetCfgStaInfo_t *staInfo = &ApStaList[ii];
            printf("    Ap Station %d is connected\n", ii);
            printf("    NAME: %s\n", staInfo->Name);
            printf("    MAC:  %02x:%02x:%02x:%02x:%02x:%02x\n", staInfo->MacAddr[0], staInfo->MacAddr[1], staInfo->MacAddr[2], staInfo->MacAddr[3], staInfo->MacAddr[4], staInfo->MacAddr[5]);
            printf("    IP:   %d.%d.%d.%d\n", SL_IPV4_BYTE(staInfo->Ip,3), SL_IPV4_BYTE(staInfo->Ip,2), SL_IPV4_BYTE(staInfo->Ip,1), SL_IPV4_BYTE(staInfo->Ip,0));
            // Display_printf(display, 0, 0,"\n\r NAME: %s\n\r", staInfo->Name);
            // Display_printf(display, 0, 0,"\n\r IP:   %d.%d.%d.%d\n", SL_IPV4_BYTE(staInfo->Ip,3), SL_IPV4_BYTE(staInfo->Ip,2), SL_IPV4_BYTE(staInfo->Ip,1), SL_IPV4_BYTE(staInfo->Ip,0));
            SlNetCfgIpV4Args_t *staInfo2 = &ApStaList[ii];
            printf("    Gateway: %d.%d.%d.%d\n\n", SL_IPV4_BYTE(staInfo2->IpGateway,3),SL_IPV4_BYTE(staInfo2->IpGateway,2),SL_IPV4_BYTE(staInfo2->IpGateway,1),SL_IPV4_BYTE(staInfo2->IpGateway,0));
        }

        break;
    case SL_WLAN_EVENT_STA_REMOVED:
        printf("\n\n A station with following parameters have been removed from the AP: %s", (signed char*)SSID_NAME);
        printf("\n\n %02x:%02x:%02x:%02x:%02x:%02x \n\n",
               pWlanEvent->Data.STARemoved.Mac[0],
               pWlanEvent->Data.STARemoved.Mac[1],
               pWlanEvent->Data.STARemoved.Mac[2],
               pWlanEvent->Data.STARemoved.Mac[3],
               pWlanEvent->Data.STARemoved.Mac[4],
               pWlanEvent->Data.STARemoved.Mac[5]);
        break;
    default:
        break;
    }
    printf("\n");
    printf("out of WLAN Event Handler Switch statement ...");
    printf("\n");

    retc = 940;
}

void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
{
    /* Unused in this application */
}


void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
{
    /* Unused in this application */
}

void check_device_initial_mode(void)
{
    mode = sl_Start(0, 0, 0);
    Display_printf(display, 0, 0,"\n\rMode: %d", mode);
    if (mode < 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, mode, DEVICE_ERROR);
    }
    switch(mode)
    {
    case 0:
        printf("Role = Station \n");
        break;
    case 1:
        printf("Role = Reserved! \n");
        break;
    case 2:
        printf("Role = Access Point \n");
        break;
    case 3:
        printf("Role = ROLE_P2P \n");
        break;
    case 4:
        printf("Role = ROLE_TAG \n");
        break;
    default:
        printf("Some Error Occured! No such role!! \n");
        break;
    }
}

void configure_AP_mode(void)
{
    if(mode != ROLE_AP)
    {
        /* Set NWP role as STA */
        mode = sl_WlanSetMode(ROLE_AP);
        if (mode < 0)
        {
            printf("\n AP Mode could not be configfured!! \n");
        }

        /* For changes to take affect, we restart the NWP */
        status = sl_Stop(SL_STOP_TIMEOUT);
        if (status < 0)
        {
            printf("Device could not be stopped post mode change!! \n");
        }

        mode = sl_Start(0, 0, 0);
        if (mode < 0)
        {
            printf("Device could not be restarted post mode change!! \n");
        }
    }
}

void AP_configuration(void)
{
    if(mode == ROLE_AP)
    {
        printf("Device successfully configured to %d mode (i.e. AP Mode) \n", mode);
    }

    if(mode == ROLE_AP)
    {

        printf("Configuring AP parameters now... \n");

        // as per response from TI post, there is no need to restart the device after every change. Hence, keeping only a single restart at the end of this if statement.
        // set device name

        status = sl_NetAppSet (SL_NETAPP_DEVICE_ID,SL_NETAPP_DEVICE_URN, strlen(device_name), (signed char*)device_name);
        if( status )
        {
            printf("Device Name Could not be Updated \n");
        }
        else
        {
            printf("Device Name Updated \n");
        }

        // set SSID for the AP

        status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SSID, strlen(SSID_NAME), (signed char*)SSID_NAME);
        if(status)
        {
            printf("SSID Could not be Updated \n");
        }
        else
        {
            printf("SSID Name Updated \n");
        }

        // set country code for AP

        status = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, (signed char*)country_code);
        if(status)
        {
            printf("Device Country Code could not be updated \n");
        }
        else
        {
            printf("Device Country Code updated \n");
        }

        // set security settings

        status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_SECURITY_TYPE, 1, (_u8 *)&SECURITY_TYPE);;

        if(status)
        {
            Display_printf(display, 0, 0, "Security Type could not be updated");
        }
        else
        {
            printf("Device Security Settings updated \n");
        }

        // set password for updated security type

        status = sl_WlanSet(SL_WLAN_CFG_AP_ID, SL_WLAN_AP_OPT_PASSWORD, strlen(SECURITY_KEY), (signed char*)SECURITY_KEY);

        if(status)
        {
            Display_printf(display, 0, 0, "Security Type could not be updated");
        }
        else
        {
            printf("Device Security Password updated \n");
        }

        // set Tx power levels => 0 dB backoff for now

        status = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_AP_TX_POWER,1,(signed char*)ApPower);

        if(status)
        {
            printf("Device power level could not be updated \n");
        }
        else
        {
            printf("Device power updated \n");
        }

        /* For changes to take affect, we restart the NWP */
        status = sl_Stop(SL_STOP_TIMEOUT);
        if (status < 0)
        {
            printf("Device could not be stopped post mode change!! \n");
        }

        mode = sl_Start(0, 0, 0);
        if (mode < 0)
        {
            printf("Device could not be restarted post mode change!! \n");
        }
        else
        {
            printf("Device restarted successfully post AP settings and mode configurations !! \n\n\n");
        }
    }
}

void config_network_parameters(void)
{

    printf("Configuring Network Parameters now... \n");

    SlNetCfgIpV4Args_t ipV4;
    ipV4.Ip = (_u32)SL_IPV4_VAL(10,1,1,200);                                // IP address
    ipV4.IpMask = (_u32)SL_IPV4_VAL(255,255,255,0);                         // Subnet mask
    ipV4.IpGateway = (_u32)SL_IPV4_VAL(10,1,1,1);                           // Default gateway address
    ipV4.IpDnsServer = (_u32)SL_IPV4_VAL(8,16,32,64);                          // _u32 DNS server address
    status = sl_NetCfgSet(SL_NETCFG_IPV4_AP_ADDR_MODE,SL_NETCFG_ADDR_STATIC,sizeof(SlNetCfgIpV4Args_t), (_u8 *)&ipV4);
    if(status)
    {
        printf("Network Parameters Could not be Updated ... \n");
    }
    else
    {
        printf("Network Parameters Updated Successfully ... \n");
    }
}

void get_device_config_parameters(void)
{
    printf("Getting device configuration parameters through get_device_config_parameters function!! \n\n");

    _u8 macAddressVal[SL_MAC_ADDR_LEN];
    _u16 macAddressLen = SL_MAC_ADDR_LEN;
    _u16 ConfigOpt1 = 0;
    sl_NetCfgGet(SL_NETCFG_MAC_ADDRESS_GET,&ConfigOpt1,&macAddressLen,(_u8 *)macAddressVal);
    printf("AP MAC address is: %02x:%02x:%02x:%02x:%02x:%02x \n ", macAddressVal[0], macAddressVal[1], macAddressVal[2], macAddressVal[3], macAddressVal[4], macAddressVal[5]);

    _u16 len = sizeof(SlNetCfgIpV4Args_t);
    _u16 ConfigOpt2 = 0;  //return value could be one of the following: SL_NETCFG_ADDR_DHCP / SL_NETCFG_ADDR_DHCP_LLA / SL_NETCFG_ADDR_STATIC
    SlNetCfgIpV4Args_t ipV4 = {0};
    sl_NetCfgGet(SL_NETCFG_IPV4_AP_ADDR_MODE,&ConfigOpt2,&len,(_u8 *)&ipV4);
    printf("DHCP is %s \n\r IP %d.%d.%d.%d \n\r MASK %d.%d.%d.%d \n\r GW %d.%d.%d.%d \n\r DNS %d.%d.%d.%d \n",
        (ConfigOpt2 == SL_NETCFG_ADDR_DHCP) ? "ON" : "OFF",
        SL_IPV4_BYTE(ipV4.Ip,3),SL_IPV4_BYTE(ipV4.Ip,2),SL_IPV4_BYTE(ipV4.Ip,1),SL_IPV4_BYTE(ipV4.Ip,0),
        SL_IPV4_BYTE(ipV4.IpMask,3),SL_IPV4_BYTE(ipV4.IpMask,2),SL_IPV4_BYTE(ipV4.IpMask,1),SL_IPV4_BYTE(ipV4.IpMask,0),
        SL_IPV4_BYTE(ipV4.IpGateway,3),SL_IPV4_BYTE(ipV4.IpGateway,2),SL_IPV4_BYTE(ipV4.IpGateway,1),SL_IPV4_BYTE(ipV4.IpGateway,0),
        SL_IPV4_BYTE(ipV4.IpDnsServer,3),SL_IPV4_BYTE(ipV4.IpDnsServer,2),SL_IPV4_BYTE(ipV4.IpDnsServer,1),SL_IPV4_BYTE(ipV4.IpDnsServer,0));

    printf("\n");
    printf("\n");
}

// ping activation
void ping_first_success(void)
{

    SlNetAppPingReport_t report;                                                    // report structure that will be available at the end of ping
    SlNetAppPingCommand_t pingCommand;
    pingCommand.Ip = SL_IPV4_VAL(10,1,1,201);                                       // destination IP address is 10.1.1.200
    pingCommand.PingSize = 150;                                                     // size of ping, in bytes
    pingCommand.PingIntervalTime = 100;                                             // delay between pings, in milliseconds
    pingCommand.PingRequestTimeout = 1000;                                          // timeout for every ping in milliseconds
    pingCommand.TotalNumberOfAttempts = 50;                                         // number of ping requests
    pingCommand.Flags = 2;                                                          // report at the end of first successful ping.
    status = sl_NetAppPing( &pingCommand, SL_AF_INET, &report, NULL );
    if (status)
    {
        printf("\n\r ~~~~~ Ping Failure!! ~~~~~");
    }
    printf("\n");

    while(report.PacketsReceived != 1) {}
}

void ping_second_confirmation(void)
{
    // This function verifies that the connection is still there and then data transfer is initiated.
    // ping_first_success function returns upon first siccessful ping. While this function sends 20 pings and ensures 90 % success before creating and connecting the socket.

    SlNetAppPingReport_t report;                                                    // report structure that will be available at the end of ping
    SlNetAppPingCommand_t pingCommand;
    pingCommand.Ip = SL_IPV4_VAL(10,1,1,201);                                       // destination IP address is 10.1.1.200
    pingCommand.PingSize = 150;                                                     // size of ping, in bytes
    pingCommand.PingIntervalTime = 100;                                             // delay between pings, in milliseconds
    pingCommand.PingRequestTimeout = 1000;                                          // timeout for every ping in milliseconds
    pingCommand.TotalNumberOfAttempts = 50;                                         // number of ping requests
    pingCommand.Flags = 0;                                                          // report at the end of first successful ping
    status = sl_NetAppPing( &pingCommand, SL_AF_INET, &report, NULL );
    if (status)
    {
        printf("\n\r ~~~~~ Ping Failure!! ~~~~~");
    }
    printf("\n");
    if(report.PacketsReceived >= 45)
    {
        printf("\n\r 90%% pings were successfully returned...");
        printf("\n\r Connection can be assumed rock solid ;) ");
        printf("\n\r Socket creation and connection can be processed now...");
        printf("\n");
    }
    else
    {
        unsigned char ping_success_rate = 0;
        ping_success_rate = ((1-((report.PacketsReceived-report.PacketsSent)/report.PacketsSent))*100);
        printf("\n \r Ping success rate is %d, reconnection shall be done before creating and connecting a socket!!", ping_success_rate);
        printf("\n");
        while(1);
    }
    flag_second_ping = 1;
}

void socket_task(void *pvParameters)
{
    long counter1 = 0;
    long counter2 = 0;
    unsigned char status_socket = 0;

    _i16 Sd;
    SlSockAddrIn_t Addr;
    _i8 SendBuf[] = "Hello from AP !!!";
    _i8 RecvBuf[1460] ={0};
    Sd = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, 0);                   // IPv4 socket (UDP, TCP, etc), UDP Packets, Null
    if( Sd < 0 )
    {
        printf("Socket opening failed!!");
    }

    Addr.sin_family = SL_AF_INET;
    Addr.sin_port = sl_Htons(5001);
    Addr.sin_addr.s_addr = SL_INADDR_ANY;                                       // bind to any address
    // Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(192,168,1,31));              // bind to this specific address only.
    status_socket = sl_Bind(Sd, ( SlSockAddr_t *)&Addr, sizeof(SlSockAddrIn_t));
    if(status_socket)
    {
        printf("\n\n\n Socket Binding failed");
    }
    else
    {
        printf("\n socket binding completed \n");
    }

    Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,1,1,201));              // connect with this specific address only.

    status_socket = sl_Connect(Sd, ( SlSockAddr_t *)&Addr, sizeof(SlSockAddrIn_t));    // address specified in this statement is the same from which the data is to be received and to which the data is to be sent.

    if(status_socket)
    {
        printf("\n\n\n Socket Connection failed");
    }

    else
    {
        printf("\n\n\n Socket Connection completed...");
    }

    while(1)
    {
        strcpy(msg1, "AP Message # ");
        ltoa(counter1, msg2, 10);
        ltoa(counter2, msg3, 10);
        strcat(msg1, msg2);
        strcat(msg1, " & ");
        strcat(msg1, msg3);

        status_socket = sl_Send(Sd, msg1, strlen(msg1), 0);

        // SL_WLAN_RATE_1M
        if( strlen(msg1) != status_socket )
        {
            printf("\n\n\n All packets could not be sent");
            printf("\n");
        }
/*
        else
        {
            printf("\n\n\n Packets sent successfully");
            printf("\n");
        }*/

        status_socket = sl_Recv(Sd, RecvBuf, 1460, 0);
        if (status < 0)
        {
            printf("\n\n\nPacket reception failed!!");
        }
        else
        {
            // printf("\n\n\n number of packets received = %d", status_socket);
            printf(" \n received messages is: %s", RecvBuf);
            // printf(" \n ");
            // printf(" \n ");
        }
        counter1++;
        if(counter1 == 50000)
        {
            // printf(" \n received messages is: %s", RecvBuf);
            // printf(" \n ");
            counter2++;
            counter1 = 0;
        }
        // strcpy(msg1, "AP Message # ");
    }

    printf("\n\n Out of socket sending and receiving infinite loop!!");
    printf("\n\n");
    while(1);
}

void mainThread(void *pvParameters)
{
    pthread_attr_t      pAttrs_spawn;
    struct sched_param  priParam;

    SPI_init();
    Display_init();
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        /* Failed to open display driver */
        while(1);
    }

    /* Start the SimpleLink Host */
    pthread_attr_init(&pAttrs_spawn);
    priParam.sched_priority = SPAWN_TASK_PRIORITY;
    status = pthread_attr_setschedparam(&pAttrs_spawn, &priParam);
    status |= pthread_attr_setstacksize(&pAttrs_spawn, TASK_STACK_SIZE);

    status = pthread_create(&spawn_thread, &pAttrs_spawn, sl_Task, NULL);
    if(status)
    {
        printError("Task create failed", status);
    }

    check_device_initial_mode();

    configure_AP_mode();

    AP_configuration();

    config_network_parameters();

    get_device_config_parameters();

    do
    {
        printf( "\n" );
        printf( "la la la la" );
        printf( "\n" );
    }while(retc !=940);

    printf( "\n" );
    printf( "out of infinite loop!!! " );
    printf( "\n" );

    ping_first_success();

    ping_second_confirmation();

    do
    {
        printf( "\n" );
        printf( "Ping Second Confirmation received..." );
        printf( "\n" );
    }while(flag_second_ping !=1);


    unsigned int retc1 = 0;
    retc1 = xTaskCreate( socket_task, /* Pointer to the function that implements the task. */
                        "Socket Task",/* Text name for the task. This is to facilitate debugging only. */
                        1024, /* Stack depth - small microcontrollers will use much less stack than this. */
                        NULL,           /* This example does not use the task parameter. */
                        4,                                  // This task will run at Maximum priority.
                        NULL );                             // This example does not use the task handle.

        if(retc1 != pdPASS)
        {
            printf("\n\n");
            printf("Socket Task Creation failed!!!");
            printf("\n\n");
            while(1)
            {
                ;
            }
        }

        if(retc1 == pdPASS)
        {
            printf("\n\n");
            printf("Socket Task Creation Succeeded !!!");
            printf("\n\n");
        }

    while(1);

}

STA_28Feb2023_main_FreeRTOS.c
/*
 *  ======== main_freertos.c ========
 */
#include <stdint.h>

/* POSIX Header files */
#include <pthread.h>

/* RTOS header files */
#include "FreeRTOS.h"
#include "task.h"

/* TI-DRIVERS Header files */
#include "ti_drivers_config.h"

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>

extern void * mainThread(void *arg0);

/* Stack size in bytes */
#define THREADSTACKSIZE   1024

/*
 *  ======== main ========
 */
int main(void)
{
    pthread_t thread;
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int retc;
    int detachState;

    // Call board init functions
    Board_init();

    /* Set priority and stack size attributes */
    pthread_attr_init(&pAttrs);
    priParam.sched_priority = 1;

    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&pAttrs, detachState);
    if(retc != 0)
    {
        /* pthread_attr_setdetachstate() failed */
        while(1)
        {
            ;
        }
    }

    pthread_attr_setschedparam(&pAttrs, &priParam);

    retc |= pthread_attr_setstacksize(&pAttrs, THREADSTACKSIZE);
    if(retc != 0)
    {
        /* pthread_attr_setstacksize() failed */
        while(1)
        {
            ;
        }
    }

    retc = pthread_create(&thread, &pAttrs, mainThread, NULL);
    if(retc != 0)
    {
        /* pthread_create() failed */
        while(1)
        {
            ;
        }
    }

    /* Start the FreeRTOS scheduler */
    vTaskStartScheduler();

    return (0);
}

void vApplicationMallocFailedHook()
{
    /* Handle Memory Allocation Errors */
    while(1)
    {
    }
}

void vApplicationStackOverflowHook(TaskHandle_t pxTask,
                                   char *pcTaskName)
{
    //Handle FreeRTOS Stack Overflow
    while(1)
    {
    }
}

void vApplicationTickHook(void)
{
}

void vPreSleepProcessing(uint32_t ulExpectedIdleTime)
{
}

void
vApplicationIdleHook(void)
{
    /* Handle Idle Hook for Profiling, Power Management etc */
}

#if defined (__GNUC__)
void * _sbrk(uint32_t delta)
{
    extern char _end;     /* Defined by the linker */
    extern char __HeapLimit;
    static char *heap_end;
    static char *heap_limit;
    char *prev_heap_end;

    if(heap_end == 0)
    {
        heap_end = &_end;
        heap_limit = &__HeapLimit;
    }

    prev_heap_end = heap_end;
    if(prev_heap_end + delta > heap_limit)
    {
        return((void *) -1L);
    }
    heap_end += delta;
    return((void *) prev_heap_end);
}

#endif

STA_28Feb2023_platform.c
#include <ti/drivers/net/wifi/simplelink.h>
#include <ti/drivers/net/wifi/slnetifwifi.h>

#include <ti/display/Display.h>

#include <ti/drivers/SPI.h>

// TI-Driver includes
#include "ti_drivers_config.h"
#include "pthread.h"

#include "FreeRTOS.h"
#include "Task.h"

#define APPLICATION_NAME                      ("UDP STA Configuration...")
#define APPLICATION_VERSION                   ("1.0.0.0")
#define DEVICE_ERROR                          ("Device error, please refer \"DEVICE ERRORS CODES\" section in errors.h")
#define WLAN_ERROR                            ("WLAN error, please refer \"WLAN ERRORS CODES\" section in errors.h")
#define SL_STOP_TIMEOUT                       (200)

#define UDPPORT 							  (1000)
#define SPAWN_TASK_PRIORITY                   (9)
#define TASK_STACK_SIZE                       (2048)
#define SLNET_IF_WIFI_PRIO                    (5)
#define SLNET_IF_WIFI_NAME                    "CC32xx"

#define SSID_NAME                             "HCTRIVEDI_AP1"                   // AP SSID to which the STA is supposed to get connected
#define SECURITY_TYPE                         SL_WLAN_SEC_TYPE_WPA_WPA2         // Security type could be SL_WLAN_SEC_TYPE_OPEN
#define SECURITY_TYPE_printf                  "SL_WLAN_SEC_TYPE_WPA_WPA2"       // Security type could be SL_WLAN_SEC_TYPE_OPEN
#define SECURITY_KEY                          "HarshAPConnect"                  // Password of the secured AP

pthread_t udpThread = (pthread_t)NULL;
pthread_t spawn_thread = (pthread_t)NULL;
int32_t             mode;
Display_Handle display;
unsigned char flag_SlWlanEvent = 0;
unsigned char flag_config_nw_parameters = 0;
unsigned char ping_status=0;
unsigned char flag_second_ping = 0;
unsigned char status = 0;


char msg1[26], msg2[6], msg3[6];

extern void echoFxn(uint32_t arg0, uint32_t arg1);
extern int32_t ti_net_SlNet_initConfig();

/*
 *  ======== printError ========
 */
void printError(char *errString, int code)
{
    Display_printf(display, 0, 0, "Error! code = %d, Description = %s\n", code,
            errString);
    while(1);
}

void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
{
    // unused in this application...
}

void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent)
{
    /* Unused in this application */
}

void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer)
{
    /* Unused in this application */
}

void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest, SlNetAppResponse_t *pNetAppResponse)
{
    /* Unused in this application */
}

void SimpleLinkHttpServerEventHandler(SlNetAppHttpServerEvent_t *pHttpEvent,
                                      SlNetAppHttpServerResponse_t *pHttpResponse)
{
    /* Unused in this application */
}

void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
{
    if(pWlanEvent == NULL)
    {
        return;
    }

    switch(pWlanEvent->Id)
    {
    case SL_WLAN_EVENT_CONNECT:
        printf("\n\n");
        printf("********************");
        printf("\n\n");
        printf("Connected to AP with following parameters:");
        printf("\n AP SSID: %s",pWlanEvent->Data.Connect.SsidName);
        printf("\n Communication Channel: %s",pWlanEvent->Data.Connect.Channel);
        printf("********************");
        flag_SlWlanEvent = 1;
        break;
    case SL_WLAN_EVENT_DISCONNECT:
        printf("\n\n");
        printf("********************");
        printf("\n\n");
        printf("Disconnected from AP with following parameters:");
        printf("\n AP SSID: %s",pWlanEvent->Data.Disconnect.SsidName);
        printf("\n Reason for Disconnection: %s",pWlanEvent->Data.Disconnect.ReasonCode);
        printf("\n\n");
        printf("********************");
        break;
    }
}

void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
{
    /* Unused in this application */
}

void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
{
    /* Unused in this application */
}

void Connect(void)
{
    SlWlanSecParams_t   secParams = {0};
    int16_t ret = 0;
    secParams.Key = (signed char*)SECURITY_KEY;
    secParams.KeyLen = strlen(SECURITY_KEY);
    secParams.Type = SECURITY_TYPE;
    printf("Connecting to : %s.\r\n",SSID_NAME);
    ret = sl_WlanConnect((signed char*)SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0);
    if (ret)
    {
        printError("Connection failed", ret);
    }
    else
    {
        printf("\n");
        printf("sl_WlanConnect function did not throw any error!! We shall wait for the SL_WLAN_EVENT_CONNECT though!!");
        printf("\n");
    }
}

void check_device_role(void)
{
    if(mode == ROLE_STA)
    {
        printf("The device is working in STA Mode ...");
        printf("\n");

    }
    else
    {
        printError("Failed to configure device to STA Role", mode);
    }
}

void config_STA_parameters(void)
{
    _u8 status = 0;                             // setup a variable to hold return values...
    // set STA Tx power level...
    _u8  stapower = 5;
    _u8  maxpower = 15;
    status = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_STA_TX_POWER,1,(_u8 *)&stapower);
    if (status != 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, status, WLAN_ERROR);
    }
    else
    {
        printf("STA Transmit power level configured successfully...");
        printf("\n");
        printf("STA Transmit power level = %d dBm", (maxpower - stapower));
        printf("\n");
    }
    // set STA Country Code...
    _u8*  str = "US";                                                       // string of 2 characters. i.e. - "US"
    status = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_COUNTRY_CODE, 2, str);
    if (status != 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, status, WLAN_ERROR);
    }
    else
    {
        printf("STA country code configured successfully...");
        printf("\n");
        printf("STA country code = %s", str);
        printf("\n");
    }
    // For changes to take affect, we restart the NWP
    status = sl_Stop(SL_STOP_TIMEOUT);
    if (status < 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, status, DEVICE_ERROR);
    }

    mode = sl_Start(0, 0, 0);
    if (mode < 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, mode, DEVICE_ERROR);
    }
}

void config_nw_parameters(void)
{
    int status_config_nw_parameters = 0;
    SlNetCfgIpV4Args_t ipV4;
    ipV4.Ip          = (_u32)SL_IPV4_VAL(10,1,1,201);            // _u32 IP address
    ipV4.IpMask      = (_u32)SL_IPV4_VAL(255,255,255,0);         // _u32 Subnet mask for this STA
    ipV4.IpGateway   = (_u32)SL_IPV4_VAL(10,1,1,1);              // _u32 Default gateway address
    ipV4.IpDnsServer = (_u32)SL_IPV4_VAL(8,16,32,64);            // _u32 DNS server address

    status_config_nw_parameters = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE,SL_NETCFG_ADDR_STATIC,sizeof(SlNetCfgIpV4Args_t),(_u8 *)&ipV4);

    if(status_config_nw_parameters >= 0)
    {
        printf("\n Network parameters configured successfully and are as follows...");
        printf("\n");
        printf("IP Address: %d.%d.%d.%d",SL_IPV4_BYTE(ipV4.Ip,3),SL_IPV4_BYTE(ipV4.Ip,2),SL_IPV4_BYTE(ipV4.Ip,1),SL_IPV4_BYTE(ipV4.Ip,0));
        printf("\n");
        printf("Subnet Mask: %d.%d.%d.%d", SL_IPV4_BYTE(ipV4.IpMask,3),SL_IPV4_BYTE(ipV4.IpMask,2),SL_IPV4_BYTE(ipV4.IpMask,1),SL_IPV4_BYTE(ipV4.IpMask,0));
        printf("\n");
        printf("Gateway: %d.%d.%d.%d", SL_IPV4_BYTE(ipV4.IpGateway,3),SL_IPV4_BYTE(ipV4.IpGateway,2),SL_IPV4_BYTE(ipV4.IpGateway,1),SL_IPV4_BYTE(ipV4.IpGateway,0));
        printf("\n");
        printf("DNS Server: %d.%d.%d.%d", SL_IPV4_BYTE(ipV4.IpDnsServer,3),SL_IPV4_BYTE(ipV4.IpDnsServer,2),SL_IPV4_BYTE(ipV4.IpDnsServer,1),SL_IPV4_BYTE(ipV4.IpDnsServer,0));
        printf("\n");
    }

    sl_Stop(0);
    sl_Start(NULL,NULL,NULL);
    flag_config_nw_parameters = 1;
}

void first_ping_attempt(void)
{
    SlNetAppPingReport_t ping1_report;
    SlNetAppPingCommand_t pingCommand;

    pingCommand.Ip = SL_IPV4_VAL(10,1,1,200);     // destination IP address is 10.1.1.200
    pingCommand.PingSize = 150;                   // size of ping, in bytes
    pingCommand.PingIntervalTime = 100;           // delay between pings, in milliseconds
    pingCommand.PingRequestTimeout = 1000;        // timeout for every ping in milliseconds
    pingCommand.TotalNumberOfAttempts = 20;       // max number of ping requests. 0 - forever
    pingCommand.Flags = 2;                        // report at the end of first successful ping

    ping_status = sl_NetAppPing( &pingCommand, SL_AF_INET, &ping1_report, NULL );

    if(ping_status)
    {
        printf("\n\r ~~~~~ Ping Failure ~~~~~");
    }
    printf("\n");
    // while(ping1_report.PacketsReceived !=1){}

}

void second_ping_attempt(void)
{
    SlNetAppPingReport_t ping2_report;
    SlNetAppPingCommand_t pingCommand;

    pingCommand.Ip = SL_IPV4_VAL(10,1,1,200);     // destination IP address is 10.1.1.200
    pingCommand.PingSize = 150;                   // size of ping, in bytes
    pingCommand.PingIntervalTime = 100;           // delay between pings, in milliseconds
    pingCommand.PingRequestTimeout = 1000;        // timeout for every ping in milliseconds
    pingCommand.TotalNumberOfAttempts = 50;       // max number of ping requests. 0 - forever
    pingCommand.Flags = 0;                        // report at the end of first successful ping

    ping_status = sl_NetAppPing( &pingCommand, SL_AF_INET, &ping2_report, NULL );

    if(ping_status)
    {
        printf("\n\r ~~~~~ Ping Failure ~~~~~");
    }
    printf("\n");
    if(ping2_report.PacketsReceived >=45)
    {
        printf("\n\n");
        printf("90%% of the ping response was positive...");
        printf("Connection can be assumed rock solid...");
        printf("Socket creation and data transfer can be initiated...");
    }
    flag_second_ping = 1;
}

void socket_task(void *pvParameters)
{
    long counter1 = 0;
    long counter2 = 0;

    _i16 Sd;
    SlSockAddrIn_t Addr;
    _i8 SendBuf[] = "Hello from STA !!!";
    _i8 RecvBuf[1460] ={0};
    Sd = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, 0);                   // IPv4 socket (UDP, TCP, etc), UDP Packets, Null
    if( Sd < 0 )
    {
        printf("Socket opening failed!!");
    }

    Addr.sin_family = SL_AF_INET;
    Addr.sin_port = sl_Htons(5001);
    Addr.sin_addr.s_addr = SL_INADDR_ANY;                                       // bind to any address
    // Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(192,168,1,31));              // bind to this specific address only.
    status = sl_Bind(Sd, ( SlSockAddr_t *)&Addr, sizeof(SlSockAddrIn_t));
    if(status)
    {
        printf("\n\n\n Socket Binding failed");
    }
    else
    {
        printf("\n socket binding completed \n");
    }

    Addr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,1,1,200));              // connect with this specific address only.

    status = sl_Connect(Sd, ( SlSockAddr_t *)&Addr, sizeof(SlSockAddrIn_t));    // address specified in this statement is the same from which the data is to be received and to which the data is to be sent.

    if(status)
    {
        printf("\n\n\n Socket Connection failed");
    }

    while(1)
    {
        strcpy(msg1, "STA Message # ");
        ltoa(counter1, msg2, 10);
        ltoa(counter2, msg3, 10);
        strcat(msg1, msg2);
        strcat(msg1, " & ");
        strcat(msg1, msg3);

        status = sl_Send(Sd, msg1, strlen(msg1), 0);
        // SL_WLAN_RATE_1M
        if( strlen(msg1) != status )
        {
            printf("\n\n\n All packets could not be sent");
        }

        status = sl_Recv(Sd, RecvBuf, 1460, 0);
        if (status < 0)
        {
            printf("\n\n\nPacket reception failed!!");
        }
        else
        {
            printf("\n\n\n number of packets received = %d", status);
            printf(" \n received messages is: %s", RecvBuf);
            // printf(" \n ");
            // printf(" \n ");
        }
        counter1++;
        if(counter1 == 50000)
        {
            // printf(" \n received messages is: %s", RecvBuf);
            // printf(" \n ");
            counter2++;
            counter1 = 0;
        }
    }
    printf("\n\n Out of infinite loop!!!");
    printf("\n\n");
}

void mainThread(void *pvParameters)
{
    int32_t             status = 0;
    pthread_attr_t      pAttrs_spawn;
    struct sched_param  priParam;

    SPI_init();
    Display_init();
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL) {
        /* Failed to open display driver */
        while(1);
    }

    /* Start the SimpleLink Host */
    pthread_attr_init(&pAttrs_spawn);
    priParam.sched_priority = SPAWN_TASK_PRIORITY;
    status = pthread_attr_setschedparam(&pAttrs_spawn, &priParam);
    status |= pthread_attr_setstacksize(&pAttrs_spawn, TASK_STACK_SIZE);

    status = pthread_create(&spawn_thread, &pAttrs_spawn, sl_Task, NULL);
    if(status)
    {
        printError("Task create failed", status);
    }

    /* Turn NWP on - initialize the device*/
    mode = sl_Start(0, 0, 0);
    if (mode < 0)
    {
        Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, mode, DEVICE_ERROR);
    }

    switch(mode)
    {
    case 0:
        printf("\n");
        printf("Role = STA i.e. Station");
        printf("\n");
        break;
    case 1:
        printf("Role = Reserved");
        printf("\n");
        break;
    case 2:
        printf("Role = AP i.e. Access Point");
        printf("\n");
        break;
    case 3:
        printf("Role = P2P i.e. WiFi Direct");
        printf("\n");
        break;
    case 4:
        printf("Role = Role_Tag i.e. Mane pan nathi khabar aa to...");
        printf("\n");
        break;
    default:
        printf("Somthing went wrong... No such role defined at SimpleLink Level");
        printf("\n");
    }

    if(mode != ROLE_STA)
    {
        /* Set NWP role as STA */
        mode = sl_WlanSetMode(ROLE_STA);
        if (mode != 0)
        {
            Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, mode, WLAN_ERROR);
        }

        /* For changes to take affect, we restart the NWP */
        status = sl_Stop(SL_STOP_TIMEOUT);
        if (status < 0)
        {
            Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, status, DEVICE_ERROR);
        }

        mode = sl_Start(0, 0, 0);
        if (mode < 0)
        {
            Display_printf(display, 0, 0,"\n\r[line:%d, error code:%d] %s\n\r", __LINE__, mode, DEVICE_ERROR);
        }
    }

    check_device_role();                    // check device role after configuration..

    config_STA_parameters();                // configure STA parameters and restart the device at the end of configuration for the changes to take place

    check_device_role();                    // check device role after configuration...

    config_nw_parameters();                 // configure network parameters like IP Address, Gateway, Submetmask etc...

    Connect();

    printf("returned after connection attempt!!");
    printf("\n");

    while(flag_SlWlanEvent != 1)
    {
        unsigned int timer1 = 0;
        printf("Waiting for STA to get connected to proposed AP");
        while(timer1 != 64000)
        {
            timer1++;
        }
        printf("\n");
    }

    printf("\n\n");
    printf("********************");
    printf("\n\n");
    printf("Connection done successfully... Attempting Ping to AP...");
    printf("********************");
    printf("\n\n");

    first_ping_attempt();

    second_ping_attempt();

    do
    {
        printf("\n Second ping confirmation received... Awaiting socket creation...");
    }while(flag_second_ping != 1);


    unsigned int retc1 = 0;
    retc1 = xTaskCreate( socket_task, /* Pointer to the function that implements the task. */
                         "Socket Task",/* Text name for the task. This is to facilitate debugging only. */
                         1024, /* Stack depth - small microcontrollers will use much less stack than this. */
                         NULL,           /* This example does not use the task parameter. */
                         4,                                  // This task will run at Maximum priority.
                         NULL );                             // This example does not use the task handle.

    if(retc1 != pdPASS)
    {
        printf("\n\n");
        printf("Socket Task Creation failed!!!");
        printf("\n\n");
        while(1)
        {
            ;
        }
    }

    if(retc1 == pdPASS)
    {
        printf("\n\n");
        printf("Socket Task Creation Succeeded !!!");
        printf("\n\n");
    }

    while(1);


}

Please let me know if any other information is required on this from my side.

Regards,

H C Trivedi

  • Along with above mentioned queries, I've one more query as follows:

    Can I replace spawn_thread with FreeRTOS task? If yes, how? 

    Regards,

    H C Trivedi

  • Hi,

    I suggest you take a look at the examples in the SDK.

    Specifically, you can look in the network_terminal example for UDP or TCP client and server.

    In your code, it seems like you are using UDP (any reason for it?) and not TCP which is more reliable. Also, socket_connect() is usually used in TCP. This is why I am asking.

    The claim that you cannot do the complete 50000 cycles implies a crash. Can you debug your application and detect where/when it happens?

    Seems like your socket task() has 2048 bytes of stack size whereas you defined a receive buffer of 1460 bytes (and there are more variables and calls). It is best if you can move the receive buffer outside the function or at least increase the stack size so you don't get a stack overflow.

    Regards,

    Shlomi

  • Thanks for the prompt response Shlomi...

    I suggest you take a look at the examples in the SDK.

    I've already referred to the example provided in the SDK for UDP Echo. The changes with respect to the example is as follows:

    • The entire example is based on POSIX Threads. I've modified most of them as FreeRTOS Tasks. 
    • The example used BSD sockets, whereas I'm using simplelink sockets.
    • The example implements Echo task that echos back the packets received. I'm generating my own counter and transmitting the data.
    In your code, it seems like you are using UDP (any reason for it?) and not TCP which is more reliable. Also, socket_connect() is usually used in TCP. This is why I am asking.

    I want to use UDP protocol as the end application I'm considering is Video transmission. And socket_connect() function is because I'm using connection oriented UDP protocol as specified in TI's doc SWRU455. Hence, instead of using sendto, I'm using send command. 

    The claim that you cannot do the complete 50000 cycles implies a crash. Can you debug your application and detect where/when it happens?

    How do I debug? I tried running the code 4 times. After posting this query, when I ran the code for the forth time, it went upto 5990 value. Then it switched back to main_thread and stayed there at while(1) statement. My socket_task has a priority higher to that of main_thread. In such case, it should logically not switch back to main_thread unless vTaskDelay kindly of thing happens. Is that correct?

    Seems like your socket task() has 2048 bytes of stack size whereas you defined a receive buffer of 1460 bytes (and there are more variables and calls). It is best if you can move the receive buffer outside the function or at least increase the stack size so you don't get a stack overflow.

    I'll give it a shot and let you know, whether increasing the stack size makes a difference or not. If yes, the how much.

    Along with above mentioned queries, I've one more query as follows:

    Can I replace spawn_thread with FreeRTOS task? If yes, how? 

    Also, do you have any idea on this?

    Regards,

    H C Trivedi

  • I'll give it a shot and let you know, whether increasing the stack size makes a difference or not. If yes, the how much.

    hello Shlomi,

    I tried increasing the stack size to 4096 for socket_task and checked the results. The counter value went up to 7900 and then it switched back to main_thread. Do you still think that stacksize is still a problem?

  • Hi,

    Hard to tell what could cause the application to stop working and where it is stuck.

    Stack size of 4096 bytes should be enough so I wouldn't go this way.

    In order to know how to debug and where it is stuck, I would run with IDE step by step and see when it is getting stuck (and what is the call stack when it happens).

    It is a little harder to debug with freeRTOS (with TIRTOS you have ROV to better debug).

    Shlomi

  • Hello Shlomi,

    I already checked going step by step while the code was running. However, the behaviour is completely random! Sometimes is stops at 512 message transmission, sometimes at 9970, sometimes 5990 etc etc. I also wrote code for various Hooks provided by FreeRTOS so that I can debug if something is there. However, it also did not help.

    I also tried one more thing. I created a queue using FreeRTOS. Passed values to the queue from a task and fetched the value in socket task. This also resulted in the same. After a while the task execution stops and returns to the main thread while(1) statement. I simply do not understand what causes the tasks to return to the main thread. 

    Can you please suggest some workaround?

    Regards,

    H C Trivedi

  • Hi,

    I cannot explain why it leaves the while(1) without debugging.

    have you modified the stack size on both sides (station and AP)?

    maybe just for the test see what happens if you move to TCP or even work uni-directional, i.e. one side is only sending and the other side receiving.

    Regards,

    Shlomi

  • Hello Shlomi,

    Yes, I've modified the stack size on AP as well as STA sides.

    maybe just for the test see what happens if you move to TCP or even work uni-directional, i.e. one side is only sending and the other side receiving.

    Well Said. I'll try that.

    Regards,

    H C Trivedi

  • and you mentioned that it goes out to the wile(1) of the main thread, does it print the "Out of infinite loop" on the socket thread for example? I am trying to understand whether you leave the task gracefully (and by order) or the task just crashes for some reason with no tracks that make sense in any way.

  • does it print the "Out of infinite loop" on the socket thread for example?

    Hello Shlomi, it does not print "Out of socket sending and receiving infinite loop!!" It directly switches to the main thread.

  • At least in terms of task priority, seems like it is OK as the socket_task has priority 4 which is higher than 1 for the main_thread.

    In this case, either the task crashed (memory overrun or other reasons) or it is still running but not getting time slot.

    I can see on freeRTOSconfig.h that INCLUDE_eTaskGetState is set so maybe you can ask for the task state (you need to look into the freertos documentation).

    You can start by setting the INCLUDE_xTaskGetSchedulerState to 1 and then you have xTaskGetSchedulerState that is used in the code so maybe you can use it to get the state.

    Shlomi

  • I can see on freeRTOSconfig.h that INCLUDE_eTaskGetState is set so maybe you can ask for the task state (you need to look into the freertos documentation).

    You can start by setting the INCLUDE_xTaskGetSchedulerState to 1 and then you have xTaskGetSchedulerState that is used in the code so maybe you can use it to get the state.

    I'll try to incorporate this and let you know. 

    Also, I tried transmission only (and left reception portion commented), and it worked. I can share the code for your reference here if you wish to have a look. 

    Also, by any chance do you have any idea on how to incorporate FreeRTOS plus TCP library into CCS workspace? I went through some of FreeRTOS based UDP implementation and socket tasks implementation there seems to be much simpler. They use sl_recv equivalent function in blocking mode. Hence task execution becomes much simpler. 

    Thanks

    H C Trivedi

  • OK, thanks. let me know.

    Strange that TX only worked. Since RX is by default in blocking mode, it means that if the other side does not transmit, then the task should be waiting on the sl_Recv() call.

    One other experiment you can do is working in non-blocking so if there is nothing waiting on sl_Recv(), you should get an error EAGAIN and then call again for sl_Recv() and in this way the task would always execute when it gets time.

    Not sure about the last question.

    Shlomi

  • hello Shlomi,

    I think my code worked. It now transmits and receives continuously, simultaneously. 

    I'm still not clear about how to implement MCS (modulation and coding techniques) and configuration of data rates for transmission and reception. Can you please help?

    Regards,

    H C Trivedi

  • Hi,

    Can you elaborate what you mean exactly?

    Do you mean a way to control the Wi-Fi MCS rates (like MCS0-MCS7)?

    If this is the case, there is no way to control it since it is automatically set as part of the rate adaptation in the firmware (according to link conditions, retransmissions, etc).

    Shlomi

  • hello  Shlomi,

    Do you mean a way to control the Wi-Fi MCS rates (like MCS0-MCS7)?

    Yes, I meant exactly the same. 

    If this is the case, there is no way to control it since it is automatically set as part of the rate adaptation in the firmware (according to link conditions, retransmissions, etc).

    I think this refers to the throughput. But initially you should be able to set modulation scheme and information rate in line with 802.11 b/g/n protocols. Once you configure the device pertaining to a protocol and MCS, that should define the base information rate. Based on environmental conditions, link conditions and other parameters, information rate shall vary (and is less than what we have set initially).

    for reference:

    https://community.cisco.com/t5/wireless-mobility-knowledge-base/802-11ac-mcs-rates/ta-p/3155920

    https://d2cpnw0u24fjm4.cloudfront.net/wp-content/uploads/MCS-Index-802.11n-and-802.11ac.pdf

    Also, in simplelink Socket API, there are some Enums defined such as SL_SOCK_TX_RATE_1M and many other. 

    Regards,

    H C Trivedi

  • Hi,

    I know the MCS rates but it doesn't mean we have an API to mandate a specific rate.

    the define you are talking about is if you bypass the Wi-Fi MAC layer and work directly on top of the Wi-Fi radio (transceiver mode) and then you can control the specific rate.

    But this is not in operational mode when you are connected to an AP.

    Shlomi

  • hello Shlomi,

    is this feature not available even when my CC3235 itself is an AP?

    BR

    H C Trivedi

  • Hi,

    Unfortunately it does not exist. Even in Linux you can choose in general 11n/11a, yes/no but not specific rates.

    Shlomi

  • Hello,

    So in case of wireless video communication system, where CC3235 is receiving data from camera at 1Mbps rate and if it transmits wirelessly at some other rate, then would there not be any problem?

    Trivedi

  • Hi Trivedi,

    If WiFi together with the current UDP throughput will be higher than 1 Mbps, than all will be OK. But if throughput  will be lower, it will not work.

    Of course client (software) which read video stream from CC3235 need to have own buffer. For video streaming at local network is better to use UDP and maybe even UDP multicast in case of multiple clients. RTP  is commonly used.

    Jan

  • Hello Jane,

    I'm using UDP protocol based streaming only and the client is also CC3235 only. If i keep both the devices in an an-echoic chamber, at a distance of 1m in Line-of-Sight, will I be able to predict/measure/calculate approximate information rate / throughput? 

    Trivedi

  • Hi Trivedi,

    Sure. You know how much data did you sent via UDP and what is sending interval. But better is to do measurement at client side.

    Jan

  • I'm sorry Jan, I still did not understand. Let me explain what I've done.

    1. I configured one CC3235 as AP and another as STA. 
    2. Then I created two FreeRTOS Task that runs one-by-one. Transmit task transmits the counter (as of now) to the STA and the Receive Task receives the message transmitted by STA.
    3. After sending let's say 50 counts, I introduce vTaskDelay(500). This will introduce 500 ticks worth of delay to the transmit task execution.

    In this scenario,

    1. How do I calculate the throughput?
    2. How do I carryout measurements on the client / STA side?

    Regards,

    Trivedi

  • Hi Trivedi,

    You know how many bytes you sent (server side) or you are received (at client side). You know interval how long it takes (time between fist and last packet).  Form this you can calculate throughput. In case of measurement at client side you can calculate packet lost rate if your UDP packets have some kind of packet ID (packet number).

    Jan