【cc3200】wlan_station項目修改爲與服務器通訊

資料來源:郭書軍老師的《CC3200應用指南》

主要是裏面的osi_TaskCreate讓我眼前一亮,創建三個任務,然後分別去執行,就像多進程一樣(可能就是多進程……)
實現的效果如下
串口助手發送數據123456(無視後面的回顯,我也不知道怎麼回事),服務端接收到123456,服務端發送5425,串口助手打印5425

串口助手:
這裏寫圖片描述

爲了簡便,用socket調試工具模擬服務器:
這裏寫圖片描述

先把wlan_station工程導入,然後着手修改,在創建WlanStationMode後面添加兩個任務,分別是發送方法和接收方法

int iNewSockID=0,iFlag=1;//用於代碼控制

void main(){

……
    //
    // Start the WlanStationMode task
    //
    lRetVal = osi_TaskCreate( WlanStationMode, \
                                (const signed char*)"Wlan Station Task", \
                                OSI_STACK_SIZE, NULL, 1, NULL );
    if(lRetVal < 0)
    {
        ERR_PRINT(lRetVal);
        LOOP_FOREVER();
    }

    lRetVal = osi_TaskCreate(SendTask,"SENDTASK",OSI_STACK_SIZE, NULL, 1, NULL);
    lRetVal = osi_TaskCreate(ReceiveTask,"RECEIVETASK",OSI_STACK_SIZE, NULL, 1, NULL);

    //
    // Start the task scheduler
    //
    osi_start();
}

可以看到,我們的串口助手一開始創建了三個任務,也就是說,此時執行了三條線,第一條用來初始化設備,第二條用來創建發送任務,第三條用來創建接收任務

我們一條線一條線來看

首先第一條線是WlanStationMode(只寫修改部分)
前面是一些配置WLAN,不用改,把檢查連接部分改成BsdTcpClient函數,該函數從tcp_socket複製

void WlanStationMode( void *pvParameters ){

……

    lRetVal = WlanConnect();
    if(lRetVal < 0)
    {
        UART_PRINT("Failed to establish connection w/ an AP \n\r");
        LOOP_FOREVER();
    }

    UART_PRINT("\r\nConnection established w/ AP and IP is aquired \n\r");

    //0xc0a8032f 192.168.3.47 本地PC
    lRetVal = BsdTcpClient(8000,0xc0a8032f);
    if(lRetVal < 0)
    {
        UART_PRINT("BsdTcpClient<0 \n\r");

    }

    lRetVal = sl_Stop(SL_STOP_TIMEOUT);

……

}

BsdTcpClient函數傳入IP地址和PORT,

int BsdTcpClient(unsigned short usPort,unsigned int g_ulDestinationIp){

    UART_PRINT("\r\n 啓動BsdTcpClient方法,創建socket \r\n");

……
    // connecting to TCP server
    iStatus = sl_Connect(iSockID, ( SlSockAddr_t *)&sAddr, iAddrSize);
    if( iStatus < 0 )
    {
        // error
        sl_Close(iSockID);
        UART_PRINT("\r\n  iStatus < 0  \r\n");
    }
    UART_PRINT("\r\n 連接服務器成功 \r\n");

    //設置非阻塞模式
    long lNonBlocking=1;
    iStatus=sl_SetSockOpt(iSockID,SL_SOL_SOCKET,SL_SO_NONBLOCKING,&lNonBlocking,sizeof(lNonBlocking));
    if(iStatus<0){
        sl_Close(iSockID);
    }

    iNewSockID=iSockID;//先設置非阻塞,然後再讓接收方法執行
    while(iFlag){
        osi_Sleep(100);
    }

……
}

程序會停在上面的while循環裏。

現在我們來看第二條線,其中的代碼控制

void SendTask(void *pvParameters){

    char cGetChar;
    char cTxBuf[100];
    int iCounter=0;
    int iStatus;
    UART_PRINT("\r\n Create SendTask\r\n");
    while(1){

        cGetChar=MAP_UARTCharGetNonBlocking(UARTA0_BASE);

        if( (cGetChar!=0xff) && (iNewSockID>0) ){

            cTxBuf[iCounter++]=cGetChar;

            if(cGetChar==0x0d || cGetChar==0x1b){

                UART_PRINT("\r\n當檢測到串口輸入的數據中包含回車或十六進制1b時進入此方法\r\n");

                cTxBuf[iCounter++]=0x0a;

                iStatus=sl_Send(iNewSockID,cTxBuf,iCounter,0);


                if( iStatus>0 && cGetChar==0x0d ){
                    UART_PRINT("\r\n 發送的數據爲: %s \r\n",cTxBuf);
                    iCounter=0;
                }else{
                    UART_PRINT("\r\n cGetChar==0x1b,退出BsdTcpClient的循環\r\n");
                    iFlag=0;
                }
            }//if(cGetChar==0x0d || cGetChar==0x1b)

        }//if( (cGetChar!=0xff) && (iNewSockID>0) )
        osi_Sleep(100);
    }//while(1)
}

程序會一直跑在while循環裏

第三條線,接收方法

void ReceiveTask(void *pvParameters){

    char cRxBuf[100];
    int iStatus;
    UART_PRINT("\r\n Create ReceiveTask\r\n");
    while(1){

        if(iNewSockID>0){

            iStatus=sl_Recv(iNewSockID,cRxBuf,100,0);

            if(iStatus>0){

                if( cRxBuf[iStatus-2]==0x0d ){

                    cRxBuf[iStatus]=0;
                    UART_PRINT("\r\n收到的是%s\r\n",cRxBuf);

                }else{
                    UART_PRINT("\r\n cRxBuf[iStatus-2]是0x1b,結束循環 \r\n");
                    iFlag=0;
                }
            }

        }//if(iNewSockID>0)

        osi_Sleep(100);
    }//while(1)

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章