[参考] 基于 Ai-M61-32S 的AP网页配网实现 Step 3

[复制链接]
查看738 | 回复4 | 2023-12-6 21:08:52 | 显示全部楼层 |阅读模式

本帖最后由 WT_0213 于 2023-12-7 11:23 编辑

在 基于 Ai-M61-32S 的AP网页配网实现 Step 2 中已经将 WIFI 信息存储到了 flash当中。

[参考] 基于 Ai-M61-32S 的AP网页配网实现 Step 2 https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=43766

接下来就是读取WIFI信息数据,并连接到WIFI。

创建 WIFI相关代码

wifi/wifi_event.h

/**
 * @file wifi_event.h
 * @author your name ([email]you@domain.com[/email])
 * @brief
 * @version 0.1
 * @date 2023-06-29
 *
 * @copyright Copyright (c) 2023
 *
*/
#ifndef WIFI_EVENT_H
#define WIFI_EVENT_H
#include "stdint.h"

int wifi_start_firmware_task(void);
void wifi_event_handler(uint32_t code);
uint8_t wifi_connect(char* ssid, char* passwd);
#endif

wifi/wifi_event.c

/**
 * @file wifi_event.c
 * @author your name ([email]you@domain.com[/email])
 * @brief
 * @version 0.1
 * @date 2023-06-29
 *
 * @copyright Copyright (c) 2023
 *
*/
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

#include <lwip/tcpip.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#include "bl_fw_api.h"
#include "wifi_mgmr_ext.h"
#include "wifi_mgmr.h"
#include "bflb_irq.h"
#include "bflb_uart.h"
#include "bflb_l1c.h"
#include "bflb_mtimer.h"

#include "bl616_glb.h"
#include "rfparam_adapter.h"

#include "board.h"
#include "log.h"

#include "storage.h"
#define DBG_TAG "WIFI EVENT"

#define WIFI_STACK_SIZE     (1024*4)
#define TASK_PRIORITY_FW    (16)

static wifi_conf_t conf =
{
    .country_code = "CN",
};
static TaskHandle_t wifi_fw_task;
static uint32_t sta_ConnectStatus = 0;
xQueueHandle queue;

/**
 * @brief WiFi 任务
 *
 * @return int
*/
int wifi_start_firmware_task(void)
{
    LOG_I("Starting wifi ...");

    /* enable wifi clock */

    GLB_PER_Clock_UnGate(GLB_AHB_CLOCK_IP_WIFI_PHY | GLB_AHB_CLOCK_IP_WIFI_MAC_PHY | GLB_AHB_CLOCK_IP_WIFI_PLATFORM);
    GLB_AHB_MCU_Software_Reset(GLB_AHB_MCU_SW_WIFI);

    /* set ble controller EM Size */

    GLB_Set_EM_Sel(GLB_WRAM160KB_EM0KB);

    if (0 != rfparam_init(0, NULL, 0)) {
        LOG_I("PHY RF init failed!");
        return 0;
    }

    LOG_I("PHY RF init success!");

    /* Enable wifi irq */

    extern void interrupt0_handler(void);
    bflb_irq_attach(WIFI_IRQn, (irq_callback)interrupt0_handler, NULL);
    bflb_irq_enable(WIFI_IRQn);

    xTaskCreate(wifi_main, (char*)"fw", WIFI_STACK_SIZE, NULL, TASK_PRIORITY_FW, &wifi_fw_task);

    return 0;
}
/**
 * @brief wifi event handler
 *      WiFi 事件回调
 *
 * @param code
*/


