[bsp][amebaz] BSP工程更新,适配新的WLAN框架

This commit is contained in:
tyx 2018-10-19 16:45:41 +08:00 committed by tangyuxin
parent 1699a12b15
commit 646cb6cabc
24 changed files with 1437 additions and 13239 deletions

View File

@ -13,15 +13,24 @@ CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=1000
CONFIG_RT_DEBUG=y
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_DEBUG_INIT=0
CONFIG_RT_DEBUG_THREAD=0
CONFIG_RT_USING_HOOK=y
CONFIG_RT_IDEL_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=256
CONFIG_RT_USING_TIMER_SOFT=y
CONFIG_RT_TIMER_THREAD_PRIO=4
CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
CONFIG_RT_DEBUG=y
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
# CONFIG_RT_DEBUG_IPC_CONFIG is not set
# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
# CONFIG_RT_DEBUG_MEM_CONFIG is not set
# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
#
# Inter-Thread communication
@ -53,13 +62,14 @@ CONFIG_RT_USING_DEVICE=y
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="dbg"
# CONFIG_RT_USING_MODULE is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
# CONFIG_RT_USING_USER_MAIN is not set
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_PRIORITY=10
#
# C++ features
@ -82,7 +92,7 @@ CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_USING_MSH_DEFAULT=y
# CONFIG_FINSH_USING_MSH_ONLY is not set
CONFIG_FINSH_USING_MSH_ONLY=y
CONFIG_FINSH_ARG_MAX=10
#
@ -94,26 +104,49 @@ CONFIG_FINSH_ARG_MAX=10
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
CONFIG_RT_USING_SERIAL=y
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_PIN is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_MTD is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
CONFIG_RT_USING_WIFI=y
CONFIG_RT_USING_WLAN_STA=y
CONFIG_RT_USING_WLAN_AP=y
CONFIG_WIFI_DEVICE_STA_NAME="w0"
CONFIG_WIFI_DEVICE_AP_NAME="ap"
# CONFIG_RT_USING_AUDIO is not set
#
# Using WiFi
#
CONFIG_RT_USING_WIFI=y
CONFIG_RT_WLAN_DEVICE_STA_NAME="wlan0"
CONFIG_RT_WLAN_DEVICE_AP_NAME="wlan1"
CONFIG_RT_WLAN_DEFAULT_PROT="lwip"
CONFIG_RT_WLAN_SCAN_WAIT_MS=10000
CONFIG_RT_WLAN_CONNECT_WAIT_MS=10000
CONFIG_RT_WLAN_SSID_MAX_LENGTH=32
CONFIG_RT_WLAN_PASSWORD_MAX_LENGTH=32
CONFIG_RT_WLAN_SCAN_SORT=y
CONFIG_RT_WLAN_CFG_INFO_MAX=3
CONFIG_RT_WLAN_WORKQUEUE_THREAD_NAME="wlan_job"
CONFIG_RT_WLAN_WORKQUEUE_THREAD_SIZE=2048
CONFIG_RT_WLAN_WORKQUEUE_THREAD_PRIO=22
CONFIG_RT_WLAN_DEV_EVENT_NUM=2
# CONFIG_RT_WLAN_PROT_LWIP_PBUF_FORCE is not set
CONFIG_RT_WLAN_DEBUG=y
CONFIG_RT_WLAN_CMD_DEBUG=y
# CONFIG_RT_WLAN_MGNT_DEBUG is not set
# CONFIG_RT_WLAN_DEV_DEBUG is not set
# CONFIG_RT_WLAN_PROT_DEBUG is not set
# CONFIG_RT_WLAN_CFG_DEBUG is not set
# CONFIG_RT_WLAN_LWIP_DEBUG is not set
#
# Using USB
#
@ -127,15 +160,21 @@ CONFIG_RT_USING_LIBC=y
# CONFIG_RT_USING_PTHREADS is not set
#
# Network stack
# Network
#
#
# Socket abstraction layer
#
# CONFIG_RT_USING_SAL is not set
#
# light weight TCP/IP stack
#
CONFIG_RT_USING_LWIP=y
CONFIG_RT_USING_LWIP141=y
# CONFIG_RT_USING_LWIP202 is not set
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP202=y
# CONFIG_RT_USING_LWIP_IPV6 is not set
CONFIG_RT_LWIP_IGMP=y
CONFIG_RT_LWIP_ICMP=y
# CONFIG_RT_LWIP_SNMP is not set
@ -178,11 +217,18 @@ CONFIG_LWIP_SO_SNDTIMEO=1
CONFIG_LWIP_SO_RCVBUF=1
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_RT_LWIP_STATS is not set
# CONFIG_RT_LWIP_DEBUG is not set
#
# Modbus master and slave stack
#
# CONFIG_RT_USING_MODBUS is not set
#
# AT commands
#
# CONFIG_RT_USING_AT is not set
# CONFIG_LWIP_USING_DHCPD is not set
#
@ -212,7 +258,6 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_NANOPB is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
#
# Wi-Fi
@ -230,7 +275,16 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_WIZNET is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
#
# security packages
@ -242,6 +296,7 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
#
# language packages
#
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
@ -258,6 +313,7 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_RDB is not set
#
# system packages
@ -271,22 +327,29 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_CMSIS is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
#
# peripheral libraries and drivers
#
# CONFIG_PKG_USING_STM32F4_HAL is not set
# CONFIG_PKG_USING_STM32F4_DRIVERS is not set
CONFIG_PKG_USING_REALTEK_AMEBA=y
CONFIG_PKG_REALTEK_AMEBA_PATH="/packages/peripherals/realtek_ameba"
CONFIG_PKG_USING_REALTEK_AMEBA_LATEST_VERSION=y
# CONFIG_PKG_USING_REALTEK_AMEBA_V100 is not set
CONFIG_PKG_REALTEK_AMEBA_VER="latest"
# CONFIG_PKG_USING_CC3200_SDK is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_AHT10 is not set
# CONFIG_PKG_USING_AP3216C is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_U8G2 is not set
#
# miscellaneous packages
#
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
@ -298,17 +361,52 @@ CONFIG_PKG_REALTEK_AMEBA_VER="latest"
#
# sample package
#
# CONFIG_PKG_USING_SAMPLES is not set
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
#
# example package: hello
#
# CONFIG_PKG_USING_HELLO is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_MDNS is not set
# CONFIG_PKG_USING_UPNP is not set
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RDBD_SRC is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
#
# Test Packages of RealThread
#
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
#
# Env config
#
# CONFIG_SYS_AUTO_UPDATE_PKGS is not set
# CONFIG_SYS_CREATE_MDK_IAR_PROJECT is not set
# CONFIG_SYS_PKGS_DOWNLOAD_ACCELERATE is not set
CONFIG_RT_USING_UART0=y
# CONFIG_BSP_USING_UART0 is not set
CONFIG_BSP_USING_WIFI=y

View File

@ -26,10 +26,6 @@ config $ENV_DIR
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "$ENV_DIR/tools/scripts/cmds/Kconfig"
config RT_USING_UART0
bool "Using RT_USING_UART0"
default y
source "$BSP_DIR/drivers/Kconfig"
select PKG_USING_REALTEK_AMEBA

View File

@ -17,8 +17,8 @@ amebaz 是由Realtek推出的Cortex-M4内核的WiFi SOC芯片rtl8710b系列
| 环境 | 说明 |
| ------------ | ------------------------------------------------------------ |
| PC操作系统 | Linux/MacOS/Windows |
| 编译器 | arm-none-eabi-gcc version 6.3.1 20170620 (release)/iar |
| 构建工具 | scons/iar |
| 编译器 | arm-none-eabi-gcc version 6.3.1 20170620 (release) |
| 构建工具 | scons |
| 依赖软件环境 | Env工具/(IAR或arm-none-eabi-gcc)/git/调试器驱动 |
1) 下载源码
@ -40,9 +40,9 @@ amebaz 是由Realtek推出的Cortex-M4内核的WiFi SOC芯片rtl8710b系列
Windows
>在[RT-Thread官网][1]下载ENV工具包
>在[RT-Thread官网][1]下载ENV工具包并参考官网给出的env使用教程
3) 配置芯片型号
3) 配置工程(可选)
Linux/Mac
@ -56,8 +56,6 @@ amebaz 是由Realtek推出的Cortex-M4内核的WiFi SOC芯片rtl8710b系列
menuconfig
```
在menuconfig页面配置并选择对应的芯片型号若开发环境为IAR则需要生成工程
4) 下载package
amebaz配套的驱动库以package形式提供故需先下载对应的package(realtek-ameba)请使用env下载package
@ -66,28 +64,11 @@ amebaz配套的驱动库以package形式提供故需先下载对应的package
pkgs --update
```
5) 生成工程(Mac/Linux下请跳过此步骤)
*该板级支持包不支持生成mdk的工程及iar工程后续会支持iar工程
Windows IAR
5) 编译
```bash
SET RTT_CC=iar
scons --target=iar -s
```
*该板级支持包不支持生成mdk的工程
6) 编译
使用IAR请参见对应教程
Windows arm-none-eabi-gcc
使用以下指令设置gcc路径
```bash
SET RTT_EXEC_PATH=[GCC路径]
```
Windows可以使用env编译工程无需设置GCC工具链路径直接在bsp/amebaz工程目录下编译即可。
Linux/Mac arm-none-eabi-gcc
使用以下指令设置gcc路径
@ -148,15 +129,103 @@ msh />
*默认串口
## 4. WIFI简单使用
## 4. 驱动支持情况及计划
### 4.1 wifi扫描命令
wifi 扫描命令格式如下
```unknown
wifi scan
```
命令说明
| 字段 | 描述 |
| ---- | ------------------------ |
| wifi | 有关wifi命令都以wifi开头 |
| scan | wifi执行扫描动作 |
在调试工具中输入该命令,即可进行 wifi 命令扫描,调试信息如下
```unknown
scan ap down
SSID MAC security rssi chn Mbps
------------------------------- ----------------- -------------- ---- --- ----
NEO-shanghai-ap2 58:66:ba:a1:ee:71 WPA2_TKIP_PSK -74 11 0
WQ1 88:25:93:94:51:54 WPA2_AES_PSK -76 13 0
shyc1 a0:40:a0:a3:e8:c9 WPA2_AES_PSK -77 13 0
KVIP 70:65:82:3b:71:43 WPA2_AES_PSK -83 11 0
YST2016 88:25:93:c6:67:d1 WPA2_TKIP_PSK -84 4 0
```
> 注:
>
> 测试命令有关 wifi,均以wifi开头。
### 4.2 wifi 接入
接入 wifi 之前,先介绍一下其接入的命令 ,如下
```unknown
wifi join ssid 123456789
```
命令说明
| 字段 | 描述 |
| --------- | ---------------------------------- |
| wifi | 有关wifi命令都以wifi开头 |
| join | wifi执行连接动作 |
| ssid | 热点的名字 |
| 123456789 | 热点的密码,没有密码可不输入这一项 |
了解上述命令,并且成功完成前面步骤,在串口中输入 `wifi w0 join realthread_VIP 123456789` ,如下日志表示连接成功
```unknown
WIFI wlan0 Setting:
==============================
MODE => STATION
SSID => realthread_VIP
CHANNEL => 6
SECURITY => AES
PASSWORD => 123456789
[I/WLAN.mgnt] wifi connect success ssid:realthread_VIP
```
另外提供一个简单的测试使用命令查询设备IP地址命令ifconfig。
```unknown
network interface: w0 (Default)
MTU: 1500
MAC: 00 e0 4c d5 ac 46
FLAGS: UP LINK_UP ETHARP BROADCAST
ip address: 172.16.200.110
gw address: 172.16.200.1
net mask : 255.255.255.0
dns server #0: 172.16.200.1
dns server #1: 223.5.5.5
```
## 5. 驱动支持情况及计划
| 驱动 | 支持情况 | 备注 |
| ---------- | :------: | :--------------------------: |
| UART | 支持 | UART0 |
| UART | 支持 | UART0 |
| WLAN | 部分支持 | 仅支持STA模式 |
## 6. 已知问题
## 5. 联系人信息
wlan仅支持STA模式连接WIFI输入错误密码时会宕机。
## 7. 联系人信息
维护人:
[flyingcys][4] < [flyingcys@163.com][5] >

