3

Although, this dongle works (for awhile), there is a problem with the bluetooth driver. After streaming for about an hour, the driver eats up all the Pi memory and the Pi stops responding. Power cycling is the only fix. This may be related to the flood of messages it puts out on dmesg. I tried clearing dmesg, but that does not recover the lost memory. You can watch the memory slowly decrease by running htop while streaming to a bluetooth speaker. I think the memory problem is with the bluetooth driver, because the problem does not occur when using a different bluetooth dongle.

Maybe someone with driver coding experience could find a solution. Please post any ideas you might have regarding the memory problem.

#the bluetooth driver floods dmesg with about 10 messages per second...
dmesg|tail
[  329.685269] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  329.765265] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37
[  330.725279] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  330.805278] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 38
[  331.765273] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  331.845278] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37
[  332.805301] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  332.885305] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 38
[  333.845301] rtk_btcoex: count_pan_packet_timeout: pan_packet_count 0
[  333.925309] rtk_btcoex: count_a2dp_packet_timeout: a2dp_packet_count 37

Steps to compile the bluetooth and wifi drivers for EDIMAX EW-7611ULB on Raspberry Pi

The compile process:

First, install the headers for your OS

sudo apt-get install raspberrypi-kernel-headers

--- the system is now ready to compile ---

BLUETOOTH DRIVER

#get bluetooth driver from the Edimax site
wget http://www.edimax.us/download/drivers/EW-7611ULB/EW-7611ULB_Bluetooth_driver.zip
unzip EW-7611ULB_Bluetooth_driver.zip
cd EW-7611ULB_Bluetooth_driver
cd Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax

Fix source file so will compile with >= 4.9.x kernels

In Section "(II.) Bluetooth Driver Installation", before running "sudo make install -s", you need to edit the file bluetooth_usb_driver/rtk_coex.c At line 448, change:

#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
#if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
    bt_cb(skb)->req.start = true;
#else
    bt_cb(skb)->hci.req_start = true;
#endif
#endif

to:

#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
#if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
    bt_cb(skb)->req.start = true;
#elif HCI_VERSION_CODE >= KERNEL_VERSION(4,9,0)
    bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
#else
    bt_cb(skb)->hci.req_start = true;
#endif
#endif

Fix the Makefile

change depmod line to in TWO places, BOTH the install and uninstall sections:

depmod -a -v                                           

Compile and install the driver

sudo make install -s
sudo reboot

This completes the bluetooth driver install. If you want, you can test by connecting something using bluetoothctl. Read the Bluetooth driver info below to prevent your logfiles from filling up.

If you later want to use a different Bluetooth dongle, you'll need to revert to the stock Bluetooth driver as follows:

cd EW-7611ULB_Bluetooth_driver
cd Linux_BT_USB_v3.1_20150526_8723BU_BTCOEX_20150119-5844_Edimax
sudo make uninstall -s
sudo reboot

WIFI DRIVER

sudo apt update
#get the wifi driver
sudo apt install git
git clone https://github.com/lwfinger/rtl8723bu.git

####   optional    ###################################################
#if you don't want TWO wlan devices (wlan0 and wlan1) in ifconfig    #
#disable concurrent mode, by commenting out the line in the Makefile #
#cd rtl8723bu                                                        #
#nano Makefile                                                       #
#(put # in front of this line):                                      #
#EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE                            #
######################################################################

#make the driver
sudo make
sudo make install
sudo modprobe -v 8723bu
#This driver cannot work with the standard driver rtl8xxxu
#so create 50-rtl8xxxu.conf with one line: 
blacklist rtl8xxxu
sudo nano /etc/modprobe.d/50-rtl8xxxu.conf 

This completes the WIFI driver install

Bluetooth Driver Info

The bluetooth driver floods the message log with some info, so to prevent it overloading your logfile, edit /etc/rsyslog.conf and add the following line to discard those messages:

:msg, contains, "rtk_btcoex"    ~

Log file example snip shown below:

...snip from /etc/rsyslog.conf.........................

###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*         /var/log/auth.log
:msg, contains, "rtk_btcoex"    ~
*.*;auth,authpriv.none      -/var/log/syslog
#cron.*             /var/log/cron.log
daemon.*            -/var/log/daemon.log
kern.*              -/var/log/kern.log
lpr.*               -/var/log/lpr.log
mail.*              -/var/log/mail.log
user.*              -/var/log/user.log
#kern.info           -/var/log/kern.info

...snip...............................................

