1

I want to program an EEPROM which is 16/32 bit. I am writing the file from a C program, but fwrite() seems to be doing only 8 bits? I wrote a simple example, and using xxd (and hexdump) to look at the results, but the file seems to be only 8 bits. I wonder if I'm only seeing 8 bits due to the limitations of hexdump & xxd, or if the problem is with fwrite()?

Anyone know how I can check that all the bits are being written to the file?

#include <stdio.h>
#include <stdlib.h>

const unsigned int dataSize = 255;
unsigned long tmp[] = { 0xFFFF, 0xFFDD, 0xFDDD, 0xF000, 0x0F0F, 0x0001, 0x1010 };
  
int main() {
    const char *path = "text.bin";
    FILE *fp = fopen(path, "wb"); 
    const void *data = tmp;
 
    if (!fp) {
        fprintf(stderr, "fopen() failed for '%s'\n", path);
    } else {
        fwrite(data, 1, dataSize, fp);
    }
  
    return 0;
}

Using xxd I see:

00000000: ffff 0000 0000 0000 ddff 0000 0000 0000  ................
00000010: ddfd 0000 0000 0000 00f0 0000 0000 0000  ................
00000020: 0f0f 0000 0000 0000 0100 0000 0000 0000  ................
00000030: 1010 0000 0000 0000 0000 0000 0000 0000  ................
00000040: c005 5182 b27f 0000 0000 0000 0000 0000  ..Q.............
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 00    ...............

EDIT: I'm trying to ensure there are 32 bits written to the file. The results of xxd are:

00000000: 11111111 11111111 00000000 00000000 00000000 00000000  ......

Which show there are 16 bits for the 0xFFFF but where are the other 16 bits? Ideally I'd like to see 16 zeros followed by 16 ones for 0xFFFF for a 32 bit boundary.

I'm wondering if this is a problem with the xxd software not displaying it, rather than C not writing it.

(I realise the names and the file pointer isn't closed, it was just something I knocked up in 2 minutes to help display the problem, I picked 255 out of the air.)

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Rick Dearman
  • 356
  • 2
  • 12
  • 2
    The array is not 255 bytes long; you are telling the system to read out of bounds of your `tmp` array (which is anything but temporary, but that's a naming issue and tangential to the other problems). You're invoking undefined behaviour, which is not good. You should use `fclose(fp);` after the `fwrite()`, but the system should handle that for you. – Jonathan Leffler Feb 13 '21 at 13:58
  • Could you please show us what you want the contents of the file to be? It's not clear – zwol Feb 13 '21 at 13:58

2 Answers2

1

To control the exact output in the file, you should use the exact width types from <stdint.h> instead of unsigned long, which seems to have 64 bits on your system.

The reason you do not see 16 zeroes followed by 16 ones is your target system uses little-endian representation for integer types larger than 8 bits. Endianness determines the order of bytes in memory for these types.

Furthermore, you should not write 255 bytes from the tmp array which has a size of 28 bytes.

Here is a modified version:

#include <stdio.h>
#include <stdint.h>

// data has 256 bytes
uint32_t data[64] = { 0xFFFF, 0xFFDD, 0xFDDD, 0xF000, 0x0F0F, 0x0001, 0x1010 };
  
int main() {
    const char *path = "text.bin";
    FILE *fp = fopen(path, "wb"); 
 
    if (!fp) {
        fprintf(stderr, "fopen() failed for '%s'\n", path);
    } else {
        size_t written = fwrite(data, 1, sizeof data, fp);
        if (written != sizeof data) {
            fprintf(stderr, "fwrite() only wrote %zu bytes\n", written);
        }
        fclose(fp);
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

Problem: 16 bit data (2 byte) chunks are stored in 64-bit-type (8 byte) array. This explains the output.

Solution:

  • Assign x byte data to "x-byte type" (use "Fixed-Width Integer Types")
  • fwrite the exact number of bytes (do not guess)

Please note that 0xFFFF is 2 bytes. Assigned data is 7 * 2 = 14 bytes. "tmp" array is 7 * 8 = 56 bytes.

sidcoder
  • 460
  • 2
  • 6