RTL8723D BLUETOOTH MODULE USAGE


1. Bluetooth Dependency Libraries Preparation

expat:https://github.com/libexpat/libexpat/releases

dbus:https://dbus.freedesktop.org/releases/dbus/

zlib:http://www.zlib.net/

libffi:https://www.sourceware.org/libffi/

gettext:http://www.gnu.org/software/gettext/

glib:http://ftp.gnome.org/pub/gnome/sources/glib/

libical:https://github.com/libical/libical

readline:http://ftp.gnu.org/gnu/readline/

ncurses:http://ftp.gnu.org/gnu/ncurses/

bluez:https://mirrors.edge.kernel.org/pub/linux/bluetooth/

alsa-lib:http://www.linuxfromscratch.org/blfs/view/svn/multimedia/alsa-lib.html

alsa-utils:http://www.linuxfromscratch.org/blfs/view/stable/multimedia/alsa-utils.html

sndfile:http://www.mega-nerd.com/libsndfile/#Download

sbc:https://mirrors.edge.kernel.org/pub/linux/bluetooth/

bluez-alsa:https://github.com/Arkq/bluez-alsa

bt_lib.tar.bz2 is the source code.


2. Bluetooth Dependency Libraries Compilation

Take arm-linux-gnueabihf- 8.2 as example, change the path of lib install by yourself.

Set the environment variable INSTALL_PATH as the compilation output path of bluez.

export INSTALL_PATH=/customer/bluetooth/bluez_build

zlib:

export CC=arm-linux-gnueabihf-gcc

export AR=arm-linux-gnueabihf-ar

export RANLIB=arm-linux-gnueabihf-ranlib

./configure --prefix=$INSTALL_PATH/zlib

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/zlib/lib/pkgconfig/:$PKG_CONFIG_PATH

libffi:

./configure --prefix=$INSTALL_PATH/libffi --host=arm-linux --target=arm-linux CC=arm-linux-gnueabihf-gcc

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/libffi/lib/pkgconfig/:$PKG_CONFIG_PATH

gettext:

glib only needs the header file of gettext to assist in compilation, if the server environment has been installed, porting is not required.

The compilation command is as follows:

./configure --prefix=$INSTALL_PATH/gettext --disable-libasprintf --host=arm-linux --target=arm-linux CC=arm-linux-gnueabihf-gcc

make && make install

Note: The above is based on gettext-0.20.1, there may be a bug in this version of configure, the first configuration of --disable-libasprintf will fail. Configure and make, after reports an error, add --disable-libasprintf and configure again.

Q1:

A:Add --disable-libasprintf to configure

glib:

echo ac_cv_type_long_long=yes>>arm-linux-gnueabihf.cache

echo glib_cv_stack_grows=no>>arm-linux-gnueabihf.cache

echo glib_cv_uscore=no>>arm-linux-gnueabihf.cache

echo ac_cv_func_posix_getpwuid_r=yes>>arm-linux-gnueabihf.cache

echo ac_cv_func_posix_getgrgid_r=yes>>arm-linux-gnueabihf.cache

./configure --prefix=$INSTALL_PATH/glib --host=arm-linux --target=arm-linux CC="arm-linux-gnueabihf-gcc" CFLAGS="-I$INSTALL_PATH/zlib/include -I$INSTALL_PATH/libffi/include" LDFLAGS="-L$INSTALL_PATH/zlib/lib -L$INSTALL_PATH/libffi/lib" LIBS="-lz -lffi" --cache-file=arm-linux-gnueabihf.cache

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/glib/lib/pkgconfig/:$PKG_CONFIG_PATH

Q1:

A: Refer to gettext above for transplant by yourself. Or install gettext on the server: apt-get install gettext

Q2:

A: For convenience, solve the problem on the server: apt-get install libglib2.0-dev

Q3:

A:Refer to https://blog.csdn.net/zmlovelx/article/details/81664043

Q4: Prompt c:28:17: fatal error: ffi.h: No such file or directory when compiling.

A:The header file directory of libffi installation is not correctly specified.

Q5:The following logs appeared during compilation.

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_void'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_double'

./.libs/libgobject-2.0.so: undefined reference to `ffi_prep_cif'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint32'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_float'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint64'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint64'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_pointer'

./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint32'

./.libs/libgobject-2.0.so: undefined reference to `ffi_call'

A:The lib path of libffi is not specified correctly or the library is not linked

Q6:The following logs appeared during compilation.

