Linux之蓝牙协议栈 bluez移植

一、前言

使用情景:将嵌入式Linux系统作为slaver,并定义相关服务与手机进行发送接受及通知等相关操作。

二、编译依赖和BlueZ

1、zlib

LIB_TAR = zlib-1.2.11
LIB_PATH = $(PWD)/../libtar/zlib-1.2.11.tar.gz

all:
	cd $(LIB_TAR) &&  CC=$(LIB_CC)  ./configure --prefix=$(OUT_DIR)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

2、libffi

LIB_TAR = libffi-3.0.13
LIB_PATH = $(PWD)/../libtar/libffi-3.0.13.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

3、glib

LIB_TAR = glib-2.40.0
LIB_PATH = $(PWD)/../libtar/glib-2.40.0.tar.xz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR)  --host=arm-linux CC=$(LIB_CC) PKG_CONFIG_PATH=$(OUT_DIR)/lib/pkgconfig  glib_cv_stack_grows=no glib_cv_uscore=yes ac_cv_func_posix_getpwuid_r=yes ac_cv_func_posix_getgrgid_r=yes CPPFLAGS="-I$(OUT_DIR)/include/" LDFLAGS="-L$(OUT_DIR)/lib/"
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvJf $(LIB_PATH)  -C ./
	cd $(LIB_TAR) && git apply $(PWD)/patch/glib/001-glib-gdate-suppress-string-format-literal-warning.patch

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

PS:编译该库的时候出现异常报错,解决方法如下

diff --git a/code/glib-2.40.0/glib/gdate.c b/code/glib-2.40.0/glib/gdate.c
index 670f7aa..5f03e61 100644
--- a/code/glib-2.40.0/glib/gdate.c
+++ b/code/glib-2.40.0/glib/gdate.c
@@ -2439,6 +2439,9 @@ win32_strftime_helper (const GDate     *d,
  *
  * Returns: number of characters written to the buffer, or 0 the buffer was too small
  */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
 gsize     
 g_date_strftime (gchar       *s, 
                  gsize        slen, 
@@ -2549,3 +2552,5 @@ g_date_strftime (gchar       *s,
   return retval;
 #endif
 }
+
+#pragma GCC diagnostic pop

4、expat

LIB_TAR = expat-2.1.0
LIB_PATH = $(PWD)/../libtar/expat-2.1.0.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

5、dbus

LIB_TAR = dbus-1.9.4
LIB_PATH = $(PWD)/../libtar/dbus-1.9.4.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux --with-x=no --disable-tests --enable-abstract-sockets CC=$(LIB_CC) CPPFLAGS="-I$(OUT_DIR)/include/" LDFLAGS="-L$(OUT_DIR)/lib/"
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

6、libical

LIB_TAR = libical-1.0
LIB_PATH = $(PWD)/../libtar/libical-1.0.tar.gz

all:
	cd $(LIB_TAR) && ./bootstrap
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC)
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

7、ncurses

LIB_TAR = ncurses-5.9
LIB_PATH = $(PWD)/../libtar/ncurses-5.9.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) --with-shared
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./
	cd .. && git apply $(PWD)/patch/ncurses/001-ncurses-curses-note-error.patch

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

PS:编译该库时发生异常报错,解决方案如下

diff --git a/code/ncurses-5.9/include/curses.tail b/code/ncurses-5.9/include/curses.tail
index 098c898..e81cc5a 100644
--- a/code/ncurses-5.9/include/curses.tail
+++ b/code/ncurses-5.9/include/curses.tail
@@ -101,7 +101,7 @@ extern NCURSES_EXPORT(mmask_t) mousemask (mmask_t, mmask_t *);
 extern NCURSES_EXPORT(bool)    wenclose (const WINDOW *, int, int);
 extern NCURSES_EXPORT(int)     mouseinterval (int);
 extern NCURSES_EXPORT(bool)    wmouse_trafo (const WINDOW*, int*, int*, bool);
-extern NCURSES_EXPORT(bool)    mouse_trafo (int*, int*, bool);              /* generated */
+extern NCURSES_EXPORT(bool)    mouse_trafo (int*, int*, bool);
 
 #if NCURSES_SP_FUNCS
 extern NCURSES_EXPORT(bool)    NCURSES_SP_NAME(has_mouse) (SCREEN*);

8、readline

LIB_TAR = readline-6.3
LIB_PATH = $(PWD)/../libtar/readline-6.3.tar.gz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) bash_cv_wcwidth_broken=yes
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvzf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

9、bluez

LIB_TAR = bluez-5.44
LIB_PATH = $(PWD)/../libtar/bluez-5.44.tar.xz

all:
	cd $(LIB_TAR) && ./configure --prefix=$(OUT_DIR) --host=arm-linux CC=$(LIB_CC) CFLAGS="-I$(OUT_DIR)/include/ -I$(OUT_DIR)/include/glib-2.0 -I$(OUT_DIR)/include/dbus-1.0" LDFLAGS="-lncurses  -lreadline -ldbus-1 -lglib-2.0 -lical -L/$(OUT_DIR)/lib -L$(OUT_DIR)/lib" DBUS_CFLAGS="-I$(OUT_DIR)/lib/dbus-1.0/include" DBUS_LIBS="-L$(OUT_DIR)/lib" GLIB_CFLAGS="-I$(OUT_DIR)/lib/glib-2.0/include" GLIB_LIBS="-L$(OUT_DIR)/lib" ICAL_CFLAGS="-I$(OUT_DIR)/include" ICAL_LIBS="-L$(OUT_DIR)/lib" --enable-library --sysconfdir=/etc --localstatedir=/var --enable-experimental --with-systemdsystemunitdir=/lib/systemd/system --with-systemduserunitdir=/usr/lib/system --with-dbusconfdir=$(OUT_DIR)/dbus-1/system.d --enable-testing --enable-experimental  --enable-deprecated --disable-systemd --disable-udev --disable-cups --disable-obex
	cd $(LIB_TAR) && make && make install

