我正在开发一个裸金属软件,其中有几个类有串行通信外设(UART,I2C,SPI).等)。这些外围设备必须是可互换的,以尽量减少今后可能的工作。
通过互换,我的意思是业务逻辑模块应该可以使用任何外设而不需要额外的(软件开发)工作。我的子系统是一个SoC,并与FPGA和许多其他传感器和子系统通信.特别是FPGA通信是用大量的软外围IP来实现的,所以外设的互换性是我非常关心的问题。
这些外围类可以具有相同的公共读写功能,但它们的属性差别很大(一些具有主从关系,一些具有设备ID,有些具有地址大小模式等等)。我认为可以使用单个init()函数来管理这些差异。
我的问题是,我还没有想出一个工作的设计模式来满足我的需要。我尝试过策略模式,但是它导致了一个高度耦合的系统(需要“知道”通信类的策略类来初始化它们)。我一直在查找对象适配器模式,但我不确定它是否对我有用。实际上,我会猜到这是一个常见的设计问题,尤其是对于嵌入式软件设计,但是我还没有能够在网上找到相同的场景。
有人能解决这个问题吗?还是我想得太多了,也许我不需要这样的设计模式?
发布于 2022-03-15 14:01:20
正常的设计模式可能不是很适合这一点,您可能最终会在一个有用的抽象层之上编写一个无用的抽象层,而这一层太多了。
事实上,这些公共汽车并没有太多的共同点,所以在软件中互相交换没有意义。您可能只是想将一个特定的引脚路由到某个硬件外围设备,然后让该外围设备的驱动程序从那里接管,而不需要在顶部进行抽象。
如果您仍然坚持这个设计,那么我想列出不同总线的共同点:它们发送、接收、半双工或全双工,它们有波特率,它们有各种形式的通信错误等等。这可以构成一个抽象的基类,SPI、UART等可以从中继承。也许它们中的一些或全部使用DMA,并且DMA驱动程序可以集成在基类中?此外,如果有相同类型的多个硬件外设,则不能将驱动程序实现为单例,但必须允许每个类的多个实例。
更接近硬件,您将不得不使用某种形式的双缓冲--无论实际驱动程序是否使用中断或DMA,您都希望清楚地将开销抽象层逻辑与驱动程序分离开来,这样就不会意外地将诸如vtable这样的缓慢C++概念拖到实时关键代码中。让抽象层使用一个数据集,驱动程序使用另一个数据集-无论如何,由于重新进入的原因,至少需要2个缓冲区。
请注意,在C++中这样做比在C中容易得多。如果坚持使用C++,则必须更频繁地反汇编,以检查代码没有乱七八糟地插入一些无声的函数/库调用等等。与C相比,C++的主要优点是更容易实现继承,仅此而已。
https://stackoverflow.com/questions/71482700
复制相似问题