./.libs/libgio-2.0.so: undefined reference to `inflateReset'

./.libs/libgio-2.0.so: undefined reference to `inflateEnd'

./.libs/libgio-2.0.so: undefined reference to `inflateGetHeader'

./.libs/libgio-2.0.so: undefined reference to `deflate'

./.libs/libgio-2.0.so: undefined reference to `deflateInit_'

./.libs/libgio-2.0.so: undefined reference to `inflateInit2_'

./.libs/libgio-2.0.so: undefined reference to `inflate'

./.libs/libgio-2.0.so: undefined reference to `deflateSetHeader'

./.libs/libgio-2.0.so: undefined reference to `deflateEnd'

./.libs/libgio-2.0.so: undefined reference to `deflateReset'

./.libs/libgio-2.0.so: undefined reference to `inflateInit_'

./.libs/libgio-2.0.so: undefined reference to `deflateInit2_'

A:The lib path of zlib is not specified correctly or the library is not linked

expat:

./configure --prefix=$INSTALL_PATH/expat --host=arm-linux --target=arm-linux CC=arm-linux-gnueabihf-gcc

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/expat/lib/pkgconfig/:$PKG_CONFIG_PATH

dbus:

echo ac_cv_have_abstract_sockets=yes>arm-linux-gnueabihf.cache

./configure --prefix=$INSTALL_PATH/dbus --host=arm-linux --target=arm-linux --disable-tests CC="arm-linux-gnueabihf-gcc -I$INSTALL_PATH/zlib/include -I$INSTALL_PATH/libffi/include -I$INSTALL_PATH/gettext/include -I$INSTALL_PATH/glib/include -I$INSTALL_PATH/expat/include -L$INSTALL_PATH/zlib/lib -L$INSTALL_PATH/libffi/lib -L$INSTALL_PATH/gettext/lib -L$INSTALL_PATH/glib/lib -L$INSTALL_PATH/expat/lib" --cache-file=arm-linux-gnueabihf.cache --with-x=no

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/dbus/lib/pkgconfig/:$PKG_CONFIG_PATH

Q1:

A:There is no library of zlib and libffi, use configure to link.

Q2:

A:Only dbus test needs to use glib, we can solve this error without compiling test, add --disable-tests in configure. Link all the libraries of glib can also fix it.

./configure --prefix=$INSTALL_PATH --host=arm-linux --target=arm-linux CC="arm-linux-gnueabihf-gcc" CFLAGS="-I$INSTALL_PATH/include" LDFLAGS="-L$INSTALL_PATH/lib" LIBS="-lz -lffi -lgmodule-2.0 -lglib-2.0 -lgio-2.0 -lgobject-2.0 -lgthread-2.0" --cache-file=arm-linux-gnueabihf.cache --with-x=no

Q3:The following logs appeared during configuration.

checking for EXPAT... configure: error: Package requirements (expat) were not met:

No package 'expat' found

A:Specify the path of the expat library

export EXPAT_LIBS="-lexpat -L$INSTALL_PATH/lib/"

export EXPAT_CFLAGS="-I$INSTALL_PATH/include/"

libical:

export CC=arm-linux-gnueabihf-gcc

export CXX=arm-linux-gnueabihf-g++

cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH/libical

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/libical/lib/pkgconfig/:$PKG_CONFIG_PATH

ncurses:

export CPPFLAGS="-P"

./configure --prefix=$INSTALL_PATH/ncurses --host=arm-linux --target=arm-linux --without-cxx-binding CC="arm-linux-gnueabihf-gcc" --enable-widec --with-shared

make && make install

Q1:

A:Use --without-cxx-binding to skip C++ compilation to avoid this. https://stackoverflow.com/questions/46793314/error-when-compiling-ncurses,There is no other way except to change the version.

readline:

./configure --prefix=$INSTALL_PATH/readline --host=arm-linux --target=arm-linux bash_cv_wcwidth_broken=yes CC=arm-linux-gnueabihf-gcc

make && make install

bluez:

