当前位置:首页 > 消费电子 > 消费电子
[导读]在物联网浪潮中,蓝牙低功耗(BLE)凭借其极低的功耗和便捷的连接方式,成为传感器、穿戴设备、智能家居的首选无线协议。在嵌入式Linux平台上,BlueZ是官方蓝牙协议栈,它提供了从HCI层到GATT层的完整API。本文以树莓派4B为例,展示如何用C语言开发一个BLE外设驱动,实现物联网设备的无线数据交互。


在物联网浪潮中,蓝牙低功耗(BLE)凭借其极低的功耗和便捷的连接方式,成为传感器、穿戴设备、智能家居的首选无线协议。在嵌入式Linux平台上,BlueZ是官方蓝牙协议栈,它提供了从HCI层到GATT层的完整API。本文以树莓派4B为例,展示如何用C语言开发一个BLE外设驱动,实现物联网设备的无线数据交互。

BlueZ协议栈概览

BlueZ是Linux内核的蓝牙子系统,包含核心驱动、L2CAP、SMP、ATT/GATT等协议层。用户空间通过D-Bus接口或Socket与内核交互。对于BLE开发,最常用的工具是bluetoothctl(交互式控制)和gatttool(GATT操作)。但若要集成到产品中,则需要直接调用BlueZ的D-Bus API或使用libbluetooth库。

开发环境准备

在树莓派上安装依赖:

sudo apt install bluez bluez-tools libbluetooth-dev

确认蓝牙适配器正常工作:

hciconfig -a

# 若hci0未开启,执行

sudo hciconfig hci0 up

编写BLE外设(Peripheral)

以下代码创建一个BLE GATT服务器,广播一个自定义服务,包含一个可读写的特征值。使用BlueZ的D-Bus API(通过GLib)。

#include <glib.h>

#include <gio/gio.h>


GDBusProxy *adapter, *advertising, *application;

const char *service_uuid = "0000180f-0000-1000-8000-00805f9b34fb";

const char *char_uuid = "00002a19-0000-1000-8000-00805f9b34fb";


static void on_characteristic_read(GDBusProxy *proxy, GVariant *value) {

   // 返回电池电量(示例固定值80%)

   guchar level = 80;

   GVariant *new_val = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, &level, 1, 1);

   g_dbus_proxy_call_sync(proxy, "WriteValue", g_variant_new_tuple(NULL, 0), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);

}


int main() {

   GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);

   // 获取适配器对象

   adapter = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL,

                                   "org.bluez", "/org/bluez/hci0", "org.bluez.Adapter1", NULL, NULL);

   // 设置可发现

   g_dbus_proxy_call_sync(adapter, "SetDiscoveryFilter", g_variant_new("(a{sv})", NULL), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);

   // 创建GATT应用...

   // 实际代码较长,此处省略详细注册过程

   GMainLoop *loop = g_main_loop_new(NULL, FALSE);

   g_main_loop_run(loop);

   return 0;

}

实际开发中,推荐使用libsimple-bluez或gattlib等封装库简化D-Bus调用。对于快速原型,也可用Python的bluepy或pygatt。

编写BLE中央设备(Central)

扫描并连接外设,读取特征值:

#include <bluetooth/bluetooth.h>

#include <bluetooth/hci.h>

#include <bluetooth/hci_lib.h>


int scan_and_connect() {

   int dev_id = hci_get_route(NULL);

   int sock = hci_open_dev(dev_id);

   if (sock < 0) return -1;


   inquiry_info *info = malloc(255 * sizeof(inquiry_info));

   int num = hci_inquiry(dev_id, 8, 255, NULL, &info, IREQ_CACHE_FLUSH);

   for (int i = 0; i < num; i++) {

       char addr[18];

       ba2str(&info[i].bdaddr, addr);

       printf("Found device: %s\n", addr);

   }

   free(info);

   close(sock);

   return 0;

}

实际应用要点

权限:运行BLE程序需要cap_net_admin或root权限,建议通过setcap cap_net_admin+eip ./app授权。

UUID:自定义服务/特征需使用128位UUID,标准服务使用16位UUID。

