I have a driver and code that works on IAR but does not work for Atmel Studio 7. I get an error ld returned 1 exit status
and undefined reference to '_read'
(or _write
) when I try to assign a function to a pointer inside a struct.
In the driver that I need to use there are two pointers defined as follows:
#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
In the file they have a struct defined as follows:
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 */
};
In my application I try to do:
bmm050.bus_write = i2c_write;
bmm050.bus_read = i2c_read;
My functions are defined as:
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);
EDIT: I am attaching the error code as asked:
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
答案 0 :(得分:1)
我猜您的i2c_write
和i2c_read
函数会调用printf
,write
,putc
,puts
或类似函数。是?
您看到的错误是包装器_write_r
和_read_r
尝试调用基础write
和read
函数,而无法找到它们。例如,参见this discussion (sec. 6.4)中the newlib C library这些函数的实现add a leading underscore to exported names。
当您注释掉bmm050.bus_write = i2c_write
和bmm050.bus_read = i2c_read
行时,错误会消失,因为您的代码中没有其他内容会调用read
或write
。如果您未在代码中引用i2c_read
,例如当这些行被注释掉时,链接器可以从编译的目标文件中删除i2c_read
。如果没有i2c_read
,则不需要_read_r
或read
,因此您不会收到链接器错误。
那该怎么办?
一些选项,按照我尝试的顺序。
_read
或_write
实施。如果Atmel Studio包含适用于您的主板的BSP,则可能包括这些功能。 (我自己没有Atmel Studio,即使我这样做也可能没有相同的BSP,所以我不能告诉你更具体的东西,而不是去看哪里。)
read()
和write()
(没有前导下划线)。 i2c_read
和i2c_write
,以便他们直接访问设备的I2C寄存器。如果您可以从这些函数中删除C库的I / O例程,则不再需要_read
或_write
。_write
的示例实现。那个,加上线程下面的链接,可以帮助你(即使你不会说德语)。 _read
和_write
,这将在您的特定目标上执行一些有意义的输入和输出。我收集了那个I2C,但您可能在某些时候想要UART,LCD,七段显示器,Nixie或其他东西 - 编写您希望的任何I / O例程!请注意,这基本上涉及与#3相同类型的工作,但在不同的上下文中。另见:
_write_r
能够与之交谈!