./configure --prefix=$INSTALL_PATH/bluez --mandir=$INSTALL_PATH/bluez/man --sysconfdir=$INSTALL_PATH/bluez/etc --localstatedir=$INSTALL_PATH/bluez/var --host=arm-linux CC="arm-linux-gnueabihf-gcc -I$INSTALL_PATH/zlib/include -I$INSTALL_PATH/libffi/include -I$INSTALL_PATH/gettext/include -I$INSTALL_PATH/glib/include -I$INSTALL_PATH/expat/include -I$INSTALL_PATH/dbus/include -I$INSTALL_PATH/libical/include -I$INSTALL_PATH/ncurses/include -I$INSTALL_PATH/readline/include -L$INSTALL_PATH/zlib/lib -L$INSTALL_PATH/libffi/lib -L$INSTALL_PATH/gettext/lib -L$INSTALL_PATH/glib/lib -L$INSTALL_PATH/expat/lib -L$INSTALL_PATH/dbus/lib -L$INSTALL_PATH/libical/lib -L$INSTALL_PATH/ncurses/lib -L$INSTALL_PATH/readline/lib -lreadline -lncursesw" --enable-debug --enable-test --enable-shared --enable-testing --disable-udev --disable-systemd --disable-cups --disable-obex --enable-library --enable-tools --enable-deprecated

make && make install

export PKG_CONFIG_PATH=$INSTALL_PATH/bluez/lib/pkgconfig/:$PKG_CONFIG_PATH

Q1:xxx are required during configuration

A:pkgconfig is not in the environment variable PKG_CONFIG_PATH.

Redefine an environment variable BLUEALSA_INSTALL_PATH as the output path of compiling bluealsa.

export BLUEALSA_INSTALL_PATH=/customer/bluetooth/bluealsa_build

export CC=arm-linux-gnueabihf-gcc

export CXX=arm-linux-gnueabihf-g++

alsa-lib:

./configure --prefix=$BLUEALSA_INSTALL_PATH/alsa/ --host=arm-linux --disable-aload --disable-rawmidi --disable-seq --disable-ucm --disable-alisp --disable-old-symbols --disable-python --enable-debug CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ --with-plugindir=$BLUEALSA_INSTALL_PATH/alsa/lib --with-configdir=$BLUEALSA_INSTALL_PATH/alsa/etc

make && make install

export PKG_CONFIG_PATH=$BLUEALSA_INSTALL_PATH/alsa/lib/pkgconfig/:$PKG_CONFIG_PATH

alsa-utils:

./configure --prefix=$BLUEALSA_INSTALL_PATH/alsa-utils --host=arm-linux --with-curses=ncurses CC="arm-linux-gnueabihf-gcc -lasound -I$BLUEALSA_INSTALL_PATH/alsa/include -L$BLUEALSA_INSTALL_PATH/alsa/lib" --disable-xmlto --disable-alsamixer

make && make install

sndfile:

./configure --prefix=$BLUEALSA_INSTALL_PATH/sndfile/ --host=arm-linux-gnueabihf --enable-shared CC=arm-linux-gnueabihf-gcc

make && make install

export PKG_CONFIG_PATH=$BLUEALSA_INSTALL_PATH/sndfile/lib/pkgconfig/:$PKG_CONFIG_PATH

sbc:

./configure --prefix=$BLUEALSA_INSTALL_PATH/sbc/ --host=arm-linux --enable-shared --enable-debug CC=arm-linux-gnueabihf-gcc

make && make install

export PKG_CONFIG_PATH=$BLUEALSA_INSTALL_PATH/sbc/lib/pkgconfig/:$PKG_CONFIG_PATH

bluez-alsa:

autoreconf --install

./configure --prefix=$BLUEALSA_INSTALL_PATH/bluez-alsa --host=arm-linux --enable-debug --enable-shared --enable-pcm-test CFLAGS="-I$INSTALL_PATH/zlib/include -I$INSTALL_PATH/libffi/include -I$INSTALL_PATH/gettext/include -I$INSTALL_PATH/glib/include -I$INSTALL_PATH/expat/include -I$INSTALL_PATH/dbus/include -I$INSTALL_PATH/libical/include -I$INSTALL_PATH/ncurses/include -I$INSTALL_PATH/readline/include -I$INSTALL_PATH/bluez/include -I$BLUEALSA_INSTALL_PATH/alsa/include -I$BLUEALSA_INSTALL_PATH/sndfile/include -I$BLUEALSA_INSTALL_PATH/sbc/include" LDFLAGS="-L$INSTALL_PATH/zlib/lib -L$INSTALL_PATH/libffi/lib -L$INSTALL_PATH/gettext/lib -L$INSTALL_PATH/glib/lib -L$INSTALL_PATH/expat/lib -L$INSTALL_PATH/dbus/lib -L$INSTALL_PATH/libical/lib -L$INSTALL_PATH/ncurses/lib -L$INSTALL_PATH/readline/lib -L$INSTALL_PATH/bluez/lib -L$BLUEALSA_INSTALL_PATH/alsa/lib -L$BLUEALSA_INSTALL_PATH/sndfile/lib -L$BLUEALSA_INSTALL_PATH/sbc/lib" LIBS="-lz -lffi -lglib-2.0 -lgmodule-2.0"

