c - 使用函数指针移植通用 C 驱动程序

标签 c embedded driver i2c

我正在尝试将可用于 IMU 的通用 C 驱动程序移植到基于 Nordic 模块的嵌入式平台。最好的方法是正确修改接口(interface)函数以适应我的系统。所以驱动程序可以在github上找到here ,具有用于写/读寄存器的接口(interface):

typedef int32_t (*lsm6dso_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
typedef int32_t (*lsm6dso_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);

typedef struct {
  /** Component mandatory fields **/
  lsm6dso_write_ptr  write_reg;
  lsm6dso_read_ptr   read_reg;
  /** Customizable optional pointer **/
  void *handle;
} lsm6dso_ctx_t;

我的读/写寄存器功能是:

void write_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t val)
{
    uint8_t cmd[2] = {0, 0};
    cmd[0] = reg;
    cmd[1] = val;
    nrf_drv_twi_tx(m_twi, ADDR, cmd, 2, true);
    nrf_delay_ms(1);
}

void read_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t *val)
{
    nrf_drv_twi_tx(m_twi, ADDR, &reg, 1, true);
    nrf_delay_ms(1);

    nrf_drv_twi_rx(m_twi, ADDR, val, 1);
    nrf_delay_ms(1);
}

问题 -

1 - 我不确定如何将 m_twi 驱动程序实例函数传递到 lsm6dso_ctx_t 结构。它说该结构是可定制的,但我不确定如何增强它。

2 - 函数指针也让我困惑 - 如何将我的函数指向 lsm6dso_write_ptr 指针。我知道需要修改我的函数以提供多字节读/写,我认为这是可行的。

最佳答案

您应该实现两个功能:

static int32_t your_callback_lsm6dso_read_reg(void *ctx, uint8_t reg, uint8_t* data,
                         uint16_t len) {
      // read from register ret
      // len length of data to data pointer
      // return 0 on success

      // something like: (I have no idea about nrf_* interface)
      nrf_drv_twi_t const *m_twi = ctx;
      nrf_drv_twi_rx(m_twi, reg, data, len);

      return 0;
}

static int32_t your_callback_lsm6dso_write_reg(void *ctx, uint8_t reg, uint8_t* data,
                          uint16_t len)
       // write to register ret  len length od data from data pointer
       // return 0 on success

       // something like: (I have no idea about nrf* interface)
       nrf_drv_twi_t const *m_twi = ctx;
       nrf_drv_twi_tx(m_twi, reg, data, len);

       return 0;
 }

然后实例化该结构:

 lsm6dso_ctx_t lsm6dso_ctx = { your_callback_lsm6dso_write_reg, your_callback_lsm6dso_read_reg, m_twi };

并像这样使用它:

lsm6dso_some_function_from_the_library(&lsm6dso_ctx, ...)

库中的函数将调用来自 lsm6dso_ctx 的函数指针,第一个参数作为结构中的 void* 指针。该结构中的 void* 指针用于传递自定义数据。然后,您可以将句柄从 void* 指针转换为自定义指针并调用适当的函数。

how can I point my function to the lsm6dso_write_ptr pointer.

我认为你的困惑来自于此,事实恰恰相反。 lsm6dso_ctx_t 内的函数指针应指向您的函数。

然后您就拥有了一个 lsm6dso_ctx_t 结构实例,可与驱动程序中的所有函数一起使用。驱动程序有一些逻辑,它会调用随结构传递的函数来执行输入/输出操作。

关于c - 使用函数指针移植通用 C 驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57838309/

相关文章:

c - '->' doesnt doesn' t 适用于结构内部的结构

c - 打印到缓冲区或文件重用代码

embedded - 我如何学习为嵌入式系统构建自己的引导加载程序?

c - IAR 嵌入式工作台。 __iar_program_start 在哪里?

c# - C# 的 NDIS 中间驱动程序接口(interface)

c - 释放内存/跨平台兼容性问题

C套接字编程: HTTP request not working continously

c - 确定在嵌入式 C 中运行时使用哪个变量

c++ - 使用 C++ 安装驱动程序

在内核中异步调用 DeviceIoControl