【问题标题】:Function pointer in struct not working?结构中的函数指针不起作用?
【发布时间】:2016-10-19 13:42:01
【问题描述】:

我有一个适用于 IAR 但不适用于 Atmel Studio 7 的驱动程序和代码。当我尝试将函数分配给内部指针时,我收到错误 ld returned 1 exit statusundefined reference to '_read'(或 _write)一个结构。

在我需要使用的驱动中有两个指针定义如下:

#define BMM050_WR_FUNC_PTR \
    s8 (*bus_write)(u8, u8, \
    u8 *, u8)

#define BMM050_RD_FUNC_PTR \
    s8 (*bus_read)(u8, u8, \
    u8 *, u8)re

在文件中,它们有一个定义如下的结构:

struct bmm050_t {
    u8 company_id;/**<mag chip id*/
    u8 dev_addr;/**<mag device address*/

    BMM050_WR_FUNC_PTR;/**< bus write function pointer*/
    BMM050_RD_FUNC_PTR;/**< bus read function pointer*/
    void (*delay_msec)(BMM050_MDELAY_DATA_TYPE);/**< delay function pointer*/

    s8 dig_x1;/**< trim x1 data */
    s8 dig_y1;/**< trim y1 data */

    s8 dig_x2;/**< trim x2 data */
    s8 dig_y2;/**< trim y2 data */

    u16 dig_z1;/**< trim z1 data */
    s16 dig_z2;/**< trim z2 data */
    s16 dig_z3;/**< trim z3 data */
    s16 dig_z4;/**< trim z4 data */

    u8 dig_xy1;/**< trim xy1 data */
    s8 dig_xy2;/**< trim xy2 data */

    u16 dig_xyz1;/**< trim xyz1 data */
};

在我的应用程序中,我尝试这样做:

bmm050.bus_write = i2c_write;
bmm050.bus_read = i2c_read;

我的函数定义为:

int8_t i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

int8_t i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

编辑:我按要求附上错误代码:

c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/5.3.1/../../../../arm-none-eabi/lib/armv6-m\libc.a(lib_a-writer.o): In function `_write_r':
C:\Users\aba\Documents\Atmel Studio\7.0\Project1\Project1\Debug\writer.c(1,1): error: undefined reference to `_write'
c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/5.3.1/../../../../arm-none-eabi/lib/armv6-m\libc.a(lib_a-readr.o): In function `_read_r':
C:\Users\aba\Documents\Atmel Studio\7.0\Project1\Project1\Debug\readr.c(1,1): error: undefined reference to `_read'
collect2.exe(0,0): error: ld returned 1 exit status

【问题讨论】:

  • 使用调试器,获取转储、回溯等所有内容,然后看看 BMM050_MDELAY_DATA_TYPE 究竟是什么。
  • 您显示的所有代码都没有提及_read_write(仅bus_readi2c_read 等)。是什么让您认为链接器在抱怨此代码?
  • 我评论了我尝试分配功能的那两行,错误消失了。 BMM050_MDELAY_DATA_TYPEuint_32t 并且由于某种原因 bmm050.delay_msec = delay_cycles_ms 工作正常
  • 为了喜欢混淆,请使用typedef 而不是 icky 宏!
  • 据我所知,要抱怨_read(而不是bus_read),那么您显示的代码中可能存在剪切粘贴错误(例如,第二个宏定义有一个尾随 re) 或其他一些宏内容正在启动(你没有在某处将 i2c 定义为空字符串?...在​​你的赋值语句中出现杂散空格?)。

标签: c struct function-pointers undefined-reference atmelstudio


【解决方案1】:

我猜你的i2c_writei2c_read 函数调用printfwriteputcputs 或类似函数。是的?

您看到的错误是包装器_write_r_read_r 试图调用底层writeread 函数,但无法找到它们。参见,例如,this discussion (sec. 6.4)the newlib C library 中这些功能的实现。

当您注释掉 bmm050.bus_write = i2c_writebmm050.bus_read = i2c_read 行时,错误会消失,因为您的代码中没有其他内容调用 readwrite。如果您没有在代码中引用i2c_read,例如当这些行被注释掉时,链接器可以从编译的目标文件中删除i2c_read。没有i2c_read,就不需要_read_rread,因此不会出现链接器错误。

那该怎么办?

几个选项,按照我尝试的顺序。

  1. 如果您有支持合同,请致电您的板级支持包 (BSP) 供应商。
  2. 搜索 Atmel Studio 源/库,查看它们是否为您的特定硬件提供 _read_write 实现。如果 Atmel Studio 包含适用于您的电路板的 BSP,则可能包含这些功能。 (我自己没有 Atmel Studio,即使我有也可能不会有相同的 BSP,所以我不能更具体地告诉你在哪里看。)
  3. 修改您的i2c_readi2c_write,以便它们直接访问设备的I2C 寄存器。如果您可以从这些函数中消除调用 C 库的 I/O 例程,您将不再需要 _read_write
  4. 如果您找不到现有实现或不再需要一个,请在线查找实现。例如,this blog post(德语)包括_write 的示例实现。加上线程中它下面的链接,可能会对您有所帮助(即使您不会说德语)。
  5. 最后,如有必要,滚动您自己的_read_write,这将对您的特定目标进行一些有意义的输入和输出。我猜那是 I2C,但您可能在某些时候希望它是 UART、LCD、七段显示器、Nixie 或其他东西——编写任何您想要的 I/O 例程!请注意,这基本上涉及与 #3 相同类型的工作,但在不同的上下文中。

另见:

  • this answer,这与不同平台上的类似情况有关
  • this discussion 实现您自己的操作系统(有效地)以便 _write_r 有话可说!

【讨论】:

    猜你喜欢
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多