make && make install

export PKG_CONFIG_PATH=$BLUEALSA_INSTALL_PATH/bluez-alsa/lib/pkgconfig/:$PKG_CONFIG_PATH

Q1:

A:sudo apt-get install libtool

All the libraries that Bluetooth A2DP depends on have been compiled. bt_build.tar.bz2 is the packaging of the files compiled by arm-linux-gnueabihf-8.2 according to the above.


3. Kernel Configuration

The following configuration needs to be opened in the kernel:

  1. Turn on the support of the Bluetooth subsystem in the kernel.

    Networking support --->

    Bluetooth subsystem support (set to y or m)

  2. Select the required Bluetooth function

    The two items marked in red are related to the Bluetooth chip controller. BR/EDR is traditional Bluetooth, LE is a low-power Bluetooth. Their protocols are different and need to be selected based on the mode supported by the Bluetooth chip.

    The Bluetooth here is traditional Bluetooth, and BR/EDR is set to y. The third is the self-test of Bluetooth, and the fourth is debugfs, set it to y.

    Configure as shown below, or it can be set to m. BNEP and HIDP are not used here.

    BNEP:Bluetooth Networking Encapsulation Protocal, generally used as a network card. HIDP is used in devices such as Bluetooth, keyboard and mouse.

    Select the red box option in the figure below to select the connection method of the Bluetooth device, here is uart.

  3. Turn on ALSA.

    Device Drivers --->

    Sound card support -→

  4. Support loading firmware in user space.

    Device Drivers --->

    Generic Driver Options -→

  5. Replace the kernel.


4. File System Prepration

Copy the relevant lib and bin files to the board. Delete unnecessary things (such as include, man, etc.) and copy the entire install directory to the board, so as to avoid some errors caused by the path.


4.1. Build The bluez Operating Environment Of The Board

The following figure is the directory compiled by bluez and the libraries it depends on

Copy the corresponding library and its symbolic link file from the lib directory under each directory in the above figure, and make a strip, copy it to the /lib directory of the board or other places and add it to the environment variable of the board.

Copy the corresponding tools and strip in the bluez and dbus directories. The following are some commonly used tools. Please copy them according to the actual situation. Copy them to the /bin directory or other places on the board and add them to the environment variables on the board.

Copy bluetoothd (the daemon of bluez) to the /bin directory or other places on the board and add it to the environment variables on the board.

Create a new etc/bluetooth directory under the $INSTALL_PATH directory on the board, and copy the src/main.conf in the bluez source code to the $INSTALL_PATH/etc/bluetooth on the board. This file is the Bluetooth config file and stores some basic information, such as Bluetooth name etc.


4.2. Build The bluez-alsa Operating Environment On The Board

The following figure shows the directory compiled by bluez-alsa and the libraries it depends on.

Copy the corresponding library and its symbolic link file from the lib directory under each directory in the above figure, and make a strip, copy it to the /lib directory of the board or other places and add it to the environment variable of the board.

Note: The library in this alsa-lib needs to be copied to the $BLUEALSA_INSTALL_PATH/alsa/lib on the board

Find the relevant tool from each directory, make a strip, copy it to the /bin directory of the board or other places and add it to the environment variables of the board.

Copy alsa/share, alsa/etc to the absolute path corresponding to the board, that is, the path of the directory in the server must be consistent with the board.

Copy 20-bluealsa.conf (bluez-alsa/share/alsa/alsa.conf.d/20-bluealsa.conf) generated by bluez-alsa to $BLUEALSA_INSTALL_PATH/alsa/etc/alsa.conf.d/. Without this file, bluez-alsa cannot virtualize an alsa device

bluetooth.tar.bz2 is the file transplanted to the board according to the above.


