0

UPDATE This code below works. It turns out my problem lied further down the chain with the software I was using to interface with the device and download files off. I pulled the SD card out of the device and plugged it directly into my PC, and you wouldn't believe it, but the data was there in the file.

Just another classic case of how assumptions screw you over. Never assume anything :)

I'll keep the post here just incase someone else comes along and finds this usefeul.

===============================================================

I am trying to write a logger that creates a file on the SD card of a device, and stores data into it. Right now, all I am trying to do is write the text "hello123" into the log file, however when I download the file off the card and open with a text editor there is no ASCII data in there, and contains binary data (series of ^@) characters.

The file is created without any problems, it's just when I try to write to it. I call this function after another log function that runs on the devices firmware, so we can assume that the SD card is mounted and the CS pin to the SD is high (well low, but inverted).

So the sequence of events is:

  1. Program starts
  2. Main logging function called and SD line selected
  3. My log function called
  4. My DEBUG.LOG file is created
  5. DEBUG.LOG written to and closed
  6. Program continues on

The f_ functions used are a part of the FatFS library.

My code is as follows:

#include <ff.h>
#include <stdio.h>
#include <string.h>
#include "main.h"

unsigned char filename[10] = "debug.log";
unsigned char line[360];
static FIL logFile;
unsigned char error = 0;
FRESULT fresult;
UINT written = 0;
FATFS fatfs[1];

