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.

CC3200-LAUNCHXL: Getting WiFi working with FreeRTOS and no heap

Part Number: CC3200-LAUNCHXL
Other Parts Discussed in Thread: CC3200

I am working with the CC3220 launchpad and I am trying to join a WiFi network. The network uses WPA authorization and IPv4. The project is running FreeRTOS and has no heap, also we are using SPI to communicate with the NWP. So far this is what we are trying to do:

#define EMERGE_SSID "our_name"

#define EMERGE_PASSWORD "our_password"

//Initialize SPI to communicate with the network processor
SPI_init();

uint8_t ssid_length = strlen(EMERGE_SSID);
uint8_t password_length = strlen(EMERGE_PASSWORD);
char ssid[ssid_length] = EMERGE_SSID;
char password[password_length] = EMERGE_PASSWORD;

memset(&connect_parameters, 0x0, sizeof(ConnectCmdType));

//Set the SSID and security parameters for the network we are going to join
connect_parameters.ssid = (uint8_t*) ssid;
connect_parameters.secParams.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;
connect_parameters.secParams.KeyLen = password_length;
connect_parameters.secParams.Key = (int8_t*) password;

app_CB.Status = 0;
app_CB.Role = ROLE_RESERVED;
app_CB.Exit = FALSE;

memset(&app_CB.CmdBuffer, 0x0, CMD_BUFFER_LEN);
memset(&app_CB.gDataBuffer, 0x0, sizeof(app_CB.gDataBuffer));
memset(&app_CB.CON_CB, 0x0, sizeof(app_CB.CON_CB));

ret_val = sem_init(&app_CB.CON_CB.connectEventSyncObj, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.CON_CB.eventCompletedSyncObj, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.CON_CB.ip4acquireEventSyncObj, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.CON_CB.ip6acquireEventSyncObj, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

memset(&app_CB.P2P_CB, 0x0, sizeof(app_CB.P2P_CB));

ret_val = sem_init(&app_CB.P2P_CB.DeviceFound, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.P2P_CB.RcvConReq, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.P2P_CB.RcvNegReq, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

ret_val = sem_init(&app_CB.WowlanSleepSem, 0, 0);
if (ret_val != 0)
{
FW_ASSERT(1);
}

pthread_attr_init(&pAttrs_spawn);
priParam.sched_priority = WIFI_SPAWN_PRIORITY;
ret_val = pthread_attr_setschedparam(&pAttrs_spawn, &priParam);
FW_ASSERT(ret_val == 0);

ret_val = pthread_attr_setdetachstate(&pAttrs_spawn, PTHREAD_CREATE_DETACHED);
FW_ASSERT(ret_val == 0);

ret_val = pthread_create_static(&gSpawn_thread, &pAttrs_spawn, sl_Task, NULL);
FW_ASSERT(ret_val == 0);

ret_val = sl_Start(0, 0, 0);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanSetMode(ROLE_STA);
FW_ASSERT(ret_val == 0);

ret_val = sl_Stop(SL_STOP_TIMEOUT);
FW_ASSERT(ret_val == 0);

ret_val = sl_Start(0, 0, 0);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanPolicySet(SL_WLAN_POLICY_CONNECTION, SL_WLAN_CONNECTION_POLICY(1, 0, 0, 0), NULL, 0);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanProvisioning(SL_WLAN_PROVISIONING_CMD_STOP, 0xFF, 0, NULL, 0x0);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanProfileDel(0xFF);
FW_ASSERT(ret_val == 0);

ret_val = sl_NetCfgSet(SL_NETCFG_IPV4_STA_ADDR_MODE, SL_NETCFG_ADDR_DHCP, 0, 0);
FW_ASSERT(ret_val == 0);

IfBitmap = !(SL_NETCFG_IF_IPV6_STA_LOCAL | SL_NETCFG_IF_IPV6_STA_GLOBAL);
ret_val = sl_NetCfgSet(SL_NETCFG_IF, SL_NETCFG_IF_STATE, sizeof(IfBitmap), (const unsigned char *)&IfBitmap);
FW_ASSERT(ret_val == 0);

ScanDefault.ChannelsMask = CHANNEL_MASK_ALL;
ScanDefault.RssiThreshold = RSSI_TH_MAX;
ret_val = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_SCAN_PARAMS, sizeof(ScanDefault), (uint8_t *)&ScanDefault);
FW_ASSERT(ret_val == 0);

ucConfigOpt = SL_WLAN_SCAN_POLICY(0, 0);
ret_val = sl_WlanPolicySet(SL_WLAN_POLICY_SCAN, ucConfigOpt, NULL, 0);
FW_ASSERT(ret_val == 0);

ucPower = 0;
ret_val = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, SL_WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (uint8_t *)&ucPower);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanPolicySet(SL_WLAN_POLICY_PM, SL_WLAN_NORMAL_POLICY, NULL, 0);
FW_ASSERT(ret_val == 0);