View File

@ -15,19 +15,12 @@
#include <rthw.h>
#include <rtthread.h>
/**
* @addtogroup ameba
*/
/*@{*/
#include <rtdevice.h>
int main(void)
{
rt_kprintf("build time: %s %s\n", __DATE__, __TIME__);
rt_kprintf("Hello RT-Thread!\n");
rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
return 0;
}
/*@}*/

View File

@ -0,0 +1,9 @@
config BSP_USING_UART0
bool "Using UART0"
select RT_USING_SERIAL
default y
config BSP_USING_WIFI
bool "Using WIFI"
select RT_USING_WIFI
default y

View File

@ -5,14 +5,9 @@ list = os.listdir(cwd)
objs = []
src = Split('''
board.c
drv_uart.c
''')
if GetDepend(['RT_USING_LWIP']):
src += Split('''
drv_wifi.c
''')
board.c
drv_uart.c
''')
CPPPATH = [cwd]

View File

@ -37,7 +37,7 @@ struct device_uart
rt_uint32_t irqno;
};
#ifdef RT_USING_UART0
#ifdef BSP_USING_UART0
static struct rt_serial_device serial0;
static struct device_uart uart0;
#endif
@ -230,7 +230,7 @@ int rt_hw_uart_init(void)
struct rt_serial_device *serial;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef RT_USING_UART0
#ifdef BSP_USING_UART0
{
struct device_uart *uart;

View File

@ -1,453 +0,0 @@
/*
* File : drv_wifi.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
* 2018-5-30 flyingcys add amebaz wifi driver
*/
#include <rtthread.h>
#include <wlan_dev.h>
#include <skbuff.h>
#include "amebaz_wlan.h"
//#define ETH_RX_DUMP
//#define ETH_TX_DUMP
//#define MINI_DUMP
struct sk_buff * rltk_wlan_get_recv_skb(int idx);
struct sk_buff * rltk_wlan_alloc_skb(unsigned int total_len);
#define MAX_ADDR_LEN 6
struct ameba_wifi
{
struct rt_wlan_device parent;
rt_uint8_t dev_addr[MAX_ADDR_LEN];
int idx;
int connected;
};
#ifdef RT_USING_WLAN_STA
static struct ameba_wifi wifi_sta;
#endif
#ifdef RT_USING_WLAN_AP
static struct ameba_wifi wifi_ap;
#endif
#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
static void packet_dump(const char *msg, const struct pbuf *p)
{
const struct pbuf *q;
rt_uint32_t i, j;
rt_uint8_t *ptr;
rt_kprintf("%s %d byte\n", msg, p->tot_len);
#ifdef MINI_DUMP
return;
#endif
i = 0;
for (q = p; q != RT_NULL; q = q->next)
{
ptr = q->payload;
for (j = 0; j < q->len; j++)
{
if ((i % 8) == 0)
{
rt_kprintf(" ");
}
if ((i % 16) == 0)
{
rt_kprintf("\r\n");
}
rt_kprintf("%02x ", *ptr);
i++;
ptr++;
}
}
rt_kprintf("\n\n");
}
#endif /* dump */
#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
void netif_set_connected(int connected)
{
wifi_sta.connected = connected;
if (connected)
{
netifapi_netif_set_link_up(wifi_sta.parent.parent.netif);
}
else
{
netifapi_netif_set_link_down(wifi_sta.parent.parent.netif);
}
}
void rltk_wlan_set_netif_info(int idx_wlan, void * dev, unsigned char * dev_addr)
{
struct ameba_wifi *wifi;
if(idx_wlan == 0)
wifi = &wifi_sta;
rtw_memcpy(wifi->dev_addr, dev_addr, 6);
rt_hw_wifi_init();
}
void netif_rx(int idx, unsigned int len)
{
struct ameba_wifi *wifi;
struct pbuf *p, *q;
int sg_len = 0;
struct sk_buff *skb = RT_NULL;
if(idx == 0)
wifi = &wifi_sta;
#if CONFIG_WLAN
if(!wifi->connected || !rltk_wlan_running(idx))
return;
#endif
skb = rltk_wlan_get_recv_skb(idx);
if(!skb)
{
rt_kprintf("netif_rx rltk_wlan_get_recv_skb NULL.\n");
return;
}
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != RT_NULL)
{
pbuf_take(p, skb->data, len);
skb_pull(skb, len);
#ifdef ETH_RX_DUMP
packet_dump("RX dump", p);
#endif /* ETH_RX_DUMP */
if(wifi->parent.parent.netif->input(p, wifi->parent.parent.netif) != ERR_OK)
{
pbuf_free(p);
}
}
else
{
rt_kprintf("pbuf_alloc NULL for wifi RX.\n");
}
}
int netif_is_valid_IP(int idx, unsigned char *ip_dest)
{
struct netif * pnetif;
struct ip_addr addr = { 0 };
u32_t *ip_dest_addr = (u32_t*)ip_dest;
if(idx == 0)
pnetif = wifi_sta.parent.parent.netif;
addr.addr = *ip_dest_addr;
if(pnetif == RT_NULL)
return 0;
if(pnetif->ip_addr.addr == 0)
return 1;
if(ip_addr_ismulticast(&addr) || ip_addr_isbroadcast(&addr,pnetif))
{
return 1;
}
if(ip_addr_cmp(&(pnetif->ip_addr), &addr))
return 1;
return 0;
}
void netif_post_sleep_processing(void)
{
}
void netif_pre_sleep_processing(void)
{
}
unsigned char *rltk_wlan_get_ip(int idx)
{
struct ameba_wifi *wifi;
if(idx == 0)
wifi = &wifi_sta;
return (unsigned char *)&(wifi->parent.parent.netif->ip_addr);
}
struct netif *rltk_wlan_get_netif(int idx)
{
struct netif *netif;
if(idx == 0)
netif = wifi_sta.parent.parent.netif;
else if(idx == 1)
netif = wifi_ap.parent.parent.netif;
return netif;
}
rt_err_t rt_ameba_wifi_init(rt_device_t dev)
{
return RT_EOK;
}
rt_err_t rt_ameba_wifi_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
rt_err_t rt_ameba_wifi_close(rt_device_t dev)
{
return RT_EOK;
}
rt_size_t rt_ameba_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
rt_size_t rt_ameba_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
rt_err_t rt_ameba_wifi_control(rt_device_t dev, int cmd, void *args)
{
switch(cmd)
{
case NIOCTL_GADDR:
{
struct ameba_wifi *wifi = (struct ameba_wifi *)dev;
if(args)
memcpy(args, wifi->dev_addr, MAX_ADDR_LEN);
else
return -RT_ERROR;
}
break;
case WIFI_INIT:
{
rt_wlan_mode_t mode = *(rt_wlan_mode_t *)args;
rt_kprintf("mode:%d\n", mode);
}
break;
case WIFI_SCAN:
{
struct rt_wlan_scan_result *dst = RT_NULL;
dst = (struct rt_wlan_scan_result *)rt_malloc(sizeof(struct rt_wlan_scan_result));
if(dst == RT_NULL)
{
rt_kprintf("rt_malloc for scan result failed!\n");
return -RT_ENOMEM;
}
memset(dst, 0, sizeof(struct rt_wlan_scan_result));
if(amebaz_wifi_scan(dst) != RT_EOK)
{
rt_kprintf("amebaz_wifi_scan failed...\n");
return -RT_ERROR;
}
*(struct rt_wlan_scan_result **)args = dst;
}
break;
case WIFI_JOIN:
break;
case WIFI_EASYJOIN:
{
struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev;
if(amebaz_wifi_connect(wlan->info->ssid, (char *)args) != RT_EOK)
{
rt_kprintf("amebaz_wifi_connect failed...\n");
return -RT_ERROR;
}
}
break;
case WIFI_SOFTAP:
{
struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev;
if(amebaz_wifi_ap_start(wlan->info->ssid, (char *)args, wlan->info->channel) != RT_EOK)
{
rt_kprintf("amebaz_wifi_ap_start failed...\n");
return -RT_ERROR;
}
}
break;
case WIFI_DISCONNECT:
if(amebaz_wifi_disconnect() != RT_EOK)
{
rt_kprintf("amebaz_wifi_disconnect failed...\n");
return -RT_ERROR;
}
break;
case WIFI_GET_RSSI:
{
int *rssi = (int *)args;
*rssi = amebaz_wifi_get_rssi();
}
break;
case WIFI_ENTER_POWERSAVE:
break;
case WIFI_CFG_MONITOR:
break;
case WIFI_SET_CHANNEL:
{
int channel = *(int *)args;
amebaz_wifi_set_channel(channel);
}
break;
case WIFI_GET_CHANNEL:
{
int *channel = (int *)args;
*channel = amebaz_wifi_get_channel();
}
break;
case WIFI_SET_MONITOR_CALLBACK:
break;
}
return RT_EOK;
}
rt_err_t rt_ameba_wifi_tx(rt_device_t dev, struct pbuf* p)
{
rt_err_t result = RT_EOK;
struct ameba_wifi *wifi = (struct ameba_wifi *)dev;
int idx;
rt_base_t level;
struct sk_buff *skb = RT_NULL;
idx = wifi->idx;
level = rt_hw_interrupt_disable();
if(wifi->connected && rltk_wlan_check_isup(idx))
rltk_wlan_tx_inc(idx);
else
{
rt_hw_interrupt_enable(level);
// rt_kprintf("is not: connected && rltk_wlan_check_isup(idx)\n");
result = -RT_ERROR;
goto _exit;
}
rt_hw_interrupt_enable(level);
#ifdef ETH_TX_DUMP
packet_dump("TX dump", p);
#endif /* ETH_TX_DUMP */
skb = rltk_wlan_alloc_skb(p->tot_len);
if(skb != RT_NULL)
{
/* copy pbuf to a whole ETH frame */
pbuf_copy_partial(p, skb->tail, p->tot_len, 0);
skb_put(skb, p->tot_len);
rltk_wlan_send_skb(idx, skb);
}
else
{
rt_kprintf("rltk_wlan_alloc_skb NULL for WIFI TX.\n");
result = -RT_ENOMEM;
}
_exit:
level = rt_hw_interrupt_disable();
rltk_wlan_tx_dec(idx);
rt_hw_interrupt_enable(level);
return result;
}
int rt_hw_wifi_init(void)
{
rt_kprintf("%s %d\n", __FUNCTION__, __LINE__);
#ifdef RT_USING_WLAN_STA
wifi_sta.parent.parent.parent.init = rt_ameba_wifi_init;
wifi_sta.parent.parent.parent.open = rt_ameba_wifi_open;
wifi_sta.parent.parent.parent.close = rt_ameba_wifi_close;
wifi_sta.parent.parent.parent.read = rt_ameba_wifi_read;
wifi_sta.parent.parent.parent.write = rt_ameba_wifi_write;
wifi_sta.parent.parent.parent.control = rt_ameba_wifi_control;
wifi_sta.parent.parent.parent.user_data = RT_NULL;
//
wifi_sta.idx = 0;
//
wifi_sta.parent.parent.eth_rx = RT_NULL;
wifi_sta.parent.parent.eth_tx = rt_ameba_wifi_tx;
/* register wifi device */
eth_device_init(&wifi_sta.parent.parent, WIFI_DEVICE_STA_NAME);
#endif
#ifdef RT_USING_WLAN_AP
#endif
return RT_EOK;
}

View File

@ -6,10 +6,11 @@ CPPPATH = [cwd, str(Dir('#'))]
src = []
if GetDepend(['RT_USING_LWIP']):
src += Split('''
amebaz_wlan.c
''')
src += Split('''
drv_wifi.c
drv_wlan.c
''')
group = DefineGroup('amebaz_wlan', src, depend = [''], CPPPATH = CPPPATH)
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -1,642 +0,0 @@
/*
* File : amebaz_wlan.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
* 2018-6-12 flyingcys add amebaz wlan interface
*/
#include <rtthread.h>
#include <netif/ethernetif.h>
#include "wifi_structures.h"
#include "wifi_constants.h"
#include <wifi/wifi_util.h>
#include <wifi/wifi_conf.h>
#define PASSWD_LEN 65
#define SCAN_WAIT_TIME 10000
typedef enum
{
WIFI_NONE,
WIFI_STATION,
WIFI_AP,
} rt_wlan_mode_t;
struct rt_wlan_info
{
rt_wlan_mode_t mode; /* wifi mode */
rtw_security_t security;
char *ssid;
uint8_t bssid[6];
/* maximal data rate */
uint32_t datarate;
/* radio channel */
uint16_t channel;
/* signal strength */
int16_t rssi;
};
typedef struct rt_wlan_scan_result
{
char ap_num;
struct rt_wlan_info *ap_table;
} rt_wlan_scan_result_t;
static rtw_network_info_t wifi_info = {0};
static rtw_ap_info_t ap_info = {0};
static unsigned char wifi_password[65] = {0};
static unsigned char ap_password[PASSWD_LEN] = {0};
static rt_sem_t scan_done_sem = RT_NULL;
static char *scan_buf = RT_NULL;
static int ApNum = 0;
extern struct netif *rltk_wlan_get_netif(int idx);
static void LwIP_ReleaseIP(uint8_t idx)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
struct netif *pnetif = rltk_wlan_get_netif(idx);
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 0, 0, 0, 0);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
}
static rtw_result_t amebaz_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result )
{
if (malloced_scan_result->scan_complete != RTW_TRUE) {
rtw_scan_result_t* record = &malloced_scan_result->ap_details;
record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */
++ ApNum;
if(malloced_scan_result->user_data)
memcpy((void *)((char *)malloced_scan_result->user_data+(ApNum-1)*sizeof(rtw_scan_result_t)), (char *)record, sizeof(rtw_scan_result_t));
}
else
{
rt_kprintf("ap num:%d\n", ApNum);
if(scan_done_sem)
{
rt_sem_release(scan_done_sem);
}
}
return RTW_SUCCESS;
}
static int amebaz_wifi_do_scan(void)
{
int ret = RTW_SUCCESS;
rt_kprintf("wifi scan start...\n");
scan_buf = malloc(65*sizeof(rtw_scan_result_t));
if(scan_buf == NULL){
ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY;
return -RT_ENOMEM;
}
memset(scan_buf, 0, 65 * sizeof(rtw_scan_result_t));
if((ret = wifi_scan_networks(amebaz_scan_result_handler, scan_buf)) != RTW_SUCCESS){
rt_kprintf("ERROR: wifi scan failed\n\r");
return -RT_ERROR;
}
return RT_EOK;
}
int amebaz_wifi_scan(struct rt_wlan_scan_result *dst)
{
rt_uint32_t i;
rt_uint32_t j = 0;
scan_done_sem = rt_sem_create("scandone", 0, RT_IPC_FLAG_FIFO);
if(scan_done_sem == RT_NULL)
return -RT_ENOMEM;
if(amebaz_wifi_do_scan() != RT_EOK)
{
rt_kprintf("amebaz_wifi_do_scan failed...\n");
return -RT_ERROR;
}
if(rt_sem_take(scan_done_sem, rt_tick_from_millisecond(SCAN_WAIT_TIME)) != RT_EOK)
{
rt_kprintf("scan wait timeout...\n");
return -RT_ETIMEOUT;
}
if(scan_done_sem)
{
rt_sem_delete(scan_done_sem);
scan_done_sem = RT_NULL;
}
rtw_scan_result_t *ptr = (rtw_scan_result_t *)scan_buf;
dst->ap_num = ApNum;
ApNum = 0;
dst->ap_table = (struct rt_wlan_info *)rt_malloc(sizeof(struct rt_wlan_info) * dst->ap_num);
if(dst->ap_table == RT_NULL)
{
rt_kprintf("rt_malloc for ap table failed...\n");
goto __exit;
}
for(i = 0; i < dst->ap_num; i ++)
{
dst->ap_table[i].mode = 1;
dst->ap_table[i].security = ptr->security;
dst->ap_table[i].ssid = (char *)rt_malloc(33);
if(dst->ap_table[i].ssid == RT_NULL)
{
rt_kprintf("rt_malloc for ssid Failed! times:%d,total:%d\n",i,ApNum);
j = i;
goto __exit;
}
memset(dst->ap_table[i].ssid, 0, 33);
memcpy(dst->ap_table[i].ssid, ptr->SSID.val, ptr->SSID.len);
memcpy(dst->ap_table[i].bssid, ptr->BSSID.octet, 6);
dst->ap_table[i].datarate = 0;
dst->ap_table[i].channel = ptr->channel;
dst->ap_table[i].rssi = ptr->signal_strength;
ptr ++;
}
if(scan_buf != RT_NULL)
{
rt_free(scan_buf);
scan_buf = RT_NULL;
}
return RT_EOK;
__exit:
if(scan_buf != RT_NULL)
{
rt_free(scan_buf);
scan_buf = RT_NULL;
}
if(dst->ap_table)
{
for(i = 0; i < j; i ++)
rt_free(dst->ap_table[i].ssid);
rt_free(dst->ap_table);
dst->ap_table = RT_NULL;
dst->ap_num = 0;
}
return -RT_ERROR;
}
void amebaz_wifi_info_init(void)
{
memset(wifi_info.ssid.val, 0, sizeof(wifi_info.ssid.val));
memset(wifi_info.bssid.octet, 0, 6);
memset(wifi_password, 0, sizeof(wifi_password));
wifi_info.ssid.len = 0;
wifi_info.password = NULL;
wifi_info.password_len = 0;
wifi_info.key_id = -1;
memset(ap_info.ssid.val, 0, sizeof(ap_info.ssid.val));
ap_info.ssid.len = 0;
ap_info.security_type = RTW_SECURITY_UNKNOWN;
ap_info.password = NULL;
ap_info.password_len = 0;
ap_info.channel = 1;
}
static int amebaz_wifi_set_sta_info(char *ssid, char *passwd)
{
if(ssid == RT_NULL || strlen(ssid) > 32)
{
rt_kprintf("Invalid argument...\n");
return -RT_EINVAL;
}
strcpy(wifi_info.ssid.val, ssid);
wifi_info.ssid.len = strlen(ssid);
if(passwd != NULL)
{
if(strlen(passwd) > 64)
{
rt_kprintf("Invalid argument...\n");
return -RT_EINVAL;
}
strcpy(wifi_password, passwd);
wifi_info.password = wifi_password;
wifi_info.password_len = strlen(passwd);
}
else
wifi_info.password = RT_NULL;
return RT_EOK;
}
static int amebaz_wifi_set_ap_info(char *ssid, char *passwd, int channel)
{
if(ssid == RT_NULL || strlen(ssid) > 32)
{
rt_kprintf("Invalid argument...\n");
return -RT_EINVAL;
}
strcpy(ap_info.ssid.val, ssid);
ap_info.ssid.len = strlen(ssid);
if(passwd != NULL)
{
if(strlen(passwd) > 64)
{
rt_kprintf("Invalid argument...\n");
return -RT_EINVAL;
}
strcpy(ap_password, passwd);
ap_info.password = ap_password;
ap_info.password_len = strlen(passwd);
}
else
ap_info.password = RT_NULL;
ap_info.channel = channel;
return RT_EOK;
}
static int amebaz_wifi_do_connect(void)
{
int mode, ret;
char empty_bssid[6] = {0};
char assoc_by_bssid = 0;
rt_kprintf("amebaz wifi do connect start...\n");
if(memcmp (wifi_info.bssid.octet, empty_bssid, 6))
{
assoc_by_bssid = 1;
}
else if(wifi_info.ssid.val[0] == 0)
{
ret = RTW_BADARG;
return -RT_ERROR;
}
if(wifi_info.password != RT_NULL)
{
if((wifi_info.key_id >= 0) && (wifi_info.key_id <= 3))
{
wifi_info.security_type = RTW_SECURITY_WEP_PSK;
}
else
{
wifi_info.security_type = RTW_SECURITY_WPA2_AES_PSK;
}
}
else
{
wifi_info.security_type = RTW_SECURITY_OPEN;
}
//Check if in AP mode
wext_get_mode(WLAN0_NAME, &mode);
if(mode == IW_MODE_MASTER)
{
#if 0
#if CONFIG_LWIP_LAYER
dhcps_deinit();
#endif
wifi_off();
vTaskDelay(20);
if (wifi_on(RTW_MODE_STA) < 0){
printf("\n\rERROR: Wifi on failed!");
ret = RTW_ERROR;
goto EXIT;
}
#endif
}
if(assoc_by_bssid)
{
rt_kprintf("Joining BSS by BSSID \"MAC_FMT\" ...\n", MAC_ARG(wifi_info.bssid.octet));
ret = wifi_connect_bssid(wifi_info.bssid.octet, (char*)wifi_info.ssid.val, wifi_info.security_type, (char*)wifi_info.password,
ETH_ALEN, wifi_info.ssid.len, wifi_info.password_len, wifi_info.key_id, NULL);
}
else
{
rt_kprintf("\n\rJoining BSS by SSID %s...\n\r", (char*)wifi_info.ssid.val);
ret = wifi_connect((char*)wifi_info.ssid.val, wifi_info.security_type,
(char*)wifi_info.password, wifi_info.ssid.len,
wifi_info.password_len, wifi_info.key_id, NULL);
}
if(ret!= RTW_SUCCESS)
{
if(ret == RTW_INVALID_KEY)
rt_kprintf("ERROR:Invalid Key\n");
rt_kprintf("ERROR: Can't connect to AP\n");
return -RT_ERROR;
}
rt_kprintf("now start dhcp...\n");
netif_set_connected(1);
dhcp_start(netif_default);
rt_kprintf("dhcp success...\n");
return RT_EOK;
}
int amebaz_wifi_connect(char *ssid, char *passwd)
{
int ret;
ret = amebaz_wifi_set_sta_info(ssid, passwd);
if(ret != RT_EOK)
{
amebaz_wifi_info_init();
return ret;
}
if(amebaz_wifi_do_connect() != RT_EOK)
{
amebaz_wifi_info_init();
rt_kprintf("amebaz_wifi_do_connect failed...\n");
return -RT_ERROR;
}
amebaz_wifi_info_init();
return RT_EOK;
}
static int amebaz_wifi_do_disconnect(void)
{
int timeout = 20;
char essid[33];
int ret = RTW_SUCCESS;
if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0)
{
rt_kprintf("\nWIFI disconnected!\n");
return -RT_ERROR;
}
if((ret = wifi_disconnect()) < 0)
{
return -RT_ERROR;
}
while(1)
{
if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0)
{
rt_kprintf("\nWIFI disconnected!\n");
break;
}
if(timeout == 0)
{
rt_kprintf("ERROR: Deassoc timeout!\n\r");
ret = RTW_TIMEOUT;
break;
}
vTaskDelay(10);
timeout --;
}
LwIP_ReleaseIP(WLAN0_IDX);
if(ret != RTW_SUCCESS)
return -RT_ERROR;
rt_kprintf("amebaz wifi do disconnect success...\n");
return RT_EOK;
}
int amebaz_wifi_disconnect(void)
{
int ret = RT_EOK;
ret = amebaz_wifi_do_disconnect();
if(ret != RT_EOK)
rt_kprintf("amebaz_wifi_do_disconnect failed...\n");
amebaz_wifi_info_init();
return ret;
}
static int amebaz_wifi_do_ap_start(void)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
struct netif *pnetif = rltk_wlan_get_netif(1);
int timeout = 20;
int ret = RTW_SUCCESS;
if(ap_info.ssid.val[0] == 0){
rt_kprintf("ERROR: SSID can't be empty\n\r");
return -RT_ERROR;
}
if(ap_info.password == NULL)
{
ap_info.security_type = RTW_SECURITY_OPEN;
}
else
{
if(ap_info.password_len <= RTW_MAX_PSK_LEN && ap_info.password_len >= RTW_MIN_PSK_LEN)
{
ap_info.security_type = RTW_SECURITY_WPA2_AES_PSK;
}
else
{
rt_kprintf("ERROR: password length is between 8 to 64 \n");
return -RT_ERROR;
}
}
//#if CONFIG_LWIP_LAYER
// dhcps_deinit();
// IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
// IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
// IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
// netif_set_addr(pnetif, &ipaddr, &netmask,&gw);
//#ifdef CONFIG_DONT_CARE_TP
// pnetif->flags |= NETIF_FLAG_IPSWITCH;
//#endif
//#endif
wifi_off();
vTaskDelay(20);
if (wifi_on(RTW_MODE_AP) < 0)
{
rt_kprintf("ERROR: Wifi on failed!\n");
return -RT_ERROR;
}
rt_kprintf("Now start AP mode...\n");
if((ret = wifi_start_ap((char*)ap_info.ssid.val, ap_info.security_type, (char*)ap_info.password, ap_info.ssid.len, ap_info.password_len, ap_info.channel) ) < 0)
{
rt_kprintf("ERROR: Operation failed!");
return -RT_ERROR;
}
while(1)
{
char essid[33];
if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) > 0)
{
if(strcmp((const char *) essid, (const char *)ap_info.ssid.val) == 0)
{
rt_kprintf("AP %s started...\n", ap_info.ssid.val);
ret = RTW_SUCCESS;
break;
}
}
if(timeout == 0)
{
rt_kprintf("ERROR: Start AP timeout!");
ret = RTW_TIMEOUT;
break;
}
vTaskDelay(10);
timeout --;
}
if(ret != RTW_SUCCESS)
return -RT_ERROR;
//#if CONFIG_LWIP_LAYER
//LwIP_UseStaticIP(pnetif);
// dhcps_init(pnetif);
//#endif
return RT_EOK;
}
static int amebaz_wifi_do_ap_stop(void)
{
return RT_EOK;
}
int amebaz_wifi_ap_start(char *ssid, char *passwd, int channel)
{
int ret;
ret = amebaz_wifi_set_ap_info(ssid, passwd, channel);
if(ret != RT_EOK)
{
amebaz_wifi_info_init();
return ret;
}
if(amebaz_wifi_do_ap_start() != RT_EOK)
{
amebaz_wifi_info_init();
rt_kprintf("amebaz_wifi_ap_start failed...\n");
return -RT_ERROR;
}
amebaz_wifi_info_init();
return RT_EOK;
}
int amebaz_wifi_ap_stop(void)
{
int ret;
if(amebaz_wifi_do_ap_stop() != RT_EOK)
{
amebaz_wifi_info_init();
rt_kprintf("amebaz_wifi_ap_stop failed...\n");
return -RT_ERROR;
}
amebaz_wifi_info_init();
return RT_EOK;
}
int amebaz_wifi_get_rssi(void)
{
int rssi = 0;
wifi_get_rssi(&rssi);
return rssi;
}
void amebaz_wifi_set_channel(int channel)
{
wifi_set_channel(channel);
}
int amebaz_wifi_get_channel(void)
{
int channel;
wifi_get_channel(&channel);
return channel;
}
int amebaz_wifi_init(rt_wlan_mode_t mode)
{
int ret;
rtw_mode_t rtw_mode;
if(mode == WIFI_STATION)
rtw_mode = RTW_MODE_STA;
else if(mode == WIFI_AP)
rtw_mode = RTW_MODE_AP;
if(wifi_on(mode) < 0)
return -RT_ERROR;
if(wifi_set_autoreconnect(1) < 0)
return -RT_ERROR;
return RT_EOK;
}

View File

@ -1,54 +0,0 @@
/*
* File : amebaz_wlan.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
* 2018-6-12 flyingcys add amebaz wlan interface
*/
#ifndef __AMEBAZ_WLAN_H__
#define __AMEBAZ_WLAN_H__
int amebaz_wifi_scan();
void amebaz_wifi_info_init(void);
int amebaz_wifi_set_sta_info(char *ssid, char *passwd);
int amebaz_wifi_set_ap_info(char *ssid, char *passwd);
int amebaz_wifi_connect(char *ssid, char *passwd);
int amebaz_wifi_disconnect(void);
int amebaz_wifi_ap_start(char *ssid, char *passwd, int channel);
int amebaz_wifi_ap_stop(void);
int amebaz_wifi_get_rssi(void);
void amebaz_wifi_set_channel(int channel);
int amebaz_wifi_get_channel(void);
int amebaz_wifi_init(rt_wlan_mode_t mode);
#endif /* __AMEBAZ_WLAN_H__ */

View File

@ -0,0 +1,662 @@
/*
* File : drv_wifi.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
* 2018-5-30 flyingcys add amebaz wifi driver
*/
#include <skbuff.h>
#include "board.h"
#include <string.h>
#include <drv_wlan.h>
#include <wlan_dev.h>
#include "drv_wlan.h"
#include "drv_wifi.h"
#define DBG_ENABLE
#define DBG_LEVEL DBG_INFO
#define DBG_SECTION_NAME "WIFI"
#define DBG_COLOR
#include <rtdbg.h>
#define MAX_ADDR_LEN (6)
#define RT_WLAN_SSID_MAX_LEN (32)
#define WIFI_INIT_FLAG (0x1 << 0)
#define WIFI_MAC_FLAG (0x1 << 1)
#define WIFI_TYPE_STA (0)
#define WIFI_TYPE_AP (1)
struct ameba_wifi
{
struct rt_wlan_device *wlan;
rt_uint8_t dev_addr[MAX_ADDR_LEN];
rt_uint8_t flag;
int connected;
int type;
};
extern unsigned char rltk_wlan_running(unsigned char idx);
extern struct sk_buff * rltk_wlan_get_recv_skb(int idx);
extern unsigned char rltk_wlan_check_isup(int idx);
extern void rltk_wlan_tx_inc(int idx);
extern struct sk_buff * rltk_wlan_alloc_skb(unsigned int total_len);
extern void rltk_wlan_send_skb(int idx, struct sk_buff *skb);
extern void rltk_wlan_tx_dec(int idx);
extern void rtw_event_register(int event, void (*fun)(char *buf, int len, int flags, void *user_data) , void *user_data);
static const struct rt_wlan_dev_ops ops;
static struct ameba_wifi wifi_sta;
static struct ameba_wifi wifi_ap;
rt_inline struct ameba_wifi *rthw_wifi_get_dev(int idx)
{
int mode = rthw_wifi_mode_get();
if (mode == 1) return &wifi_sta;
if (mode == 2) return &wifi_ap;
if (idx == 0) return &wifi_sta;
if (idx == 1) return &wifi_ap;
return RT_NULL;
}
rt_inline int rthw_wifi_get_idx(struct ameba_wifi *wifi)
{
int mode = rthw_wifi_mode_get();
if (mode == 1) return 0;
if (mode == 2) return 0;
return wifi->type;
}
int rthw_wifi_register(struct ameba_wifi *wifi)
{
struct rt_wlan_device *wlan = RT_NULL;
if ((wifi->flag & WIFI_INIT_FLAG) == 0)
{
if (wifi->type == WIFI_TYPE_STA)
wlan = rt_wlan_dev_register(RT_WLAN_DEVICE_STA_NAME, &ops, 0, wifi);
if (wifi->type == WIFI_TYPE_AP)
wlan = rt_wlan_dev_register(RT_WLAN_DEVICE_AP_NAME, &ops, 0, wifi);
wifi->flag |= WIFI_INIT_FLAG;
wifi->wlan = wlan;
LOG_D("F:%s L:%d wifi:0x%08x wlan:0x%08x\n", __FUNCTION__, __LINE__, wifi, wlan);
}
return RT_EOK;
}
void netif_post_sleep_processing(void)
{
}
void netif_pre_sleep_processing(void)
{
}
unsigned char *rltk_wlan_get_ip(int idx)
{
struct ameba_wifi *wifi;
wifi = rthw_wifi_get_dev(idx);
if (wifi == RT_NULL)
return RT_NULL;
LOG_D("F:%s L:%d is run", __FUNCTION__, __LINE__);
/* 这里留空了,会不会炸未知 */
return RT_NULL;
}
int netif_is_valid_IP(int idx, unsigned char *ip_dest)
{
LOG_D("F:%s L:%d is run ip: %d:%d:%d:%d", __FUNCTION__, __LINE__,
ip_dest[0], ip_dest[1], ip_dest[2], ip_dest[3]);
return 1;
}
void rltk_wlan_set_netif_info(int idx, void *dev, rt_uint8_t *dev_addr)
{
struct ameba_wifi *wifi = RT_NULL;
wifi = rthw_wifi_get_dev(idx);
if (wifi == RT_NULL)
return;
LOG_D("F:%s L:%d wifi:0x%08x type:0x%x", __FUNCTION__, __LINE__, wifi, wifi->flag);
rt_memcpy(wifi->dev_addr, dev_addr, 6);
wifi->flag |= WIFI_MAC_FLAG;
rthw_wifi_register(wifi);
LOG_D("wifi type:%d", wifi->type);
LOG_D("idx:%d MAC %02x:%02x:%02x:%02x:%02x:%02x", idx, dev_addr[0], dev_addr[1], dev_addr[2], dev_addr[3], dev_addr[4], dev_addr[5]);
}
static void rtw_connect_callbackfn(char *buf, int len, int flags, void *user_data)
{
struct ameba_wifi *wifi = user_data;
LOG_D("L:%d wifi connect callback flags:%d user_data:%08x", __LINE__, flags, user_data);
wifi->connected = 1;
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_CONNECT, RT_NULL);
}
static void rtw_connect_fail_callbackfn(char *buf, int len, int flags, void *user_data)
{
struct ameba_wifi *wifi = user_data;
LOG_D("L:%d wifi connect callback flags:%d", __LINE__, flags);
wifi->connected = 0;
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_CONNECT_FAIL, RT_NULL);
}
static void rtw_disconnect_callbackfn(char *buf, int len, int flags, void *user_data)
{
struct ameba_wifi *wifi = user_data;
LOG_D("L:%d wifi disconnect callback flags:%d", __LINE__, flags);
wifi->connected = 0;
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_DISCONNECT, RT_NULL);
}
static void rtw_sta_assoc_callbackfn(char *buf, int len, int flags, void *user_data)
{
LOG_D("L:%d wifi sta assoc callback flags:%d", __LINE__, flags);
}
static void rtw_sta_disassoc_callbackfn(char *buf, int len, int flags, void *user_data)
{
LOG_D("L:%d wifi sta assoc callback flags:%d buf:%08x %08x", __LINE__, flags, *((rt_uint32_t*)buf), *((rt_uint32_t*)buf + 4));
}
void netif_rx(int idx, unsigned int len)
{
struct ameba_wifi *wifi = RT_NULL;
struct sk_buff *skb = RT_NULL;
wifi = rthw_wifi_get_dev(idx);
if (wifi == RT_NULL)
return;
LOG_D("F:%s L:%d idx:%d len:%d", __FUNCTION__, __LINE__, idx, len);
if((!wifi->connected) || (!rltk_wlan_running(idx)))
return;
skb = (struct sk_buff *)rltk_wlan_get_recv_skb(idx);
if(!skb)
{
LOG_D("netif_rx rltk_wlan_get_recv_skb NULL.");
return;
}
rt_wlan_dev_report_data(wifi->wlan, skb->data, len);
}
static rt_wlan_security_t security_map_from_ameba(rthw_security_t security)
{
rt_wlan_security_t result = SECURITY_OPEN;
switch (security)
{
case RTHW_SECURITY_OPEN: result = SECURITY_OPEN; break;
case RTHW_SECURITY_WEP_PSK: result = SECURITY_WEP_PSK; break;
case RTHW_SECURITY_WEP_SHARED: result = SECURITY_WEP_SHARED; break;
case RTHW_SECURITY_WPA_TKIP_PSK: result = SECURITY_WPA_TKIP_PSK; break;
case RTHW_SECURITY_WPA_AES_PSK: result = SECURITY_WPA_AES_PSK; break;
case RTHW_SECURITY_WPA2_AES_PSK: result = SECURITY_WPA2_AES_PSK; break;
case RTHW_SECURITY_WPA2_TKIP_PSK: result = SECURITY_WPA2_TKIP_PSK; break;
case RTHW_SECURITY_WPA2_MIXED_PSK: result = SECURITY_WPA2_MIXED_PSK; break;
case RTHW_SECURITY_WPA_WPA2_MIXED: result = SECURITY_WPA2_AES_PSK; break;
case RTHW_SECURITY_WPS_OPEN: result = SECURITY_WPS_OPEN; break;
case RTHW_SECURITY_WPS_SECURE: result = SECURITY_WPS_SECURE; break;
default: result = -1; break;
}
return result;
}
static rthw_security_t security_map_from_rtthread(rt_wlan_security_t security)
{
rt_wlan_security_t result = RTHW_SECURITY_OPEN;
switch (security)
{
case SECURITY_OPEN: result = RTHW_SECURITY_OPEN; break;
case SECURITY_WEP_PSK: result = RTHW_SECURITY_WEP_PSK; break;
case SECURITY_WEP_SHARED: result = RTHW_SECURITY_WEP_SHARED; break;
case SECURITY_WPA_TKIP_PSK: result = RTHW_SECURITY_WPA_TKIP_PSK; break;
case SECURITY_WPA_AES_PSK: result = RTHW_SECURITY_WPA_AES_PSK; break;
case SECURITY_WPA2_AES_PSK: result = RTHW_SECURITY_WPA2_AES_PSK; break;
case SECURITY_WPA2_TKIP_PSK: result = RTHW_SECURITY_WPA2_TKIP_PSK; break;
case SECURITY_WPA2_MIXED_PSK: result = RTHW_SECURITY_WPA2_MIXED_PSK; break;
case SECURITY_WPS_OPEN: result = RTHW_SECURITY_WPS_OPEN; break;
case SECURITY_WPS_SECURE: result = RTHW_SECURITY_WPS_SECURE; break;
default: result = -1; break;
}
return result;
}
static void rt_ameba_wifi_scan_callback(struct rthw_wlan_info *info, void *user_data)
{
struct rt_wlan_info wlan_info = { 0 };
struct rt_wlan_buff buff;
struct ameba_wifi *wifi = user_data;
if (info == RT_NULL)
{
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_SCAN_DONE, RT_NULL);
return;
}
memcpy(&wlan_info.bssid[0], info->bssid, 6);
strncpy(&wlan_info.ssid.val[0], info->ssid, RT_WLAN_SSID_MAX_LEN);
wlan_info.ssid.len = strlen(&wlan_info.ssid.val[0]);
wlan_info.band = info->band == RTHW_802_11_BAND_2_4GHZ ? RTHW_802_11_BAND_2_4GHZ : RTHW_802_11_BAND_5GHZ;
wlan_info.channel = info->channel;
wlan_info.datarate = info->datarate * 1000;
wlan_info.security = security_map_from_ameba(info->security);
wlan_info.rssi = info->rssi;
buff.data = &wlan_info;
buff.len = sizeof(wlan_info);
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_SCAN_REPORT, &buff);
}
static void rthw_wlan_monitor_callback(rt_uint8_t *data, int len, void *user_data)
{
rt_wlan_dev_promisc_handler(wifi_sta.wlan, data, len);
}
static rt_err_t rthw_wlan_init (struct rt_wlan_device *wlan)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static rt_err_t rthw_wlan_mode (struct rt_wlan_device *wlan, rt_wlan_mode_t mode)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d mode:%d", __FUNCTION__, __LINE__, mode);
if (mode == RT_WLAN_STATION)
{
if (wifi->type != WIFI_TYPE_STA)
{
LOG_D("this wlan not support sta mode");
return -RT_ERROR;
}
}
else if (mode == RT_WLAN_AP)
{
if (wifi->type != WIFI_TYPE_AP)
{
LOG_D("this wlan not support ap mode");
return -RT_ERROR;
}
}
return RT_EOK;
}
static rt_err_t rthw_wlan_scan (struct rt_wlan_device *wlan, struct rt_scan_info *scan_info)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
LOG_D("F:%s L:%d wifi:0x%08x type:0x%x", __FUNCTION__, __LINE__, wifi, wifi->type);
if (wifi->type != WIFI_TYPE_STA)
{
LOG_D("this wlan not support scan mode");
return -RT_ERROR;
}
if (rthw_wifi_mode_get() == RTHW_MODE_NONE)
{
if(rthw_wifi_start(RTHW_MODE_STA_AP) != RT_EOK)
{
LOG_D("L:%d wifistart failed...", __LINE__);
return -1;
}
}
rthw_wifi_scan(rt_ameba_wifi_scan_callback, wifi);
return RT_EOK;
}
static rt_err_t rthw_wlan_join (struct rt_wlan_device *wlan, struct rt_sta_info *sta_info)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
int result = 0, i;
char *ssid = RT_NULL, *key = RT_NULL;
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if (wifi->type != WIFI_TYPE_STA)
{
LOG_E("this wlan not support sta mode");
return -RT_ERROR;
}
if ((rthw_wifi_mode_get() != RTHW_MODE_STA) && (rthw_wifi_mode_get() != RTHW_MODE_STA_AP))
{
rthw_wifi_stop();
rt_thread_delay(RT_TICK_PER_SECOND / 10);
if (rthw_wifi_start(RTHW_MODE_STA_AP) != RT_EOK)
{
LOG_E("wifi on failed, join fail");
return -RT_ERROR;
}
}
for (i = 0; i < RT_WLAN_BSSID_MAX_LENGTH; i++)
{
if (sta_info->bssid[i] != 0xff || sta_info->bssid[i] != 0x00)
break;
}
if (i < RT_WLAN_BSSID_MAX_LENGTH)
{
if (sta_info->ssid.len > 0)
ssid = &sta_info->ssid.val[0];
if (sta_info->key.len > 0)
key = &sta_info->key.val[0];
LOG_D("bssid connect bssid: %02x:%02x:%02x:%02x:%02x:%02x ssid:%s ssid_len:%d key:%s key_len%d",
sta_info->bssid[0],sta_info->bssid[1],sta_info->bssid[2],sta_info->bssid[3],sta_info->bssid[4],sta_info->bssid[5],
ssid,
sta_info->ssid.len,
key,
sta_info->key.len
);
result = rthw_wifi_connect_bssid(sta_info->bssid, ssid, sta_info->ssid.len, key, sta_info->key.len, security_map_from_rtthread(sta_info->security));
}
else
{
result = rthw_wifi_connect(sta_info->ssid.val, sta_info->ssid.len, sta_info->key.val, sta_info->key.len, security_map_from_rtthread(sta_info->security));
}
if (result != 0)
{
LOG_E("amebaz_wifi_connect failed...");
return -RT_ERROR;
}
// netif_set_connected((struct ameba_wifi *)wlan, 1);
LOG_D("amebaz_wifi_connect do");
return RT_EOK;
}
static rt_err_t rthw_wlan_softap (struct rt_wlan_device *wlan, struct rt_ap_info *ap_info)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if (wifi->type != WIFI_TYPE_AP)
{
LOG_E("this wlan not support ap mode");
return -RT_ERROR;
}
if (rthw_wifi_ap_start(&ap_info->ssid.val[0], &ap_info->key.val[0], ap_info->channel) != 0)
{
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_AP_STOP, RT_NULL);
wifi->connected = 0;
return -RT_ERROR;
}
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_AP_START, RT_NULL);
wifi->connected = 1;
return RT_EOK;
}
static rt_err_t rthw_wlan_disconnect (struct rt_wlan_device *wlan)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if (wifi->type != WIFI_TYPE_STA)
{
LOG_E("this wlan not support sta mode");
return -RT_ERROR;
}
wifi->connected = 0;
rthw_wifi_sta_disconnect();
rt_wlan_dev_indicate_event_handle(wifi->wlan, RT_WLAN_DEV_EVT_AP_STOP, RT_NULL);
return RT_EOK;
}
static rt_err_t rthw_wlan_ap_stop (struct rt_wlan_device *wlan)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if (wifi->type != WIFI_TYPE_AP)
{
LOG_E("this wlan not support ap mode");
return -RT_ERROR;
}
rthw_wifi_ap_disconnect();
return RT_EOK;
}
static rt_err_t rthw_wlan_ap_deauth (struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static rt_err_t rthw_wlan_scan_stop (struct rt_wlan_device *wlan)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static int rthw_wlan_get_rssi (struct rt_wlan_device *wlan)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)(wlan->user_data);
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if (wifi->type != WIFI_TYPE_STA)
{
LOG_E("this wlan not support sta mode");
return -RT_ERROR;
}
return rthw_wifi_rssi_get();
}
static rt_err_t rthw_wlan_set_powersave (struct rt_wlan_device *wlan, int level)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static int rthw_wlan_get_powersave (struct rt_wlan_device *wlan)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return 0;
}
static rt_err_t rthw_wlan_cfg_promisc (struct rt_wlan_device *wlan, rt_bool_t start)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if(start)
{
rthw_wifi_monitor_callback_set(rthw_wlan_monitor_callback);
rthw_wifi_monitor_enable(1);
}
else
{
rthw_wifi_monitor_callback_set(RT_NULL);
rthw_wifi_monitor_enable(0);
}
return RT_EOK;
}
static rt_err_t rthw_wlan_cfg_filter (struct rt_wlan_device *wlan, struct rt_wlan_filter *filter)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static rt_err_t rthw_wlan_set_channel (struct rt_wlan_device *wlan, int channel)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
rthw_wifi_channel_set(channel);
return RT_EOK;
}
static int rthw_wlan_get_channel (struct rt_wlan_device *wlan)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return rthw_wifi_channel_get();
}
static rt_err_t rthw_wlan_set_country (struct rt_wlan_device *wlan, rt_country_code_t country_code)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static rt_country_code_t rthw_wlan_get_country (struct rt_wlan_device *wlan)
{
LOG_D("F:%s L:%d\n", __FUNCTION__, __LINE__);
return RT_EOK;
}
static rt_err_t rthw_wlan_set_mac (struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return -RT_ERROR;
}
static rt_err_t rthw_wlan_get_mac (struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
struct ameba_wifi *wifi = (struct ameba_wifi *)wlan->user_data;
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
if(mac == RT_NULL)
{
return -RT_ERROR;
}
memcpy(mac, wifi->dev_addr, MAX_ADDR_LEN);
return RT_EOK;
}
static int rthw_wlan_recv (struct rt_wlan_device *wlan, void *buff, int len)
{
LOG_D("F:%s L:%d", __FUNCTION__, __LINE__);
return RT_EOK;
}
static int rthw_wlan_send (struct rt_wlan_device *wlan, void *buff, int len)
{
struct ameba_wifi *wifi = (struct ameba_wifi *)wlan->user_data;
int idx = rthw_wifi_get_idx(wifi);
rt_base_t level;
struct sk_buff *skb = RT_NULL;
LOG_D("F:%s L:%d len:%d", __FUNCTION__, __LINE__, len);
level = rt_hw_interrupt_disable();
if(!wifi->connected || !rltk_wlan_check_isup(idx))
{
rt_hw_interrupt_enable(level);
return -RT_ERROR;
}
rltk_wlan_tx_inc(idx);
rt_hw_interrupt_enable(level);
skb = (struct sk_buff *)rltk_wlan_alloc_skb(len);
if (skb == RT_NULL)
{
LOG_W("rltk_wlan_alloc_skb NULL for WIFI TX.");
goto exit;
}
/* copy buff to a whole ETH frame */
memcpy(skb->tail, buff, len);
skb_put(skb, len);
rltk_wlan_send_skb(idx, skb);
exit:
level = rt_hw_interrupt_disable();
rltk_wlan_tx_dec(idx);
rt_hw_interrupt_enable(level);
LOG_D("F:%s L:%d end", __FUNCTION__, __LINE__);
return RT_EOK;
}
static const struct rt_wlan_dev_ops ops =
{
.wlan_init = rthw_wlan_init ,
.wlan_mode = rthw_wlan_mode ,
.wlan_scan = rthw_wlan_scan ,
.wlan_join = rthw_wlan_join ,
.wlan_softap = rthw_wlan_softap ,
.wlan_disconnect = rthw_wlan_disconnect ,
.wlan_ap_stop = rthw_wlan_ap_stop ,
.wlan_ap_deauth = rthw_wlan_ap_deauth ,
.wlan_scan_stop = rthw_wlan_scan_stop ,
.wlan_get_rssi = rthw_wlan_get_rssi ,
.wlan_set_powersave = rthw_wlan_set_powersave ,
.wlan_get_powersave = rthw_wlan_get_powersave ,
.wlan_cfg_promisc = rthw_wlan_cfg_promisc ,
.wlan_cfg_filter = rthw_wlan_cfg_filter ,
.wlan_set_channel = rthw_wlan_set_channel ,
.wlan_get_channel = rthw_wlan_get_channel ,
.wlan_set_country = rthw_wlan_set_country ,
.wlan_get_country = rthw_wlan_get_country ,
.wlan_set_mac = rthw_wlan_set_mac ,
.wlan_get_mac = rthw_wlan_get_mac ,
.wlan_recv = rthw_wlan_recv ,
.wlan_send = rthw_wlan_send ,
};
int rthw_wifi_low_init(void)
{
static rt_int8_t _init_flag = 0;
if (_init_flag)
{
return 1;
}
rt_memset(&wifi_sta, 0, sizeof(wifi_sta));
rt_memset(&wifi_ap, 0, sizeof(wifi_ap));
wifi_sta.type = WIFI_TYPE_STA;
wifi_ap.type = WIFI_TYPE_AP;
if(rthw_wifi_start(RTHW_MODE_STA_AP) != RT_EOK)
{
LOG_E("amebaz_wifi_start failed...");
return -1;
}
LOG_I("amebaz_wifi_start success");
LOG_D("F:%s L:%d wifi_sta:0x%08x wifi_ap:0x%08x", __FUNCTION__, __LINE__, &wifi_sta, &wifi_ap);
wifi_reg_event_handler(0, rtw_connect_callbackfn, &wifi_sta);
wifi_reg_event_handler(1, rtw_disconnect_callbackfn, &wifi_sta);
wifi_reg_event_handler(8, rtw_sta_assoc_callbackfn, &wifi_ap);
wifi_reg_event_handler(9, rtw_sta_disassoc_callbackfn, &wifi_ap);
_init_flag = 1;
return 0;
}
INIT_DEVICE_EXPORT(rthw_wifi_low_init);

View File

@ -25,7 +25,7 @@
#ifndef __DRV_WIFI_H__
#define __DRV_WIFI_H__
int rt_hw_wifi_init(void);
int rthw_wifi_low_init(void);
#endif /* __DRV_WIFI_H__ */

View File

@ -0,0 +1,375 @@
/*
* File : drv_wlan.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2018-7-10 tyx the first version
*/
#include "wifi_structures.h"
#include "wifi_constants.h"
#include <wifi/wifi_util.h>
#include <wifi/wifi_conf.h>
#ifdef _LITTLE_ENDIAN
#undef _LITTLE_ENDIAN
#endif
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <wlan_dev.h>
#include "drv_wlan.h"
// #define SCAN_WAIT_TIME (10000)
struct scan_user_data
{
struct rt_completion done;
scan_callback_fn fun;
void *data;
};
extern rthw_mode_t wifi_mode;
rthw_mode_t rthw_wifi_mode_get(void)
{
return wifi_mode;
}
int rthw_wifi_stop(void)
{
return wifi_off();
}
int rthw_wifi_start(rthw_mode_t mode)
{
if(wifi_on(mode) < 0)
{
rt_kprintf("ERROR: wifi_on failed\n");
return -1;
}
return 0;
}
int rthw_wifi_connect(char *ssid, int ssid_len, char *password, int pass_len, rthw_security_t security_type)
{
int mode;
rtw_wifi_setting_t setting;
mode = rthw_wifi_mode_get();
if ((mode != RTHW_MODE_STA) && (mode != RTHW_MODE_STA_AP))
{
return -1;
}
if(wext_get_mode(WLAN0_NAME, &mode) < 0)
{
rt_kprintf("L:%d wifi get mode err\n", __LINE__);
return -1;
}
if(wifi_connect(ssid, security_type, password, ssid_len, pass_len, -1, NULL) != RTW_SUCCESS)
{
rt_kprintf("wifi connect fail\n");
return -1;
}
rt_kprintf("wifi connect success\n");
rt_kprintf("Show Wi-Fi information\n");
wifi_get_setting(WLAN0_NAME,&setting);
wifi_show_setting(WLAN0_NAME,&setting);
return 0;
}
int rthw_wifi_connect_bssid(char *bssid, char *ssid, int ssid_len, char *password, int pass_len, rthw_security_t security_type)
{
int mode;
rtw_wifi_setting_t setting;
mode = rthw_wifi_mode_get();
if ((mode != RTHW_MODE_STA) && (mode != RTHW_MODE_STA_AP))
{
return -1;
}
if(wext_get_mode(WLAN0_NAME, &mode) < 0)
{
rt_kprintf("L:%d wifi get mode err\n", __LINE__);
return -1;
}
if(wifi_connect_bssid(bssid, ssid, security_type, password, 6, ssid_len, pass_len, -1, NULL) != RTW_SUCCESS)
{
rt_kprintf("wifi connect fail\n");
return -1;
}
rt_kprintf("wifi connect success\n");
rt_kprintf("Show Wi-Fi information\n");
wifi_get_setting(WLAN0_NAME,&setting);
wifi_show_setting(WLAN0_NAME,&setting);
return 0;
}
int rthw_wifi_ap_start(char *ssid, char *password, int channel)
{
int mode = 0, timeout = 20;
rtw_security_t security_type = RTW_SECURITY_WPA2_AES_PSK;
char *name = RT_NULL;
mode = rthw_wifi_mode_get();
if (mode == RTHW_MODE_AP)
{
name = WLAN0_NAME;
}
else if (mode == RTHW_MODE_STA_AP)
{
name = WLAN1_NAME;
}
else
{
return -1;
}
if(wext_get_mode(name, &mode) < 0)
{
rt_kprintf("L:%d wifi get mode err\n", __LINE__);
return -1;
}
if (password == RT_NULL)
{
security_type = RTW_SECURITY_OPEN;
}
if(wifi_start_ap(ssid, security_type, password, rt_strlen(ssid), rt_strlen(password), 6) != 0)
{
rt_kprintf("ERROR: wifi_start_ap failed\n");
return -1;
}
while(1)
{
char essid[33];
if(wext_get_ssid(name, (unsigned char *) essid) > 0)
{
if(strcmp((const char *) essid, (const char *)ssid) == 0)
{
rt_kprintf("%s started\n", ssid);
break;
}
}
if(timeout == 0)
{
rt_kprintf("Start AP timeout\n");
return -1;
}
rt_thread_delay(1 * RT_TICK_PER_SECOND);
timeout --;
}
return 0;
}
static int rthw_wifi_disconnect(char *name)
{
char essid[33];
int timeout = 20;
const rt_uint8_t null_bssid[ETH_ALEN + 2] = {0, 0, 0, 0, 0, 1, 0, 0};
if (name == RT_NULL)
return -1;
if (wext_get_ssid(name, (unsigned char *) essid) < 0)
{
rt_kprintf("\nWIFI disconnected!\n");
return -1;
}
if (wext_set_bssid(name, null_bssid) < 0)
{
rt_kprintf("Failed to set bogus BSSID to disconnect");
return -1;
}
while (1)
{
if(wext_get_ssid(name, (unsigned char *) essid) < 0)
{
rt_kprintf("WIFI disconnected!\n");
break;
}
if(timeout == 0)
{
rt_kprintf("ERROR: Deassoc timeout!\n");
return -1;
}
rt_thread_delay(10);
timeout --;
}
return 0;
}
int rthw_wifi_sta_disconnect(void)
{
int mode = 0;
char *name = RT_NULL;
mode = rthw_wifi_mode_get();
if (mode == RTHW_MODE_STA)
{
name = WLAN0_NAME;
}
else if (mode == RTHW_MODE_STA_AP)
{
name = WLAN0_NAME;
}
else
{
return -1;
}
return rthw_wifi_disconnect(name);
}
int rthw_wifi_ap_disconnect(void)
{
int mode = 0;
char *name = RT_NULL;
mode = rthw_wifi_mode_get();
if (mode == RTHW_MODE_AP)
{
name = WLAN0_NAME;
}
else if (mode == RTHW_MODE_STA_AP)
{
name = WLAN1_NAME;
}
else
{
return -1;
}
return rthw_wifi_disconnect(name);
}
int rthw_wifi_rssi_get(void)
{
int rssi = 0;
wifi_get_rssi(&rssi);
return rssi;
}
void rthw_wifi_channel_set(int channel)
{
wifi_set_channel(channel);
}
int rthw_wifi_channel_get(void)
{
int channel;
wifi_get_channel(&channel);
return channel;
}
static rtw_result_t rthw_wifi_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result)
{
struct scan_user_data* user_data = malloced_scan_result->user_data;
struct rthw_wlan_info info = { 0 };
if (malloced_scan_result->scan_complete != RTW_TRUE)
{
rtw_scan_result_t* record = &malloced_scan_result->ap_details;
if (user_data->fun != RT_NULL)
{
record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */
info.ssid = record->SSID.val;
info.bssid = record->BSSID.octet;
info.band = record->band;
info.datarate = 0;
info.channel = record->channel;
info.rssi = record->signal_strength;
info.security = record->security;
user_data->fun(&info, user_data->data);
}
}
else
{
user_data->fun(RT_NULL, user_data->data);
rt_free(user_data);
rt_kprintf("scan ap down\n");
}
return RTW_SUCCESS;
}
int rthw_wifi_scan(scan_callback_fn fun, void *data)
{
struct scan_user_data *user_data;
if (fun == RT_NULL)
{
rt_kprintf("scan callback fun is null\n");
return -1;
}
user_data = rt_malloc(sizeof(struct scan_user_data));
if (user_data == RT_NULL)
{
rt_kprintf("wifi scan malloc fail\n");
return -1;
}
user_data->fun = fun;
user_data->data = data;
if (wifi_scan_networks(rthw_wifi_scan_result_handler, user_data) != RTW_SUCCESS)
{
rt_kprintf("ERROR: wifi scan failed\n\r");
return -1;
}
return 0;
}
static rthw_wlan_monitor_callback_t monitor_callback;
static void rthw_wifi_promisc_callback(unsigned char *buf, unsigned int len, void* userdata)
{
if (monitor_callback)
{
monitor_callback(buf, len, RT_NULL);
}
}
void rthw_wifi_monitor_callback_set(rthw_wlan_monitor_callback_t callback)
{
monitor_callback = callback;
}
void rthw_wifi_monitor_enable(int enable)
{
if (enable)
{
wifi_enter_promisc_mode();
wifi_set_promisc(RTW_PROMISC_ENABLE, rthw_wifi_promisc_callback, 1);
rt_kprintf("%s run \n", __FUNCTION__);
}
else
{
wifi_set_promisc(RTW_PROMISC_DISABLE, RT_NULL, 0);
rthw_wifi_stop();
}
}

View File

@ -0,0 +1,101 @@
/*
* File : drv_wlan.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2017, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2018-7-10 tyx the first version
*/
#ifndef __DRV_WLAN_H__
#define __DRV_WLAN_H__
#include <rtthread.h>
typedef enum
{
RTHW_MODE_NONE = 0,
RTHW_MODE_STA,
RTHW_MODE_AP,
RTHW_MODE_STA_AP,
RTHW_MODE_PROMISC,
RTHW_MODE_P2P
}rthw_mode_t;
#define SHARED_ENABLED 0x00008000
#define WPA_SECURITY 0x00200000
#define WPA2_SECURITY 0x00400000
#define WPS_ENABLED 0x10000000
#define WEP_ENABLED 0x0001
#define TKIP_ENABLED 0x0002
#define AES_ENABLED 0x0004
#define WSEC_SWFLAG 0x0008
typedef enum {
RTHW_SECURITY_OPEN = 0, /**< Open security */
RTHW_SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP Security with open authentication */
RTHW_SECURITY_WEP_SHARED = ( WEP_ENABLED | SHARED_ENABLED ), /**< WEP Security with shared authentication */
RTHW_SECURITY_WPA_TKIP_PSK = ( WPA_SECURITY | TKIP_ENABLED ), /**< WPA Security with TKIP */
RTHW_SECURITY_WPA_AES_PSK = ( WPA_SECURITY | AES_ENABLED ), /**< WPA Security with AES */
RTHW_SECURITY_WPA2_AES_PSK = ( WPA2_SECURITY | AES_ENABLED ), /**< WPA2 Security with AES */
RTHW_SECURITY_WPA2_TKIP_PSK = ( WPA2_SECURITY | TKIP_ENABLED ), /**< WPA2 Security with TKIP */
RTHW_SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ), /**< WPA2 Security with AES & TKIP */
RTHW_SECURITY_WPA_WPA2_MIXED = ( WPA_SECURITY | WPA2_SECURITY ), /**< WPA/WPA2 Security */
RTHW_SECURITY_WPS_OPEN = WPS_ENABLED, /**< WPS with open security */
RTHW_SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /**< WPS with AES security */
RTHW_SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */
RTHW_SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force rtw_security_t type to 32 bits */
} rthw_security_t;
typedef enum {
RTHW_802_11_BAND_5GHZ = 0, /**< Denotes 5GHz radio band */
RTHW_802_11_BAND_2_4GHZ = 1 /**< Denotes 2.4GHz radio band */
} rthw_802_11_band_t;
struct rthw_wlan_info
{
char *ssid;
rt_uint8_t *bssid;
rthw_802_11_band_t band;
rt_uint32_t datarate;
rt_uint16_t channel;
rt_int16_t rssi;
rthw_security_t security;
};
typedef void (*scan_callback_fn)(struct rthw_wlan_info *info, void *user_data);
typedef void (*rthw_wlan_monitor_callback_t)(rt_uint8_t *data, int len, void *user_data);
rthw_mode_t rthw_wifi_mode_get(void);
int rthw_wifi_stop(void);
int rthw_wifi_start(rthw_mode_t mode);
int rthw_wifi_connect(char *ssid, int ssid_len, char *password, int pass_len, rthw_security_t security_type);
int rthw_wifi_connect_bssid(char *bssid, char *ssid, int ssid_len, char *password, int pass_len, rthw_security_t security_type);
int rthw_wifi_ap_start(char *ssid, char *password, int channel);
int rthw_wifi_rssi_get(void);
void rthw_wifi_channel_set(int channel);
int rthw_wifi_channel_get(void);
int rthw_wifi_sta_disconnect(void);
int rthw_wifi_ap_disconnect(void);
int rthw_wifi_scan(scan_callback_fn fun, void *data);
void rthw_wifi_monitor_enable(int enable);
void rthw_wifi_monitor_callback_set(rthw_wlan_monitor_callback_t callback);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\project.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -11,15 +11,14 @@
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 1000
#define RT_DEBUG
#define RT_USING_OVERFLOW_CHECK
#define RT_DEBUG_INIT 0
#define RT_DEBUG_THREAD 0
#define RT_USING_HOOK
#define RT_IDEL_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 256
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 512
#define RT_DEBUG
/* Inter-Thread communication */
@ -45,6 +44,9 @@
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
/* C++ features */
@ -62,6 +64,7 @@
#define FINSH_CMD_SIZE 80
#define FINSH_USING_MSH
#define FINSH_USING_MSH_DEFAULT
#define FINSH_USING_MSH_ONLY
#define FINSH_ARG_MAX 10
/* Device virtual file system */
@ -70,13 +73,27 @@
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_USING_PIN
/* Using WiFi */
#define RT_USING_WIFI
#define RT_USING_WLAN_STA
#define RT_USING_WLAN_AP
#define WIFI_DEVICE_STA_NAME "w0"
#define WIFI_DEVICE_AP_NAME "ap"
#define RT_WLAN_DEVICE_STA_NAME "wlan0"
#define RT_WLAN_DEVICE_AP_NAME "wlan1"
#define RT_WLAN_DEFAULT_PROT "lwip"
#define RT_WLAN_SCAN_WAIT_MS 10000
#define RT_WLAN_CONNECT_WAIT_MS 10000
#define RT_WLAN_SSID_MAX_LENGTH 32
#define RT_WLAN_PASSWORD_MAX_LENGTH 32
#define RT_WLAN_SCAN_SORT
#define RT_WLAN_CFG_INFO_MAX 3
#define RT_WLAN_WORKQUEUE_THREAD_NAME "wlan_job"
#define RT_WLAN_WORKQUEUE_THREAD_SIZE 2048
#define RT_WLAN_WORKQUEUE_THREAD_PRIO 22
#define RT_WLAN_DEV_EVENT_NUM 2
#define RT_WLAN_DEBUG
#define RT_WLAN_CMD_DEBUG
/* Using USB */
@ -85,12 +102,15 @@
#define RT_USING_LIBC
/* Network stack */
/* Network */
/* Socket abstraction layer */
/* light weight TCP/IP stack */
#define RT_USING_LWIP
#define RT_USING_LWIP141
#define RT_USING_LWIP202
#define RT_LWIP_IGMP
#define RT_LWIP_ICMP
#define RT_LWIP_DNS
@ -129,6 +149,9 @@
/* Modbus master and slave stack */
/* AT commands */
/* VBUS(Virtual Software BUS) */
@ -148,6 +171,9 @@
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
@ -173,12 +199,23 @@
/* sample package */
/* samples: kernel and components samples */
/* example package: hello */
/* Privated Packages of RealThread */
/* Network Utilities */
/* Test Packages of RealThread */
/* Env config */
#define RT_USING_UART0
#define BSP_USING_WIFI
#endif

View File

@ -9,12 +9,17 @@ if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.join(os.path.normpath(os.getcwd()), 'rt-thread')
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/gcc-arm-none-eabi-5_4-2016q3/bin'
EXEC_PATH = 'C:/work/env/tools/gnu_gcc/arm_gcc/mingw/bin'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iar'
EXEC_PATH = 'C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0'
else:
print 'Please make sure your toolchains is GNU GCC!'
exit(0)
@ -39,7 +44,7 @@ if PLATFORM == 'gcc':
NM = PREFIX + 'nm'
DEVICE = ' -DM3 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections'
CFLAGS = DEVICE + ' -g2 -w -O2 -Wno-pointer-sign -fno-common -fmessage-length=0 -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-short-enums -DF_CPU=166000000L -std=gnu99 -fsigned-char'
CFLAGS = DEVICE + ' -g2 -Wall -Wno-pointer-sign -fno-common -fmessage-length=0 -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-short-enums -DF_CPU=166000000L -std=gnu99 -fsigned-char'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
LFLAGS = DEVICE + ' -lm -lgcc -lc' + ' -g --specs=nano.specs -nostartfiles -Wl,-Map=rtthread.map -Os -Wl,--gc-sections -Wl,--cref -Wl,--entry=Reset_Handler -Wl,--no-enum-size-warning -Wl,--no-wchar-size-warning -T./rlx8711B-symbol-v02-img2_xip1.ld'
LFLAGS += ' -Wl,-wrap,rtl_printf'
@ -48,7 +53,7 @@ if PLATFORM == 'gcc':
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
CFLAGS += ' -Os -gdwarf-2'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<flash_board>
<pass>
<range>CODE 0x8000000 0x8004fff</range>
<loader>$PROJ_DIR$\packages\realtek_ameba-latest\sdk-ameba-v4.0b_without_NDA_GCC_V1.0.0\component\soc\realtek\8711b\misc\iar_utility\common\flashloader\FlashRTL8195aMP.flash</loader>
<abs_offset>0x00000000</abs_offset>
</pass>
<pass>
<range>CODE 0x800b020 0x807ffff</range>
<loader>$PROJ_DIR$\packages\realtek_ameba-latest\sdk-ameba-v4.0b_without_NDA_GCC_V1.0.0\component\soc\realtek\8711b\misc\iar_utility\common\flashloader\FlashRTL8195aMP.flash</loader>
<abs_offset>0xb020</abs_offset>
</pass>
<pass>
<range>CODE 0x10005000 0x10005A6B</range>
<loader>$PROJ_DIR$\packages\realtek_ameba-latest\sdk-ameba-v4.0b_without_NDA_GCC_V1.0.0\component\soc\realtek\8711b\misc\iar_utility\common\flashloader\FlashRTL8195aMP.flash</loader>
<abs_offset>0xb000</abs_offset>
<args>--concat</args>
</pass>
<ignore>CODE 0x10005a6c 0x1003dfff</ignore>
</flash_board>