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'm making some test with the example code for simplelink SDK 1.3 to learn how to work with this device, but the execution of the TCP socket example is not working.
It seems it's blocked somewhere because debugging it stops here:
and the output is strange, printing two times instead of once:
I didn't change the code from the original version and other examples are working fine, so I don't understand what is going on or if I'm doing something wrong.
I'll copy the example code down here:
/* * main.c - TCP socket sample application * * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ * * * 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. * */ /* * Application Name - TCP socket * Application Overview - This is a sample application demonstrating how to open * and use a standard TCP socket with CC3100. * Application Details - processors.wiki.ti.com/.../CC31xx_TCP_Socket_Application * doc\examples\tcp_socket.pdf */ #include "simplelink.h" #include "sl_common.h" #define APPLICATION_VERSION "1.3.0" #define SL_STOP_TIMEOUT 0xFF /* IP addressed of server side socket. Should be in long format, * E.g: 0xc0a8010a == 192.168.1.10 */ #define IP_ADDR 0xc0a80166 #define PORT_NUM 5001 /* Port number to be used */ #define BUF_SIZE 1400 #define NO_OF_PACKETS 1000 /* Application specific status/error codes */ typedef enum{ DEVICE_NOT_IN_STATION_MODE = -0x7D0, /* Choosing this number to avoid overlap w/ host-driver's error codes */ TCP_SEND_ERROR = DEVICE_NOT_IN_STATION_MODE - 1, TCP_RECV_ERROR = TCP_SEND_ERROR -1, STATUS_CODE_MAX = -0xBB8 }e_AppStatusCodes; /* * GLOBAL VARIABLES -- Start */ union { _u8 BsdBuf[BUF_SIZE]; _u32 demobuf[BUF_SIZE/4]; } uBuf; _u8 g_Status = 0; /* * GLOBAL VARIABLES -- End */ /* * STATIC FUNCTION DEFINITIONS -- Start */ static _i32 configureSimpleLinkToDefaultState(); static _i32 establishConnectionWithAP(); static _i32 initializeAppVariables(); static _i32 BsdTcpClient(_u16 Port); static _i32 BsdTcpServer(_u16 Port); static void displayBanner(); /* * STATIC FUNCTION DEFINITIONS -- End */ /* * ASYNCHRONOUS EVENT HANDLERS -- Start */ /*! \brief This function handles WLAN events \param[in] pWlanEvent is the event passed to the handler \return None \note \warning */ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) { if(pWlanEvent == NULL) { CLI_Write(" [WLAN EVENT] NULL Pointer Error \n\r"); return; } switch(pWlanEvent->Event) { case SL_WLAN_CONNECT_EVENT: { SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); /* * Information about the connected AP (like name, MAC etc) will be * available in 'slWlanConnectAsyncResponse_t' - Applications * can use it if required * * slWlanConnectAsyncResponse_t *pEventData = NULL; * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; * */ } break; case SL_WLAN_DISCONNECT_EVENT: { slWlanConnectAsyncResponse_t* pEventData = NULL; CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected; /* If the user has initiated 'Disconnect' request, 'reason_code' is * SL_USER_INITIATED_DISCONNECTION */ if(SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION == pEventData->reason_code) { CLI_Write(" Device disconnected from the AP on application's request \n\r"); } else { CLI_Write(" Device disconnected from the AP on an ERROR..!! \n\r"); } } break; default: { CLI_Write(" [WLAN EVENT] Unexpected event \n\r"); } break; } } /*! \brief This function handles events for IP address acquisition via DHCP indication \param[in] pNetAppEvent is the event passed to the handler \return None \note \warning */ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) { if(pNetAppEvent == NULL) { CLI_Write(" [NETAPP EVENT] NULL Pointer Error \n\r"); return; } switch(pNetAppEvent->Event) { case SL_NETAPP_IPV4_IPACQUIRED_EVENT: { SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED); /* * Information about the connection (like IP, gateway address etc) * will be available in 'SlIpV4AcquiredAsync_t' * Applications can use it if required * * SlIpV4AcquiredAsync_t *pEventData = NULL; * pEventData = &pNetAppEvent->EventData.ipAcquiredV4; * */ } break; default: { CLI_Write(" [NETAPP EVENT] Unexpected event \n\r"); } break; } } /*! \brief This function handles callback for the HTTP server events \param[in] pHttpEvent - Contains the relevant event information \param[in] pHttpResponse - Should be filled by the user with the relevant response information \return None \note \warning */ void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse) { /* Unused in this application */ CLI_Write(" [HTTP EVENT] Unexpected event \n\r"); } /*! \brief This function handles general error events indication \param[in] pDevEvent is the event passed to the handler \return None */ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) { /* * Most of the general errors are not FATAL are are to be handled * appropriately by the application */ CLI_Write(" [GENERAL EVENT] \n\r"); } /*! \brief This function handles socket events indication \param[in] pSock is the event passed to the handler \return None */ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) { if(pSock == NULL) { CLI_Write(" [SOCK EVENT] NULL Pointer Error \n\r"); return; } switch( pSock->Event ) { case SL_SOCKET_TX_FAILED_EVENT: /* * TX Failed * * Information about the socket descriptor and status will be * available in 'SlSockEventData_t' - Applications can use it if * required * * SlSockEventData_u *pEventData = NULL; * pEventData = & pSock->socketAsyncEvent; */ switch( pSock->socketAsyncEvent.SockTxFailData.status ) { case SL_ECLOSE: CLI_Write(" [SOCK EVENT] Close socket operation, failed to transmit all queued packets\n\r"); break; default: CLI_Write(" [SOCK EVENT] Unexpected event \n\r"); break; } break; default: CLI_Write(" [SOCK EVENT] Unexpected event \n\r"); break; } } /* * ASYNCHRONOUS EVENT HANDLERS -- End */ /* * Application's entry point */ int main(int argc, char** argv) { _i32 retVal = -1; retVal = initializeAppVariables(); ASSERT_ON_ERROR(retVal); /* Stop WDT and initialize the system-clock of the MCU These functions needs to be implemented in PAL */ stopWDT(); initClk(); /* Configure command line interface */ CLI_Configure(); displayBanner(); /* * Following function configures the device to default state by cleaning * the persistent settings stored in NVMEM (viz. connection profiles & * policies, power policy etc) * * Applications may choose to skip this step if the developer is sure * that the device is in its default state at start of application * * Note that all profiles and persistent settings that were done on the * device will be lost */ retVal = configureSimpleLinkToDefaultState(); if(retVal < 0) { if (DEVICE_NOT_IN_STATION_MODE == retVal) { CLI_Write(" Failed to configure the device in its default state \n\r"); } LOOP_FOREVER(); } CLI_Write(" Device is configured in default state \n\r"); /* * Assumption is that the device is configured in station mode already * and it is in its default state */ /* Initializing the CC3100 device */ retVal = sl_Start(0, 0, 0); if ((retVal < 0) || (ROLE_STA != retVal) ) { CLI_Write(" Failed to start the device \n\r"); LOOP_FOREVER(); } CLI_Write(" Device started as STATION \n\r"); /* Connecting to WLAN AP - Set with static parameters defined at the top After this call we will be connected and have IP address */ retVal = establishConnectionWithAP(); if(retVal < 0) { CLI_Write(" Failed to establish connection w/ an AP \n\r"); LOOP_FOREVER(); } CLI_Write(" Connection established w/ AP and IP is acquired \n\r"); CLI_Write(" Establishing connection with TCP server \n\r"); /*Before proceeding, please make sure to have a server waiting on PORT_NUM*/ retVal = BsdTcpClient(PORT_NUM); if(retVal < 0) CLI_Write(" Failed to establishing connection with TCP server \n\r"); else CLI_Write(" Connection with TCP server established successfully \n\r"); CLI_Write(" Starting TCP server\r\n"); /*After calling this function, you can start sending data to CC3100 IP * address on PORT_NUM */ retVal = BsdTcpServer(PORT_NUM); if(retVal < 0) CLI_Write(" Failed to start TCP server \n\r"); else CLI_Write(" TCP client connected successfully \n\r"); /* Stop the CC3100 device */ retVal = sl_Stop(SL_STOP_TIMEOUT); if(retVal < 0) LOOP_FOREVER(); return 0; } /*! \brief This function configure the SimpleLink device in its default state. It: - Sets the mode to STATION - Configures connection policy to Auto and AutoSmartConfig - Deletes all the stored profiles - Enables DHCP - Disables Scan policy - Sets Tx power to maximum - Sets power policy to normal - Unregisters mDNS services - Remove all filters \param[in] none \return On success, zero is returned. On error, negative is returned */ static _i32 configureSimpleLinkToDefaultState() { SlVersionFull ver = {0}; _WlanRxFilterOperationCommandBuff_t RxFilterIdMask = {0}; _u8 val = 1; _u8 configOpt = 0; _u8 configLen = 0; _u8 power = 0; _i32 retVal = -1; _i32 mode = -1; mode = sl_Start(0, 0, 0); ASSERT_ON_ERROR(mode); /* If the device is not in station-mode, try configuring it in staion-mode */ if (ROLE_STA != mode) { if (ROLE_AP == mode) { /* If the device is in AP mode, we need to wait for this event before doing anything */ while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); } } /* Switch to STA role and restart */ retVal = sl_WlanSetMode(ROLE_STA); ASSERT_ON_ERROR(retVal); retVal = sl_Stop(SL_STOP_TIMEOUT); ASSERT_ON_ERROR(retVal); retVal = sl_Start(0, 0, 0); ASSERT_ON_ERROR(retVal); /* Check if the device is in station again */ if (ROLE_STA != retVal) { /* We don't want to proceed if the device is not coming up in station-mode */ ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE); } } /* Get the device's version-information */ configOpt = SL_DEVICE_GENERAL_VERSION; configLen = sizeof(ver); retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (_u8 *)(&ver)); ASSERT_ON_ERROR(retVal); /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */ retVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0); ASSERT_ON_ERROR(retVal); /* Remove all profiles */ retVal = sl_WlanProfileDel(0xFF); ASSERT_ON_ERROR(retVal); /* * Device in station-mode. Disconnect previous connection if any * The function returns 0 if 'Disconnected done', negative number if already disconnected * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes */ retVal = sl_WlanDisconnect(); if(0 == retVal) { /* Wait */ while(IS_CONNECTED(g_Status)) { _SlNonOsMainLoopTask(); } } /* Enable DHCP client*/ retVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val); ASSERT_ON_ERROR(retVal); /* Disable scan */ configOpt = SL_SCAN_POLICY(0); retVal = sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0); ASSERT_ON_ERROR(retVal); /* Set Tx power level for station mode Number between 0-15, as dB offset from max power - 0 will set maximum power */ power = 0; retVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (_u8 *)&power); ASSERT_ON_ERROR(retVal); /* Set PM policy to normal */ retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0); ASSERT_ON_ERROR(retVal); /* Unregister mDNS services */ retVal = sl_NetAppMDNSUnRegisterService(0, 0); ASSERT_ON_ERROR(retVal); /* Remove all 64 filters (8*8) */ pal_Memset(RxFilterIdMask.FilterIdMask, 0xFF, 8); retVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask, sizeof(_WlanRxFilterOperationCommandBuff_t)); ASSERT_ON_ERROR(retVal); retVal = sl_Stop(SL_STOP_TIMEOUT); ASSERT_ON_ERROR(retVal); retVal = initializeAppVariables(); ASSERT_ON_ERROR(retVal); return retVal; /* Success */ } /*! \brief Connecting to a WLAN Access point This function connects to the required AP (SSID_NAME). The function will return once we are connected and have acquired IP address \param[in] None \return 0 on success, negative error-code on error \note \warning If the WLAN connection fails or we don't acquire an IP address, We will be stuck in this function forever. */ static _i32 establishConnectionWithAP() { SlSecParams_t secParams = {0}; _i32 retVal = 0; secParams.Key = PASSKEY; secParams.KeyLen = pal_Strlen(PASSKEY); secParams.Type = SEC_TYPE; retVal = sl_WlanConnect(SSID_NAME, pal_Strlen(SSID_NAME), 0, &secParams, 0); ASSERT_ON_ERROR(retVal); /* Wait */ while((!IS_CONNECTED(g_Status)) || (!IS_IP_ACQUIRED(g_Status))) { _SlNonOsMainLoopTask(); } return SUCCESS; } /*! \brief Opening a client side socket and sending data This function opens a TCP socket and tries to connect to a Server IP_ADDR waiting on port PORT_NUM. If the socket connection is successful then the function will send 1000 TCP packets to the server. \param[in] port number on which the server will be listening on \return 0 on success, -1 on Error. \note \warning A server must be waiting with an open TCP socket on the right port number before calling this function. Otherwise the socket creation will fail. */ static _i32 BsdTcpClient(_u16 Port) { SlSockAddrIn_t Addr; _u16 idx = 0; _u16 AddrSize = 0; _i16 SockID = 0; _i16 Status = 0; _u16 LoopCount = 0; for (idx=0 ; idx<BUF_SIZE ; idx++) { uBuf.BsdBuf[idx] = (_u8)(idx % 10); } Addr.sin_family = SL_AF_INET; Addr.sin_port = sl_Htons((_u16)Port); Addr.sin_addr.s_addr = sl_Htonl((_u32)IP_ADDR); AddrSize = sizeof(SlSockAddrIn_t); SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( SockID < 0 ) { CLI_Write(" [TCP Client] Create socket Error \n\r"); ASSERT_ON_ERROR(SockID); } Status = sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize); if( Status < 0 ) { sl_Close(SockID); CLI_Write(" [TCP Client] TCP connection Error \n\r"); ASSERT_ON_ERROR(Status); } while (LoopCount < NO_OF_PACKETS) { Status = sl_Send(SockID, uBuf.BsdBuf, BUF_SIZE, 0 ); if( Status <= 0 ) { CLI_Write(" [TCP Client] Data send Error \n\r"); Status = sl_Close(SockID); ASSERT_ON_ERROR(TCP_SEND_ERROR); } LoopCount++; } Status = sl_Close(SockID); ASSERT_ON_ERROR(Status); return SUCCESS; } /*! \brief Opening a server side socket and receiving data This function opens a TCP socket in Listen mode and waits for an incoming TCP connection. If a socket connection is established then the function will try to read 1000 TCP packets from the connected client. \param[in] port number on which the server will be listening on \return 0 on success, -1 on Error. \note This function will wait for an incoming connection till one is established \warning */ static _i32 BsdTcpServer(_u16 Port) { SlSockAddrIn_t Addr; SlSockAddrIn_t LocalAddr; _u16 idx = 0; _u16 AddrSize = 0; _i16 SockID = 0; _i32 Status = 0; _i16 newSockID = 0; _u16 LoopCount = 0; _i16 recvSize = 0; for (idx=0 ; idx<BUF_SIZE ; idx++) { uBuf.BsdBuf[idx] = (_u8)(idx % 10); } LocalAddr.sin_family = SL_AF_INET; LocalAddr.sin_port = sl_Htons((_u16)Port); LocalAddr.sin_addr.s_addr = 0; SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( SockID < 0 ) { CLI_Write(" [TCP Server] Create socket Error \n\r"); ASSERT_ON_ERROR(SockID); } AddrSize = sizeof(SlSockAddrIn_t); Status = sl_Bind(SockID, (SlSockAddr_t *)&LocalAddr, AddrSize); if( Status < 0 ) { sl_Close(SockID); CLI_Write(" [TCP Server] Socket address assignment Error \n\r"); ASSERT_ON_ERROR(Status); } Status = sl_Listen(SockID, 0); if( Status < 0 ) { sl_Close(SockID); CLI_Write(" [TCP Server] Listen Error \n\r"); ASSERT_ON_ERROR(Status); } newSockID = sl_Accept(SockID, ( struct SlSockAddr_t *)&Addr, (SlSocklen_t*)&AddrSize); if( newSockID < 0 ) { sl_Close(SockID); CLI_Write(" [TCP Server] Accept connection Error \n\r"); ASSERT_ON_ERROR(newSockID); } while (LoopCount < NO_OF_PACKETS) { recvSize = BUF_SIZE; do { Status = sl_Recv(newSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0); if( Status <= 0 ) { sl_Close(newSockID); sl_Close(SockID); CLI_Write(" [TCP Server] Data recv Error \n\r"); ASSERT_ON_ERROR(TCP_RECV_ERROR); } recvSize -= Status; } while(recvSize > 0); LoopCount++; } Status = sl_Close(newSockID); ASSERT_ON_ERROR(Status); Status = sl_Close(SockID); ASSERT_ON_ERROR(Status); return SUCCESS; } /*! \brief This function initializes the application variables \param[in] None \return 0 on success, negative error-code on error */ static _i32 initializeAppVariables() { g_Status = 0; pal_Memset(uBuf.BsdBuf, 0, sizeof(uBuf)); return SUCCESS; } /*! \brief This function displays the application's banner \param None \return None */ static void displayBanner() { CLI_Write("\n\r\n\r"); CLI_Write(" TCP socket application - Version "); CLI_Write(APPLICATION_VERSION); CLI_Write("\n\r*******************************************************************************\n\r"); }
Federico,
Are you using one of our examples in the SDK? If you run a example does it work properly?
BR,
Vince
Yes, I tried to run two examples before it, precisely getting_started_with_wlan_ap and getting_started_with_wlan_station, and they both worked properly.
Federico,
Can you set a break point after sl_Start() and check the value of mode variable?
BR,
Vince
I already tried that, but the breakpoint was never reached, so the value of mode shouldn't change. sl_Start never returns value because it never completes. I followed the code and debugging I found that it is struck for some reason here in nonos.c:
_SlNonOsRetVal_t _SlNonOsMainLoopTask(void) { _i8 i=0; void* pValue; #ifndef SL_TINY_EXT for (i=0 ; i<NONOS_MAX_SPAWN_ENTRIES ; i++) #endif { _SlNonOsSpawnEntry_t* pE = &g__SlNonOsCB.SpawnEntries[i]; if (pE->IsAllocated == TRUE) { _SlSpawnEntryFunc_t pF = pE->pEntry; pValue = pE->pValue; /* Clear the entry */ pE->pEntry = NULL; pE->pValue = NULL; pE->IsAllocated = FALSE; /* execute the spawn function */ pF(pValue); } } return NONOS_RET_OK; }
I don't know why, but pF(pValue) at some point doesn't complete and I also can't enter it while debugging.
I am struggling to understand the problem, but it is very low-level stuff and it's quite complex for me to understand what is going on and what is not working.
Federico,
I just ran the same example and did not experience your issue. Can you send me a picture of the jumper configurations on both boards? Also, are you using the CC3100BOOST or CC3100MODBOOST?
BR,
Vince
Federico,
Can you test this on a new board? I have again tried reproducing and do not get the same issue.
BR,
Vince
Hi
I tried to run it on another MSP430FR5969 and also with another CC3100BOOST, but I always get the same results.
But today I updated CCS to the latest version and something changed: when building the project, I got this error:
<Linking>
"../lnk_msp430fr5969.cmd", line 174: error #10099-D: program will not fit into available memory. run placement with alignment fails for section ".stack" size 0x200 . Available memory ranges:
RAM size: 0x800 unused: 0x137 max hole: 0x137
error #10010: errors encountered during linking; "getting_started_with_wlan_station.out" not built
>> Compilation failure
makefile:166: recipe for target 'getting_started_with_wlan_station.out' failed
I reduced the dimension of the stack to 128 from 512 in the MSP430 Linker->Basic Options and that seems to solve the problem since I could build successfully the project, even this error never appeared before.
But, when I try running the program, it stops again as before, but this time I get this output on the serial terminal:
TCP socket application - Version 1.3.0
***************************************************************
[GENERAL EVENT]
I searched in the code and find that was a Handler for an interrupt. I don't know why an interrupt would be called during the configuration of the device.
BR
Federico
Federico,
Increase your stack back, and turn optimizations on for the project.
BR,
Vince