STM32MP157 Linux系统移植开发篇18:Linux内核蓝牙驱动移植

本文章为《STM32MP157 Linux系统移植开发篇》系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板)。stm32mp157是ARM双核,2个A7核,1个M4核,A7核上可以跑Linux操作系统,M4核上可以跑FreeRTOS、RT-Thread等实时操作系统,STM32MP157开发板所以既可以学嵌入式linux,也可以学stm32单片机。

针对FS-MP1A开发板,除了Linux系统移植篇外,还包括其他多系列教程,包括Cortex-A7开发篇、Cortex-M4开发篇、扩展板驱动移植篇、Linux应用开发篇、FreeRTOS系统移植篇、Linux驱动开发篇、硬件设计篇、人工智能机器视觉篇、Qt应用编程篇、Qt综合项目实战篇等。欢迎关注,更多stm32mp157开发教程及视频,可加技术交流Q群459754978,感谢关注。

关于FS-MP1A开发板:
手机淘宝分享码:复制本行文字打开手淘₤T4FPXn3YYJ2₤
链接:https://item.taobao.com/item.htm?id=622457259672

1.实验原理

FS-MP1A开发板蓝牙采用AP6236,WIFI蓝牙二合一芯片。蓝牙部分通过usart3与SoC进行数据交互。

蓝牙部分移需要配置usart3的设备树与AP_CK32KO管脚,可参考stm32mp157c-dk2.dts中的相关配置。

查看原理图得出AP6236数据管脚与STM32MP157A的管脚对应关系如下:

原理图网络编号对应管脚管脚功能管脚功能码
BT_UART_TXPD8USART3_TXAF7
BT_UART_RXPD9USART3_RXAF7
BT_UART_CTSPD11USART3_CTSAF7
BT_UART_RTSPD12USART3_RTSAF7
BT_WIFI_RSTPD13IOANALOG
AP_CK32KOPI8RTC_OUT2ANALOG
  1. 蓝牙设备树节点

参考文档:

Documentation/devicetree/bindings/net/broadcom-bluetooth.txt

Documentation/devicetree/bindings/serial/st,stm32-usart.txt

内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

arch/arm/boot/dts/stm32mp151.dtsi

stm32mp151中usart3定义如下:

usart3: serial@4000f000 {

compatible = "st,stm32h7-uart";

reg = <0x4000f000 0x400>;

interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;

clocks = <&rcc USART3_K>;

resets = <&rcc USART3_R>;

wakeup-source;

power-domains = <&pd_core>;

dmas = <&dmamux1 45 0x400 0x5>,

<&dmamux1 46 0x400 0x1>;

dma-names = "rx", "tx";

status = "disabled";

};

上述代码只对usart3做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。

参考文档或stm32mp157c-dk2.dts对于usart2设备节点的描述,增加usart3内容如下:

&usart3 {

pinctrl-names = "default", "sleep", "idle";

pinctrl-0 = <&usart3_pins_bt>;

pinctrl-1 = <&usart3_idle_pins_bt>;

pinctrl-2 = <&usart3_sleep_pins_bt>;

uart-has-rtscts;

status = "okay";

bluetooth {

shutdown-gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;

compatible = "brcm,bcm43438-bt";

max-speed = <3000000>;

vbat-supply = <&v3v3>;

vddio-supply = <&v3v3>;

};

};

同时stm32mp15-pinctrl.dtsi对于usart3的描述与FS-MP1A所使用管脚不一致,所以无法直接使用,需参考其增加如下内容:

usart3_pins_bt: usart3-bt-0 {

pins1 {

pinmux = <STM32_PINMUX('D', 8, AF7)>, /* USART3_TX */

<STM32_PINMUX('D', 12, AF7)>; /* USART3_RTS */

bias-disable;

drive-push-pull;

slew-rate = <0>;

};

pins2 {

pinmux = <STM32_PINMUX('D', 9, AF7)>, /* USART3_RX */

<STM32_PINMUX('D', 11, AF7)>; /* USART3_CTS_NSS */

bias-disable;

};

};

