在嵌入式Linux上使用CF接口的蓝牙模块

2019-07-13 02:47发布

导读:
  随着各种支持蓝牙通信技术的设备的出现, 蓝牙通信变得越来越普及和广泛. 因此在嵌入式设备上集成蓝牙模块的需求变得越来越普遍. 本文以Anycom公司的CF接口的LSE139蓝牙模块为例, 介绍了如何配置使其在具有CF插槽的嵌入式arm-linux上工作.
  1. 配置环境
  操作系统: arm-linux
  内核: 2.4.19
  2. 内核/驱动支持
  为了使内核支持蓝牙, 需要给内核打补丁: 我使用的是http://www.holtmann.org/linux/kernel/patch-2.4.19-mh18.gz 这里需要根据你的内核版本下载不同的补丁. 设备驱动方面, 这个就要看你的运气了, 因为不同版本的内核对蓝牙设备的支持是不一样的. 低版本的内核支持的蓝牙设备要少一些. 我使用的这款蓝牙模块直到内核2.6.6-rc2才得以支持. 所以我不得不更改驱动KERNEL_SOURCE_DIR/drivers/bluetooth/bluecard_cs.c, 使得LSE139在2.4的内核上也可以正常工作. 如果你需要这个Patch, 可以给我发消息或者写信. 我的Email地址是lijinlei1@hotmail.com.
  然后对内核作出以下配置:
  None.gif
  
  #
  None.gif
  
  # Bluetooth support
  None.gif
  
  #
  None.gif
  
  CONFIG_BLUEZ=m
  None.gif
  
  CONFIG_BLUEZ_L2CAP=y
  None.gif
  
  CONFIG_BLUEZ_SCO=y
  None.gif
  
  CONFIG_BLUEZ_RFCOMM=m
  None.gif
  
  CONFIG_BLUEZ_RFCOMM_TTY=y
  None.gif
  
  CONFIG_BLUEZ_BNEP=m
  None.gif
  
  CONFIG_BLUEZ_BNEP_MC_FILTER=y
  None.gif
  
  CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
  None.gif
  
  None.gif
  
  #
  None.gif
  
  # Bluetooth device drivers
  None.gif
  
  #
  None.gif
  
  CONFIG_BLUEZ_HCIUSB=n
  None.gif
  
  CONFIG_BLUEZ_HCIUART=n
  None.gif
  
  CONFIG_BLUEZ_HCIUART_H4=n
  None.gif
  
  CONFIG_BLUEZ_HCIDTL1=n
  None.gif
  
  CONFIG_BLUEZ_HCIBT3C=n
  None.gif
  
  CONFIG_BLUEZ_HCIBLUECARD=m
  None.gif
  
  CONFIG_BLUEZ_HCIBTUART=n
  None.gif
  
  CONFIG_BLUEZ_HCIVHCI=n
  None.gif
  
  CONFIG_BLUEZ_HCIUSB_SCO=n
  None.gif
  
  CONFIG_BLUEZ_HCIUART_BCSP=n
  None.gif
  
  CONFIG_BLUEZ_HCIBFUSB=n
  None.gif
  
  注意CONFIG_BLUEZ_HCIBLUECARD是对"CF"接口的蓝牙设备的支持.
  重新编译内核和模块, 然后安装到设备上并重新启动设备. 如果你不知道怎样编译内核和模块, 请参阅其他文献.
  2. pcmcia_cs的修改
  由于CF卡通过PCMCIA总线工作, 所以对pcmcia设备的配置也必须修改, 以保证cardmgr能够正确识别新设备并装载正确的Driver. 以下必须手工修改: /etc/pcmcia/config:
  None.gif
  
  --- config.orig 2007-09-28 16:18:54.000000000 +0200
  None.gif
  +++ config 2007-09-28 16:17:40.000000000 +0200
  None.gif
  @@ -23,6 +23,9 @@
  None.gif
  
  device "serial_cs"
  None.gif
  class "serial" module "serial_cs"
  None.gif
  
  None.gif
  +device "bluecard_cs"
  None.gif
  + class "bluetooth" module "bluecard_cs"
  None.gif
  +
  None.gif
  # dummy drivers
  None.gif
  
  
  None.gif
  
  device "dummy_cs" module "dummy_cs"
  None.gif
  @@ -52,3 +55,8 @@
  None.gif
  
  card "Serial or Modem"
  None.gif
  function serial_port
  None.gif
  
  bind "serial_cs"
  None.gif
  +
  None.gif
  +card "Anycom LSE139 Bluetooth Compact Flash Card"
  None.gif
  + version "BTCFCARD", "LSE139"
  None.gif
  + bind "bluecard_cs"
  None.gif
  +
  注意其中增加(前面带+的)的部分. 做了这部分的修改后, 必须重新启动cardmgr. 然后插入蓝牙模块, 这时cardmgr应该可以正确的识别蓝牙模块并装载bluecard_cs.o. 如果一切正常应该没有任何警告和错误消息出现. 如果出现类似"收到不能识别的数据包" 之类的错误, 八成是驱动有问题了.
  3. 安装bluez
  需要交叉编译并安装到设备上的包有:
  bluez-libs_2.21
  bluez-utils_2.21
  如果你安装高版本的bluez, 那么你可能还需要DBUS, 在这里不带DBUS功能的bluez于我的嵌入式设备已经够用, 所以我选择了一个低版本的Bluez. 当我编译bluez的时候编译器抱怨PATH_MAX未定义, 这个时候在出错的C文件头部加上#include
  4. 启动蓝牙设备
  None.gif
  
  root@ereader:~#/etc/init.d/bluetooth start
  如果你没有这个脚本, 从其他Linux计算机上拷贝一个稍微修改一下就可以用了.
  运行这个脚本后, 确保hcid 和 krfcommd这两个后台进程已经跑起来了.
  然后可以运行hciconfig hci0, 可以看到蓝牙模块已经成功被初始化, 而且会显示正确的BD地址.
  5. 扫描周围的蓝牙模块
  None.gif
  
  root@ereader:~#hcitool scan
  None.gif
  
  Scanning ...
  None.gif
  00:12:37:95:57:C9 Alex Henzen
  None.gif
  
  00:0C:76:47:33:2F edbuntu-0
  None.gif
  00:17:B0:4C:B0:71 Nokia 6021
  None.gif
  00:16:41:F6:E0:E0 NB003
  None.gif
  
  00:16:41:D7:84:D7 NB024
  None.gif
  
  00:16:41:D9:1A:1C jinlei-Windows
  现在可以说你的蓝牙设备已经可以正常工作了. 但如果我们想利用蓝牙通信帮助我们做一点事情, 还有很多其他工作要做. 下面我们举两个应用场景.
  应用场景1: 通过蓝牙手机拨号上网首先你需要一个可以上网的手机, 支持数据业务, 支持蓝牙通信, 并正确的配置好. 然后在设备上使用modprobe rfcomm插入rfcomm.o模块.
  第一步, 扫描手机提供的蓝牙服务类型
  None.gif
  
  root@ereader:~# sdptool browse 00:12:D2:CE:6C:A1
  None.gif
  Browsing 00:12:D2:CE:6C:A1 ...
  None.gif
  
  None.gif
  Service Name: Headset Audio Gateway
  None.gif
  
  Service RecHandle: 0x10005
  None.gif
  Service Class ID List:
  None.gif
  
  "Headset Audio Gateway" (0x1112)
  None.gif
  "Generic Audio" (0x1203)
  None.gif
  Protocol Descriptor List:
  None.gif
  
  "L2CAP" (0x0100)
  None.gif
  "RFCOMM" (0x0003)
  None.gif
  Channel: 29
  None.gif
  Language Base Attr List:
  None.gif
  
  code_ISO639: 0x454e
  None.gif
  encoding: 0x6a
  None.gif
  base_offset: 0x100
  None.gif
  Profile Descriptor List:
  None.gif
  
  "Headset" (0x1108)
  None.gif
  Version: 0x0100
  None.gif
  
  None.gif
  Service Name: Dial-Up Networking
  None.gif
  
  Service RecHandle: 0x10042
  None.gif
  Service Class ID List:
  None.gif
  
  "Dialup Networking" (0x1103)
  None.gif
  Protocol Descriptor List:
  None.gif
  
  "L2CAP" (0x0100)
  None.gif
  "RFCOMM" (0x0003)
  None.gif
  Channel: 2
  None.gif
  Language Base Attr List:
  None.gif
  
  code_ISO639: 0x454e
  None.gif
  encoding: 0x6a
  None.gif
  base_offset: 0x100
  None.gif
  Profile Descriptor List:
  None.gif
  
  "Dialup Networking" (0x1103)
  None.gif
  Version: 0x0100
  None.gif
  可以看到这个手机提供了两种蓝牙服务类型, 便携式耳麦和拨号服务. 我们只对后者感兴趣. 注意该手机在Channel 2上提供拨号连接.
  第二步, 与手机配对(Pair)
  None.gif
  
  root@ereader:~#rfcomm connect 0 00:12:D2:CE:6C:A1 2
  请参考rfcomm的帮助了解各个参数的意义. 倒数第二个参数是手机的BD地址, 最后一个参数是连接到哪个channel. 为了确保这一步可以成功, 修改/etc/bluetooth/hcid.conf, 了解pin_helper的用法, 为自己的蓝牙设备设置一个PIN码. 以后这个PIN码就成为配对时的鉴权工具. 当手机收到配对请求时, 输入相同的PIN码即可.
  第三步, 安装拨号工具
  交叉编译pppd并安装到设备上. 在这之前你可能还要做很多其他的工作比如重新编译内核使其具备对PPP协议的支持等. 可以参考我的另外一篇文章"在嵌入式Linux上使用CF接口的Modem (CDMA/GPRS)"
  第四步, 编写拨号脚本 (假设这个手机是使用中国联通运营商的CDMA手机)
  建立文件/etc/ppp/chat-unicom (这里以中国联通的UIM卡为例),使之具有下面的内容:
  None.gif
  
  # /etc/ppp/chat-unicom
  None.gif
  # this is the chat script for unicom
  None.gif
  
  None.gif
  
  ABORT "NO CARRIER"
  None.gif
  ABORT "NO DIALTONE"
  None.gif
  ABORT "ERROR"
  None.gif
  ABORT "NO ANSWER"
  None.gif
  ABORT "BUSY"
  None.gif
  TIMEOUT 120
  None.gif
  "" at
  None.gif
  
  OK atdt#777
  None.gif
  CONNECT
  ABORT "***" 意思是如果结果回显中碰到这样的字符串则中断拨号程序,#777是通过中国联通通信网络上网的拨号号码.
  第五步, 开始拨号
  modprobe ppp_async
  ln -s /dev/rfcomm0 /dev/modem /usr/sbin/pppd connect '/usr/sbin/chat -v -f /etc/ppp/chat-unicom' user card password card /dev/modem 115200 nodetach crtscts debug usepeerdns defaultroute
  None.gif
  
  nodetach的意思是pppd在前台运行,不脱离控制台,这样可以看到pppd的输出. 默认行为是后台运行。
  好了,大功告成,现在可以享受网上冲浪之旅了。
  应用场景2: 与PC连接组成无线局域网, 并可以通过PC上网首先你的电脑需支持蓝牙通信, 并安装了bluez-utils. 然后在设备上使用modprobe bnep插入bnep.o模块. 这里我假设你的电脑运行的是Linux. Windows上的配置应该更为简单, 略.
  第一步, 修改/etc/network/interfaces使得当设备与PC连接起来后自动配置Interface:
  None.gif
  
  iface bnep0 inet dhcp
  这里我们使用DHCP. 因为我想让PC充当DHCP服务器给我的设备分配IP地址.所以我们在PC上也要做一些配置.
  第二步, PC配置.
  修改/etc/bluetooth/hcid.conf, 如下(只列出改动的部分):
  None.gif
  
  lm accept, master
  None.gif
  PAND_ENABLED=1
  None.gif
  PAND_OPTIONS="--listen --role=NAP --devup /etc/bluetooth/pan/dev-up"
  改动完成后重启bluetooth服务, 确保pand后台服务已经跑起来了.
  建立脚本/etc/bluetooth/pan/dev-up, 如下:
  None.gif
  
  #!/bin/sh
  None.gif
  echo 1 > /proc/sys/net/ipv4/ip_forward
  None.gif
  
  ifup bnep0
  这里的第二行是指我们共享该计算机的Internet连接(IP转发), 第三行是指当bluetooth连接建立起来后自动唤起interface.然后是配置DHCP服务器(修改/etc/dhcp3/dhcpd.conf), 使得它能够给连接到bnep0上的设备分配IP地址, 并告知DNS服务器的IP地址等, 请参考http://www.yolinux.com/TUTORIALS/DHCP-Server.html获得关于如何配置DHCP服务的信息.
  重启DHCP服务.
  第三步, 连接到PC
  None.gif
  
  pand -c 00:16:41:D9:1A:1C -r PANU -d NAP -z -n
  这里第二个参数是PC上蓝牙模块的BD地址, 其他参数请参考pand的帮助信息. 如果连接成功建立, 使用ifconfig应该可以看到一个新的interface已经建立(bnep0), 然后其IP地址也自动获得. 应该可以PING通PC了, 而且可以上网了.
  Good Luck!
  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1828477

本文转自
http://blog.csdn.net/mlite/archive/2007/10/17/1828477.aspx