このチュートリアルは、Wei Dongshan Baiwen.com によって作成されたDShanMCU-RA6M5 開発ボードに基づいて書かれています。必要な学生はここから入手できます: https://item.taabao.com/item.htm?id=728461040949
サポート情報の入手: https://renesas-docs.100ask.net
ルネサス MCU ゼロベース エントリ シリーズ チュートリアルの概要: https://blog.csdn.net/qq_35181236/article/details/132779862
第31章 WIFI & Bluetoothモジュールドライバー実験
この章の目的
- WiFi Bluetooth チップ W800 の通信プロトコルを理解する;
- シリアル ポートを使用して AT コマンドを送受信し、開発ボード ネットワーキングを実装する方法を学びます。
31.1 W800 工場出荷時のファームウェアのプログラミング
W800 ファームウェアをプログラミングするときは、X/Y モデム シリアル ポート プロトコルを使用する必要があります。したがって、X/Y モデム プロトコルをサポートするシリアル ポート ツールが必要です (本書では Xshell を使用します)。
31.1.1 Xshell ソフトウェアのインストール
Xshell の無料試用版のダウンロード入口アドレスは次のとおりです。
https://www.xshell.com/zh/free-for-home-school/
Web サイトにアクセスして情報を入力すると、Xshell 担当者が、入力した電子メール アドレスに無料のダウンロード リンクを送信します。
電子メール内のリンクをコピーしてブラウザに貼り付け、ダウンロード、ダウンロード、インストールを行います。
31.1.2 Xshellの使用
Xshell がインストールされたら、ダブルクリックしてソフトウェアを実行し、ポップアップ セッション ウィンドウで [新規] をクリックしてシリアル ポート接続を追加します。
次に、次の図に示すように、「接続」項目でプロトコルを「シリアル」に設定します。
次に、「接続」の「シリアル ポート」に移動してシリアル ポートを選択します (下の図の COM20 は一例です。次のセクションの手順に従って USB シリアル ポートを使用して W800 を接続した後、ポートが異なる場合があります) ) を選択し、図に示すように通信パラメータを設定します。
設定後、右下の「接続」をクリックして、指定したシリアルデバイスに接続します。
31.1.3 ハードウェア接続
W800 のハードウェア インターフェイス図は次のとおりです。
上の図に示すようにハードウェアを接続した後、Xshell を使用してシリアル ポートを開き、次に上の図の WIFI_RESET ピンを GND に短絡して W800 をリセットします。その後、W800 は文字「C」を Xshell に送信し続けます。以下の図に示すように:
この状態に入ると、次のセクションの内容に従ってファームウェアをプログラムできます。
31.1.4 ファームウェアのプログラミング手順
W800 がプログラミング状態になったら、次の図に示すように、Xshell 表示ウィンドウでマウスを右クリックし、[転送] -> [YMODEM (Y)] -> [YMODEM で送信 (S)] を選択します。
次に、データ パッケージ内のファームウェアの場所に移動し、w800.fls を選択してプログラミングを開始します。
最後に、転送とプログラミングが完了するまで待ちます。
プログラミングが完了すると、W800 はまだプログラミング状態にあることを示す「C」を出力し続けます。この時点で、BOOT ピンを GND から切り離し、W800 を手動で再度リセットして、W800 が復帰できるようにします。以下の図に示すように、通常の動作状態です。
Xshell が「ユーザータスク」を出力すると、W800 が動作状態に入ったことを意味します。このとき、Xshell ウィンドウにコマンド「AT+」と車両キーを直接入力することができます (Xshell は入力コマンドを表示しません)。「+OK」が返されれば、次のようにファームウェアのプログラミングは成功です。形:
31.2 AT+ コマンドの概要
W800 のファームウェア AT+ コマンドについては、本書の付属資料に含まれる公式マニュアル「WM_W800_SDK_AT コマンド ユーザーマニュアル.pdf」に詳しく説明されています。
W800 は多くの AT+ コマンドをサポートしていますが、本書では一般的に使用されるいくつかのコマンドのみを示します。
命令 | コマンド形式 | 応答 | 説明する |
---|---|---|---|
AT+ | 「AT+\r\n」 | 「+OK\r\n\r\n」 | テスト コマンド、応答 +OK はテストの成功を示します |
AT+Z | 「AT+Z\r\n」 | 「+OK\r\n\r\n」 | ソフトウェア リセット後、+OK という応答は、リセット コマンドが正常に送信されたことを示します。リセット後、「ユーザー タスク」という応答が返されます。 |
AT+E | 「AT+E\r\n」 | 「+OK\r\n\r\n」 | 切り替えコマンドをエコーする場合は、コマンドを 1 回入力すると状態が切り替わり、エコー状態では W800 がコマンドと結果を合わせて応答します。 |
AT+RSTF | 「AT+RSTF\r\n」 | 「+OK\r\n\r\n」 | FLASH で工場出荷時の設定を復元します。復元された設定は、システムが再起動されるまで有効になりません。 |
AT+WPRT | "AT+WPRT=[!?][タイプ]\r\n" 例: AT+WPRT=0\r\n | "+OK[=type]\r\n\r\n" 例: +OK=0\r\n\r\n | ワイヤレスネットワークタイプの設定/照会:l 0:STA;l 2:SoftAP;l 3:APSTA |
AT+WSCAN | 「AT+WSCAN\r\n」 | 「+OK=……」 | このコマンドは、無線ネットワークの種類が STA の場合にのみ有効で、無線ネットワークのスキャンに使用され、完了後に戻ります。 |
AT+SSID | 「AT+SSID=[!?][SSID]」例:AT+SSID=100ask\r\n | 「+OK[=ssid]\r\n」 | ワイヤレスネットワーク名、つまりSSIDを設定/照会します。 |
AT+キー | 「AT+KEY=[!?][フォーマット],[インデックス],[キー]\r\n」 | 「+OK[=フォーマット,インデックス,キー]\r\n」 | ネットワークキーの設定/問い合わせ |
AT+WJOIN | 「AT+WJOIN\r\n」 | 「+OK=<bsid>,<type>…\r\n」 | 現在のネットワーク タイプが STA の場合、このコマンドの機能は AP に接続することです。現在のネットワーク タイプが SoftAP または APSTA の場合、このコマンドの機能は |
AT+WLEAV | 「AT+WLEAV\r\n」 | 「+OK\r\n\r\n」 | 無線ネットワークの種類が STA の場合、現在の無線ネットワークを切断するために使用されます。 |
AT+NIP | 「AT+NIP=[!?][タイプ]…\r\n」 | 「+OK[=タイプ]…\r\n」 | ワイヤレス ネットワーク カードが STA として機能する場合、このコマンドはローカル IP アドレスの設定/照会に使用されます。 |
AT+LKSTT | 「AT+LKSTT\r\n」 | +OK[=ステータス、IP、ネットマスク、ゲートウェイ、dns1、dns2]\r\n\r\n | ローカルネットワーク接続ステータスのクエリ |
AT+SKCT | 「AT+SKCT=[プロトコル]…\r\n」 | 「+OK=<socket>\r\n」 | ソケットを作成します。クライアント モードでは、接続が完了する (成功または失敗) まで待ってから戻ります。サーバー モードでは、作成が完了したらすぐに戻ります。 |
AT+SKCLS | 「AT+SKCLS=<socket>\r\n」 | 「+OK\r\n\r\n」 | 指定されたソケットを閉じます。 |
AT+SKSND | 「AT+SKSND=[ソケット],[サイズ]\r\n」 | 「+OK\r\n\r\n」 | OK 応答後にデータ ストリームを送信する |
AT+SKRCV | 「AT+SKRCV=[ソケット],[サイズ]\r\n」 | 「+OK\r\n\r\n」 | OK と応答すると、rxdata のデータがシリアル ポートに送信されます。 |
31.3 モジュール構成
この実験では UART のみを使用します。FSP で UART とそのピンを構成するには、前の操作を参照してください。この実験は構成結果のみを示しています。
31.3.1 ハードウェア接続
オンボード W800 の概略図を以下に示します。
使用される RA6M5 プロセッサ ピンは P505 と P506 で、SCI の UART6 の TX/RX ピンに対応します。
31.3.2 UARTモジュール構成
- UART6
- UART7
31.4 ドライバー
31.4.1 デバイスオブジェクトのカプセル化
「30.3 デバイスオブジェクトのカプセル化」をベースに、タイマーのデバイスオブジェクトを改良し、遅延機能を実現するタイムアウト機能を追加しました。コードは以下のように表示されます。
static struct TimerDev gSystickDevice = {
.name = "Systick",
.channel = 0xFF,
.status = 0,
.Init = SystickInit,
.Start = NULL,
.Stop = NULL,
.Read = NULL,
.Timeout = HAL_Delay,
.next = NULL
};
void SystickTimerDevicesCreate(void)
{
TimerDeviceInsert(&gSystickDevice);
gSystickDevice.Init(&gSystickDevice);
}
static int HAL_Delay(struct TimerDev *ptdev, uint32_t timeout)
{
if(NULL == ptdev) return -EINVAL;
if(0 == ptdev->status) return -EIO;
uint32_t dwStart = dwTick;
uint32_t dwWait = timeout;
/* Add a freq to guarantee minimum wait */
if (dwWait < HAL_MAX_DELAY)
{
dwWait += (uint32_t)(1);
}
while((dwTick - dwStart) < dwWait)
{
}
return ESUCCESS;
}
31.4.2 UARTの初期化
この実験では 2 つの UART を使用します。
- UART6: WiFi Bluetooth チップ W800 と通信します。
- UART7: デバッグ印刷。
UART6 の場合、W800 が毎回送受信するデータの長さが不定であるため、DTC や DMA を使用してデータ送信を補助するのは適切ではないため、リング バッファが使用されます。UART6 の初期化時にリング バッファが適用されましたが、UART7 はデバッグ シリアル ポートとしてリング バッファを使用しませんでした。コードは以下のように表示されます。
static struct RingBuffer *gWiFiBuffer = NULL;
static struct UartDev gWiFiDevice = {
.name = "WiFi Uart",
.channel = 6,
.Init = UARTDrvInit,
.Read = UARTDrvRead,
.Write = UARTDrvWrite,
.next = NULL
};
void UartDevicesCreate(void)
{
UartDeviceInsert(&gLogDevice);
UartDeviceInsert(&gWiFiDevice);
gLogDevice.Init(&gLogDevice);
}
static int UARTDrvInit(struct UartDev *ptdev)
{
if(NULL == ptdev) return -EINVAL;
switch(ptdev->channel)
{
case 0:case 1:case 2:
case 3:case 4:case 5:
case 6:
{
fsp_err_t err = g_uart6.p_api->open(g_uart6.p_ctrl, g_uart6.p_cfg);
assert(FSP_SUCCESS == err);
gWiFiBuffer = RingBufferNew(1024);
assert(NULL != gWiFiBuffer);
break;
}
case 7:
{
fsp_err_t err = g_uart7.p_api->open(g_uart7.p_ctrl, g_uart7.p_cfg);
assert(FSP_SUCCESS == err);
break;
}
case 8:case 9:
break;
default:break;
}
return ESUCCESS;
}
31.4.3 割り込みコールバック関数
UART6 および UART7 の場合、割り込みコールバック関数を提供する必要があります。動作は似ており、UART6 は「送信完了」と「受信完了」の両方の状況を処理する必要がありますが、UART7 は「送信完了」のみを処理する必要があります。UART6 割り込みコールバック関数のコードは次のとおりです。
void uart6_callback(uart_callback_args_t * p_args)
{
switch(p_args->event)
{
case UART_EVENT_RX_COMPLETE:
{
break;
}
case UART_EVENT_TX_COMPLETE:
{
gUart6TxCplt = true;
break;
}
case UART_EVENT_RX_CHAR:
{
gWiFiBuffer->Write(gWiFiBuffer, (unsigned char*)&p_args->data, 1);
break;
}
case UART_EVENT_ERR_PARITY:case UART_EVENT_ERR_FRAMING:
case UART_EVENT_ERR_OVERFLOW:case UART_EVENT_BREAK_DETECT:
case UART_EVENT_TX_DATA_EMPTY:
break;
default:break;
}
}
- 11行目:UART6の送信完了フラグをtrueとして書き込みます。
- 16 行目: データを受信した場合は、UART6 のバッファに書き込みます。
31.4.4 UART送信機能
UART デバイスの送信関数は比較的単純で、UART6 および UART7 デバイス構造の書き込み関数を呼び出すだけです。
static int UARTDrvWrite(struct UartDev *ptdev, unsigned char * const buf, unsigned int length)
{
if(NULL == ptdev) return -EINVAL;
if(NULL == buf) return -EINVAL;
if(0 == length) return -EINVAL;
switch(ptdev->channel)
{
case 0:case 1:case 2:
case 3:case 4:case 5:
case 6:
{
fsp_err_t err = g_uart6.p_api->write(g_uart6.p_ctrl, buf, length);
assert(FSP_SUCCESS == err);
UART6WaitTxCplt();
break;
}
case 7:
{
fsp_err_t err = g_uart7.p_api->write(g_uart7.p_ctrl, buf, length);
assert(FSP_SUCCESS == err);
UART7WaitTxCplt();
break;
}
case 8:case 9:
break;
default:break;
}
return ESUCCESS;
}
31.4.5 UARTデータ読み出し機能
UART6 の場合、UART データを読み取るとき、データはリング バッファから読み取られます。UART7 の場合、FSP カプセル化関数を呼び出してデータを読み取ります。コードは以下のように表示されます。
static int UARTDrvRead(struct UartDev *ptdev, unsigned char *buf, unsigned int length)
{
if(NULL == ptdev) return -EINVAL;
if(NULL == buf) return -EINVAL;
if(0 == length) return -EINVAL;
switch(ptdev->channel)
{
case 0:case 1:case 2:
case 3:case 4:case 5:
case 6:
{
if(gWiFiBuffer->Read(gWiFiBuffer, buf, length) != length)
return -EIO;
break;
}
case 7:
{
fsp_err_t err = g_uart7.p_api->read(g_uart7.p_ctrl, buf, length);
assert(FSP_SUCCESS == err);
UART7WaitRxCplt();
break;
}
case 8:case 9:
break;
default:break;
}
return (int)length;
}
31.5 W800 WiFi Bluetooth モジュール
WiFi Bluetooth モジュールのデバイス ドライバー コードは、Devices/wifi_bluetooth フォルダーのファイル dev_wifi_bt.c/.h にあります。
31.5.1 W800の初期化
W800 を初期化するには、実際には W800 で使用されるシリアル デバイスを初期化する必要があります。つまり、UART6 を初期化します。
static UartDevice *pWiFiBtDev = NULL;
int WiFiBtDevInit(void)
{
pWiFiBtDev = UartDeviceFind("WiFi");
if(NULL==pWiFiBtDev) return -ENXIO;
if(pWiFiBtDev->Init(pWiFiBtDev) != ESUCCESS) return -EIO;
return ESUCCESS;
}
31.5.2 AT+コマンド復帰判定
AT+ コマンドの概要で説明したように、各 AT+ コマンドには対応する応答があります。ほとんどのコマンドでは、受信した応答が「+OK」であるかどうかを判断するだけで済みます。この関数を次の関数にカプセル化します。
static int WiFiBtDevCmdRet(const char *ret)
{
unsigned short timeout = 3000;
unsigned char i = 0;
unsigned char buf[128] = {
0};
while(timeout)
{
if(strstr((char*)buf, ret))
{
return ESUCCESS;
}
else if(strstr((char*)buf, "+ERR"))
{
return -EIO;
}
else if(pWiFiBtDev->Read(pWiFiBtDev, &buf[i], 1)==1)
{
printf("%c", buf[i]);
i++;
}
mdelay(1);
timeout--;
}
return -EIO;
}
- 08行目:受信データから指定された応答文字列を読み出せた場合はESUCCESSを返します。
- 行 12: 応答に「+ERR」がある場合は、コマンドが失敗し、-EIO が返されたことを意味します。
- 行 16: 必要な応答またはエラー応答がない場合は、引き続きバッファからデータを読み取り、出力します。
- 行 21 ~ 22: タイムアウト待機カウントダウン。タイムアウトして終了した場合は、-EIO を返します。
31.5.3 W800 の動作モードを設定する
W800 の WiFi 機能には、STA、SoftAP、APSTA の 3 つの動作モードがあり、列挙型を定義します。
typedef enum{
STA = 0,
SoftAP = 2,
APSTA = 3
}WorkType;
コマンド "AT+WPRT=<type>\r\n" ('\r' が必要であることに注意してください) を発行して、W800 の動作モードを設定します。具体的な実装は非常に簡単で、UART デバイスの write 関数を呼び出してこの文字列を送信し、応答を待つだけです。コードは以下のように表示されます。
int WiFiBtDevSetWorkType(WorkType type)
{
char str[64];
sprintf(str, "AT+WPRT=%d\r\n", type);
if(pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)str, strlen(str)) != ESUCCESS)
return -EIO;
mdelay(100);
return WiFiBtDevCmdRet("+OK");
}
31.5.4 W800のDHCPステータスを設定する
W800 がホットスポット接続後に自動的に IP アドレスを取得するようにしたい場合は、W800 の DHCP 機能を有効にする必要があります。W800 の IP アドレスを固定したい場合は、DHCP 自動割り当て機能をオフにする必要があります。そしてIPを指定します。
DHCP 機能を有効にするコマンドは「AT+NIP=0\r\n」です。コードは次のとおりです。
int WiFiBtDevEnableDHCP(void)
{
int ret = -EIO;
char *str = "AT+NIP=0\r\n";
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)str, strlen(str));
if(ESUCCESS!= ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
return ret;
}
IP を手動で設定するには、コマンド「AT+NIP=1,[IP],[net_mask],[gate_way]\r\n」を使用します。これにより、DHCP 機能がオフになり、IP、サブネット マスク、デフォルト ゲートウェイを指定します。 。コードは以下のように表示されます。
int WiFiBtDevDisableDHCP(const char *ip, const char *netmask, const char *gateway)
{
int ret = -EIO;
char str[64];
sprintf(str, "AT+NIP=1,%s,%s,%s\r\n", ip, netmask, gateway);
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)str, strlen(str));
if(ESUCCESS!= ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
return ret;
}
31.5.5 指定されたホットスポットに接続する
ホットスポットに接続するには、次の 3 つのコマンドが必要です。
- ホットスポットの名前を設定します: AT+SSID=[SSID]\r\n;
- ホットスポットに接続するためのパスワードを設定します: AT+KEY=[キー形式],[キーインデックス番号],[キー文字列]\r\n;
- ホットスポットに接続します: AT+WJOIN\r\n;
キーを設定するためのパラメータについて、マニュアルには次のように説明されています。
- キー形式: 0-16 進形式、1-ASCII 形式。
- キーインデックス番号: 1 ~ 4 は WEP 暗号化キーに使用され、他の暗号化方式は 0 に固定されます。
- キー文字列: 二重引用符で囲まれています。さまざまなセキュリティ モードに従って、キーの長さと形式の要件は次のように定義されます。
この実験では、ホットスポットに接続するための 3 つの命令を関数にカプセル化しています。呼び出し元は、ホットスポットの名前とパスワードを渡すだけで済みます。
int WiFiBtDevConnectWiFi(const char *name, const char *password)
{
int ret = -EIO;
char ssid[32];
sprintf(ssid, "AT+SSID=%s\r\n", name);
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)ssid, strlen(ssid));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
if(ESUCCESS != ret) return ret;
char key[32] ;
sprintf(key, "AT+KEY=1,0,%s\r\n", password);
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)key, strlen(key));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
if(ESUCCESS != ret) return ret;
char join[32] = "AT+WJOIN\r\n";
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)join, strlen(join));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
int ret1 = WiFiBtDevCmdRet("\r\n\r\n");
if(ret==ESUCCESS && ret1)
mdelay(1000);
return ret;
}
31.5.6 ホットスポットからの切断
ホットスポットを切断するには、コマンド「AT+WLEAV\r\n」を送信するだけです。コードは次のとおりです。
int WiFiBtDevDisconnectWiFi(void)
{
int ret = -EIO;
char *leavw = "AT+WLEAV\r\n";
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)leavw, strlen(leavw));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet(“+OK”);
return ret;
}
31.5.7 ローカルIPの取得
ホットスポットが接続されており、DHCP 自動 IP 取得機能が有効になっている場合、ユーザーはマシンに割り当てられた IP アドレスを知りたい場合があります。このとき、コマンド「AT+LKSTT\r\n」を使用してクエリする必要があります。マシンの IP コードは以下のように表示されます。
int WiFiBtDevGetLocalIP(void)
{
int ret = -EIO;
char lkstt[32] = "AT+LKSTT\r\n";
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)lkstt, strlen(lkstt));
if(ESUCCESS != ret) return ret;
mdelay(100);
unsigned short timeout = 100;
while(timeout)
{
unsigned char c = 0;
if(pWiFiBtDev->Read(pWiFiBtDev, &c, 1)==1)
{
printf("%c", c);
}
mdelay(1);
timeout--;
}
return ESUCCESS;
}
このコマンドは「+OK」以降の内容を印刷する必要があるため、終了の判断が難しいため、すべてのデータを受信してから印刷するために、意図的に長いタイムアウトを設定しています。読者はコードを改良し、コードから IP を解析できます。
31.5.8 ソケット接続の確立
W800 がホットスポットに接続された後、コマンド「AT+SKCT」を使用してサーバーと通信する必要があります。このコマンドは、プロトコル、ローカル ロール、IP アドレス、リモート ポート、ローカル ポートなどの多くのパラメータを渡す必要があります。本書では、このコマンドのパラメータがカプセル化されており、次の構造を使用して接続情報を記述しています。
typedef enum{
TCP = 0,
UDP = 1
}NetworkProtocol;
typedef enum{
Client = 0,
Server = 1
}LocalRole;
typedef struct{
NetworkProtocol Protocl;
LocalRole Role;
char *IP;
unsigned int RemotePort;
unsigned int LocalPort;
unsigned int SocketPort;
}ConnectInfo;
アプリケーション プログラムは ConnectInfo 構造体を構築し、AT コマンドを構築して W800 に送信する必要があります。ネットワーク接続機能で、接続に成功するとポート番号も記録されます。コードは以下のように表示されます。
int WiFiBtDevConnect(ConnectInfo *info)
{
int ret = -EIO;
char skct[128];
sprintf(skct, "AT+SKCT=%d,%d,%s,%d,%d\r\n", \
info->Protocl, \
info->Role, \
info->IP, \
info->RemotePort, \
info->LocalPort
);
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)skct, strlen(skct));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK=");
if(ESUCCESS != ret) return ret;
/* 获取连接成功后的socket号 */
unsigned short timeout = 1000;
unsigned char i = 0;
unsigned char buf[32] = {
0};
while(timeout)
{
if(strstr((char*)buf, "\r\n"))
{
printf("\r\n");
break;
}
else if(pWiFiBtDev->Read(pWiFiBtDev, &buf[i], 1)==1)
{
printf("%c", buf[i]);
i++;
}
mdelay(1);
timeout--;
}
for(i=0;buf[i]!='\r'; i++)
{
if(buf[i]>='0' && buf[i]<='9')
{
buf[i] = buf[i] - '0';
info->SocketPort = info->SocketPort*10 + buf[i];
}
}
printf("IP:%s - SocketPort:%d\r\n", info->IP, info->SocketPort);
return ret;
}
- 37 行目: 返されたソケット番号の最後の番号の後には '\r' が続きます。この値はソケット番号を解析するときには必要ありません。したがって、for ループの判断では '\r' まで ASCII は実行されません。を読み取って数値に変換計算します。
31.5.9 指定されたソケットの切断
ネットワークから切断するために使用されるコマンドは、「AT+SKCLS=<socket>\r\n」です。本書では、次の機能がカプセル化されています。
int WiFiBtDevDisconnect(ConnectInfo info)
{
int ret = -EIO;
char skcls[32];
sprintf(skcls, "AT+SKCLS=%d\r\n", info.SocketPort);
ret = pWiFiBtDev->Write(pWiFiBtDev, (unsigned char*)skcls, strlen(skcls));
if(ESUCCESS != ret) return ret;
mdelay(100);
ret = WiFiBtDevCmdRet("+OK");
return ret;
}
31.6 テスト手順
この実験では、まずネットワーク デバッグ アシスタントを使用して Windows コンピューターの TCP サービスを開き、次にボードを起動します。ボード上のプログラムは、まず W800 を使用してホットスポットに接続し、次に Windows コンピュータへの TCP 接続を確立します。
テスト関数のコードは次のとおりです。
void WiFiBtAppTest(void)
{
UartDevicesRegister();
TimerDevicesRegister();
WiFiBtDevInit();
WiFiBtDevSetWorkType(STA);
WiFiBtDevEnableDHCP();
WiFiBtDevConnectWiFi("X-IOT", "x-iot.cq");
WiFiBtDevGetLocalIP();
ConnectInfo connect = {
.Protocl = TCP,
.Role = Client,
.IP = "192.168.50.193",
.RemotePort = 8080,
.LocalPort = 1024
};
int ret = WiFiBtDevConnect(&connect);
while(1)
{
if(ret != ESUCCESS)
{
ret = WiFiBtDevConnect(&connect);
delay(1);
}
}
}
31.7 テスト結果
シリアル ポート アシスタントを開いて情報を確認し、ネットワーク アシスタントを開いて TCP サービスを開始します。次に、コンパイルされたバイナリ ファイルをボードに書き込んで実行すると、次の図に示すように、シリアル ポート アシスタント上の W800 の応答情報と、ネットワーク アシスタント上のネットワーク接続情報を確認できます。