usart3_idle_pins_bt: usart3-idle-bt-0 {

pins1 {

pinmux = <STM32_PINMUX('D', 8, ANALOG)>, /* USART3_TX */

<STM32_PINMUX('D', 12, ANALOG)>, /* USART3_RTS */

<STM32_PINMUX('D', 11, ANALOG)>; /* USART3_CTS_NSS */

};

pins2 {

pinmux = <STM32_PINMUX('D', 9, AF7)>; /* USART3_RX */

bias-disable;

};

};

usart3_sleep_pins_bt: usart3-sleep-bt-0 {

pins {

pinmux = <STM32_PINMUX('D', 8, ANALOG)>, /* USART3_TX */

<STM32_PINMUX('D', 12, ANALOG)>, /* USART3_RTS */

<STM32_PINMUX('D', 11, ANALOG)>, /* USART3_CTS_NSS */

<STM32_PINMUX('D', 9, ANALOG)>; /* USART3_RX */

};

};

2)RTC节点

AP6236需要使用一个外部输入的32.768KHz的时钟源,因此我们需要使能RTC的外部32.768KHz功能

参考文档:

Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt

内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

arch/arm/boot/dts/stm32mp151.dtsi

stm32mp151中rtc定义如下:

rtc: rtc@5c004000 {

compatible = "st,stm32mp1-rtc";

reg = <0x5c004000 0x400>;

clocks = <&scmi0_clk CK_SCMI0_RTCAPB>,

<&scmi0_clk CK_SCMI0_RTC>;

clock-names = "pclk", "rtc_ck";

interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;

status = "disabled";

};

上述代码只对rtc做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。

参考stm32mp157f-dk2.dts对于rtc设备节点的描述,需增加内容如下:

rtc {

st,lsco = <RTC_OUT2_RMP>;

pinctrl-0 = <&rtc_out2_rmp_pins_a>;

pinctrl-names = "default";

status = "okay";

};

2.实验目的

熟悉基于Linux操作系统下的蓝牙设备驱动移植配置过程。

3.实验平台

华清远见开发环境,FS-MP1A平台;

4.实验步骤

  1. 导入交叉编译工具链

linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

  1. 开启32.768KHz时钟

修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件中的rtc节点添加如下内容:

rtc {

st,lsco = <RTC_OUT2_RMP>;

pinctrl-0 = <&rtc_out2_rmp_pins_a>;

pinctrl-names = "default";

status = "okay";

};

其中红色字体部分为要添加的内容。

添加rtc相关头文件。

#include <dt-bindings/rtc/rtc-stm32.h>

  1. 添加usart3配置

修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件,在文件末尾添加如下内容:

&usart3 {

pinctrl-names = "default", "sleep", "idle";

pinctrl-0 = <&usart3_pins_bt>;

pinctrl-1 = <&usart3_idle_pins_bt>;

pinctrl-2 = <&usart3_sleep_pins_bt>;

uart-has-rtscts;

status = "okay";

bluetooth {

shutdown-gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;

compatible = "brcm,bcm43438-bt";

max-speed = <3000000>;

vbat-supply = <&v3v3>;

vddio-supply = <&v3v3>;

};

};

  1. 添加功能管脚配置

要添加管脚配置需要有pinctrl节点,如果之前已经做了MIPI LCD移植或者RGB LCD则在arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件下找到pinctrl节点添加如下配置,如果之前没有做MIPI LCD移植或者RGB LCD那么需要新建一个pinctrl节点,然后添加如下配置。

