store and restore struct in file in C - c

I need to store a struct in a file and read it back to return it then.
I would try to write it to the file like this:
void lld_tpWriteCalibration(struct cal cal) {
FIL fdst; /* file objects */
UINT bw; /* File write count */
/* Create destination file on the drive 0 */
wf_open(&fdst, "0:calibration.txt", FA_CREATE_ALWAYS | FA_WRITE);
wf_write(&fdst, cal, sizeof(cal), &bw);
wf_close(&fdst);
}
Would that work?
And how can I read it back and return it from this function?
struct cal lld_tpReadCalibration(void) {
}
The struct is:
struct cal {
float xm;
float ym;
float xn;
float yn;
};
Thanks for your help.

You can retrieve your structure the same way you stored it.
read(&fdst, &cal, sizeof(cal));
But you got to be careful, you won't be able to do this on every architecture because of endianess problem.

You'll be OK with that structure and that writing/reading technique if you only try to read the file on the same type of machine as you write it on. The data written like that is not reliably portable across different types of machines.

Related

C embedded change values of struct from another file

Hello I am working on a small roboter project at uni and I have run into following issue.
I have a typedef called RoboterData inside of a header file because I want to make use of it across multiple files. Inside of the main file I have a RoboterData data variable which holds important data.
My goal is to have access from other files to this data having the ability to get and set it from another file. I want to avoid the use of a global variable.
Here are the relevant code fragments of my approach:
main.h
typedef struct {
DriveMode mode;
short sensor_left;
short sensor_mid;
short sensor_right;
int left_eng_speed;
int right_eng_speed;
} RoboterData;
main.c
# include "motors.h"
// The Data I want to get and set from other files.
RoboterData data;
// Call to a funcion defined in motors.c
drive_straight(RoboterData *data);
motors.h
void drive_straight(RoboterData *data);
motors.c
# include "main.h"
enum {
ENG_STILL = 0,
ENG_SLOW = 50,
ENG_MID = 155,
ENG_FAST = 200
}
void drive_straight(RoboterData *data) {
data ->left_eng_speed = ENG_FAST;
data ->right_eng_speed = ENG_FAST;
set_duty_cycle(LEFT_ENG, ENG_FAST);
set_duty_cycle(RIGHT_ENG, ENG_FAST);
}
When I later try to print out the values left_eng_speed and right_eng_speed via serial port it stays at 0. I know C is call by value but since I am passing a ptr to my struct the value I am passing is the adress of the struct and when I dereference it via '->' I should be able to access its original data from my understanding and not a copy because the only thing I copied was the address.
If someone could explain to me why this is not working and provide a viable alternative, I would be very greatfull.
// Call to a funcion defined in motors.c
drive_straight(RoboterData *data);
This is a function declaration. It doesn't do anything. You want
drive_straight(&data);
to actually call the function.

File System Open Files Randomly

One of my clients asked me to play sound from an SD card. But file selection should be random because the device is used to scare animals in the field(animals should not get used to sound pattern). I can generate random numbers by
void RNG_Generate_Numbers()
{
HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number1);
HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number2);
}
And I can count files via
void File_Find_File(file_manager_t *file_manage)
{
file_manage->file_result = f_readdir(&file_manage->file_direction, &file_manage->file_info);
if( (file_manage->file_result != FR_OK) || (file_manage->file_info.fname[0] == '\0') )
{
file_manage->file_counter = 0;
}
else
{
++file_manage->file_counter;
}
}
Everything till here is just fine. But when It comes to select files randomly, I could not find any method to do it. Any help is appreciated.
Edit: This is file_manager structure;
typedef struct __file_manager /* struct tag */
{
FATFS drive_handler;
FIL file_handler;
FRESULT file_result;
uint8_t file_disk_status;
DIR file_direction;
FILINFO file_info;
uint8_t file_rx_buffer[512];
char file_current_dir[256];
uint32_t file_bytes_read;
uint32_t file_bytes_write;
size_t file_counter;
}file_manager_t ;
The simplest solution would be to move all files into a single directory and name each file in a sequence starting from zero. Getting a random files name would then be as simple as:
sprintf(file_name, "%d.mp3", rand() % my_files);