ret_val = sl_NetAppMDNSUnRegisterService(0, 0, 0);
FW_ASSERT(ret_val == 0);

memset(RxFilterIdMask.FilterBitmap, 0xFF, 8);
ret_val = sl_WlanSet(SL_WLAN_RX_FILTERS_ID, SL_WLAN_RX_FILTER_REMOVE, sizeof(SlWlanRxFilterOperationCommandBuff_t), (uint8_t *)&RxFilterIdMask);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanSetMode(ROLE_STA);
FW_ASSERT(ret_val == 0);

ret_val = sl_Stop(SL_STOP_TIMEOUT);
FW_ASSERT(ret_val == 0);

ret_val = sl_Start(0, 0, 0);
FW_ASSERT(ret_val == 0);

app_CB.Role = ROLE_STA;
SET_STATUS_BIT(app_CB.Status, STATUS_BIT_NWP_INIT);

ret_val = sl_Stop(SL_STOP_TIMEOUT);
FW_ASSERT(ret_val == 0);

ret_val = sl_Start(0, 0, 0);
FW_ASSERT(ret_val == 0);

ret_val = sl_WlanConnect((const signed char *)connect_parameters.ssid, strlen((const char *)(connect_parameters.ssid)), 0, &connect_parameters.secParams, 0);
FW_ASSERT(ret_val == 0);

We also have defined the following callback functions:

void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent);

void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent);

void SimpleLinkHttpServerEventHandler( SlNetAppHttpServerEvent_t *pHttpEvent, SlNetAppHttpServerResponse_t *pHttpResponse);

void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent);

void SimpleLinkSockEventHandler(SlSockEvent_t *pSock);

void SimpleLinkFatalErrorEventHandler(SlDeviceFatal_t *slFatalErrorEvent);

void SimpleLinkNetAppRequestEventHandler(SlNetAppRequest_t *pNetAppRequest, SlNetAppResponse_t *pNetAppResponse);

void SimpleLinkNetAppRequestMemFreeEventHandler(uint8_t *buffer);

When we call this code, nothing seems to happen. Our status never changes and none of the callbacks are ever called. Are we missing a step in the initialization process, or is there something else happening that is preventing us from properly joining a network?