&pinctrl {

... ...

usart3_pins_bt: usart3-bt-0 {

pins1 {

pinmux = <STM32_PINMUX('D', 8, AF7)>, /* USART3_TX */

<STM32_PINMUX('D', 12, AF7)>; /* USART3_RTS */

bias-disable;

drive-push-pull;

slew-rate = <0>;

};

pins2 {

pinmux = <STM32_PINMUX('D', 9, AF7)>, /* USART3_RX */

<STM32_PINMUX('D', 11, AF7)>; /* USART3_CTS_NSS */

bias-disable;

};

};

usart3_idle_pins_bt: usart3-idle-bt-0 {

pins1 {

pinmux = <STM32_PINMUX('D', 8, ANALOG)>, /* USART3_TX */

<STM32_PINMUX('D', 12, ANALOG)>, /* USART3_RTS */

<STM32_PINMUX('D', 11, ANALOG)>; /* USART3_CTS_NSS */

};

pins2 {

pinmux = <STM32_PINMUX('D', 9, AF7)>; /* USART3_RX */

bias-disable;

};

};

usart3_sleep_pins_bt: usart3-sleep-bt-0 {

pins {

pinmux = <STM32_PINMUX('D', 8, ANALOG)>, /* USART3_TX */

<STM32_PINMUX('D', 12, ANALOG)>, /* USART3_RTS */

<STM32_PINMUX('D', 11, ANALOG)>, /* USART3_CTS_NSS */

<STM32_PINMUX('D', 9, ANALOG)>; /* USART3_RX */

};

};

... ...

};

  1. 修改串口名称映射关系

修改arch/arm/dts/stm32mp157a-fsmp1a.dts文件,在aliases节点中添加如下内容:

aliases {

serial0 = &uart4;

serial5 = &usart3;

};

其中红色字体部分为要添加的内容。

  1. 配置内核

由于内核源码默认配置以及支持AP62xx,本节列出主要选项,如下:

linux@ubuntu:$ make menuconfig

Device Drivers --->

<*> Broadcom specific AMBA --->

[*] Support for BCMA in a SoC

[*] ChipCommon-attached serial flash support

[*] BCMA Broadcom GBIT MAC COMMON core driver

[*] BCMA GPIO driver

6)编译内核及设备树

linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040

7)重启测试

将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,系统启动后查看/lib/firmware/brcm目录下是否包含BCM.hcd固件,如果没有发现这个文件可从【华清远见-FS-MP1A开发资料\02-程序源码\04-Linux系统移植\04-移植相关文件\02-Linux内核移植\AP6236固件】下拷贝到/lib/firmware/brcm目录下。

开启蓝牙设备

root@fsmp1a:# hciconfig hci0 up

查看设备地址

root@fsmp1a:# hcitool dev

扫描蓝牙设备

root@fsmp1a:# hcitool scan

硬件平台:华清远见FS-MP1A开发板(STM32MP157)

部分开发教程下载:加QQ群459754978,群文件里有。

部分视频课程收看:华清远见研发中心的个人空间_哔哩哔哩_Bilibili

淘宝购买链接:https://item.taobao.com/item.htm?id=622457259672

手机淘宝分享码:复制本行文字打开手淘₤T4FPXn3YYJ2₤