5. Functional Verification

  1. insmod hci_xxx.ko(Please ignore build-in)

  2. power on the Bluetooth module

  3. load the corresponding firmware (provided by the Bluetooth manufacturer)

  4. /var/run

    mkdir /var/run
    
    mount tmpfs /var/run -t tmpfs
    

    Mount /var/run to tmpfs, because bluealsa needs to go to this directory to create a directory and create a socket when it is initialized, so the directory needs to be writable.

    Bluealsa needs to access /var/run/dbus when it is running. In fact, it needs to access var/run/dbus generated by bluez compilation, so a link is made here to solve this problem.

    ln -s /customer/bluetooth/bluez_build/dbus/var/run/dbus /var/run/dbus
    
  5. start the dbus daemon, dbus-daemon --system &

  6. start the bluez daemon, bluetoothd -n -C &

  7. start bluealsa,bluealsa -p a2dp-source &

  8. use bluetoothctl or other tools to check the status of bluetooth controller, open/close, information modify, configuration status, scanning and pairing.

    To view the status of Bluetooth, you can use the show command in bluetoothctl or run hciconfig -a directly.

    Powered: Whether Bluetooth is turned on.

    Discoverable: Whether it can be discovered.

    Use hciconfig hci0 up (please change hci0 according to the actual situation) or the power on command in bluetoothctl to turn on Bluetooth.

    Turn on Bluetooth

    The Bluetooth name can be modified by hciconfig hci0 name xxx or system-alias xxx in bluetoothctl and modifying conf.

    To set the proxy capability of Bluetooth, please set it according to the actual situation.

    The discoverable and connectable Bluetooth can be set by hciconfig hci0 piscan or discoverable on in bluetoothctl. Set by bluetoothctl, the default time is only 180s to discover and connect to Bluetooth. Remove the # in main.conf and you can always find the connection.

    Use the scan on/off command in bluetoothctl to scan the Bluetooth switch.

    Use pair + mac address in bluetoothctl to pair Bluetooth.

    Use the trust + mac address in bluetoothctl to set up and add the Bluetooth speaker as a trusted device.

    Use the connect + mac address in bluetoothctl to connect to Bluetooth.

    Put data to Bluetooth speaker.

    aplay -D bluealsa:HCI=hci0,DEV=49:f5:31:5e:93:c8,PROFILE=a2dp /mnt/music/Wav_File/8K_16bit_STERO_30s.wav
    

    hci0 is the hci controller corresponding to the Bluetooth on the board, 49:f5:31:5e:93:c8 is the Bluetooth address of the Bluetooth speaker used, /mnt/music/Wav_File/8K_16bit_STERO_30s.wav is the finished wav file, above Please refer to actual conditions for parameters. If you need to play other formats, such as MP3, bluealsa needs other dependencies, please transplant it yourself.


6. FAQ

Q: dbus-daemon启动后kill掉无法重新启动,出现如下log:

A:delete $INSTALL_PATH/dbus/var/run/dbus/pid, or modify rcS file, add rm $INSTALL_PATH(Corresponding to the install path of the board)/dbus/var/run/dbus/pid –f, after dbus starts, it will create this file, if the file is not deleted when the dbus is powered on last time, the dbus cannot be started. In order to avoid modifying the rcs file, the file generated by the dbus must be deleted every time the device is turned on.

Q: After dbus-daemon is started, the following log is printed out:

A:Edit $INSTALL_PATH/dbus/etc/dbus-1/system.d/bluetooth.conf file, delete "lp" group

Q: After dbus-daemon is started, the following log is printed out:

A:Add the messagebus user to the passwd file. Add messagebus:x:500:500::/home/messagebus:/bin/sh to passwd. If it is not resolved, it may be that libnss_files is missing under /lib. Find libnss_files.so.2 and libnss_files-2.28.so from the toolchain, and put them under /lib

Q:Start bluetoothd error, report the following log:

D-Bus setup failed: Connection ":1.0" is not allowed to own the service "org.bluez" due to security policies in the configuration file

bluetoothd[124]: Unable to get on D-Bus

A:The configuration file (bluetooth.conf) required by bluetoothd is missing.

Q:Bluealsa startup error, report the following log:

bluealsa: Couldn't initialize controller thread: Bad file descriptor

A:An error occurred when bluealsa initialized the thread. It is recommended to add log to bluealsa to locate the error.

Q:The following log appears when aplay is executed.

A:The location of the 20-bluealsa.conf configuration file generated by bluez-alsa is incorrect. The file needs to be placed in the $BLUEALSA_INSTALL_PATH/alsa/etc/alsa.conf.d/ directory

Q:The following log appears when aplay is executed

A:Incorrect path of libasound_module_pcm_bluealsa.so.

The above is the process of build A2DP in Takoyaki(The bluetooth moudle is rtl8723d), Please refer bluez-alsa demo for detail code.