wince蓝牙驱动相关

[复制链接]
 楼主| high 发表于 2008-3-16 14:10 | 显示全部楼层 |阅读模式
之前没有摸过蓝牙,这回的项目里面有蓝牙模块.而我目前对蓝牙只知道的有:1.我们的设计里蓝牙模块是连接在串口上的.2.蓝牙不是蓝色的牙齿.呵呵,&nbsp;,我不得不提前开始接触一下蓝牙协议栈.粗看起来还挺复杂庞大的.单蓝牙组织公布的规范1.1多达1084页.先看张图(不知道如何贴图,图片是msdn里面蓝牙协议栈的结构图,可以访问http://msdn2.microsoft.com/en-us/library/ms890956.aspx)&nbsp;<br /><br />&nbsp;&nbsp;<br /><br /><br />东西很多,先分类吧!从底向上看,蓝牙的协议和规范可以分这些大类:&nbsp;<br /><br />一:最底层.就是上图蓝色部分.其中有射频规范,基带规范和链路管理层(Link&nbsp;Manager&nbsp;Protocol).一个好消息是,不要管这部分内容.因为这部分都在蓝牙模块里面实现了.可能需要稍微了解下的就是链路管理协议主要是负责认证,加密,链路管理和控制这些功能.还有一些有趣的信息,一个主设备最大和7个从设备建立链接,从设备之间不能互通.主设备到从设备的最大数据传输速率为723.2kbps,反向57.6kbps.也可以配置为双向433.9kbps.&nbsp;<br /><br />二:接口层.协议栈和硬件之间的接口.在WinCE中,它也包括了3个部分:第一,HCI(Host&nbsp;Controller&nbsp;Interface),第二,Bluetooth&nbsp;Universal&nbsp;Transport&nbsp;Manager,第三,HCI&nbsp;Transport&nbsp;layer主机控制接口层.第一层向上提供一个接口,第三层是和硬件的接口,比如连接到Host的是串口,那第三层就是一个串口的抽象的传输层,那为什么还需要第二层呢?第二层叫统一传输管理,是因为WinCE是一个开放的平台,它也不知道蓝牙究竟是连接串口,usb口,sdio甚至一些pcmcia等其他的pnp设备,等等,而且作为HCI的上层也不想知道你用什么物理接口.于是它抽象出来这么一个东西来统一管理.简单说就是大一统所有的接口了,它先去扫描PCMCIA,USB和sdio等pnp设备,如果没有就根据注册表取默认的设备接口.最后被选定的接口会被安排到这里[HKEY_LOCAL_MACHINESoftwareMicrosoftBluetoothHCI]&nbsp;<br /><br />第二和第三部分的代码在WINCE500PUBLICCOMMONOAKDRIVERSBLUETOOTHTRANSPORTS目录下面,那个univ目录的就是Universal&nbsp;Transport&nbsp;Manager,其他是各个具体的Transport&nbsp;layer的实现.&nbsp;<br /><br />刚才说到如果没有扫描到pnp的蓝牙设备就使用默认的,这个默认的接口在哪里?其实也是根据注册表来找接口,看看下面的内容吧:1代表优先级别.name=COM2,baud=1c200,这很明显,就是以115200的波特率打开COM2口了.&nbsp;<br /><br />IF&nbsp;BSP_BLUETOOTH_BUILTIN_UART&nbsp;<br /><br />[HKEY_LOCAL_MACHINESoftwareMicrosoftBluetoothTransportsBuiltIn1]&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&quot;driver&quot;=&quot;bthuart.dll&quot;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&quot;flags&quot;=dword:4&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&quot;name&quot;=&quot;COM2:&quot;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&quot;baud&quot;=dword:1c200&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&quot;resetdelay&quot;=dword:1388&nbsp;<br /><br />ENDIF<br /><br /> 相关链接:<a href='http://chenyq2008.spaces.live.com'>http://chenyq2008.spaces.live.com</a>
 楼主| high 发表于 2008-3-16 14:10 | 显示全部楼层

2

细说HCI&nbsp;<br /><br />对于HCI接口,它向上提供了一个访问底层硬件的统一接口.比如提供给l2cap.其实不用关心HCI内部怎么实现的,只要懂得怎么使用就可以,更进一步,如果所有应用都是在l2cap上的,连HCI接口也没有必要知道.比如我们的应用只是基于winsock,rfcomm,或者obex,这些都是l2cap的上层,就不要关心HCI的上层接口.它是透明的,当它不存在好了.&nbsp;<br /><br />如果好奇HCI的上层(比如l2cap)如何使用hci接口?其实是使用HCI_EstablishDeviceContext()这个函数来获得接口,并注册相关回调函数和事件响应函数.这些模块源代码都在WINCE500PRIVATEWINCEOSCOMMBLUETOOTH目录里面.&nbsp;<br /><br />对于一些特殊的应用,比如你有一些蓝牙耳机这样的应用,就不是通过l2cap了,那么就要从hci层扩展.还是使用同样的接口方法,只是参数不同了.耳机这样的应用是要处理的是同步的连接SCO数据包,于是透过参数告知hci,将sco数据发给自己来处理.具体来说就是第2个参数BTH_CONTROL_ROUTE_BY_LINKTYPE,第5个参数BT_LINK_TYPE_SCO,以次来调用HCI_EstablishDeviceContext().<br />
 楼主| high 发表于 2008-3-16 14:10 | 显示全部楼层

3

三:协议层.这一层包括L2CAP,SDP,RFCOMM.首先要说L2CAP,之前已经提及这个协议,它建立在HCI上面.全名是逻辑链路控制和适应协议(Logical&nbsp;Link&nbsp;Controller&nbsp;and&nbsp;Adaption&nbsp;Protocol)看看它的功能:分发数据给更高层,数据包分段和重组...看过tcpip协议栈,感觉这一层像ip层.如果想基于L2CAP上做第3方扩展应用,就要知道如何使用L2CAP接口.其实就是使用L2CAP_EstablishDeviceContext()来获得L2CAP层的接口,这是不是和HCI的接口太像了?接下来是SDP,这是一个服务发现协议(service&nbsp;discovery&nbsp;protocol)蓝牙设备是要组网的,就是用这个协议来寻找和定位其他蓝牙设备.另外一个RFCOMM是模拟串口协议,是ETSI&nbsp;TS07.10标准的子集.没有听过这个标准.反正,这个模块的作用是使得上层就像操作串口一样使用蓝牙.&nbsp;<br /><br />&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;蓝牙协议栈的实体究竟在哪里?WinCE实现了2个动态链接库来实现,一个是btd.dll另外一个是btdrt.dll.由device.exe加载.btd.dll包含了协议栈各个层.而btdrt.dll提供了一组api来访问各个层.btdrt.dll其实是一个runtime库<br />
 楼主| high 发表于 2008-3-16 14:11 | 显示全部楼层

4

四:应用层.摘抄一段:&nbsp;<br /><br />蓝芽协议栈的最上部是各种应用模型(Profile)。其中较典型的有服务发现&nbsp;(Service&nbsp;Discovery&nbsp;Application),互通(Intercom),无绳电话(Cordless&nbsp;Telephony),传真(FAX),拨号网络(Dial-up&nbsp;Networking),耳机(Headset),局域网访问(LAN&nbsp;Access),文件传输(File&nbsp;Transfer),同步(Synchronization),Object&nbsp;Push等。各种Profile从协议栈中选取不同的协议组合来完成特定的功能。&nbsp;下面列出各种Profile需要的协议组合,协议排列顺序按照从上到下的顺序:&nbsp;服务发现(Service&nbsp;Discovery&nbsp;Application),包括SDP、L2CAP、LMP、Baseband;&nbsp;互通(Intercom),无绳电话(Cordless&nbsp;Telephony),包括TCS、SDP、L2CAP、LMP、Baseband;传真(FAX),拨号网络(Dial-up&nbsp;Networking),耳机(Headset),包括SDP/RFCOMM、L2CAP、LMP、Baseband;&nbsp;局域网访问(LAN&nbsp;Access),包括TCP/IP,PPP,SDP/RFCOMM,L2CAP,LMP,Baseband;&nbsp;文件传输(File&nbsp;Transfer),同步(Synchronization),Object&nbsp;Push,含OBEX,SDP/RFCOMM,L2CAP,LMP,Baseband。&nbsp;<br />
 楼主| high 发表于 2008-3-16 14:11 | 显示全部楼层

蓝牙耳机功能

蓝牙耳机功能,也就是bluetooth&nbsp;headset&nbsp;/headfree&nbsp;profile,实现起来比想象的复杂.早期的蓝牙规范只定义了headset的profile,&nbsp;headset的实现原理,是在hci层之上扩展一个接口,传输sco同步面向连接的音频数据包.限定音频流只能是单声道8k的话音级别的pcm.&nbsp;随着需求发展,明显已经不能满足了,于是又补充了a2dp协议.a2dp协议在l2cap上层,使用sbc压缩并使用acl异步数据包传输,可以支持cd级别的音频流.但是wince5并不支持a2dp,要wince6才有.上面2种都是透过hci层来传送音频流,这意味着还要受到hci总线带宽的限制.hci接口常见的有uart,spi,usb.为了突破这个限制,有一些设备会使用独立的pcm总线来传音频流.比如csr的芯片就有独立的pcm总线.我们的设计中,将蓝牙芯片的pcm接到了音频芯片的pcm,这提供了最大的灵活性.&nbsp;<br /><br />如果你想实现headset,那么就要使用AG(audio&nbsp;gateway)服务btagsvc.dll,并且创建一个蓝牙音频驱动btscosnd.dll.在你的应用中使用DeviceIoControl发送IOCTL_AG_OPEN_AUDIO给AG服务,继而,AG服务会建立sco连接并使用waveOutMessage()发送WODM_BT_SCO_AUDIO_CONTROL给蓝牙音频驱动.蓝牙音频驱动于是建立了对hci层的连接,透过参数告知hci要处理的是sco数据,最后创建了一个线程处理sco的事件.&nbsp;<br /><br />这个过程不会很顺利,一般会遇到一些问题.尤其是自己板上已经有另外一个音频设备的时候.在google中搜索你会体会到很多人在解决这个坎坷的问题.哪些问题呢?假设板载的音频设备是device0,在透过wave&nbsp;api来使用驱动时候,希望使用device1,却无法成功.这个问题是微软造成的.上面提到AG会使用waveOutMessage发消息给音频驱动,,waveOutMessage的发送对象竟然是固定的0.也就是device0.所以这限制了蓝牙音频驱动必须是device0.如何决定谁成为device0呢?并不是注册表中的Index项,那只是决定了WAV0还是WAV1.答案是order项.因此,本质就是,第一个被加载的音频驱动才是device0.&nbsp;<br /><br />通过以上方法,成功在wince5上实现了蓝牙headset&nbsp;profile.但是音质的确不很满意.<br />
yujian598 发表于 2008-9-27 15:45 | 显示全部楼层

在bluelab上可以对音质进行调解的

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

1078

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部