首页 > 编程语言 >pico-sdk(五)-程序架构之库结构(2)

pico-sdk(五)-程序架构之库结构(2)

时间:2024-11-24 21:32:33浏览次数:11  
标签:USB Pico 微控制器 之库 pico 寄存器 PLL sdk

pico-sdk(五)-程序架构之库结构(2)

硬件结构体库

hardware_structs 库提供了一组 C 结构体,这些结构体表示了系统地址空间中 RP 系列微控制器寄存器的内存映射布局1。能够用来替换较低层级的接口调用(这些内容原本需要用较低级别的 hardware_regs 中的宏定义来编写)。

*(volatile uint32_t *)(PIO0_BASE + PIO_SM1_SHIFTCTRL_OFFSET) |= PIO_SM1_SHIFTCTRL_AUTOPULL_BITS;

可以用如下的代码来替换(其中 pio0 是指向类型为 pio_hw_t 的指针,指针的地址为 PIO0_BASE):

pio0->sm[1].shiftctrl |= PIO_SM1_SHIFTCTRL_AUTOPULL_BITS;

这些结构体以及指向内存映射寄存器块的相关指针,隐藏了处理单个内存位置、指针类型转换和易失性访问的细节,降低了程序的复杂性和易错性风险。另外一个好处是,在使用较旧的编译器时,这些结构体往往能生成更优的二进制码,旧版本的编译器鼓励重复使用带偏移量的指针进行读写操作,不主张在每次访问寄存器时都生成一个 32 位的常量。

这些结构体头文件的命名与 hardware_ 库和 hardware_regs 库的头文件保持一致。例如,可以通过引入头文件 hardware/pio.h 来访问 hardware_pio 库的功能,如果想要直接访问寄存器,可以将 hardware_structs 库的 hardware/structs/pio.h 头文件包含进来,这个头文件中默认包含了 hardware/regs/pio.h 头文件,以获取寄存器字段的定义。PIO 的头文件内容有点长,可以参考 hardware/structs/pll.h 较短的示例来了解这些头文件实际包含的内容:

typedef struct {
    _REG_(PLL_CS_OFFSET) // PLL_CS
    // Control and Status
    // 0x80000000 [31]    LOCK         (0) PLL is locked
    // 0x40000000 [30]    LOCK_N       (0) PLL is not locked +
    // 0x00000100 [8]     BYPASS       (0) Passes the reference clock to the output instead of the...
    // 0x0000003f [5:0]   REFDIV       (0x01) Divides the PLL input reference clock
    io_rw_32 cs;
 
    _REG_(PLL_PWR_OFFSET) // PLL_PWR
    // Controls the PLL power modes
    // 0x00000020 [5]     VCOPD        (1) PLL VCO powerdown +
    // 0x00000008 [3]     POSTDIVPD    (1) PLL post divider powerdown +
    // 0x00000004 [2]     DSMPD        (1) PLL DSM powerdown +
    // 0x00000001 [0]     PD           (1) PLL powerdown +
    io_rw_32 pwr;
 
    _REG_(PLL_FBDIV_INT_OFFSET) // PLL_FBDIV_INT
    // Feedback divisor
    // 0x00000fff [11:0]  FBDIV_INT    (0x000) see ctrl reg description for constraints
    io_rw_32 fbdiv_int;
 
    _REG_(PLL_PRIM_OFFSET) // PLL_PRIM
    // Controls the PLL post dividers for the primary output
    // 0x00070000 [18:16] POSTDIV1     (0x7) divide by 1-7
    // 0x00007000 [14:12] POSTDIV2     (0x7) divide by 1-7
    io_rw_32 prim;
 
    _REG_(PLL_INTR_OFFSET) // PLL_INTR
    // Raw Interrupts
    // 0x00000001 [0]     LOCK_N_STICKY (0) 
    io_rw_32 intr;
 
    _REG_(PLL_INTE_OFFSET) // PLL_INTE
    // Interrupt Enable
    // 0x00000001 [0]     LOCK_N_STICKY (0) 
    io_rw_32 inte;
 
    _REG_(PLL_INTF_OFFSET) // PLL_INTF
    // Interrupt Force
    // 0x00000001 [0]     LOCK_N_STICKY (0) 
    io_rw_32 intf;
 
    _REG_(PLL_INTS_OFFSET) // PLL_INTS
    // Interrupt status after masking & forcing
    // 0x00000001 [0]     LOCK_N_STICKY (0) 
    io_ro_32 ints;
} pll_hw_t;

该结构体包含了一个寄存器映射的内存块布局,其中一些成员变量的定义与全局地址映射的基地址相关联。

