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.)
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;
}
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.
Related
I tried to send a raw packet with ethernet type 0x0101 but it seems not to be working, if I use ethernet type 0x1000 it is working properly.
Basically I open a raw socket:
int sd = socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC, htons(0x0101));
int r = sendmsg(sd, msgSend, 0);
accordingly with iana ethernet type 0101-01FF are experimental, so to my understating can be used for experiments.
If I use 0x0101 tcpdump shows:
00:00:01.001914 aa:00:00:2e:00:02 > 08:00:27:0b:ed:84, 802.3, length 257: LLC, dsap Null (0x00) Individual, ssap Null (0x00) Command, ctrl 0x0000: Information, send s0
0x0000: 0000 0000 efbe adde aaaa db00 0000 0000 ................
0x0010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0030: 0000
while when I use 0x1000 is shows:
00:00:00.439876 aa:00:00:2e:00:02 > 08:00:27:0b:ed:84, ethertype Trail (0x1000), length 64:
0x0000: 0000 0000 efbe adde aaaa db00 0000 0000 ................
0x0010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0030: 0000
What am I missing?
Tcpdump interprets the value 0x0101 in this position as Ethernet Frame Length.
Values smaller than 0x600 (1536 decimal) are assumed to be the frame length (parsed as Frametype IEEE 802.2 LLC) instead of the next protocol id (parsed as Frametype Ethernet II).
Here you see, that tcpdump indeed interprets 0x101 (257 decimal) as the length:
00:00:01.001914 aa:00:00:2e:00:02 > 08:00:27:0b:ed:84, 802.3, length 257: LLC, dsap Null (0x00) Individual, ssap Null (0x00) Command, ctrl 0x0000: Information, send s0
But your frame should be correctly on-wire as you intended it.
unsigned int PointSet[] = { (10<<16) | 3, (4<<16) | 2, 0xFFFF0002 };
What does this mean ?
| 3 what operation is it?
This creates an array of three integers. The commas separate the constant-value expressions. The | is bitwise OR operator.
(10<<16)|3 = (0xA<<16)|3 = (0x000A0000)|0x3 = 0x000A0003
(4<<16)|2 = (0x00040000)|0x2 = 0x00040002
Your array is { 0x000A0003, 0x00040002, 0xFFFF0002 }
unsigned int PointSet[] = { (10<<16) | 3, (4<<16) | 2, 0xFFFF0002 };
10 = 0000 0000 0000 0000 0000 0000 0000 1010 (Binary)
0x0000000A = 0 0 0 0 0 0 0 A
0000 0000 0000 1010 0000 0000 0000 0000 (16 bit shift)
0x000A0000 = 0 0 0 A 0 0 0 0
3 = 0000 0000 0000 0000 0000 0000 0000 0011
0x000A0003 = 0000 0000 0000 1010 0000 0000 0000 0011 (... | 3)
0x00000004 = 0000 0000 0000 0000 0000 0000 0000 0100
0x00040000 = 0000 0000 0000 0100 0000 0000 0000 0000 (16 bit shift)
0x00000002 = 0000 0000 0000 0000 0000 0000 0000 0010
0x00040002 = 0000 0000 0000 0100 0000 0000 0000 0010 (... | 2)
unsigned int PointSet[] = {0x000A0003, 0x00040002,0xFFFF0002};
I was going through K&R and decided to do an experiment. In K&R first the while loop is taught and then the for loop is taught. In doing so, the same program is written with both a while loop and for loop. These programs both have the same output and functionally do the same thing. I then thought to compare the two binary files using vim -d <(xxd celsius) <(xxd ccelsius) and thought that they would be the same file; however, they are not. While there are certain segment of the file that are the same there are significant differences as well. I was wondering why these differences exist and if there was any way to make the files compile to the same binary. I am using gcc as my compiler.
C Files
celsius.c
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300; floating-point version */
int main(void)
{
float fahr, celsius;
int lower, upper, step;
lower = 0; /* lower limit of temperature table */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
ccelcius.c
#include <stdio.h>
/* print Fahrenheit-Celsius table */
int main(void)
{
float fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20)
printf("%3.0f %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}
Hex Diff File
diff <(xxd celsius) <(xxd ccelsius)
14,15c14,15
< 000000d0: c00e 0000 0100 0000 a700 0000 0000 0000 ................
< 000000e0: c00e 0000 0400 0000 0000 0000 0000 0000 ................
---
> 000000d0: e00e 0000 0100 0000 8d00 0000 0000 0000 ................
> 000000e0: e00e 0000 0400 0000 0000 0000 0000 0000 ................
19,20c19,20
< 00000120: 680f 0000 0100 0000 0600 0000 0000 0000 h...............
< 00000130: 680f 0000 0100 0000 0000 0000 0000 0000 h...............
---
> 00000120: 6e0f 0000 0100 0000 0600 0000 0000 0000 n...............
> 00000130: 6e0f 0000 0100 0000 0000 0000 0000 0000 n...............
24,25c24,25
< 00000170: 700f 0000 0100 0000 1a00 0000 0000 0000 p...............
< 00000180: 700f 0000 0200 0000 0000 0000 0000 0000 p...............
---
> 00000170: 740f 0000 0100 0000 1a00 0000 0000 0000 t...............
> 00000180: 740f 0000 0200 0000 0000 0000 0000 0000 t...............
29c29
< 000001c0: 900f 0000 0100 0000 0c00 0000 0000 0000 ................
---
> 000001c0: 900f 0000 0100 0000 1800 0000 0000 0000 ................
34,35c34,35
< 00000210: 9c0f 0000 0100 0000 0d00 0000 0000 0000 ................
< 00000220: 9c0f 0000 0000 0000 0000 0000 0000 0000 ................
---
> 00000210: a80f 0000 0100 0000 0b00 0000 0000 0000 ................
> 00000220: a80f 0000 0000 0000 0000 0000 0000 0000 ................
39,40c39,40
< 00000260: ac0f 0000 0100 0000 4800 0000 0000 0000 ........H.......
< 00000270: ac0f 0000 0200 0000 0000 0000 0000 0000 ................
---
> 00000260: b40f 0000 0100 0000 4800 0000 0000 0000 ........H.......
> 00000270: b40f 0000 0200 0000 0000 0000 0000 0000 ................
73c73
< 00000480: 1985 c866 b4a1 304e 965d 4a68 80be 0434 ...f..0N.]Jh...4
---
> 00000480: 37e9 3480 21a8 3e96 b783 ea6a 3feb 00d8 7.4.!.>....j?...
76c76
< 000004b0: 2800 0080 1800 0000 c00e 0000 0000 0000 (...............
---
> 000004b0: 2800 0080 1800 0000 e00e 0000 0000 0000 (...............
237,256c237,256
< 00000ec0: 5548 89e5 4883 ec20 c745 fc00 0000 00c7 UH..H.. .E......
< 00000ed0: 45f0 0000 0000 c745 ec2c 0100 00c7 45e8 E......E.,....E.
< 00000ee0: 1400 0000 f30f 2a45 f0f3 0f11 45f8 f30f ......*E....E...
< 00000ef0: 1045 f8f3 0f2a 4dec 0f2e c80f 825d 0000 .E...*M......]..
< 00000f00: 0048 8d3d 9400 0000 f20f 1005 8000 0000 .H.=............
< 00000f10: f30f 100d 8000 0000 f30f 1055 f8f3 0f5c ...........U...\
< 00000f20: d1f3 0f5a caf2 0f59 c1f2 0f5a c0f3 0f11 ...Z...Y...Z....
< 00000f30: 45f4 f30f 5a45 f8f3 0f5a 4df4 b002 e825 E...ZE...ZM....%
< 00000f40: 0000 00f3 0f10 45f8 f30f 2a4d e8f3 0f58 ......E...*M...X
< 00000f50: c1f3 0f11 45f8 8945 e4e9 90ff ffff 8b45 ....E..E.......E
< 00000f60: fc48 83c4 205d c390 ff25 a200 0000 0000 .H.. ]...%......
< 00000f70: 4c8d 1d91 0000 0041 53ff 2581 0000 0090 L......AS.%.....
< 00000f80: 6800 0000 00e9 e6ff ffff 0000 0000 0000 h...............
< 00000f90: 721c c771 1cc7 e13f 0000 0042 2533 2e30 r..q...?...B%3.0
< 00000fa0: 6620 2536 2e31 660a 0000 0000 0100 0000 f %6.1f.........
< 00000fb0: 1c00 0000 0000 0000 1c00 0000 0000 0000 ................
< 00000fc0: 1c00 0000 0200 0000 c00e 0000 3400 0000 ............4...
< 00000fd0: 3400 0000 680f 0000 0000 0000 3400 0000 4...h.......4...
< 00000fe0: 0300 0000 0c00 0100 1000 0100 0000 0000 ................
< 00000ff0: 0000 0001 0000 0000 0000 0000 0000 0000 ................
---
> 00000ec0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 00000ed0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 00000ee0: 5548 89e5 4883 ec20 0f57 c0c7 45fc 0000 UH..H.. .W..E...
> 00000ef0: 0000 f30f 1145 f8f3 0f10 0591 0000 000f .....E..........
> 00000f00: 2e45 f80f 825b 0000 0048 8d3d 9800 0000 .E...[...H.=....
> 00000f10: f20f 1005 8800 0000 f30f 100d 7400 0000 ............t...
> 00000f20: f30f 5a55 f8f3 0f10 5df8 f30f 5cd9 f30f ..ZU....]...\...
> 00000f30: 5acb f20f 59c1 f20f 1145 f00f 28c2 f20f Z...Y....E..(...
> 00000f40: 104d f0b0 02e8 2400 0000 8945 ecf3 0f10 .M....$....E....
> 00000f50: 0543 0000 00f3 0f58 45f8 f30f 1145 f8e9 .C.....XE....E..
> 00000f60: 93ff ffff 8b45 fc48 83c4 205d c390 ff25 .....E.H.. ]...%
> 00000f70: 9c00 0000 4c8d 1d8d 0000 0041 53ff 257d ....L......AS.%}
> 00000f80: 0000 0090 6800 0000 00e9 e6ff ffff 0000 ....h...........
> 00000f90: 0000 9643 0000 0042 0000 a041 0000 0000 ...C...B...A....
> 00000fa0: 721c c771 1cc7 e13f 2533 6420 2536 2e31 r..q...?%3d %6.1
> 00000fb0: 660a 0000 0100 0000 1c00 0000 0000 0000 f...............
> 00000fc0: 1c00 0000 0000 0000 1c00 0000 0200 0000 ................
> 00000fd0: e00e 0000 3400 0000 3400 0000 6e0f 0000 ....4...4...n...
> 00000fe0: 0000 0000 3400 0000 0300 0000 0c00 0100 ....4...........
> 00000ff0: 1000 0100 0000 0000 0000 0001 0000 0000 ................
258c258
< 00001010: 800f 0000 0100 0000 0000 0000 0000 0000 ................
---
> 00001010: 840f 0000 0100 0000 0000 0000 0000 0000 ................
518,519c518,519
< 00002050: 2502 0000 0003 00c0 1d00 0000 0000 0000 %...............
< 00002060: c01d 0000 0000 0000 0200 0000 0f01 1000 ................
---
> 00002050: 2502 0000 0003 00e0 1d00 0000 0000 0000 %...............
> 00002060: e01d 0000 0000 0000 0200 0000 0f01 1000 ................
521c521
< 00002080: c00e 0000 0100 0000 1c00 0000 0100 0001 ................
---
> 00002080: e00e 0000 0100 0000 1c00 0000 0100 0001 ................
In the first example
celsius = (5.0/9.0) * (fahr-32.0);
is using double to compute the result, and then truncating that to float, which is then promoted back to double to be printed with the %f format.
In the second example, again the calculation uses double
printf("%3.0f %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
but there is no truncation to float, since a double is expected. So the computations have slightly different results.
If you do a diff of the disassembly, the results are pretty much identical when compiled with optimizations on, even if the binary doesn't exactly match (I've changed both source files to use floats exclusively because of Weather Vane's comments):
celsius.c
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300; floating-point version */
int main(void)
{
float fahr, celsius;
static const int lower = 0;
static const int upper = 300;
static const int step = 20;
fahr = lower;
while (fahr <= upper) {
celsius = (5.0f/9.0f) * (fahr-32.0f);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}
ccelsius.c
#include <stdio.h>
/* print Fahrenheit-Celsius table */
int main(void)
{
float fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20)
printf("%3.0f %6.1f\n", fahr, (5.0f/9.0f)*(fahr-32.0f));
}
To compile
cc -Wall -O3 celsius.c -o celsius && cc -Wall -O3 ccelsius.c -o ccelsius
diff <(objdump -d celsius) <(objdump -d ccelsius)
2c2
< celsius: file format elf64-x86-64
---
> ccelsius: file format elf64-x86-64
According to http://wiki.osdev.org/FAT I'm trying to get the total FAT size. But the result is riddiculus.
What am I doing wrong?
Any help is appreciated! Thank you.
int main(int argc, char *argv[]){
if(argc == 1){
printf("Root directory:\n");
} else {
char *file_name = argv[1];
printf("Checking %s...\n", file_name);
FILE *file = fopen(file_name, "r");
if (file==NULL) {fputs ("File error\n",stderr); exit (1);}
unsigned char boot[512];
fread(boot, 512, 1, file);
// Sectors per FAT. The size of the FAT in sectors.
unsigned int sectors_per_fat = (boot[39]<<24)|(boot[38]<<16)|(boot[37]<<8)|boot[36];
unsigned int fat_count = boot[16];
unsigned int bytes_per_block = (boot[12]<<8)|boot[11];
unsigned int total_fat_size = sectors_per_fat*fat_count*bytes_per_block;
printf("%d\n", total_fat_size);
/*
36-4 Sectors per FAT
16-1 Number of File Allocation Tables.
11-2 Number of bytes per block (almost always 512).
*/
fclose(file);
}
return 0;
}
the file:
0000000: eb58 906d 6b66 732e 6661 7400 0201 2000 .X.mkfs.fat... .
0000010: 0200 0000 00f8 0000 2000 4000 0000 0000 ........ .#.....
0000020: 400d 0300 0306 0000 0000 0000 0200 0000 #...............
0000030: 0100 0600 0000 0000 0000 0000 0000 0000 ................
0000040: 8000 29c8 a726 5e4e 4f20 4e41 4d45 2020 ..)..&^NO NAME
0000050: 2020 4641 5433 3220 2020 0e1f be77 7cac FAT32 ...w|.
0000060: 22c0 740b 56b4 0ebb 0700 cd10 5eeb f032 ".t.V.......^..2
0000070: e4cd 16cd 19eb fe54 6869 7320 6973 206e .......This is n
0000080: 6f74 2061 2062 6f6f 7461 626c 6520 6469 ot a bootable di
0000090: 736b 2e20 2050 6c65 6173 6520 696e 7365 sk. Please inse
00000a0: 7274 2061 2062 6f6f 7461 626c 6520 666c rt a bootable fl
00000b0: 6f70 7079 2061 6e64 0d0a 7072 6573 7320 oppy and..press
00000c0: 616e 7920 6b65 7920 746f 2074 7279 2061 any key to try a
00000d0: 6761 696e 202e 2e2e 200d 0a00 0000 0000 gain ... .......
00000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.
0000200: 5252 6141 0000 0000 0000 0000 0000 0000 RRaA............
0000210: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000220: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000240: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000250: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000260: 0000 0000 0000 0000 0000 0000 0000 0000 ................
....
I used these to create the file:
dd if=/dev/zero of=disk.img bs=1k count=100000
losetup /dev/loop0 disk.img
mkdosfs -s 1 -F 32 /dev/loop0 100000
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
typedef struct {
char name[124];
int age;
int class;
} student;
main( ) {
student s1;
int fd = -1;
int fh = creat( "student.db", O_CREAT | S_IRUSR | S_IWUSR );
fd = open( "student.db", O_RDWR | O_APPEND );
if ( fd<0 ) {
perror( "failed to create student file:" );
return;
}
s1.age = 15;
s1.class = 9;
strcpy( s1.name, "John" );
int ret = write( fd, &s1, sizeof( student ) );
printf( "ret of write: %d \n", ret );
system( "gvim student.db" );
}
I am trying to write a record to a file. Since structure contains integer elements only name is written successfully, whereas the int elements are displayed as garbage. Could anyone please have a look at the code. Any help would be appreciated.
Using a command like od -x you can get a hex dump of file contents useful for debugging.
You'ld make it easier for yourself if you reorder the structure members, so the integers are first.
An example, showing a file with count of 64bit fibonacci sequence from 0.. :
ladm#ash:~/src/fib/fibs_tab> od -x < fib_uint64| head
0000000 005e 0000 0000 0000 0000 0000 0000 0000
0000020 0001 0000 0000 0000 0001 0000 0000 0000
0000040 0002 0000 0000 0000 0003 0000 0000 0000
0000060 0005 0000 0000 0000 0008 0000 0000 0000
0000100 000d 0000 0000 0000 0015 0000 0000 0000
0000120 0022 0000 0000 0000 0037 0000 0000 0000
0000140 0059 0000 0000 0000 0090 0000 0000 0000
0000160 00e9 0000 0000 0000 0179 0000 0000 0000
0000200 0262 0000 0000 0000 03db 0000 0000 0000
0000220 063d 0000 0000 0000 0a18 0000 0000 0000
First integer is a count 0x5e (93), followed by 3 empty higher significant bytes, then sequence begins. 0,1,1,2,3,5 and so on.