Thank you! Charles

  • Hi Charles,

    You general approach seems okay assuming your definitions for the event handlers are similar to the ones in our examples. I would recommend halting the application during a debug session to see where the application is stuck hanging.

    However, to ensure there aren't some issues in your specific code, can you test the connection to this AP using one of the out-of-the-box examples from our SDK?

    For example, the power_measurement or httpget demos will connect based on a statically defined profile. Try dropping your SSID, password, and security type into one of these examples and see if the system connects.

    Also, please confirm that you are working with a 2.4GHz network. Only the CC3x35x devices support 5GHz.

    Best Regards,
    Ben M
  • Hey Ben,

    The code isn't actually hanging anywhere. It gets through all of that just fine, but it never calls any of the callbacks and it doesn't seem to connect. I will try out the network_terminal example I have and let you know if I can get that working on our network. Also, it is definitely a 2.4GHz network we are connecting to. I am realizing that I think I put the wrong board, it looks like we are actually using a CC3220 launchpad, not a CC3200.

    Thanks again!
    Charles
  • Update: So I ran the network_terminal example and still was unable to join the network.
    I typed:
    wlanconnect -s "our_ssid" -t WPA/WPA2 -p "our_password"
    And it responded with:
    [WLAN ERROR] Device disconnected from the AP:
    BSSID: 0:0:0:0:0:0
    [wlanconnect] : Failed to connect to AP: our_ssid

    It seems odd that it is disconnecting from the AP when it doesn't seem to ever connect.

    Thanks again!
    Charles

  • Hi Charles,

    This isn't an enterprise network, is it?

    Best,
    Ben M
  • Hey Ben,

    It is not an enterprise network. I actually got the network_terminal example working using that network (someone changed the password) and using my phone's network as a hotspot. I still can't connect to either using my application, though.

    Thanks!

    Charles

  • Hi Charles,

    Ah, good. Can you show me what your SimpleLinkWlanEventHandler and SimpleLinkNetAppEventHandler are (roughly) defined as?

    Best,
    Ben M
  • Hey Ben,

    Yup, here they are:

    ///////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief This handler gets called whenever a WLAN event is reported by the host driver/NWP
    ///
    /// @param[in] pWlanEvent - Pointer to Wlan event data.
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
    {
    if (!pWlanEvent)
    {
    return;
    }

    switch (pWlanEvent->Id)
    {
    case SL_WLAN_EVENT_CONNECT:
    {
    SET_STATUS_BIT(app_CB.Status, STATUS_BIT_CONNECTION);

    // Copy new connection SSID and BSSID to global parameters
    memcpy(app_CB.CON_CB.ConnectionSSID, pWlanEvent->Data.Connect.SsidName,
    pWlanEvent->Data.Connect.SsidLen);
    memcpy(app_CB.CON_CB.ConnectionBSSID, pWlanEvent->Data.Connect.Bssid,
    SL_WLAN_BSSID_LENGTH);

    //TODO: ChARLES post connection indication

    sem_post(&app_CB.CON_CB.connectEventSyncObj);
    break;
    }
    case SL_WLAN_EVENT_DISCONNECT:
    {
    CLR_STATUS_BIT(app_CB.Status, STATUS_BIT_CONNECTION);
    CLR_STATUS_BIT(app_CB.Status, STATUS_BIT_IP_ACQUIRED);
    CLR_STATUS_BIT(app_CB.Status, STATUS_BIT_IPV6_ACQUIRED);

    // If ping operation is running, release it.
    if (IS_PING_RUNNING(app_CB.Status))
    {
    sem_post(&app_CB.CON_CB.eventCompletedSyncObj);
    }

    memset(&(app_CB.CON_CB.ConnectionSSID), 0x0, sizeof(app_CB.CON_CB.ConnectionSSID));
    memset(&(app_CB.CON_CB.ConnectionBSSID), 0x0,
    sizeof(app_CB.CON_CB.ConnectionBSSID));

    //TODO: ChARLES post disconnection indication

    break;
    }
    case SL_WLAN_EVENT_PROVISIONING_STATUS:
    {
    // Do nothing, this suppress provisioning event is because
    // simplelink is configured to default state.
    break;
    }
    case SL_WLAN_EVENT_STA_ADDED:
    {
    memcpy(&(app_CB.CON_CB.ConnectionBSSID), pWlanEvent->Data.STAAdded.Mac,
    SL_WLAN_BSSID_LENGTH);
    break;
    }
    case SL_WLAN_EVENT_STA_REMOVED:
    {
    memcpy(&(app_CB.CON_CB.ConnectionBSSID), pWlanEvent->Data.STAAdded.Mac,
    SL_WLAN_BSSID_LENGTH);
    memset(&(app_CB.CON_CB.ConnectionBSSID), 0x0, sizeof(app_CB.CON_CB.ConnectionBSSID));
    break;
    }
    case SL_WLAN_EVENT_RXFILTER:
    {
    // Do nothing
    break;
    }
    case SL_WLAN_EVENT_P2P_DEVFOUND:
    {
    sem_post(&(app_CB.P2P_CB.DeviceFound));
    break;
    }
    case SL_WLAN_EVENT_P2P_REQUEST:
    {
    memset(&(app_CB.P2P_CB.p2pPeerDeviceName), '\0',
    sizeof(app_CB.P2P_CB.p2pPeerDeviceName));
    memcpy(&app_CB.P2P_CB.p2pPeerDeviceName, pWlanEvent->Data.P2PRequest.GoDeviceName,
    pWlanEvent->Data.P2PRequest.GoDeviceNameLen);

    sem_post(&app_CB.P2P_CB.RcvNegReq);
    break;
    }
    case SL_WLAN_EVENT_P2P_CONNECT:
    {
    sem_post(&app_CB.P2P_CB.RcvConReq);
    break;
    }
    case SL_WLAN_EVENT_P2P_CLIENT_ADDED:
    {
    sem_post(&app_CB.P2P_CB.RcvConReq);
    break;
    }
    case SL_WLAN_EVENT_P2P_DISCONNECT:
    {
    CLR_STATUS_BIT(app_CB.Status, STATUS_BIT_CONNECTION);
    break;
    }
    default:
    {
    // We shouldn't get here
    FW_ASSERT(1);
    break;
    }
    }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief This handler gets called whenever a Netapp event is reported by the host driver/NWP
    ///
    /// @param[in] pNetAppEvent - Pointer to Netapp event data.
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
    {
    if (!pNetAppEvent)
    {
    return;
    }

    switch (pNetAppEvent->Id)
    {
    case SL_NETAPP_EVENT_IPV4_ACQUIRED:
    {
    SlIpV4AcquiredAsync_t *pEventData = NULL;

    SET_STATUS_BIT(app_CB.Status, STATUS_BIT_IP_ACQUIRED);

    // Ip Acquired Event Data
    pEventData = &pNetAppEvent->Data.IpAcquiredV4;
    app_CB.CON_CB.IpAddr = pEventData->Ip;

    // Gateway IP address
    app_CB.CON_CB.GatewayIP = pEventData->Gateway;

    //TODO: CHARLES send event SWIFI_AP_CONNECTED_IND

    sem_post(&(app_CB.CON_CB.ip4acquireEventSyncObj));
    break;
    }
    case SL_NETAPP_EVENT_IPV6_ACQUIRED:
    {
    uint32_t i = 0;

    SET_STATUS_BIT(app_CB.Status, STATUS_BIT_IPV6_ACQUIRED);

    for (i = 0; i < 4; i++)
    {
    app_CB.CON_CB.Ipv6Addr[i] = pNetAppEvent->Data.IpAcquiredV6.Ip[i];
    }

    //TODO: CHARLES send event SWIFI_AP_CONNECTED_IND

    sem_post(&app_CB.CON_CB.ip6acquireEventSyncObj);
    break;
    }
    case SL_NETAPP_EVENT_DHCPV4_LEASED:
    {
    SET_STATUS_BIT(app_CB.Status, STATUS_BIT_IP_LEASED);
    SET_STATUS_BIT(app_CB.Status, STATUS_BIT_IP_ACQUIRED);

    app_CB.CON_CB.StaIp = pNetAppEvent->Data.IpLeased.IpAddress;

    sem_post(&(app_CB.CON_CB.ip4acquireEventSyncObj));
    break;
    }
    case SL_NETAPP_EVENT_DHCPV4_RELEASED:
    {
    // Do nothing
    break;
    }
    default:
    {
    // We shouldn't get here
    FW_ASSERT(1);
    break;
    }
    }
    }

    We don't seem to ever hit them though, so I think something in the initialization process is going wrong.

    Thanks!
    Charles
  • Charles,

    These look okay. Then it is most likely something going on with the fact that you are using no-heap and creating the sl_Task() thread with pthread_create_static(). I'm not certain what yet, but that task is critical in the process of receiving the asynchronous events from the NWP and feeding the indications to the handlers.

    Can you verify that assumption?

    Thanks,
    Ben M
  • Hey Ben,

    Sorry for the slow response, we got a little bit sidetracked. We ended up getting this working by just enabling a heap. It seems like there was an issue trying to do everything statically, but we didn't have time to try and fix it so we decided we could add a heap.

    We did have one mistake in the code that I posted as well. We weren't properly setting the strings for the SSID or password. We switched to using this:

    static const uint8_t kSsidDefault[] = {'O','U','R','S','S','I','D'};
    static const char kPwdDefault[] = {'O','U','R','P','W','D'};

    uint8_t ssid_length = sizeof(kSsidDefault);

    uint8_t password_length = sizeof(kPwdDefault);

    memcpy(ssid, kSsidDefault, ssid_length);
    memcpy(password, kPwdDefault, password_length);
    memset(&connect_parameters, 0x0, sizeof(ConnectCmdType));

    //Set the SSID and security parameters for the network we are going to join
    connect_parameters.ssid = (uint8_t*) ssid;
    connect_parameters.sec_params.Type = SL_WLAN_SEC_TYPE_WPA_WPA2;
    connect_parameters.sec_params.KeyLen = password_length;
    connect_parameters.sec_params.Key = (int8_t*) password;

    Thanks for the help!