此外,可以使用任一原子(setclearxor) 地址别名来分别对寄存器中指定的位进行 setclearxor 操作(而不是让CPU执行读/改/写操作);例如:

hw_set_alias(pio0)->sm[1].shiftctrl = PIO_SM1_SHIFTCTRL_AUTOPULL_BITS;

等同于:

hw_set_bits(&pio0->sm[1].shiftctrl, PIO_SM1_SHIFTCTRL_AUTOPULL_BITS);

硬件原子(置位 / 清零 / 异或)输入输出别名在 SDK 库中被广泛使用,以避免在两个内核或中断请求(IRQ)和前台代码同时访问寄存器时发生某些类别的数据竞争。

在 RP 系列微控制器上,原子寄存器别名(atomic register aliases)2是外设的一个固有部分,而不是 CPU 的一项功能,因此系统直接内存访问(DMA)也能够对寄存器执行原子置位 / 清零 / 异或操作。

硬件寄存器库

硬件寄存器(hardware_regs)库是一整套针对所有 RP 系列微控制器寄存器的头文件,是根据硬件本身自动生成的。可以通过这个库直接查看或修改一个内存映射寄存器。不过,高级别库中提供了更友好的 C/C++ 接口。

据个例子,以下列出了 hardware/regs/sio.h 代码片段:

// Description : Single-cycle IO block
// Provides core-local and inter-core hardware for the two
// processors, with single-cycle access.
// =============================================================================
#ifndef HARDWARE_REGS_SIO_DEFINED
#define HARDWARE_REGS_SIO_DEFINED
// =============================================================================
// Register : SIO_CPUID
// Description : Processor core identifier
// Value is 0 when read from processor core 0, and 1 when read
// from processor core 1.
#define SIO_CPUID_OFFSET 0x00000000
#define SIO_CPUID_BITS 0xffffffff
#define SIO_CPUID_RESET "-"
#define SIO_CPUID_MSB 31
#define SIO_CPUID_LSB 0
#define SIO_CPUID_ACCESS "RO"
#endif

这些头文件都有大量的注释(与数据手册中寄存器列表或 SVD 文件所提供的信息相同)。它们定义了每个寄存器的偏移量、这些寄存器中各个字段的布局,以及字段的访问类型,例如,RO 表示只读。

硬件寄存器(hardware_regs)库中的头文件仅包含注释和 #define 语句。这意味着它们既可以被汇编文件(.S 文件,这样就可以使用 C 预处理器)包含,也可以被 C 和 C++ 文件包含。

TinyUSB 端口

除了核心 SDK 库之外,pico-sdk 中还提供了一个TinyUSB 端口,用来为 RP 系列微控制器提供标准设备和主机 USB3 支持,并在 SDK 中实现了一些构建基础架构,以便于将其轻松整合到应用程序中。

在应用程序的 CMakeLists.txt 文件中添加 tinyusb_devtinyusb_host 库的依赖,用来使应用程序使用 USB 设备或主机功能。此外,tinyusb_board 库可用于提供 TinyUSB 应用中经常使用的额外 “板级支持” 代码。欲了解更多信息和用于设置全功能应用程序的示例代码,请参阅 Pico Examples 中的 README。

RP 系列微控制器的 USB 硬件支持主机和设备模式,但这两种模式不能同时使用。TinyUSB 还提供 tinyusb_pico_pio_usb 库,通过 PIO 实现对 USB 的支持 。

FreeRTOS 端口

RP2040 和 RP2350(两者都支持 Arm 和 RISC-V 架构)均支持 FreeRTOS 端口,既可以在单个内核上运行,也可以在双核对称多处理(SMP)模式下运行。

SDK 并不直接依赖于 FreeRTOS,但确实提供了一些与 FreeRTOS 一起使用的库(特别是网络相关的库)。pico-examples 仓库中包含了一些使用 FreeRTOS 的示例,在构建时应设置 FREERTOS_KERNEL_PATH 变量。

在 Pico W 上使用 Wi-Fi

Pico SDK 中的 IP 支持由 lwIP 提供。lwIP 的原始 API 始终得到支持:完整的 API,包括阻塞套接字,可以在 FreeRTOS 下使用。

IP 和 Wi-Fi 支持中使用了几个不同的库构建块:pico_lwip 用于 lwIP,pico_cyw43_driver 用于 Wi-Fi 芯片驱动,pico_async_context 用于以一致的方式访问非线程安全的 API(lwIP),无论是轮询、使用多个内核还是运行 FreeRTOS。

默认情况下,libcyw43 许可用于非商业用途,但 Raspberry Pi Pico W、Pico WH 或任何围绕 RP2040 和 CYW43439 构建产品的用户都可以享受免费的商业使用许可

