esp-open-rtosを使ってみる

SoftAPモードとStationモード

ESP8266にはWiFiの利用方法として、SoftAPモード、Stationモードの2つのモードが有ります。
そこで、各モードで起動して、裏でどのようなタスクが動いているのか、確認してみました。
タスクの一覧にはvTaskList()を使いますが、ソースと同じ場所にあるFreeRTOSConfig.hに以下を追加しないとビルドが通 りません。
/* Blink FreeRTOSConfig overrides.

   This is intended as an example of overriding some of the default FreeRTOSConfig settings,
   which are otherwise found in FreeRTOS/Source/include/FreeRTOSConfig.h
*/

/* We sleep a lot, so cooperative multitasking is fine. */
#define configUSE_PREEMPTION 0

/* Blink doesn't really need a lot of stack space! */
#define configMINIMAL_STACK_SIZE 128

/* ここに追加機能を定義する */
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1

/* Use the defaults for everything else */
#include_next<FreeRTOSConfig.h>

//#define configUSE_TRACE_FACILITY



以下のコードでSoftAPモードとして起動します。
APの情報(SSIDとパスワード)は以下で指定しています。
#define AP_SSID "esp-open-rtos"
#define AP_PSK "esp-open-rtos"

/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <string.h>
#include <espressif/esp_common.h>
#include <esp/uart.h>
#include <FreeRTOS.h>
#include <task.h>
#include <dhcpserver.h>
#include <ssid_config.h>

#include <lwip/api.h>

#define AP_SSID "esp-open-rtos"
#define AP_PSK "esp-open-rtos"

void WifiTask(void *pvParameters)
{
    TickType_t nowTick;
    nowTick = xTaskGetTickCount();

    uint8_t if_index;
    if (sdk_wifi_get_opmode() == SOFTAP_MODE) {
      printf("[%s:%d] start SOFTAP MODE\n",pcTaskGetName(0),nowTick);
      if_index = SOFTAP_IF;
    }
    if (sdk_wifi_get_opmode() == STATION_MODE) {
      printf("[%s:%d] start STATION MODE\n",pcTaskGetName(0),nowTick);
      if_index = STATION_IF;
    }
    printf("[%s:%d] if_index=%d\n",pcTaskGetName(0),nowTick,if_index);

    struct ip_info info;
    while(1) {
      if(sdk_wifi_get_ip_info(if_index, &info)) {
        /*
        #define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
        ip4_addr2_16(ipaddr), \
        ip4_addr3_16(ipaddr), \
        ip4_addr4_16(ipaddr)
        #define IPSTR"%d.%d.%d.%d"
        */
        nowTick = xTaskGetTickCount();
        printf("[%s:%d] IPaddress="IPSTR"\n",pcTaskGetName(0),nowTick,IP2STR(&info.ip));
        if(ip4_addr1_16(&info.ip) != 0) break;
      }
      vTaskDelay(100);
    }
    printf("[%s:%d] Netmask="IPSTR"\n",pcTaskGetName(0),nowTick,IP2STR(&info.netmask));
    printf("[%s:%d] Gateway="IPSTR"\n",pcTaskGetName(0),nowTick,IP2STR(&info.gw));

    char buffer[256];
    vTaskList(buffer);
    printf("%s",buffer);

    while(1) {
      vTaskDelay(100);
    }
}

void user_init(void)
{
    uart_set_baud(0, 115200);
    printf("[%s] uxTaskPriorityGet=%d\n",pcTaskGetName(0),(int)uxTaskPriorityGet(0));

    uint8_t wifiMode = SOFTAP_MODE;
    //uint8_t wifiMode = STATION_MODE;
    printf("[%s] wifiMode=%d\n",pcTaskGetName(0),wifiMode);

    if (wifiMode == SOFTAP_MODE) {
      printf("[%s] SOFTAP_MODE\n",pcTaskGetName(0));
      struct ip_info ap_ip;
      IP4_ADDR(&ap_ip.ip, 172, 16, 0, 1);
      IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0);
      IP4_ADDR(&ap_ip.netmask, 255, 255,0, 0);
      sdk_wifi_set_ip_info(1, &ap_ip);

      struct sdk_softap_config ap_config =
      { .ssid = AP_SSID, .ssid_hidden = 0,.channel = 3, .ssid_len = strlen(AP_SSID),
        .authmode =AUTH_WPA_WPA2_PSK, .password = AP_PSK, .max_connection =3, .beacon_interval = 100, };

      sdk_wifi_set_opmode(SOFTAP_MODE);
      sdk_wifi_softap_set_config(&ap_config);

      // Start DHCP-Server with 4 leases
      ip_addr_t first_client_ip;
      IP4_ADDR(&first_client_ip, 172, 16, 0, 2);
      dhcpserver_start(&first_client_ip,4);
    }

    if (wifiMode == STATION_MODE) {
      printf("[%s] STATION_MODE\n",pcTaskGetName(0));
      struct sdk_station_config st_config = {
        .ssid =WIFI_SSID,
        .password =WIFI_PASS,
      };

      sdk_wifi_set_opmode(STATION_MODE);
      sdk_wifi_station_set_config(&st_config);
    }

    xTaskCreate(WifiTask, "WifiTask", 512, NULL, 2, NULL);
}

