我正在为 ARM Cortex-M4 处理器编写可重用的 C++ 模块。该模块使用大量存储空间来完成其任务,而且时间紧迫。
为了允许我的模块的用户自定义其行为,我使用不同的后端类来允许不同的低级任务实现。其中一个后端是存储后端,它旨在将实际数据存储在不同类型的易失性/非易失性 RAM 中。它主要由执行速度非常快并且会被非常频繁地调用的 set/get 函数组成。它们大多是这种形式:
uint8_t StorageBackend::getValueFromTable(int row, int column, int parameterID)
{
return table[row][column].parameters[parameterID];
}
uint8_t StorageBackend::getNumParameters() { return kNumParameters; }
基础表和数组的大小和数据类型取决于用户定义的功能,因此我无法避免使用存储后端。一个主要问题是需要将实际数据放入 RAM 地址空间的某个部分(例如,用于使用外部 RAM),我不想将我的模块限制为特定的存储选项。
现在我想知道选择什么设计模式来将存储方面与我的主模块分开。
- 具有虚函数的类将是一个简单而强大的选择。但是,我担心在时间紧迫的环境中经常调用虚拟 set/get 函数的成本。特别是对于存储后端,这可能是一个严重的问题。
- 为模块主类提供不同后端的模板参数(甚至可能使用 CRTP 模式?)。这将避免虚函数,甚至允许内联存储后端的设置/获取函数。但是,它需要在头文件中实现整个主类,这不是特别整洁......
- 使用简单的 C 风格函数来形成存储后端。
- 对简单的 set/get 函数使用宏(编译后这应该与选项 2 大致相同,所有 set/get 函数都内联。)
- 自己定义存储数据结构并允许使用宏作为数据类型进行自定义。例如
RAM_UINT8 table[ROWSIZE][COLSIZE]
,用户添加#define RAM_UINT8 __attribute__ ((section ("EXTRAM"))) uint8_t
这样做的缺点是它需要所有数据都位于 RAM 的相同、连续的部分中——这在嵌入式目标上并不总是可能的。
我想知道是否还有更多选择?现在,我倾向于选项 4,因为它足够整洁,但对实际运行时性能的影响为零。
总结一下:在 Cortex-M4 上实现低/零开销存储抽象层的最佳方式是什么?