void wifi_event_handler(uint32_t code)
{

    sta_ConnectStatus = code;
    BaseType_t xHigherPriorityTaskWoken;
    switch (code) {
        case CODE_WIFI_ON_INIT_DONE:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_INIT_DONE", __func__);
            wifi_mgmr_init(&conf);
        }
        break;
        case CODE_WIFI_ON_MGMR_DONE:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_MGMR_DONE", __func__);

        }
        break;
        case CODE_WIFI_ON_SCAN_DONE:
        {
            char* scan_msg = pvPortMalloc(128);
            memset(scan_msg, 0, 128);
            wifi_mgmr_sta_scanlist();
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_SCAN_DONE SSID numbles:%d", __func__, wifi_mgmr_sta_scanlist_nums_get());
            sprintf(scan_msg, "{\"wifi_scan\":{\"status\":0}}");
            // xQueueSend(queue, scan_msg, );
            if (wifi_mgmr_sta_scanlist_nums_get()>0) {
                xQueueSendFromISR(queue, scan_msg, &xHigherPriorityTaskWoken);
                if (xHigherPriorityTaskWoken) {
                    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
                }
            }

            vPortFree(scan_msg);
        }
        break;
        case CODE_WIFI_ON_CONNECTED:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_CONNECTED", __func__);
            void mm_sec_keydump();
            mm_sec_keydump();
        }
        break;
        case CODE_WIFI_ON_GOT_IP:
        {

            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_GOT_IP", __func__);
        }
        break;
        case CODE_WIFI_ON_DISCONNECT:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_DISCONNECT", __func__);
            char* queue_buff = pvPortMalloc(128);
            memset(queue_buff, 0, 128);
            sprintf(queue_buff, "{\"wifi_disconnect\":true}");
            xQueueSendFromISR(queue, queue_buff, pdTRUE);
            vPortFree(queue_buff);
        }
        break;
        case CODE_WIFI_ON_AP_STARTED:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STARTED", __func__);
        }
        break;
        case CODE_WIFI_ON_AP_STOPPED:
        {
            LOG_I("[APP] [EVT] %s, CODE_WIFI_ON_AP_STOPPED", __func__);
        }
        break;
        case CODE_WIFI_ON_AP_STA_ADD:
        {
            LOG_I("[APP] [EVT] [AP] [ADD] %lld", xTaskGetTickCount());
        }
        break;
        case CODE_WIFI_ON_AP_STA_DEL:
        {
            LOG_I("[APP] [EVT] [AP] [DEL] %lld", xTaskGetTickCount());
        }
        break;
        default:
        {
            LOG_I("[APP] [EVT] Unknown code %u ", code);
        }
    }
}

uint8_t wifi_connect(char* ssid, char* passwd)
{
    int ret = 255;
    // struct fhost_vif_ip_addr_cfg ip_cfg = { 0 };
    uint32_t ipv4_addr = 0;
    char* queue_buff = pvPortMalloc(128);
    memset(queue_buff, 0, 128);
    if (NULL==ssid || 0==strlen(ssid)) {
        return 1;
    }

    if (wifi_mgmr_sta_state_get() == 1) {
        wifi_sta_disconnect();
    }
    if (wifi_sta_connect(ssid, passwd, NULL, NULL, 0, 0, 0, 1)) {
        return 4;
    }
    LOG_I("Wating wifi connet");
    //等待连接成功
    sta_ConnectStatus = 0;
    for (int i = 0;i<10*30;i++) {

        vTaskDelay(100/portTICK_PERIOD_MS);
        switch (sta_ConnectStatus) {
            case CODE_WIFI_ON_MGMR_DONE:
                // vTaskDelay(2000);
                // LOG_I("wifi_mgmr_sta_scan:%d", wifi_mgmr_sta_scan(wifi_scan_config));
                vPortFree(queue_buff);
                return 3;
            case CODE_WIFI_ON_SCAN_DONE:

                // LOG_I("WIFI STA SCAN DONE %s", wifi_scan_config[0].ssid_array);

                vPortFree(queue_buff);
                return 2;
            case CODE_WIFI_ON_DISCONNECT:   //连接失败(超过了重连次数还没有连接成功的状态)
                LOG_I("Wating wifi connet Faild");
                // wifi_sta_disconnect();

                vPortFree(queue_buff);
                return 4;
            case CODE_WIFI_ON_CONNECTED:    //连接成功(表示wifi sta状态的时候表示同时获取IP(DHCP)成功,或者使用静态IP)
                // LOG_I("Wating wifi connet OK \r\n");
                break;
            case CODE_WIFI_ON_GOT_IP:
                wifi_sta_ip4_addr_get(&ipv4_addr, NULL, NULL, NULL);
                LOG_I("wifi connened %s,IP:%s", ssid, inet_ntoa(ipv4_addr));
                sprintf(queue_buff, "{\"ip\":{\"IP\":\"%s\"}}", inet_ntoa(ipv4_addr));

                flash_erase_set(SSID_KEY, ssid);
                flash_erase_set(PASS_KEY, passwd);
                xQueueSend(queue, queue_buff, portMAX_DELAY);
                LOG_I("Wating wifi connet OK and get ip OK");
                vPortFree(queue_buff);

                return 0;
            default:
                //等待连接成功
                break;
        }

    }
    vPortFree(queue_buff);
    return 14; //连接超时
}