Creating a file with the name of a structure i just read from another file

I am trying to read a structure from the file f and i need some arrays of that structure ( "nume" and "firma.nrang") to be written into another file with the name of "localitate" which is also an array of the structure i am reading.
If two structures from f have the same "localitate" array, then their "nume" and "firma.nrang" fields need to be written in the same file called "localitate". I hope i explained well enough. However, i dont know why i cannot open the files i am creating, which i specifically wanted to be text and not binary. What is the problem?
This is my code which doesnt work properly:
typedef struct
{
char localitate[10];
int nrang;
} FIRMA;
typedef struct
{
char nume[20];
int varsta;
FIRMA firma;
} ANG;
ANG x;
FILE *p;
for (i=0; i<m+n; i++)
{
fread(&x,sizeof(x),1,f);
p=fopen(x.firma.localitate,"a");
if (p==NULL)
{
printf("eroare");
exit (1);
}
fwrite(&x.nume,sizeof(x.nume),1,p);
fwrite(&x.firma.nrang,sizeof(x.firma.nrang),1,p);
fclose(p);
}

How to retrieve codec information using libvlc?

I need to get codec information when using libvlc to play remote media. Since the VLC player can achieve this(see the screenshot below), libvlc may well be able to do it too.
Also, I find that libvlc_media_tracks_get can return a related struct as follows:
typedef struct libvlc_media_track_t
{
/* Codec fourcc */
uint32_t i_codec;
uint32_t i_original_fourcc;
int i_id;
libvlc_track_type_t i_type;
/* Codec specific */
int i_profile;
int i_level;
union {
libvlc_audio_track_t *audio;
libvlc_video_track_t *video;
libvlc_subtitle_track_t *subtitle;
};
unsigned int i_bitrate;
char *psz_language;
char *psz_description;
} libvlc_media_track_t;
Maybe the member i_codec stores such information, but it's not human-readable and I don't know the meaning of a specific value. Probably there is a map between them and I haven't found it yet.
The third line already tells you that i_codec should be interpreted as fourcc.
fourcc is a sequence of four ASCII character codes, which are actually human readable, just not as an integer. A list of these codes is available here.
libvlc declares vlc_fourcc_GetDescription in vlc_fourcc.h, which can be used to get a description string.

read a png image in buffer

hi i have used libpng to convert grayscale png image to raw image using c. in that lib the function png_init_io needs file pointer to read the png. but i pass the png image as buffer is there any other alternative functions to to read png image buffer to raw image. please help me
int read_png(char *file_name,int *outWidth,int *outHeight,unsigned char **outRaw) /* We need to open the file */
{
......
/* Set up the input control if you are using standard C streams */
png_init_io(png_ptr, fp);
......
}
instead i need this like
int read_png(unsigned char *pngbuff, int pngbuffleng, int *outWidth,int *outHeight,unsigned char **outRaw) /* We need to open the file */
{
}
From the manual of png_init_io, it is apparent that you can override the read function with png_set_read_fn.
Doing this, you can fool png_init_io into thinking that it is reading from a file, while in reality you're reading from a buffer:
struct fake_file
{
unsigned int *buf;
unsigned int size;
unsigned int cur;
};
static ... fake_read(FILE *fp, ...) /* see input and output from doc */
{
struct fake_file *f = (struct fake_file *)fp;
... /* read a chunk and update f->cur */
}
struct fake_file f = { .buf = pngBuff, .size = pngbuffleng, .cur = 0 };
/* override read function with fake_read */
png_init_io(png_ptr, (FILE *)&f);
Try to use png_set_read_fn instead of png_init_io.

Resources