C,“外部"硬件抽象层中变量的类型 [英] C, "extern" type of variables in hardware abstraction layer

查看:59
本文介绍了C,“外部"硬件抽象层中变量的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a Hardware Abstraction Layer. The aim of this HAL is to easily switch between the drivers for linux and the drivers for an MCU.

我正在SPI接口上工作.以下是HAL的打开"功能的签名.SPI的接口.

I am working on the SPI interface. Below is the signature of the function of the HAL that "open" the interface of SPI.

hal/spi.h

spi_handle_t spi_open(spi_port_t channel, spi_config_t config);

spi_port_t:

spi_port_t :

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

spi_config_t:

spi_config_t :

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

所以在 mcu/spi.c 中,我有这样的观点:

So in mcu/spi.c I have at some point this :

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.

Now the problem is in hal/spi.h, I need to define what is spi_channel_t and spi_config_t.

有没有办法做类似的事情(我知道用extern是不可能的,但是对于解释很重要...):

Is there a way to make something like (I know it is impossible with extern, but for explanation matters...) :

extern spi_channel_t;
extern spi_config_t;

这会对编译器说:好吧,这两种类型都没有在头文件中定义,仍然可以在我传递给工具链的文件之一上找到它们的存储大小".

This would say to the compiler : "Ok these two types are not defined in the header file, still you can find their storage size on one of the files I passed to the toolchain".

推荐答案

您似乎在寻找的是称为 opaque type 的技巧.这是一种使用结构的 forward声明以便在C语言中实现私有封装和多态的方法.它通常用于专门编写的嵌入式系统驱动程序,并且可以这样实现:

What you seem to be looking for is the trick called opaque type. It's a way to use forward declaration of structs in order to achieve private encapsulation and polymorphism in C. It is commonly used for professionally-written embedded systems drivers in particular and can be implemented like this:

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硬件外围设备,并希望以不同的方式使用它们,但是具有相同的驱动程序代码.

Now the caller will have to pass along the spi_handle* to other functions in the driver. This isn't just handy for OO design, but it also makes it possible to run the same code with multiple instances. For example if you have 2 different SPI hardware peripherals on the MCU and want to use them differently, but with the same driver code.

这篇关于C,“外部"硬件抽象层中变量的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