cembeddedfirmwaretexas-instruments

Why am I getting "undefined reference to `_stat`" in the sys/stat.h library?


I'm trying to use the stat() function in the `#include <sys/stat.h> library however whenever I call it I get this error:

...toolchains/gcc-arm-none-eabi-8-2018/arm-gcc-macos/arm-none-eabi/lib/thumb/v6-m/nofp/libc_nano.a(lib_a-statr.o): in function `_stat_r':
statr.c:(.text._stat_r+0xe): undefined reference to `_stat'

Here is my file (I've listed all my includes, I know some might be not related to this problem but just incase I've listed all):

#include <kernel.h>
#include <device.h>
#include <drivers/i2c.h>
#include <sys/__assert.h>
#include <logging/log.h>
#include <sys/printk.h>
#include <soc.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define SOURCE_FILE   "battery.gm.fs"

int write_to_dev(struct device* dev)
{
    struct stat st;
    int nSourceFile;
    char *pFileBuffer;

    stat(SOURCE_FILE, &st); // problematic line
    // other code here
}

Whenever I call write_to_dev() I'm getting this issue. I'm basing my code off page 17 of this link: https://www.ti.com/lit/an/slua801/slua801.pdf?ts=1595360845070&ref_url=https%253A%252F%252Fwww.google.com%252F Thanks for your help!

Edit: I'm using an STM32 chip with zephyr RTOS, and TI BQ27621 fuel gauge


Solution

  • The example code you are trying to port to your device was written for a Linux system (e.g. for a Raspberry Pi). Such a system is much more capable than your MCU board: it has a full-blown operating system, file system and files and the necessary I/O operations. You can still get the relevant parts to run on your board using Zephyr OS:

    End-system dependent APIs

    Implement the functions gauge_read, gauge_write and gauge_address is required and described by the TI document. It should be rather straight-forward as it is mainly a wrapper for the I2C communication. Zephyr provides the required I2C functions.

    Now the files gauge.c and gauge.h should compile.

    FlashStream initialization

    The sample code uses file system operations to retrieve a file (in FlashStream format) to initialize the sensor. The parser for the file format is part of gauge.c and takes a string (text file contents) as input. So it does not depend on file system operations.

    I've never used such a sensor but my guess is the initialization file is short and can be easily embedded as a string. So create the initialization file, open it as a text file and copy the contents into your program:

    const char* fs =
        "W: AA 3E 02 00\n"
        "C: AA 3E 02 00 02 20 00 03\n"
        "W: AA 3E 02 00\n";
    

    Now you can initialize the sensor:

    gauge_execute_fs(pHandle, fs);
    

    The file system code (stat(), fopen() etc.) is no longer needed and can be removed. Your program should now compile and build.