資料來源:郭書軍老師的《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)
}