void writeLog()
{
    volatile unsigned char retVal;
    memset(line, 0, sizeof(line));
    
    // check if sd card is mounted
    if(f_mount(&fatfs[0], "0:", 1) != FR_OK)
    {
        error = 1; // breakpoint purposes
    }
    else
    {
        if(f_open(&logFile, (const char*)filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK){
            retVal = f_lseek(&logFile, f_size(&logFile));

            line[0] = 'h';
            line[1] = 'e';
            line[2] = 'l';
            line[3] = 'l';
            line[4] = 'o';
            line[5] = '1';
            line[6] = '2';
            line[7] = '3';
            line[8] = 0x00;
            f_puts((char const*)line, &logFile) ;
            f_puts("\r\n", &logFile);
            f_sync(&logFile);
            retVal = f_close(&logFile);
        }
    }
}

I'm not sure why it's not writing anything into the file. I mean it is as if I write 8 bytes into it, the filesize is 8 bytes, and I can see ^@^@^@^@^@^@^@^@^@^@ in my ubuntu terminal when I view it with less.

Hex dump:

$ xxd DEBUG.LOG
00000000: 0000 0000 0000 0000 0000                 ..........
jabroni
  • 167
  • 16
  • `^@` is `\0` but it would be more helpful to supply a hexdump (xxd) so we know if there indeed is only 10 bytes of data. Did you write the f_ functions in particular what's the implement of `f_puts()`? There is no includes, and in general of code prevents us from running your code. – Allan Wind May 03 '23 at 04:23
  • Why don't you use FA_OPEN_APPEND instead of FA_CREATE_ALWAYS + f_lseek()? It seems to be a FatFs, It's indeed a FAT partition? Why do mount the drive here (and not unmount it)? – Allan Wind May 03 '23 at 04:30
  • @AllanWind I did not write the `f_` functions. These are from the `ff.h` header which camef romt he fatfs library. I have updated the original post with the headers I have used and the hex dump return which was: `00000000: 0000 0000 0000 0000 0000 ..........` – jabroni May 03 '23 at 04:31
  • Please edit question with answer (don't worry about responding with a comment). It's easier for people to read than a bunch of comments. I don't know much about embedded, obviously, do you have the option to ltrace/strace so we know if the data makes it to the library? – Allan Wind May 03 '23 at 04:33
  • @AllanWind in regards to why it's not unmounted - it is, just further down the program. I call this function during the "write log" procedure right after another file is written to. – jabroni May 03 '23 at 04:33
  • Would mount fail if it's already mounted? I just want to eliminate that as an error case. – Allan Wind May 03 '23 at 04:35
  • Did you see https://stackoverflow.com/questions/36241121/fatfs-f-write-not-working?rq=2? – Allan Wind May 03 '23 at 04:35
  • @AllanWind regarding: "Would mount fail if it's already mounted? " - Yes it would. Arg 3 of the `f_mount` function checks if the volume is okay to be worked with, and will return `FR_OK` if good, and another status if bad. Funnily enough, I came across the post yesterday and have been trying to look for it again. I have read that, but the main solution seemed to revolve around flushing the buffer with `f_sync`. My `line` buffer has more than enough. – jabroni May 03 '23 at 04:41
  • ... two of answers talks about writing at least a block of data of either 32 or 256 bytes. Can you try those two experiments? – Allan Wind May 03 '23 at 04:46
  • What does `f_size(&log_file)` return after the `f_open(..., FA_CREATE_ALWAYS | FA_WRITE)`? Does the seek succeed? You do not check this return value, nor the results of `f_puts()`. – the busybee May 03 '23 at 05:47
  • @thebusybee all the functions return `FR_OK` or equivalent. I am playing around with the write at the moment. Still unable to get it to work. The file increases in size. I've confirmed this by checking the file size directly. For example, writing 512 bytes into it returns a size of `512 B`. – jabroni May 03 '23 at 05:48
  • The file names are different (upper case vs lower case). Are you sure you are reading the right file on Linux? (I know that old FAT systems use only upper case, but that time is long gone, and I don't know about FatFS.) – the busybee May 03 '23 at 05:50
  • @thebusybee yes, the system just renames the file to uppercase. Again, the file has no issue in being created, accessed, and written to (kind of), and i am just having the problem of writing the data i specify onto the card. – jabroni May 03 '23 at 05:52
  • Well, we need to eliminate all possible reasons to find the real one. ;-) Did you try with a blank SD card? – the busybee May 03 '23 at 05:54
  • @thebusybee haha yeah fair enough. Been banging my head against the wall for too long on this. I haven't tried with a blank one, no. I just keep deleting the file and allowing the program to create a new one. – jabroni May 03 '23 at 05:57
  • Last idea, I have some work to do for a living: You document the file size to be 8, but you are writing 10 characters to it according to the source... Did you investigate how that matches? – the busybee May 03 '23 at 06:25
  • @thebusybee don't we all :') I have - I implemented a string length counter that checks the length of the string inserted and compares it to what was returned from `f_puts`. – jabroni May 03 '23 at 06:27
  • And? After writing 10 characters, is the file size really just 8? – the busybee May 03 '23 at 06:28
  • @thebusybee `strlen(line) + strlen("\r\n") == 10` in case you didn't notice it. – Allan Wind May 03 '23 at 06:33
  • When you write 512 bytes they are still `\0`? – Allan Wind May 03 '23 at 06:33
  • @AllanWind That's what I mean, but the OP documents "_the filesize is 8 bytes_". But I see now, sorry, the text is quite _condensed_. This statement comes after "_if I write 8 bytes into it_". – the busybee May 03 '23 at 06:38
  • Maybe this will clear it up. Writing "hello123" in my memory register is: `68 65 6c 6f 31 32 33`. This is then passed into `f_puts` and placed in the `FIL` buffer (`debugLogFile.buff`), then passing `\r\n` adds `0d 0a` to the buffer. The file is then sync'd and closed. Running `wc -c` on that file returns a size of 10 bytes. @AllanWind I created a loop where I just looped 512 times entering a single character. The output of that file is all `\0`. – jabroni May 03 '23 at 06:45
  • @AllanWind So it turns out there is nothing wrong with my code. I was using another piece of software that I was interfacing with to the device I was connected to and turns out it's an issue with the software. It handles CSV files, so there must be an issue with custom created files that it can't handle when transferring over USB. Releived that the code works, not relieved over how much time I wasted on this -.-" Thank you both for your help. – jabroni May 04 '23 at 08:20
  • If there something to learn for others please write up an answer. – Allan Wind May 04 '23 at 08:22

0 Answers0