高级用户可以单独组合这些库,但在大多数常见情况下,它们会被整合到几个方便的库中,您可以将这些库添加到应用程序的 CMakeLists.txt 文件的依赖项中:

  • pico_cyw43_arch_lwip_poll - 用于单核,传统的轮询方式访问 Pico W 上的 lwIP。
  • pico_cyw43_arch_threadsafe_background - 用于单核或多核访问 Pico W 上的 lwIP,lwIP 回调在低优先级中断中处理,因此不需要轮询。
  • pico_cyw43_arch_lwip_sys_freertos - 用于在 FreeRTOS 下完全访问 lwIP API(NO_SYS=0)。

有关更详细的说明,请参阅 pico_cyw43_arch 头文件。许多使用 Wi-Fi 和 lwIP 与 Pico SDK 的示例可以在 pico-examples 仓库中找到。

在 Pico W 上使用 蓝牙

Pico SDK 中的蓝牙支持由 BTstack 提供。BTstack 的文档可以在 BlueKitchen 的网站上找到。

除了标准的 BTstack 许可条款外,还提供了一个补充许可,涵盖了与 Raspberry Pi Pico W 或 Raspberry Pi Pico WH 一起使用 BTstack 的商业用途。

请参见 pico-examples 仓库,其中包含了来自 BTstack 的蓝牙示例

SDK 中的蓝牙支持由多个库组成:

  • pico_btstack_ble 库增加了对蓝牙低功耗(BLE)的支持,而 pico_btstack_classic 库则增加了对传统蓝牙的支持。可以单独链接到任一库,或者同时链接到这两个库以启用 BTstack 提供的双模支持。
  • pico_btstack_cyw43 库对于蓝牙使用是必需的。它增加了对 Pico W 上的蓝牙硬件的支持,并将 BTstack 运行循环的概念与 SDK 的 pico_async_context 库集成,允许通过轮询或后台运行蓝牙,以及多核和/或 FreeRTOS 支持。

以下额外的库是可选的:

  • pico_btstack_sbc_encoder - 增加了蓝牙子带编码(SBC)编码器支持。
  • pico_btstack_sbc_decoder - 增加了蓝牙子带编码(SBC)解码器支持。
  • pico_btstack_bnep_lwip - 使用 LwIP 增加了蓝牙网络封装协议(BNEP)支持。
  • pico_btstack_bnep_lwip_sys_freertos - 在 NO_SYS=0 模式下使用 LwIP 与 FreeRTOS 一起增加蓝牙网络封装协议(BNEP)支持。

要使用 BTstack,必须在 CMakeLists.txt 中将 pico_btstack_cyw43 以及 pico_btstack_ble 和/或 pico_btstack_classic 添加到应用依赖项中。此外,需要在源树中提供一个 btstack_config.h 文件,并将其位置添加到包含路径中。更多详情,请参阅 BlueKitchen 关于如何配置 BTstack 的文档,以及 pico-examples 仓库中相关的蓝牙示例代码。

CMake 函数 pico_btstack_make_gatt_header 可用于运行 BTstack 的 compile_gatt 工具,从 BTstack GATT 文件生成 GATT 头文件。


  1. 在微控制器系统中,不同的外设(如 PIO - 可编程输入输出接口、PLL - 锁相环等)都有自己对应的内存映射区域。这些区域就像是一个个 “房间”,每个 “房间”(内存映射区域)都存放着与特定外设相关的寄存器,处理器可以像访问内存一样访问这些 “房间” 里的寄存器来配置和控制外设。 ↩︎

  2. 原子寄存器别名(Atomic Register Alias)是在计算机系统,特别是微控制器相关环境下的一个概念。它是对实际寄存器的一种替代名称(别名)机制,主要用于实现对寄存器的特定原子操作(如原子置位、原子清零、原子异或等操作),且这些操作能够以原子的方式执行,即操作过程不会被中断,保证了数据的完整性和一致性。 ↩︎

  3. RP 系列微控制器支持USB设备模式和USB主机模式。USB 设备模式(Device mode),在这种模式下,微控制器作为 USB 设备连接到主机(如电脑)。就像是一个 “从属” 角色,它会响应主机的请求。例如,当把一个带有微控制器且处于设备模式的 USB 设备(如 USB 鼠标、USB 存储设备等)插入电脑时,电脑作为主机可以向这个 USB 设备发送指令,要求获取设备信息、读取存储的数据或者执行某些操作,而 USB 设备需要按照主机的要求进行响应和操作。USB 主机模式(Host mode)。处于主机模式的微控制器可以作为 USB 主机来控制其他 USB 设备。它就像一个 “管理者”。例如,当微控制器处于主机模式并连接一个 USB 键盘时,微控制器可以主动发起对键盘的操作,如查询键盘按键状态等,而键盘会响应微控制器的请求。 ↩︎