5
  • 2
    Hello. This reads like an answer to an unasked question or a tutorial/HowTo. If you have a question hidden amongst all that detail (which is usually a good thing) maybe edit the title and first paragraph to indicate what it is a little more clearly? Commented Apr 6, 2019 at 18:22
  • I checked on this before posting, stackoverflow.blog/2011/07/01/…, encourages posting solutions of this type. But, I still need help with the Bluetooth driver. After some time streaming, the bluetooth driver slowly eats up all the Pi memory (run htop to see). The Pi stops responding, and has to be power cycled. If anyone with driver coding experience could find a solution for this, please post an answer. This may be related to the dmesg flooding problem I discussed above, but clearing dmesg does not recover the ate up memory.
    – Ken H
    Commented Apr 7, 2019 at 0:07
  • 1
    @KenH answering your own question is encouraged, but as the blog post indicates, you should still answer as an answer and not in the body of the question . The question must still be stated clearly
    – crasic
    Commented Apr 7, 2019 at 16:38
  • In addition to what @crasic said your "answer", it I've read it correctly, is not really answering your question about a memory leak in the Bluetooth driver but is rather a set of instructions on compiling the two drivers for your dongle. Commented Apr 7, 2019 at 16:45
  • My intent was to 1. Provide information to successfully compile the drivers, without having to search for answers when errors occur. 2. Ask for help with the memory leak problem. If someone were interested in working the problem, I didn't want them stalling at the driver install, before they could begin to work the problem. I've already edited to put the question first, and then show the compile steps. If you have a suggestion on a better way to present this, please let me know, and I'll do my best to fix it.
    – Ken H
    Commented Apr 8, 2019 at 16:40

2 Answers 2

0

i bought the EW-7611ULB wifi & bluetooth dongle. but bluetooth fails to work on my Ubuntu 16.04. i just modified the "EW-7611ULB_Linux_Bluetooth_Driver_1.0.0.9" bluetooth driver to work on my Ubuntu 16.04.02 LTS with the following kernel version -

Linux xxx 4.16.0 #1 SMP Wed Sep 5 18:09:34 CST 2018 x86_64 x86_64 x86_64 GNU/Linux

I did not do any fine tune, just make it functional on my system. use at your risk.

EW-7611ULB_Linux_Bluetooth_Driver_1.0.0.9.patch

diff -Naur bluetooth_usb_driver/rtk_bt.c bluetooth_usb_driver_new/rtk_bt.c
--- bluetooth_usb_driver/rtk_bt.c   2018-09-04 17:51:50.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_bt.c   2019-10-27 10:49:47.840823000 +0800
@@ -2093,7 +2093,7 @@

    if (config_len != filelen - BT_CONFIG_HDRLEN) {
        RTKBT_ERR("config length %d is not right %d", config_len,
-             filelen - BT_CONFIG_HDRLEN);
+             filelen - (int)BT_CONFIG_HDRLEN);
        return 0;
    }

