【问题标题】:Writing device library C/C++ for STM32 or ARM为 STM32 或 ARM 编写设备库 C/C++
【发布时间】:2019-10-22 00:11:05
【问题描述】:

我需要从头开始(几乎)开发 uBlox、IMU、BLE、ecc.. 等设备库。有什么文档或教程可以帮助我吗? 问题是,如何在给定数据表和 STM32 或其他 ARM 等平台的情况下使用 C/C++(如果需要,可以使用 Arduino 风格)编写设备库?

非常感谢

我尝试从 Arduino 库和各种 Github 中读取设备库,但我希望有一个指南/模板可以遵循(一般规则),以便从给定的数据表中编写适当的设备库。

我问的不是完整的权威指南,而是从哪里开始、文档、方法。

我在下面找到了这个,但对于我的目标来说,它非常基本且相当精简。

http://blog.atollic.com/device-driver-development-the-ultimate-guide-for-embedded-system-developers

【问题讨论】:

  • 你在问世界。
  • 不必要地使用字节配对。还是谢谢

标签: arm driver device stm32


【解决方案1】:

我认为您实际上不能以 Arduino 风格为 STM32 编写库。您可以在野外找到的大多数 Arduino 库都促进易用性而不是性能。例如,如果读取传感器并通过串行端口报告结果是固件必须做的唯一事情,则为特定传感器设计的简单库运行良好。当您处理更复杂的项目时,uC 有很多事情要做并满足一些实时限制,一般的 Arduino 方法并不能解决您的问题。

STM32库开发的问题在于外设、DMA和中断之间的复杂连接。我在不使用 Cube 框架的情况下在寄存器级别对它们进行编码,并且我经常发现自己在参考手册中寻找显示 DMA 通道之间的连接或诸如定时器主从关系之类的东西的表格。一些外围设备(主要是定时器)的工作方式相似,但它们中的每一个都有细微的差别。它使得开发适合所有场景的硬件库几乎是不可能的。

您需要完成的任务在 STM32 项目中也更为复杂。例如,在我的一个项目中,我使用由计时器触发的虚拟/假 DMA 传输来欺骗 SPI,以便它可以从其时钟引脚生成周期性的 8 脉冲序列(未使用数据引脚)。没有库可以为您提供这种灵活性。

不过,我相信并非一切都丢失了。我认为可以构建一个硬件抽象层(HAL,但不是 ST 的 The HAL)。因此,如果您可以将它们从硬件中抽象出来,就可以创建有用的库。 USB 库可以是这种方法的一个很好的例子,因为 STM32 设备有大约 3 种不同的 USB 外围硬件变体,为它们中的每一个编写单独的 HAL 是有意义的。然而,上层应用层可以相同。

也许这就是ST创建Cube框架的原因。但如您所知,Cube 依赖于了解每个设备硬件的外部代码生成工具。因此,可以在运行时避免一些工作。当您编写自己的库时,您无法获得相同的结果,除非您还设计了类似的外部代码生成工具。而且,Cube 生成的代码在大多数情况下都是臃肿的。您可以用开发时间换取运行时性能和代码空间。

【讨论】:

    【解决方案2】:

    我假设您将在 Linux 等平台上使用交叉工具链,并且交叉工具链与在目标 CPU 上加载目标代码的某些方法兼容。我还假设您已经拥有一个工作良好的 STM32 开发板,该开发板的文档足够好,可以弄清楚传感器如何连接到开发板或 CPU。

    首先,您应该定义您的库应该提供什么。这部分通常非常困难。在不了解硬件传感器能够提供什么的情况下,很难知道它可以提供什么。预计会有一些需求迭代。

    您需要访问传感器文档,通常以制造商数据表的形式。使用数据表并了解设备如何连接到目标 CPU/板,您将需要访问构成传感器接口的 STM32 外设。回到数据表,这次是 STM32,看看如何访问它的外设接口。这可能是简单的 GPIO 位和字节,也可能是如何使用 SPI 或 I2C 等内置外设。

    传感器的数据表将详细说明一组寄存器,描述每个寄存器的含义,包括某些寄存器中每个位或一组位的含义。您将使用 C 语言编写访问 STM32 外设的代码,这些外设将通过作为 STM32 电路板一部分的电气接口访问传感器。

    工作流程通常从写一个或三个寄存器开始,看看是否有一些可识别的效果。例如,如果您正在使用数字 IO 端口,您可以连接一个 LED 以查看是否可以打开或关闭它,或者连接一个开关以查看您是否可以正确读取其状态。这确定您的代码可以使用寄存器级访问来戳或窥视 IO。作为交叉工具链的一部分,可能有现有的辅助函数来完成这项工作。或者您可能必须开发自己的,使用指针间接访问内存映射 IO。或者可能需要一些只能从内联汇编代码访问的特殊指令。这个答案很笼统,因为我不知道 STM32 处理器或其典型生态系统的细节。

    然后您继续进行可能涉及操作序列的更复杂的操作,例如循环一两次以实现与设备的某些通信。或者它可能就像找到正确的寄存器序列以访问以操作 SPI 接口一样简单。通常,您会发现一小段代码已经足够完整,可以被您的驱动程序重用;比如如何读取或写入单个字节。然后,您可以将其作为可重用函数来简化其余工作,例如按顺序访问某些寄存器并打印您读取的寄存器内容以查看它们是否有意义。最终,您将获得两条重要信息:了解创建正式驱动程序所需的低级寄存器访问,以及了解硬件构成的组件和功能(即,您知道设备如何工作)。

    现在,扔掉你所做的大部分工作,并制定一个正式的规范。使用您现在所知道的内容来包含所有有用的内容。使用您现在所知道的开发规范,其中包含您的应用程序代码可以使用的适当接口 API。重写驱动程序,掌握部件如何工作的知识,并利用重新重写规范为您提供的空白画布。仅重用您完全确信的代码是最佳的并且适合规范规定的格式。为所有模块编写测试代码,并使用测试代码实际测试代码是否工作以及它是否符合规范。每次修改它测试的任何内容时都重复使用测试代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2018-09-28
      • 1970-01-01
      • 2019-01-29
      相关资源
      最近更新 更多