标签:USB,Pico,微控制器,之库,pico,寄存器,PLL,sdk
From: https://blog.csdn.net/qichengzong_right/article/details/143951671

相关文章

  • 社区发布非官方龙架构 .NET 9 SDK 发行版jj
    随着.NET9的发布,龙芯的Loongarch架构的.NET9SDK的发布也提上了日程,在龙芯.NET的官方支持之外,今年在社区有一个非官方龙架构.NETSDK发行版(相关链接[1]https://github.com/loongson-community/dotnet-unofficial-build[2]https://github.com/loongson-community/dotne......
  • C++编程&玩转物联网:用树莓派Pico点亮RGB彩灯世界
    RGBLED彩灯是嵌入式开发中一个简单却充满乐趣的项目元件。通过它,开发者不仅可以学习控制硬件的基础知识,还能探索颜色混合与PWM(脉宽调制)技术的实际应用。本文将以树莓派Pico为核心,带您实现控制RGBLED显示随机颜色的项目。项目简介RGBLED彩灯由红(Red)、绿(Green)、蓝(Blue)三种......
  • MicroPython 硬件 I2C 驱动 MPU6050 - RaspberryPi Pico 示例
    该文只存放了驱动文件,关于MPU6050的分析请转移到:MPU6050寄存器内容和地址陀螺仪数据输出寄存器(共6个寄存器,地址为0x43-0x48)加速度传感器数据输出寄存器(6个,地址为0x3B-0x40)温度传感器数据输出寄存器(0x41-0x42)WhoamI设备验证MPU6050的默认设备地址为0x68,其存储Who......
  • IoT平台软件:Google Cloud IoT二次开发_PythonSDK使用指南
    PythonSDK使用指南1.安装GoogleCloudIoTPythonSDK在开始使用GoogleCloudIoTPythonSDK之前,需要先安装相关的依赖库。GoogleCloudIoTCore提供了官方的Python客户端库,这将帮助我们更方便地与GoogleCloudIoTCore进行交互。以下是安装步骤:1.1安装......
  • 【Unity微信】Unity发布微信小游戏+对接第三方SDK过程
    官方文档:https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/上面的文档,能完成库的导入和发布操作下面开始调用接口获取玩家信息12///<summary>3///初始化SDK4///</summary>5privatevoidInitSDK()6{7......
  • Unity Pico开发之基础功能(1)
    前言:继专栏上一篇文章搭建开发环境后,本文就射线传送(包括区域传送、锚点传送)进行介绍,操纵摇杆在场景中移动、抓取物品、旋转镜头视角等基础功能将在下一篇文章中介绍。搭建开发环境传送门:UnityPico开发之环境搭建https://blog.csdn.net/m0_74799789/article/details/14282733......
  • Dynamsoft Barcode Reader SDK Java 10.4.2000
    ImprovingVendorManagementEfficiencywithOCRandDocumentProcessingEffectivevendormanagementintoday’sdynamicbusinesslandscapeofteninvolveshandlinglargevolumesofphysicaldocuments,whichposesasignificantchallenge.Extractingkeydeta......
  • 【火山引擎】调用火山大模型的方法 | SDK安装 | 配置 | 客户端初始化 | 设置
    豆包(Doubao)是字节跳动研发的大规模预训练语言模型。目录1安装2配置访问凭证3客户端初始化4设置地域和访问域名5设置超时/重试次数1安装通过pip安装PYTHONSDK。pipinstall'volcengine-python-sdk[ark]'2配置访问凭证获取APIKey访问凭证具体步骤......
  • 百度公共IM系统的Andriod端IM SDK组件架构设计与技术实现
    本文由百度技术团队分享,引用自百度Geek说,原题“百度AndroidIMSDK组件能力建设及应用”,本文进行了排版和内容优化。1、引言移动互联网时代,随着社交媒体、移动支付、线上购物等行业的快速发展,对即时通讯功能的需求不断增加。对于各APP而言,接入IMSDK(即时通讯软件开发工具包)能......
  • PCL Astra相机驱动&SDK
    Astra(orbbec奥比中光)乐视相机相关驱动,本教程针对Windows和Ubuntu14.04=Ubuntu18.04系统版本官网链接:https://orbbec3d.com/develop/该深度相机是乐视与奥比中光合作的体感相机,对标微软Kinect,可用于三维重建,SLAM学习,也可以作为免驱UVC摄像头体感摄像头使用相机参数:Lin......