我们开发嵌入式设备时,每个板子的硬件配置都不同。
1, 按键、LED、高低电平、外部中断等使用不同的GPIO。
2,UART、I2C、SPI等外设使用的某个片上资源,比如电源管理芯片使用了I2C-1,一个传感器使用了I2C-2.
3,不同的功能或操作模式,还需要对MCU或MPU的片上资源进行不同的配置,比如这个GPIO是默认上拉,低电平中断,另一个SPI设备工作频率50MHz,使用了某个GPIO做片选信号。
这些硬件的配置根据硬件设计而来,软件需要根据硬件设计来进行系统的配置,才能使系统正常工作。
其实在一般的系统设计中,硬件功能和软件功能之间,会有一个对接接口,我们叫做hal层,hardware abstract layer。
在简单的嵌入式项目编程中,我们可以定义一个board_projectname.h和board_projectname.c文件,也可以自己取合适的名字。
然后将每个产品的板级的一些信息定义和接口,比如GPIO的定义,片上外设的使用情况,都放在这个头文件里,其他模块可以引用这些信息。而c文件里可以放一些板级硬件相关实现。
这呢就是个初级的使用方式,首先的缺点是不能复用,每多个项目,所有东西要重新定义一遍,费时费力。
当然也可以把里面一些内容拆分一下,分成多个文件,方便组合,公共的信息各个项目都可以引用,达到复用的目的。
这样把硬件功能拆分成两部分,项目独有的和所有项目公用的。
只是这样的拆分不够灵活,可能会经常改动,那些公有功能在某个项目可能就变成特殊了呢。
如果用面向对象的类和继承的方法,就能更好的管理多种产品的硬件功能,完成分类和分级,功能逐层叠加或覆盖。
解决的一个办法,是利用C++的继承和多态,来解决复用和方便使用的问题。
基类使用某个实现,子类能够覆盖这个实现来达到自己定制的行为。
而通过多态,可以同一套代码执行,仅修改子类实现即可。
举例来说,在我们的Product产品中,定义一个Hardware类,用来管理相关的硬件功能。
class Hardware
{
public:
Hardware(){};
virtual ~Hardware(){};
virtual void PowerUpBTModule(){
// some default action
};
}
class HarwareNFC : public Hardware
{
public:
HarwareNFC(){};
virtual ~HarwareNFC(){};
virtual void PowerUpBTModule() {
// do something
};
}
class HarwareRFID : public Hardware
{
public:
HarwareRFID(){};
virtual ~HarwareRFID(){};
virtual void PowerUpBTModule() {
// do something
};
}
class Product {
public:
Product(Hardware *hal):localHAL(hal){};
virtual ~Product(){};
Hardware *localHAL;
}
int main(int argc, char** argv)
{
Product * myPro;
Hardware * hal;
if(argc >= 2)
{
hal = new HardwareNFC();
}
else
{
hal = new HardwareRFID();
}
myPro = new Product(hal);
myPro->localHAL->PowerUpBTModule();
}
举一反三的话,使用的Product类,也是可以使用多态。
不同的项目会有自己定制的Product类,每个Product类有不同的实现~~