実行すると以下の表示となります。
[uiT] uxTaskPriorityGet=14
[uiT] wifiMode=2
[uiT] SOFTAP_MODE
mode : softAP(86:0d:8e:8c:f4:00)
add if1
bcn 100
[WifiTask:136] start SOFTAP MODE
[WifiTask:136] if_index=1
[WifiTask:136] IPaddress=172.16.0.1
[WifiTask:136] Netmask=255.255.0.0
[WifiTask:136] Gateway=0.0.0.0
WifiTask        X       2       283     9
Tmr Svc         R       2       443     6
pmTask          R       1       154     2
IDLE            R       0       106     5
tcpip_thread    B       10      397     3
uiT             D       14      675     4
rtc_timer_task  S       12      135     7
DHCP Server     B       2       197     8
ppTask          B       14      433     1

ここで注意する点が2つあります。
1つは、一度でもSoftAPモードで起動すると、明示的にモードを変更しない限り、SoftAPモードのままとなります。
また、接続してくるStationへIPアドレスを払い出すために、DHCP Serverタスクを起動しますが、
このタスクは優先度が2なので、優先度が14のuser_initを終了しないと動くことができません。



Stationモードへの変更は先ほどのコードの一部を変更します。
{前略}
    //uint8_t wifiMode = SOFTAP_MODE;
    uint8_t wifiMode = STATION_MODE;
    printf("[%s] wifiMode=%d\n",pcTaskGetName(0),wifiMode);
{後略}

実行すると以下の表示となります。
[uiT] uxTaskPriorityGet=14
[uiT] wifiMode=1
[uiT] STATION_MODE
mode : sta(84:0d:8e:8c:f4:00)
add if0
[WifiTask:6] start STATION MODE
[WifiTask:6] if_index=0
[WifiTask:6] IPaddress=0.0.0.0
scandone
[WifiTask:143] IPaddress=0.0.0.0
add 0
aid 8
cnt

connected with aterm-e625c0-g, channel 10
dhcp client start...
[WifiTask:243] IPaddress=0.0.0.0
[WifiTask:343] IPaddress=0.0.0.0
ip:192.168.10.119,mask:255.255.255.0,gw:192.168.10.1
[WifiTask:443] IPaddress=192.168.10.119
[WifiTask:443] Netmask=255.255.255.0
[WifiTask:443] Gateway=192.168.10.1
WifiTask        X       2       327     8
Tmr Svc         R       2       129     6
IDLE            R       0       52      5
tcpip_thread    B       10      278     3
pmTask          B       1       97      2
ppTask          B       14      198     1
rtc_timer_task  S       12      137     7

ここでも注意する点が2つあります。
1つは、一度でもStationモードで起動すると、明示的にモードを変更しない限り、Stationモードのままとなります。
また、APへの接続を行うバックグラウンドのタスクは優先度=2で動きます。
優先度が14のuser_initを終了しないと、APへの接続ができません。



あまり使い道はないかもしれませんが、以下のようにするとWiFiを全く使わない状態で起動します。
一度でもこのモードで起動すると、明示的にSoftAPモードか、Stationモードを指定しないと、
これ以降、APへの接続を行いません。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <string.h>
#include <espressif/esp_common.h>
#include <esp/uart.h>
#include <FreeRTOS.h>
#include <task.h>
#include <dhcpserver.h>

(中略)

void user_init(void)
{
  uart_set_baud(0, 115200);
  printf("SDK version:%s\n", sdk_system_get_sdk_version());
  printf("pcTaskGetName=%s\n",pcTaskGetName(0));
  sdk_wifi_set_opmode(NULL_MODE);

  xTaskCreate(task1, "task1", 256, NULL, 2, NULL);
}

続く....