[原创] EDIMAX N150 EW-7611ULB蓝牙/wifi驱动移植及调试

1. 简介

2. 获取驱动源码

  • 购买时随包装附赠一保存驱动源码和文档的光盘

3. 蓝牙驱动移植

3.1 驱动源码路径

Linux -> Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax
		-> Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax

3.2 修改Makefile

  • 蓝牙驱动的源码放在两个目录中8723BUbluetooth_usb_driver, 共有三个Makefile文件需要修改:顶层Makefile + 8723BU/Makefile + bluetooth_usb_driver/Makefile
  • 跨平台移植驱动,需要交叉编译,交叉编译使用的Linux内核源码版本为5.4.83
  • 务必首先阅读Readme.txt
  • 修改顶层Makefile如下:
SRC_DIR := ./bluetooth_usb_driver
# 内核源码目录
MDL_DIR := /home/jun/share/work/mptcp/arm/linux_build	
# 编译完成后的驱动保存目录
DRV_DIR := ./driver			

FIRMWARE_DIR := 8723BU
##########################################
install:
    make -C $(FIRMWARE_DIR) -s

    - rm $(DRV_DIR)/*.ko
    mkdir -p $(DRV_DIR)
    make -C $(SRC_DIR) -s
    cp -f $(SRC_DIR)/rtk_btusb.ko $(DRV_DIR)/rtk_btusb.ko
    make -C $(SRC_DIR) clean -s
    echo "compile rtk_btusb success!"

##########################################

uninstall:
    make -C $(FIRMWARE_DIR) clean -s

    rm -f $(DRV_DIR)/rtk_btusb.ko
    echo "rm rtk_btusb.ko success!"
##########################################
  • 修改8723BU/Makefile如下:
# 编译完成后驱动保存目录
FW_DIR  := ../driver					
FW_NAME := rtl8723b_fw
CF_NAME := rtl8723bu_config
all:
    @echo "Copy RTL8723BU fw/config to $(FW_DIR)"
    mkdir -p $(FW_DIR)/$(FW_NAME)
    mkdir -p $(FW_DIR)/$(CF_NAME)
    cp -f $(FW_NAME) $(FW_DIR)/$(FW_NAME)
    cp -f $(CF_NAME) $(FW_DIR)/$(CF_NAME)

clean:
    rm -f $(FW_DIR)/$(FW_NAME)
    rm -f $(FW_DIR)/$(CF_NAME)
  • 修改bluetooth_usb_driver/Makefile如下:
# 交叉编译目标平台
ARCH := arm								
# 交叉编译工具
CROSS_COMPILE := aarch64-linux-gnu-		
# 编译完成后驱动保存目录
BUILD_DIR := ../driver					

ifneq ($(KERNELRELEASE),)
    obj-m := rtk_btusb.o
    rtk_btusb-y = rtk_coex.o rtk_bt.o
else
    PWD := $(shell pwd)
    # 内核源码保存目录
    KDIR := /home/jun/share/work/mptcp/arm/linux_build

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules -s
    cp *.ko $(BUILD_DIR)

clean:
    rm -rf *.o *.mod.c *.mod.o *.ko *.symvers *.order *.a

endif

3.3 编译

make install

3.4 编译错误解决

3.4.1 错误一:struct hci_ctrl类型不匹配

/bluetooth_usb_driver/rtk_coex.c:452:18: error: ‘struct hci_ctrl’ has no member named ‘req_start’; did you mean ‘req_flags’?

错误原因:

  • 5.4.83及较新版本的内核中,struct hci_crtl的定义发生了变化

    struct hci_ctrl {
    	u16 opcode;
    	u8 req_flags;
    	u8 req_event;
    	union {
    		hci_req_complete_t req_complete;
    		hci_req_complete_skb_t req_complete_skb;
    	};
    };
    
  • 旧的req_start功能由req_flags替代,设置方法如下

    bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
    

解决方法:

  • rtk_corx.c第452行中的bt_cb(skb)->hci.req_start = true;修改为bt_cb(skb)->hci.req_flags |= HCI_REQ_START;

3.4.2 错误二:setup_timer未声明

bluetooth_usb_driver/rtk_coex.c:537:3: error: implicit declaration of function ‘setup_timer’; did you mean ‘sk_stop_timer’? [-Werror=implicit-function-declaration]


错误原因:

  • 5.4.83版本内核相较于旧版本的内核,将setup_timer替换为了timer_setup

解决方法:

  • 将驱动源码中的所有setup_timer函数都替换为timer_setup

3.4.3 错误三:timer_setup参数类型不匹配

timer.h:125:27: error: passing argument 2 of ‘init_timer_key’ from incompatible pointer type [-Werror=incompatible-pointer-types]
  init_timer_key((_timer), (_fn), (_flags), NULL, NULL)

错误原因:

  • 5.4.83版本内核中timer_setup声明如下:

    void init_timer_key(struct timer_list *timer,
    		    void (*func)(struct timer_list *), unsigned int flags,
    		    const char *name, struct lock_class_key *key);
    #define __init_timer(_timer, _fn, _flags)				\
    	init_timer_key((_timer), (_fn), (_flags), NULL, NULL)
    #define timer_setup(timer, callback, flags)			\
    	__init_timer((timer), (callback), (flags))
    
  • 可见timer_setup的第二个参数为void (*func)(struct timer_list *)的回调函数指针

  • 而在蓝牙驱动源码中,timer_setup的第二个参数为void (*func)(unsigned long)类型函数指针

解决方法:

  • 对驱动源码中所有timer_setup函数的第二个参数进行强制类型转换

  • bluetooth_usb_driver/rtk_coex.h中添加如下声明

    typedef void (*p_func)(struct timer_list *);
    
  • timer_setup函数中添加强制类型转换,示例如下:

    timer_setup(&(btrtl_coex.a2dp_count_timer),(p_func)count_a2dp_packet_timeout, 0);
    

3.4.4 错误四:struct usb_interface中没有成员pm_usage_cnt

bluetooth_usb_driver/rtk_bt.c:720:29: error: ‘struct usb_interface’ has no member named ‘pm_usage_cnt’
     atomic_read(&(data->intf->pm_usage_cnt)));

错误原因:

  • 5.4.83版本内核中 struct usb_interface声明如下, 确实没有成员pm_usage_cnt

    struct usb_interface {
    	struct usb_host_interface *altsetting;
    	struct usb_host_interface *cur_altsetting;	
    	unsigned num_altsetting;	
    	struct usb_interface_assoc_descriptor *intf_assoc;
    
    	int minor;			
    	enum usb_interface_condition condition;		
    	unsigned sysfs_files_created:1;	
    	unsigned ep_devs_created:1;	
    	unsigned unregistering:1;	
    	unsigned needs_remote_wakeup:1;	
    	unsigned needs_altsetting0:1;	
    	unsigned needs_binding:1;	
    	unsigned resetting_device:1;	
    	unsigned authorized:1;		
    
    	struct device dev;		
    	struct device *usb_dev;
    	struct work_struct reset_ws;	
    };
    

解决方法:

  • 阅读驱动源码发现,所有使用pm_usage_cnt成员的地方都是DEBUG日志打印,并不会影响程序运行,如下
  • 既然不会影响程序运行,将相关日志输出全部注释得了,修改rtk_bt.c如下:

3.5 重新编译

make install
  • 编译完成后,会在顶层目录中生成一个driver目录,编译好的驱动rtk_btusb.ko就保存在这个目录下

3.6 安装驱动

  • 安装rtk_btusb.ko

    # insmod rtk_btusb.ko
    
  • 查看dmesg日志

    # dmesg
    [   82.735104] rtk_btusb: Realtek Bluetooth USB driver ver 3.1
    [   82.735118] rtk_btcoex: rtk_btcoex_init: version: 1.2
    [   82.735125] rtk_btcoex: create workqueue
    [   82.735630] rtk_btcoex: alloc buffers 1792, 2432 for ev and l2
    [   82.735832] usbcore: registered new interface driver rtk_btusb
    
  • hciconfig查看蓝牙设备

3.7 使用蓝牙播放音乐

  • 参考链接

    https://wiretuts.com/connecting-bluetooth-audio-device-to-raspberry-pi (必看)

  • 安装相关工具

    sudo apt-get install pulseaudio pulseaudio-utils pulseaudio-module-bluetooth
    或
    sudo apt-get install pulseaudio*
    
  • 修改/lib/systemd/system/bluetooth.service文件,在ExecStart配置中增加参数-C

  • 添加用户pi到组lp

    sudo usermod -a -G lp pi
    
  • 重启

    reboot
    
  • 启动pulseaudio进程, 最好在串口终端中执行此命令,否则可能会因为X11 forwarding的问题导致执行失败

    sudo pulseaudio --start
    

  • 查看bluetoothd进程是否存在,必须先启动该进程,才能通过bluetoothctl命令对蓝牙进行控制

  • 使用bluetoothctl命令连接蓝牙

    • scan on扫描蓝牙设备
    • pair 和指定的蓝牙设备进行配对
    • connect 和配对成功的蓝牙设备进行连接
  • 命令行播放音乐

    • 参考链接

      https://zhuanlan.zhihu.com/p/94871125

    • 安装soxlibsox-fmt-all

      $ sudo apt-get install sox
      $ sudo apt-get install sox libsox-fmt-all
      
    • 播放音乐, 测试成功(默认是最大音量播放,小心!!!耳朵都震聋鸟!!!)

      # play music.mp3
      
      music.mp3:
      
       File Size: 8.06M     Bit Rate: 327k
        Encoding: MPEG audio
        Channels: 2 @ 16-bit   Track: 2
      Samplerate: 44100Hz      Album: 吉他之路
      Replaygain: off         Artist: 王坚
        Duration: 00:03:17.26  Title: 天空之城(木吉他版)
      
      In:16.2% 00:00:31.95 [00:02:45.31] Out:1.41M [ =====|====- ] Hd:2.3 Clip:0
      

4. WIFI驱动移植

4.1 相关资料路径

  • 务必阅读readme.txt

  • 务必阅读document目录下的相关文档

  • 官方驱动暂不支持3.19.3版本以上的内核,并且驱动移植工作量太大了,github上有大佬已经移植好的驱动,直接使用github上的源码吧,但是可以阅读官方的文档,学习一下如何配置wifi

  • github项目链接

    https://github.com/lwfinger/rtl8723bu

4.2 wifi驱动编译

  • 注意:使用的是github上的驱动源码,并不是该模块官方的驱动源码

4.2.1 下载并解压

$ unzip rtl8723bu-master.zip
$ cd rtl8723bu-master/

4.2.2 修改Makefile

  • Platform Related中添加一新的平台arm64,并将其它的平台都设置为n

    CONFIG_PLATFORM_ARM64 = y
    

  • 添加arm64平台交叉编译相关配置

    ifeq ($(CONFIG_PLATFORM_ARM64), y)
    EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211
    EXTRA_CFLAGS += -DRTW_USE_CFG80211_STA_EVENT # only enable when kernel >= 3.2
    EXTRA_CFLAGS += -DCONFIG_P2P_IPS
    ARCH := arm64
    CROSS_COMPILE := /usr/arm/CodeSourcery/aarch64-linux-gnu/bin/aarch64-linux-gnu-
    KSRC := /home/jun/share/work/mptcp_kernel/ig10/linux_build_5.4_raspios_mptcp
    endif
    

4.2.3 编译

  • make编译
$ make
  • 编译完成后会生成一个驱动文件8723bu.ko

4.2.4 安装驱动

  • 8723bu.ko拷贝到目标主机中,insmod安装

    # insmod 8723bu.ko
    
  • 接入wifi模块,使用lsusb查看

  • ifconfig查看,(为什么有两个wlan ???)

4.2.5 启用2.4G AP

  • 编写hostapd.conf如下

    interface=wlan0
    ctrl_interface=/var/run/hostapd
    country_code=CN
    ssid=TEST			# 名称
    wpa=0				# 不加密
    wpa_passphrase=12345678
    driver=nl80211
    bridge=br0
    beacon_int=100
    hw_mode=g
    channel=6
    ieee80211n=1
    wme_enabled=1
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=CCMP
    max_num_sta=8
    wpa_group_rekey=86400
    ignore_broadcast_ssid=0
    
  • 启动hostapd进程

    # hostapd ./hostapd.conf
    

  • 使用手机连接,能够连接成功,但是无法获取IP,因为我们还没有给AP配置dhcp server

  • 配置dhcp server 和 路由后,测速效果如下:(上行竟然比下行还好?)

4.2.6 启用5G AP

  • 该模组不支持5G频段

4.2.7 启用Station Mode模式

  • 该模组不支持Station Mode模式

【本人原创文章,转载请注明出处!!!】
【禁止转载到CSDN !!!】

posted @ 2023-04-10 16:59  zhijun  阅读(298)  评论(0编辑  收藏  举报