本帖最后由 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
)
目前当前方案存在以下问题:
- 中文WIFI名称无法连接
- 设置WIFI信息后AP消失
- WIFI信息填写错误,无法修复并且重新编译也不行
解决方案:
- 尽量使用和连接英文WIFI
- 重新烧写固件
- 擦除芯片内容烧写
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网页配网实现就完成了。
如果觉得还不错的话,可以 给个 + 1 哦。