BC05端:
编译环境是CSR的ADK1.1, 里面有例程, 有关模拟串口的有RFCOMM和SPP, 还不太清楚二者的区别例程SPP有点问题, 编译可以通过, 但在链接时会找不到变量:
ld: Undefined symbols:
$_sppGetServiceHandle
$_sppStoreServiceHandle
需要在ADK1.1下加入SPP的fix文件, 并重新编译库.spp_server作用是把RF收到的数据转到实际的UART, 并把UART中收到的数据连接到RF.
PS: 处理 UART sink 可以利用MessageSinkTask()将UART中断交给自己的handler处理, MessageSend()id值是MESSAGE_MORE_DATA(0x8000+33), 用同样的方法可以成功将RF sink 与handler绑定, 但把data强制转换成(MessageMoreData*)后, SourceMap()会失败, 因此需要搞清楚CSR底层有没有对这种情况提供可行的方案.
使用MessageSinkTak()可以实现
使用rfcomm_echo_server/rfcomm_echo_client这两个例程烧录到开发板上, 可以实现两个BC05的模拟串口通信: client端将数据发送给server, server收到后再原封不动发还给client, client需要通过上位机软件来实现发送和接收.
server一直在运行等待连接, client搜索不到一分钟后超时.
工程中的.led文件, 可以在编译时自动生成.c.h文件(如果编译选项改变了的话), 用来配置灯的状态.
工程中的.button文件, 可以在编译时自动生成.c.h文件(如果编译选项改变了的话), 用来配置按键.
主要用到的API:
MessagePioTask()
PioDebounce32()
StreamConnect()
MessageSinkTask()
SPP_SERVER中 ConnectionInit()即把task和connection事件连接在一起, 这样在调用loop()以后, 底层会马上抛出CL_INIT_CFM和SPP_START_SERVICE_CFM这两个case, 可以在task中作相应处理或者忽略.
真正开始spp server功能的其实是ConnectionWriteScanEnable()和SppStartService()这两个函数, 可以根据自己实际情况调用, 不一定非在CL_INIT_CFM case中, 调用后底层会抛出一系列连接请求case, 所以task中一定要有SPP_STOP_SERVICE_CFM, SPP_CONNECT_IND, SPP_SERVICE_CONNECT_CFM等case并处理连接请求.
Android端:
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);此处的蓝牙地址字符串address中, 如果有英文的话, 要大写.
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect() maybe failed, replace it with getClass().getMethod() invoke()
synchronized 方法:
声明是为了定义变量的作用范围和作用域
通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 sy