ZHCU938C May 2018 – January 2021 CC3100 , CC3100MOD , CC3200 , CC3200MOD
实施联网应用时,需要考虑不同的应用块、上述主机驱动程序软件概念以及硬件和操作系统等系统。
图 2-1 展示了说明基本软件设计的状态机图。
图 2-1 展示了本章所述的不同状态、触发代码以在不同状态之间切换的主机驱动程序事件,以及基本错误处理事件。
下面是一个使用代码实现状态机的示例:
• 初始状态 – 下面是一个将 Wi-Fi 子系统初始化为 WLAN 工作站的示例:
case INIT:
status = sl_Start(0, 0, 0);
if (status == ROLE_STA)
{
g_State = CONFIG;
}
else
{
g_State = SIMPLELINK_ERR;
}
break;
• WLAN 连接 – 下面是 WLAN 和网络事件处理程序示例,展示了 WLAN 连接、等待成功连接和获取 IP 地址:
/* SimpleLink WLAN 事件处理程序 */
void SimpleLinkWlanEventHandler(void *pWlanEvents)
{
SlWlanEvent_t *pWlan = (SlWlanEvent_t *)pWlanEvents;
switch(pWlan->Event)
{
case SL_WLAN_CONNECT_EVENT:
g_Event |= EVENT_CONNECTED;
memcpy(g_AP_Name, pWlan->EventData.STAandP2PModeWlanConnected.ssid_name, pWlan->EventData.STAandP2PModeWlanConnected.ssid_len);
break;
case SL_WLAN_DISCONNECT_EVENT:
g_DisconnectionCntr++;
g_Event |= EVENT_DISCONNECTED;
g_DisconnectionReason = pWlan->EventData.STAandP2PModeDisconnected.reason_code;
memcpy(g_AP_Name, pWlan->EventData.STAandP2PModeWlanConnected.ssid_name, pWlan->EventData.STAandP2PModeWlanConnected.ssid_len);
break;
default:
break;
}
}
/* SimpleLink 网络事件处理程序 */
void SimpleLinkNetAppEventHandler(void *pNetAppEvent)
{
SlNetAppEvent_t *pNetApp = (SlNetAppEvent_t *)pNetAppEvent;
switch( pNetApp->Event )
{
case SL_NETAPP_IPV4_ACQUIRED:
g_Event |= EVENT_IP_ACQUIRED;
g_Station_Ip = pNetApp->EventData.ipAcquiredV4.ip;
g_GW_Ip = pNetApp->EventData.ipAcquiredV4.gateway;
g_DNS_Ip = pNetApp->EventData.ipAcquiredV4.dns;
break;
default:
break;
}
}
.
.
.
/* 启动 WLAN 连接 */
case WLAN_CONNECTION:
status = sl_WlanConnect(User.SSID,strlen(User.SSID),0,
&secParams, 0);
if (status == 0)
{
g_State = WLAN_CONNECTING;
}
else
{
g_State = SIMPLELINK_ERR;
}
/* 等待 SL_WLAN_CONNECT_EVENT 通知连接成功 */
case WLAN_CONNECTING:
if (g_Event
&EVENT_CONNECTED)
{
printf("Connected to %s\n", g_AP_Name);
g_State = WLAN_CONNECTED;
}
break;
/* 等待 SL_NETAPP_IPV4_ACQUIRED 通知接收 IP 地址 */
case WLAN_CONNECTED:
if (g_Event
&EVENT_IP_ACQUIRED)
{
printf("Received IP address:%d.%d.%d.%d\n", (g_Station_Ip>>24)&0xFF,(g_Station_Ip>>16)&0xFF,(g_Station_Ip>>8)&0xFF,(g_Station_Ip&0xFF));
g_State = GET_SERVER_ADDR;
}
break;
• 套接字连接 – 下面是使用服务器名称查询远程服务器 IP 地址、创建 TCP 套接字和连接至远程服务器套接字的示例:
case GET_SERVER_ADDR:
status = sl_NetAppDnsGetHostByName(appData.HostName,
strlen(appData.HostName),
&appData.DestinationIP, SL_AF_INET);
if (status == 0)
{
g_State = SOCKET_CONNECTION;
}
else
{
printf("Unable to reach Host\n");
g_State = SIMPLELINK_ERR;
}
break;
case SOCKET_CONNECTION:
Addr.sin_family = SL_AF_INET;
Addr.sin_port = sl_Htons(80);
/* 将 DestinationIP 字节序更改为大端字节序 */
Addr.sin_addr.s_addr = sl_Htonl(appData.DestinationIP);
AddrSize = sizeof(SlSockAddrIn_t);
SockId = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
if( SockId < 0 )
{
printf("Error creating socket\n\r");
status = SockId;
g_State = SIMPLELINK_ERR;
}
if (SockId >= 0)
{
status = sl_Connect(SockId, ( SlSockAddr_t *)
&Addr, AddrSize);
if( status >= 0 )
{
g_State = SOCKET_CONNECTED;
}
else
{
printf("Error connecting to socket\n\r");
g_State = SIMPLELINK_ERR;
}
}
break;
• 数据事务 – 下面是通过开放的套接字发送和接收 TCP 数据的示例:
case SOCKET_CONNECTED:
/* 将数据发送至远程服务器 */
sl_Send(appData.SockID, appData.SendBuff, strlen(appData.SendBuff), 0);
/* 接收远程服务器发出的数据 */
sl_Recv(appData.SockID, &appData.Recvbuff[0], MAX_RECV_BUFF_SIZE, 0);
break;
• 套接字断开连接 – 下面是关闭套接字的示例:
case SOCKET_DISCONNECT:
sl_Close(appData.SockID);
/* 重新打开套接字 */
g_State = SOCKET_CONNECTION;
break;
• 器件休眠 – 下面是让 Wi-Fi 子系统进入休眠状态的示例:
case SIMPLELINK_HIBERNATE:
sl_Stop();
g_State = …
break;