@@ -2287,6 +2287,7 @@
 static int request_bdaddr(u8 *buf)
 {
    int size;
+   loff_t pos=0;
    int rc;
    struct file *file;
    u8 tbuf[BDADDR_STRING_LEN + 1];
@@ -2310,7 +2311,11 @@
        size = BDADDR_STRING_LEN;

    memset(tbuf, 0, sizeof(tbuf));
+#if 0
    rc = kernel_read(file, 0, tbuf, size);
+#else
+   rc = kernel_read(file, tbuf, size, &pos);
+#endif
    fput(file);
    if (rc != size) {
        if (rc >= 0)
diff -Naur bluetooth_usb_driver/rtk_bt.h bluetooth_usb_driver_new/rtk_bt.h
--- bluetooth_usb_driver/rtk_bt.h   2017-12-28 21:22:28.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_bt.h   2019-10-27 10:53:06.151664000 +0800
@@ -43,12 +43,14 @@

 #define BTCOEX

-#if 1
+#if 0
 #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "\n" , ## arg)
 #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "\n" , ## arg)
 #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btusb: " fmt "\n", ## arg)
 #else
 #define RTKBT_DBG(fmt, arg...)
+#define RTKBT_INFO(fmt, arg...)
+#define RTKBT_WARN(fmt, arg...)
 #endif

 #if 1
diff -Naur bluetooth_usb_driver/rtk_coex.c bluetooth_usb_driver_new/rtk_coex.c
--- bluetooth_usb_driver/rtk_coex.c 2017-12-28 21:22:28.000000000 +0800
+++ bluetooth_usb_driver_new/rtk_coex.c 2019-10-27 10:52:46.379780000 +0800
@@ -33,10 +33,21 @@

 #define RTK_VERSION "1.2"

+#if 0
 #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
 #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
 #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
+#else
+#define RTKBT_DBG(fmt, arg...)
+#define RTKBT_INFO(fmt, arg...)
+#define RTKBT_WARN(fmt, arg...)
+#endif
+
+#if 1
 #define RTKBT_ERR(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
+#else
+#define RTKBT_ERR(fmt, arg...)
+#endif

 static struct rtl_coex_struct btrtl_coex;

@@ -44,9 +55,16 @@
 #define is_profile_busy(profile)        ((btrtl_coex.profile_status & BIT(profile)) > 0)

 static void rtk_handle_event_from_wifi(uint8_t * msg);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_a2dp_packet_timeout(unsigned long data);
 static void count_pan_packet_timeout(unsigned long data);
 static void count_hogp_packet_timeout(unsigned long data);
+#else
+static void count_a2dp_packet_timeout(struct timer_list *t);
+static void count_pan_packet_timeout(struct timer_list *t);
+static void count_hogp_packet_timeout(struct timer_list *t);
+#endif

 static int rtl_alloc_buff(struct rtl_coex_struct *coex)
 {
@@ -541,8 +559,12 @@
 {
    if (profile_index == profile_a2dp) {
        btrtl_coex.a2dp_packet_count = 0;
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.a2dp_count_timer),
                count_a2dp_packet_timeout, 0);
+   #else
+       timer_setup(&(btrtl_coex.a2dp_count_timer), count_a2dp_packet_timeout, 0);
+   #endif 
        btrtl_coex.a2dp_count_timer.expires =
            jiffies + msecs_to_jiffies(1000);
        add_timer(&(btrtl_coex.a2dp_count_timer));
@@ -550,8 +572,12 @@

    if (profile_index == profile_pan) {
        btrtl_coex.pan_packet_count = 0;
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.pan_count_timer),
                count_pan_packet_timeout, 0);
+   #else
+       timer_setup(&(btrtl_coex.pan_count_timer), count_pan_packet_timeout, 0);
+   #endif
        btrtl_coex.pan_count_timer.expires =
            jiffies + msecs_to_jiffies(1000);
        add_timer(&(btrtl_coex.pan_count_timer));
@@ -563,8 +589,13 @@
            && (0 == btrtl_coex.profile_refcount[profile_voice])) {
            btrtl_coex.hogp_packet_count = 0;
            btrtl_coex.voice_packet_count = 0;
+       #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
            setup_timer(&(btrtl_coex.hogp_count_timer),
                    count_hogp_packet_timeout, 0);
+       #else
+           timer_setup(&(btrtl_coex.hogp_count_timer),
+                   count_hogp_packet_timeout, 0);
+       #endif 
            btrtl_coex.hogp_count_timer.expires =
                jiffies + msecs_to_jiffies(1000);
            add_timer(&(btrtl_coex.hogp_count_timer));
@@ -954,7 +985,11 @@
    }
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_a2dp_packet_timeout(unsigned long data)
+#else
+static void count_a2dp_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: a2dp_packet_count %d", __func__,
            btrtl_coex.a2dp_packet_count);
@@ -971,7 +1006,11 @@
          jiffies + msecs_to_jiffies(1000));
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_pan_packet_timeout(unsigned long data)
+#else
+static void count_pan_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: pan_packet_count %d", __func__,
            btrtl_coex.pan_packet_count);
@@ -991,7 +1030,11 @@
          jiffies + msecs_to_jiffies(1000));
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void count_hogp_packet_timeout(unsigned long data)
+#else
+static void count_hogp_packet_timeout(struct timer_list *t)
+#endif
 {
    RTKBT_DBG("%s: hogp_packet_count %d", __func__,
            btrtl_coex.hogp_packet_count);
@@ -2299,7 +2342,11 @@
    //}
 }

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
 static void polling_bt_info(unsigned long data)
+#else
+static void polling_bt_info(struct timer_list *data)
+#endif
 {
    uint8_t temp_cmd[1];
    RTKBT_DBG("polling timer");
@@ -2325,7 +2372,11 @@

    if (ctl->polling_enable && !btrtl_coex.polling_enable) {
        /* setup polling timer for getting bt info from firmware */
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
        setup_timer(&(btrtl_coex.polling_timer), polling_bt_info, 0);
+   #else
+       timer_setup(&(btrtl_coex.polling_timer), polling_bt_info, 0);       
+   #endif
        btrtl_coex.polling_timer.expires =
            jiffies + msecs_to_jiffies(ctl->polling_time * 1000);
        add_timer(&(btrtl_coex.polling_timer));
@@ -2541,11 +2592,12 @@
              (void *)udpsocket_recv_data);
    INIT_DELAYED_WORK(&btrtl_coex.l2_work, (void *)rtl_l2_work);

+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
    init_timer(&btrtl_coex.polling_timer);
    init_timer(&btrtl_coex.a2dp_count_timer);
    init_timer(&btrtl_coex.pan_count_timer);
    init_timer(&btrtl_coex.hogp_count_timer);
-
+#endif
    btrtl_coex.hdev = hdev;
    btrtl_coex.wifi_on = 0;

=======================================

0

There is a much easier solution now in the latest Buster Raspberry Pi OS. TLDR: echo "" > /etc/modprobe.d/blacklist-rtl8xxxu.conf && reboot

This removes the (by default) blacklist for the rtl8xxxu driver, which then enables the WiFi on this USB chip.

REF: https://www.reddit.com/r/raspberry_pi/comments/ohdm7y/comment/hms38d5/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.