gpt4 book ai didi

c - 不使用 JMP 或 LCALL 调用任意函数的最佳策略

转载 作者:行者123 更新时间:2023-12-04 09:20:58 24 4
gpt4 key购买 nike

在嵌入式 C 中,有一些固定/通用算法是很自然的,但不止一种可能的实现。这是由于几个产品展示,有时是选项,有时只是产品路线图策略的一部分,例如可选 RAM、不同 IP 设置的 MCU、升级频率等。

在我的大多数项目中,我通过将核心内容、算法和逻辑架构与实现外部状态评估、计时、内存存储等的实际功能解耦来处理这个问题。

自然地,我使用 C 函数指针机制,并为这些指针使用一组有意义的名称。例如。

unsigned char (*ucEvalTemperature)(int *);

将温度存储在一个 int 中,返回是 OKness。

现在想象一下,对于产品的特定配置,我有一个
unsigned char ucReadI2C_TMP75(int *);

从 TMP75 设备读取 I2C 总线上的温度的功能和
unsigned char ucReadCh2_ADC(unsigned char *);

一种读取二极管压降的函数,由 ADC 读取,这是一种在非常广泛的范围内评估温度的方法。

这是相同的基本功能,但在不同的选项集产品上。

在某些配置中,我会将 ucEvalTemperature 设置为 ucReadI2C_TMP75,而在其他配置中,我将使用 ucReadCh2_ADC。在这种温和的情况下,为避免出现问题,我应该将参数类型更改为 int,因为指针始终是相同的大小,但函数签名不是,编译器会提示。好吧……那不是杀手。

这个问题在可能需要不同参数集的函数上变得很明显。签名永远不会正确,编译器将无法解析我的 Fpointers。

所以,我有三种方法:
  • 使用全局参数栈,所有函数都是 unsigned char Func(void);
  • 对每个实现使用帮助函数,让我打开正确的分配以进行/调用;
  • 使用 JMP/LCALL 程序集调用(这当然很可怕),可能会导致调用堆栈出现重大问题。

  • 既不优雅,也不沉稳……你的方法/建议是什么?

    最佳答案

    我通常更喜欢分层架构。与硬件的通信是通过“驱动程序”实现的。算法层调用由驱动程序实现的函数 (readTemp)。关键是需要定义一个接口(interface),并且所有驱动程序实现都必须遵守该接口(interface)。

    较高层应该对如何读取温度一无所知(使用 TMP75 或 ADC 无关紧要)。驱动程序架构的缺点是您通常无法在运行时切换驱动程序。对于大多数嵌入式项目,这不是问题。如果您想这样做,请定义指向驱动程序公开的函数(遵循公共(public)接口(interface))而不是实现函数的函数指针。

    关于c - 不使用 JMP 或 LCALL 调用任意函数的最佳策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/995315/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com