摘 要:基于对Linux蓝牙协议栈BlueZ 源代码的分析,给出BlueZ的组织结构和特点。分析蓝牙USB 传输驱动机制和数据处理过程, 给出实现蓝牙设备驱动的重要数据结构和流程,并总结Linux开发蓝牙USB 设备驱动的一般方法和关键技术。 关键词:Linux 系统蓝牙协议栈;设备驱动 USB Device Driver for Linux Bluetooth Stack LIANG Jun-xue, YU Bin (Institute of Electronic Technology, PLA Information Engineering University, Zhengzhou 450004) 【Abstract】This paper depicts the structure and characteristics of BlueZ based on analyzing the source code of Linux bluetooth stack BlueZ. It analyzes the implementation of bluetooth USB transport driver scheme and data processing procedure in detail, and gives the key data structure and implementation of bluetooth device driver. It summarizes the approach of developing Linux bluetooth USB device driver and the key technology. 【Key words】Linux system; bluetooth stack; device driver 计 算 机 工 程 Computer Engineering 第 34 卷 第 9 期 Vol.34 No.9 2008 年 5 月 May 2008 ·开发研究与设计技术· 文章编号:1000—3428(2008)09—0273—03 文献标识码:A 中图分类号:TP391 1 概述 蓝牙技术是开放式通信规范,而 Linux 是开放源码的操 作系统。廉价设备与免费软件的结合,促进了蓝牙技术和 Linux 的发展与融合。 Linux最早的蓝牙协议栈是由Axis Communication Inc在 1999 年发布的 OpenBT 协议栈。 随后, IBM 发布了 BlueDrekar 协议栈,但没有公开其源码。Qualcomm Incorporated 在 2001 年发布的 BlueZ 协议栈被接纳为 2.4.6 内核的一部分。此外, Rappore Technology 及 Nokia 的 Affix Bluetooth Stack 都是 Linux 系统下的蓝牙协议栈,应用在不同的设备和领域中。 BlueZ 是 Linux 的官方蓝牙协议栈,也是目前应用最广 泛的协议栈,几乎支持所有已通过认证的蓝牙设备。对于基 于主机的蓝牙应用,目前常见的硬件接口有 UART, USB 和 PC 卡等,USB 作为 PC 的标准外设接口,具有连接方便、兼 容性好和支持高速设备等特点,已广泛应用于蓝牙设备。 目前对 Linux 下 USB 设备驱动的研究已较为广泛而深 入[1-4] ,但对 Linux 下的蓝牙设备驱动还没有专门的研究。本 文在分析 USB 设备驱动蓝牙协议栈的基础上,总结了 Linux开发蓝牙 USB 驱动程序的一般方法,并深入剖析了 其关键技术。 2 Linux 蓝牙协议栈 BlueZ 简介 BlueZ 目前已成为一个开放性的源码工程。它可以很好 地在 Linux 支持的各种体系的硬件平台下运行,包括各种单 处理器平台、多处理器平台及超线程系统。 BlueZ 由多个独立的模块组成,内核空间主要包括设备 驱动层、蓝牙核心及 HCI 层、L2CAP 与 SCO 音频层、 RFCOMM, BNEP, CMTP 与 HIDP 层、通用蓝牙 SDP 库和后 台服务及面向所有层的标准套接字接口;在用户空间提供了 蓝牙配置、测试及协议分析等工具。其组织结构如图 1 所示, BlueZ 没有实现专门的 SDP 层,而是将其实现为运行在后台 的蓝牙服务库例程(图 1 没有描述该后台服务)。 RFOMM 层支 持标准的套接口,并提供了串行仿真 TTY 接口,这使串行端 口应用程序和协议可以不加更改地运行在蓝牙设备上,例如 通过点对点协议 PPP 可实现基于 TCP/IP 协议簇的所有网络 应用。BNEP 层实现了蓝牙的以太网仿真,TCP/IP 可以直接 运行于其上。 USB设备驱动 (hci_usb.o) L2CAP层(l2cap.o) RFCOMM层 (rfcomm.o) BNEP层 (bnep.o) CMTP层 (cmtp.o) 串口设备驱动 (hci_uart.o) 虚拟串口设备驱动 (hci_vhci.o) 音频 socket RFCOMM socket BNEP socket CMTP socket L2CAP socket HCI socket 内核 空间 用户 空间 串口设备 CAPI设备 输入设备 网络设备 HDIP socket 音频设备 AF_BLUETOOTH socket 音频层(sco.o) PPP TCP/IP AF_INET socket BNEP层 (bnep.o) 其他设备驱动 (bluecard_cs.o等) BlueZ工具和实用程序 HDIP层 (hdip.o) BlueZ核心 及HCI层(bluez.o/bluetooth.o) 图 1 BlueZ 组织结构 3 蓝牙 USB 设备驱动 设备驱动程序在 Linux 内核中起着重要作用,它使某个 硬件能响应一个定义良好的内部编程接口。这些接口隐藏了 设备的工作细节,用户通过一组独立于特定驱动程序的标准 调用来操作设备。而将这些调用映射到作用于实际硬件设备 的特有操作上,则是驱动程序的任务。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值