main.c增加如下内容:

.......

#include "wifi_event.h"


.......

/**
 * @brief  void queue_task(void* arg)
 * 消息队列循环读取
 * @param arg
*/
static void queue_task(void* arg)
{
    char* ssid = NULL;
    char* password = NULL;
    ssid = flash_get_data(SSID_KEY, 32);
    password = flash_get_data(PASS_KEY, 32);
    if (ssid!=NULL && strlen(ssid) > 0)
    {
        printf("read flash ssid:%s password:%s\r\n", ssid, password);
        wifi_connect(ssid, password);
    }
    else {
        printf("ssid read value is NULL:%06X\r\n", SSID_KEY);
    }
}

int main(void)
{
    .......
    // 初始化 存储
    flash_init();


    // 初始化tcp ip
    tcpip_init(NULL, NULL);
    // 启动WiFi任务
    wifi_start_firmware_task();
    char* ssid = NULL;
    ssid = flash_get_data(SSID_KEY, 32);
    if (ssid!=NULL && strlen(ssid) > 0){
        xTaskCreate(queue_task, "queue task", 1024*6, NULL, 2, NULL);
    }

   .......
}

修改 proj.conf 增加如下内容:

# wifi
set(CONFIG_VIF_MAX 2)
set(CONFIG_STA_MAX 4)
set(CONFIG_MAC_TXQ_DEPTH 32)
set(CONFIG_MAC_RXQ_DEPTH 12)

修改 CMakeLists.txt 增加如下内容:

target_sources(app PRIVATE
    wifi/wifi_event.c // 增加wifi相关代码
    storage/storage.c
    web/cJSON.c
    web/mlwip_https.c
)

目前当前方案存在以下问题:

  1. 中文WIFI名称无法连接
  2. 设置WIFI信息后AP消失
  3. WIFI信息填写错误,无法修复并且重新编译也不行

解决方案:

  1. 尽量使用和连接英文WIFI
  2. 重新烧写固件
  3. 擦除芯片内容烧写

flash_prog_cfg.ini 配置文件

[cfg] # 0:无擦除,1:程序化截面擦除,2:芯片擦除

0: no erase, 1:programmed section erase, 2: chip erase

erase = 1

改为

[cfg] # 0:无擦除,1:程序化截面擦除,2:芯片擦除

0: no erase, 1:programmed section erase, 2: chip erase

erase = 2

再执行 make flash COMX=COM?【?代表你的COM号】 命令就可以擦除数据了。

到这里基于 Ai-M61-32S 的AP网页配网实现就完成了。

如果觉得还不错的话,可以 给个 企业微信截图_20231207112020.png+ 1 哦。

本帖被以下淘专辑推荐:

回复

使用道具 举报

爱笑 | 2023-12-7 08:43:36 | 显示全部楼层
优秀
用心做好保姆工作
回复

使用道具 举报

xiaoxie888 | 2023-12-7 09:27:47 | 显示全部楼层
太厉害了
回复

使用道具 举报

心云 | 2023-12-19 08:47:38 | 显示全部楼层
回复

使用道具 举报

MrZeFr | 2024-7-8 20:37:27 | 显示全部楼层
可以判断WiFi断开,然后清除WIFI信息,然后自动重启不行吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则