C、 "extern"硬件抽象层变量类型

标签 c types embedded extern hal

我正在研究硬件抽象层。此 HAL 的目的是在 Linux 驱动程序和 MCU 驱动程序之间轻松切换。

我正在研究 SPI 接口(interface)。下面是“打开”SPI接口(interface)的HAL函数的签名。

hal/spi.h

spi_handle_t spi_open(spi_port_t channel, spi_config_t config);

spi_port_t :

  • 在 Linux 上,它是一个基本类型:uint32_t
  • 在 MCU 上,它是一个结构。

spi_config_t :

  • 在 Linux 和 MCU 上,它都是一个结构体,但具有不同的字段。

所以在 mcu/spi.c 我在某个时候有这个:

typedef spiBASE_t spi_channel_t;
typedef spiDAT1_t spi_config_t;

spi_handle_t spi_open(spi_channel_t channel, spi_config_t config) {
.
.
.
}

对于linux/spi.c:

typedef uint32_t spi_channel_t;
typedef ChannelConfig_t spi_config_t;

spi_handle_t spi_open(spi_channel_t channel, spi_config_t config) {
.
.
.
}

现在问题出在hal/spi.h,我需要定义什么是spi_channel_t和spi_config_t。

有没有办法制作类似的东西(我知道用 extern 是不可能的,但为了解释......):

extern spi_channel_t;
extern spi_config_t;

这会对编译器说:“好的,这两种类型未在头文件中定义,您仍然可以在我传递给工具链的文件之一中找到它们的存储大小”。

最佳答案

您似乎要寻找的是称为不透明类型 的技巧。这是一种使用结构的前向声明以在 C 中实现私有(private)封装和多态性的方法。它通常用于专业编写的嵌入式系统驱动程序,并且可以像这样实现:

hal/spi.h

// forward declaration of a struct, with typedef and struct tag:
typedef struct spi_handle_t spi_handle_t; 

// Require the caller to declare a spi_handle_t* pointer, not an object:
spi_handle_t* spi_init (...); 

mcu/spi.c

struct spi_handle_t
{
  // whatever you need here - these are now 100% private members
};

spi_handle_t* spi_init (...)
{
  spi_handle* result = address_of_some_static_memory_pool;

  /* init struct members here */

  return result;  
}

linux/spi.c

struct spi_handle_t
{
  uint32_t something;
  // whatever you need here - these are now 100% private members
};

spi_handle_t* spi_init (...)
{
  spi_handle* result = malloc(sizeof *result); // malloc is fine to use in Linux

  /* init struct members here */

  return result;  
}

现在调用者必须将 spi_handle* 传递给驱动程序中的其他函数。这不仅便于 OO 设计,而且还可以使用多个实例运行相同的代码。例如,如果您在 MCU 上有 2 个不同的 SPI 硬件外设,并希望以不同方式使用它们,但具有相同的驱动程序代码。

关于C、 "extern"硬件抽象层变量类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65918038/

相关文章:

Typescript:映射类型,使除所选属性之外的每个属性均为只读

assembly - ARM架构中的GT和HI指令有什么区别?

c - libspotify 在调用 sp_session_create 后因 segFault 而崩溃

arrays - 如何比较 C 中由 strdup() 创建的两个字符串数组?

c - 使应用程序通过 UDP 相互发现

java - 用户创建的新类(class)?

javascript - FlowType 包装获取而不丢失默认类型注释

c - 我的 SPI 接收缓冲区始终返回 0xFF

c++ - 使用 KDS 中断 KL25Z 板

#define可以有多个参数吗?