MTU:BLE 4.2及以上支持MTU扩展,协商更大的MTU可提升吞吐量。

连接间隔:根据功耗和实时性需求调整连接间隔(7.5ms~4s)。

白名单:生产环境中使用白名单过滤连接,防止非法设备接入。

写在最后

在嵌入式Linux上开发BLE驱动,本质是调用BlueZ提供的D-Bus接口或Socket API,实现GATT服务器的注册与客户端的数据交互。掌握hci_*、g_dbus_proxy_call等核心函数后,即可将传感器数据通过BLE广播出去,或被手机App读取。当你的物联网设备需要“低功耗、短距离、免配对”的无线链路时,BLE + BlueZ是最成熟的开源选择。从树莓派到工业ARM板,这套方案可以无缝迁移。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在物联网终端、便携医疗设备和野外传感器中,电池续航往往是产品成败的关键。嵌入式Linux虽然功能强大,但其默认配置偏向性能而非节能——CPU始终运行在高频、外设持续供电、内核定时器频繁唤醒。通过系统级的功耗调优,将续航延...

关键字: 嵌入式Linux 低功耗优化 电池续航

在工业HMI、医疗仪器面板、车载中控等嵌入式场景,用户界面的流畅度和开发效率直接决定产品上市速度。Qt作为嵌入式Linux上最成熟的图形框架,凭借跨平台、信号槽机制、丰富的控件库和QML声明式UI,成为HMI开发的首选。...

关键字: 嵌入式Linux QT HMI

传统PLC硬件专机价格高、扩展性受限,而ARM+Linux平台成本低、生态丰富。将PLC的梯形图/ST逻辑解释为软件运行时,在ARM Linux上执行,既能保留PLC的可靠性思维,又能利用Linux的网络、存储和图形能力...

关键字: 软PLC 嵌入式Linux ARM

在Zynq、ZU+等SoC FPGA平台上,ARM处理器系统(PS)与可编程逻辑(PL)通过AXI总线紧耦合,让"Linux跑应用+FPGA做加速"成为嵌入式异构计算的主流范式。两者分工清晰:PS负责网络协议、文件系统、...

关键字: 嵌入式Linux FPGA 软硬件协同

当AI模型从云端下沉到产线相机、无人机、农业传感器等边缘节点,算力受限、功耗敏感、实时性要求高成为新常态。轻量模型(MobileNet、YOLO-Nano、TinyBERT)搭配推理加速引擎,可以在几瓦功耗下实现毫秒级推...

关键字: 边缘计算 AI推理 嵌入式Linux

当嵌入式项目从“跑个Demo”走向量产,Buildroot的简洁往往不够用——你需要精确控制内核版本、库的ABI兼容性、安全补丁的追溯,甚至为不同SKU生成差异化的镜像。Yocto正是为此而生:它不是一套固化的系统,而是...

关键字: Yocto 嵌入式Linux 自定义发行版

很多刚接触嵌入式Linux的工程师看到arch/arm64/boot/dts/下成片的.dts、.dtsi文件就头大。其实设备树(Device Tree)本质就是一份"硬件简历"——用树形结构告诉内核:板子上有啥外设、挂...

关键字: 设备树 DTS 嵌入式Linux

在SPI NOR Flash只有16MB、甚至8MB的嵌入式板上,每一次字节都很贵。Buildroot的优势在于:一条make menuconfig就能通过交叉编译生成工具链、根文件系统和内核镜像,帮开发者把"臃肿"挡在...

关键字: Buildroot 根文件系统 嵌入式Linux

设备树(Device Tree, DTB)是嵌入式Linux系统中描述硬件的“骨架”。一个错误的status、一个拼错的compatible,就可能导致外设驱动无法加载或系统崩溃。本文总结十个在ARM/Linux设备树编...

关键字: 嵌入式Linux 设备树

在嵌入式Linux开发中,设备树(Device Tree)已成为描述硬件的标准。它让内核与硬件解耦,实现“一份内核,适配万千板卡”。本文将跳过繁杂的理论,直击设备树节点编写与内核驱动匹配的核心流程。

关键字: 嵌入式Linux 设备树 Device Tree
关闭