将平台特定代码与嵌入式外设驱动程序的通用逻辑代码分开
Separate platform specific code from general logic code for embedded peripheral drivers
我正在尝试为我在 STM32 上使用的一个芯片编写外设驱动程序。
为了使驱动程序适用于我将来可能使用的所有芯片,我试图将特定于平台的代码和专用于该芯片的代码分开。我想知道有没有我可以遵守的纪律?
目前,我在考虑两种可能:
使用弱函数分离。芯片驱动会依赖几个弱函数,用户提供覆盖弱函数的函数。
使用初始化结构,其中包含几个指向硬件特定函数的函数指针。而驱动会在初始化过程中使用这些提供的函数。
但我无法预知其中的利弊
在您列出的方法中,我认为 2. 是更受欢迎的选择。 2 的设置非常简单,并且不依赖于任何特定于编译器的弱指针指令。通过设置正确的指针,它还可以轻松地在几个略有不同的平台上重用代码。 2. 对 1. 有轻微的性能影响,因为您需要为每个函数调用执行额外的指针取消引用。这通常无关紧要,但在某些情况下可能会如此。
另一种常见的方法是拥有一个头文件,每个平台都有一个单独的实现文件。要为平台编译,您只需选择正确的文件。这类似于弱函数方法,但没有实际的弱指针。例如,您的项目设置可以是:
main.h
main.c
platform.h
platform.stm32.c
platform.tms570.c
要开发一个跨平台的driver/library你应该混合软件架构设计的几个原则。
一个是您的 driver/library 中的模块化和层,通常有一个基础层(一对 .h 和 .c 文件)应该满足驱动程序的所有基础和逻辑。第二层是后来的特定平台,应该包括与微控制器交互的基本功能,例如特定的SPI接口功能。如果你想为所有 stm32 系列制作驱动程序或库,你可以将其压缩在一层,因为所有 stm32 系列的 HAL 接口函数的标准名称。
关于您的第 2 点,这是创建库的标准方法。该结构允许您在 c 中创建不同的“pseudo-objects/handlers”,这在您需要创建多个不同的 instances/handlers 来连接时很有用。例如,如果您为电机驱动器开发一个库并且您正在开发遥控车,您将需要控制 4 个不同的驱动器,并且需要 4 个处理程序。
我正在尝试为我在 STM32 上使用的一个芯片编写外设驱动程序。 为了使驱动程序适用于我将来可能使用的所有芯片,我试图将特定于平台的代码和专用于该芯片的代码分开。我想知道有没有我可以遵守的纪律?
目前,我在考虑两种可能:
使用弱函数分离。芯片驱动会依赖几个弱函数,用户提供覆盖弱函数的函数。
使用初始化结构,其中包含几个指向硬件特定函数的函数指针。而驱动会在初始化过程中使用这些提供的函数。
但我无法预知其中的利弊
在您列出的方法中,我认为 2. 是更受欢迎的选择。 2 的设置非常简单,并且不依赖于任何特定于编译器的弱指针指令。通过设置正确的指针,它还可以轻松地在几个略有不同的平台上重用代码。 2. 对 1. 有轻微的性能影响,因为您需要为每个函数调用执行额外的指针取消引用。这通常无关紧要,但在某些情况下可能会如此。
另一种常见的方法是拥有一个头文件,每个平台都有一个单独的实现文件。要为平台编译,您只需选择正确的文件。这类似于弱函数方法,但没有实际的弱指针。例如,您的项目设置可以是:
main.h
main.c
platform.h
platform.stm32.c
platform.tms570.c
要开发一个跨平台的driver/library你应该混合软件架构设计的几个原则。
一个是您的 driver/library 中的模块化和层,通常有一个基础层(一对 .h 和 .c 文件)应该满足驱动程序的所有基础和逻辑。第二层是后来的特定平台,应该包括与微控制器交互的基本功能,例如特定的SPI接口功能。如果你想为所有 stm32 系列制作驱动程序或库,你可以将其压缩在一层,因为所有 stm32 系列的 HAL 接口函数的标准名称。
关于您的第 2 点,这是创建库的标准方法。该结构允许您在 c 中创建不同的“pseudo-objects/handlers”,这在您需要创建多个不同的 instances/handlers 来连接时很有用。例如,如果您为电机驱动器开发一个库并且您正在开发遥控车,您将需要控制 4 个不同的驱动器,并且需要 4 个处理程序。