【Silicon Labs BG22-EK4108A 蓝牙开发评测】四:NCP Mode 上位机开发
本帖最后由 jj1989 于 2022-2-9 09:04 编辑<div class="parsedown-markdown">
<h1>【Silicon Labs BG22-EK4108A 蓝牙开发评测】四:NCP Mode 上位机开发</h1>
<h2>前言</h2>
<p>原本计划进行功耗测试,看到有网友已经做了相关测试,并且需要使用额外的板子才能使用 power 工具,遂作罢。</p>
<p>在之前的文章中提到, <a href="https://www.silabs.com/documents/public/quick-start-guides/qsg169-bluetooth-sdk-v3x-quick-start-guide.pdf" target="_blank">QSG169:《蓝牙 SDK v3.x 快速入门指南》</a>中关于蓝牙协议栈,介绍了三种工作模式。本人对其中的 NCP 模式比较感兴趣,这次就来研究一下。</p>
<h2>NCP Mode</h2>
<p>NCP 全称为:network Co-Processor(NCP) Mode,官方对其介绍如下:</p>
<blockquote>
<p>Network Co-Processor (NCP) mode, where the Bluetooth stack runs in an EFR32 and the application runs on a separate host MCU. For this use case, the Bluetooth stack can be configured into NCP mode where the API is exposed over a serial inter- face such as UART.</p>
</blockquote>
<p>其功能结构框图如下:</p>
<p></p>
<p>如上图,蓝牙 SOC 只负责协议栈相关的处理。我们的应用程序运行在单独的设备上,可以是其它 MCU 或者 PC 上位机。可以通过名为 BGAPI 的软件接口,使用 UART 硬件接口进行蓝牙协议栈的配置。</p>
<p>在第二篇文章<a href="https://bbs.eeworld.com.cn/thread-1192192-1-1.html" target="_blank">【Silicon Labs BG22-EK4108A 蓝牙开发评测】二:开发环境初体验</a> 中,我们简单体验了一下 NCP 模式,当时使用官方提供的图形化工具 -- <em>Bluetooth NCP Commander</em> 进行蓝牙协议栈的配置。</p>
<p>继续研究,发现官方提供了一个名为 <a href="https://pypi.org/project/pybgapi/" target="_blank">PyBGAPI</a> 的 python 库。对 PyBGAPI 的介绍如下:</p>
<blockquote>
<p>This package provides a Python interface for the BGAPI binary protocol. It reads the BGAPI definition file and dynamically generates a parser for it.</p>
</blockquote>
<p>这意味着我们可以通过 python 语言来很方便地进行蓝牙协议栈的配置。接下来就以我们<a href="https://bbs.eeworld.com.cn/thread-1192920-1-1.html" target="_blank">上一篇</a>中介绍的官方例程 Bluetooth-Soc Blinky 为参考,通过 python 控制运行于 NCP 模式下的 EFR32BG22 SOC 来实现 Blinky 例程功能。</p>
<h2>代码解析</h2>
<p>关于 PyBGAPI 库的使用,可以参考官方给出的<a href="https://github.com/SiliconLabs/pybgapi-examples" target="_blank">例程</a>。这里在 empty 例程的基础上添加代码,实现我们需要的功能。 修改蓝牙名字等这些简单操作就不一一介绍了,这里讲一下关于蓝牙服务的添加及控制数据的处理。</p>
<h3>GATT 配置</h3>
<p>首先是添加蓝牙 Blinky 服务,服务 UUID 可以在官方 Blinky 例程中找到。然后是添加 Button 和 LED 两个特征,特征 UUID 同样参考官方例程。注意这里的 Button 特征属性为 Read 和 Notify,LED 特征属性为 Write 和 Read。 在 <em>gattdb_init</em> 方法中增加如下代码:</p>
<pre>
<code class="language-python"> # Blinky service
_, service = self.lib.bt.gattdb.add_service(
session,
self.lib.bt.gattdb.SERVICE_TYPE_PRIMARY_SERVICE,
self.lib.bt.gattdb.SERVICE_PROPERTY_FLAGS_ADVERTISED_SERVICE,
b"x24x12xb5xcbxd4x60x80x0cx15xc3x9bxa9xacx5ax8axde"
)
# Report button
_, self.gattdb_report_button = self.lib.bt.gattdb.add_uuid128_characteristic(
session,
service,
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_NOTIFY,
0,
0,
b"x9cxd2x70x2ax65x6dx53x9axd0x60xc3x41xa4x85xa8x61",
self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
1,
b"x00"
)
self.lib.bt.gattdb.start_service(session, service)
# LED Contorl
_, self.gattdb_led_control = self.lib.bt.gattdb.add_uuid128_characteristic(
session,
service,
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_WRITE,
0,
0,
b"x7ax08x6ax73x6cxbexd8x46x97xc2x88x40x10x65x02x5b",
self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
1,
b"x00"
)
self.lib.bt.gattdb.start_service(session, service)
</code></pre>
<h3>用户控制响应</h3>
<p>这里仅介绍 LED 控制状态的处理。在 <em>event_handler</em> 方法中添加如下代码:</p>
<pre>
<code class="language-python"> elif evt == "bt_evt_gatt_server_attribute_value":
if evt.att_opcode == self.lib.bt.gatt.ATT_OPCODE_WRITE_REQUEST:
led_status_update(evt.value)</code></pre>
<p>当 LED 特征执行写入请求操作时,就会调用 <em>led_status_update</em> 方法,进行 LED 状态的更新操作。这里仅通过打印日志反应 LED 状态,代码如下:</p>
<pre>
<code class="language-python">def led_status_update(value):
if value== b'x00':
print("led off.")
elif value == b'x01':
print("led on.")
else:
print("Invalid value.")</code></pre>
<h2>演示</h2>
<p>原计划是基于 python 开发一个桌面端的图形上位机,结合 EFR Connect 进行更直观的功能演示。奈何 iOS 端的 EFR Connect 最近更新后似乎有 bug,在 Demo 页面搜索不到对应的设备,记得上一个版本是可以的。于是乎一切从简,就做一个简单的演示吧。</p>
<p><em>注:开发板需要提前烧录好 NCP 固件。</em></p>
<p></p>
<h2>总结</h2>
<p>EFR32BG22 的这个 NCP 模式给应用开发提供了更多的选择,同时可玩性也大大提高。比如我们可以将开发板作为一个蓝牙鼠标接收器。由于提供了 python 库,因此开发也变得很简单,可轻松实现跨平台。</p>
</div>
<p> </p>
<p>关于CP 模式谢谢解析</p>
页:
[1]