prepare:
	rm -rf $(LIB_TAR)
	tar -xvJf $(LIB_PATH)  -C ./

clean:
	cd $(LIB_TAR) && make clean

distclean:
	rm -rf $(LIB_TAR)

10、Makefile

export LIB_CC=arm-himix200-linux-gcc
export OUT_DIR=/usr/etc/bluez/

all:
	$(MAKE) -f ./zlib.mk
	$(MAKE) -f ./libffi.mk
	$(MAKE) -f ./glib.mk
	$(MAKE) -f ./expat.mk
	$(MAKE) -f ./dbus.mk
	$(MAKE) -f ./libical.mk
	$(MAKE) -f ./ncurses.mk
	$(MAKE) -f ./readline.mk
	$(MAKE) -f ./bluez.mk

prepare:
	$(MAKE) prepare -f ./zlib.mk
	$(MAKE) prepare -f ./libffi.mk
	$(MAKE) prepare -f ./glib.mk
	$(MAKE) prepare -f ./expat.mk
	$(MAKE) prepare -f ./dbus.mk
	$(MAKE) prepare -f ./libical.mk
	$(MAKE) prepare -f ./ncurses.mk
	$(MAKE) prepare -f ./readline.mk
	$(MAKE) prepare -f ./bluez.mk

clean:
	$(MAKE) clean -f ./zlib.mk
	$(MAKE) clean -f ./libffi.mk
	$(MAKE) clean -f ./glib.mk
	$(MAKE) clean -f ./expat.mk
	$(MAKE) clean -f ./dbus.mk
	$(MAKE) clean -f ./libical.mk
	$(MAKE) clean -f ./ncurses.mk
	$(MAKE) clean -f ./readline.mk
	$(MAKE) clean -f ./bluez.mk

distclean:
	$(MAKE) distclean -f ./zlib.mk
	$(MAKE) distclean -f ./libffi.mk
	$(MAKE) distclean -f ./glib.mk
	$(MAKE) distclean -f ./expat.mk
	$(MAKE) distclean -f ./dbus.mk
	$(MAKE) distclean -f ./libical.mk
	$(MAKE) distclean -f ./ncurses.mk
	$(MAKE) distclean -f ./readline.mk
	$(MAKE) distclean -f ./bluez.mk

PS:在运行bluez的时候,指定的bluez配置文件路径为编译时–prefix参数所指定的路径。为了方便交叉编译后文件的移植,该参数最好为绝对根路径。

三、移植库

编译好后的文件输出目录:

bin/     dbus-1/  etc/     include/ lib/     libexec/ man/     share/   var/

挂载该目录后将下列文件依次拷贝到对应目录下

cp /mnt/bin/*   /usr/bin/  -rf
cp /mnt/lib/*    /usr/lib/  -rf
cp /mnt/libexec/*  /usr/libexec/  -rf
cp /mnt/libexec/bluetooth/bluetoothd /usr/lib/ -rf
cp /mnt/share/* /share/ -rf

上面我说过注意–prefix=$(PATH) 参数所指定的路径,如果不是交叉编译的话,var和etc会考到跟目录下的var和etc下并为本机配置该参数。但由于我们是交叉编译的,该配置文件要集中输出到输出目录$(PATH) 去,然而有个问题是该路径为dbus和bluez运行时寻找的配置路径,因此本应该在根目录下etc和var目录下寻找的配置文件就变成了$(PATH)/etc和$(PATH)/var。(有兴趣的小伙伴可以研究下代码改下这个路径)
因此需要将该目录创建出来,然后将etc和var拷贝到这里。

mkdir -p $(PATH)
cp /mnt/etc  $(PATH) -rf
cp /mnt/var  $(PATH) -rf
cp  /mnt/dbus-1/system.d/dbus-1/system.d/bluetooth.conf  $(PATH)/etc/dbus-1/system.d/bluetooth.conf

dbus需要有个messagebus用户,创建一个

adduser messagebus

开启蓝牙模块

hciconfig hci0 up

启动dbus和bluez

dbus-daemon --system --print-pid --print-address
bluetoothd -d -n --compat &

然后就可以用下列命令控制蓝牙了

扫描周围传统/低功耗蓝牙:hcitool scan/lescan
发送广播:hciconfig hci0 leadv

四、效果演示

Linux之蓝牙协议栈 bluez移植_第1张图片
这里我定义了一个具有读、写、通知功能的服务
Linux之蓝牙协议栈 bluez移植_第2张图片
开启通知按钮,收到notify字符串。
Linux之蓝牙协议栈 bluez移植_第3张图片
写个个字符串进去。
Linux之蓝牙协议栈 bluez移植_第4张图片
读到的就是写进去的字符串。
emmmmmmmmmmmmmm,完美

五、异常问题

1、

Unknown group "lp" in message bus configuration file
Failed to start message bus: The pid file "/usr/etc/bluez/var/run/dbus/pid" exists, if the message bus is not running, remove this file

将/usr/etc/bluez/var/run/dbus/pid删除掉再运行就好了。

2、

src/adapter.c:read_index_list_complete() Number of controllers: 0

当Number of controllers为0时说明蓝牙模块驱动异常。

吐槽下hcitool是真的难用,连bluez的官方都是不推荐使用了。

你可能感兴趣的:(Linux驱动篇)