HammerFet HammerFet - 1 month ago 18
C Question

C - Struct across multiple files

I'm having a problem reading and writing to structs across multiple files. Essentially I need to write to variables within a struct that are later checked during a timer interrupt. When this happens, the new timer value is taken as a member in that struct. At the moment I hard set these timer values in a while(1) loop, but later these values will be taken from some algorithm. I'm not quite sure if I'm doing this reading of struct members correctly. The project compiles, however during runtime, it sets the timers to random values. GDB degugging confirmed they are correct however.

If I set the timer values directly, everything works file.

This is an embedded project on an ARM cortex M4.

I have a structure defined in types.h

#ifndef __TYPES_H
#define __TYPES_H

typedef struct { uint32_t a; uint32_t b; uint32_t c;} myStruct;

#endif


Then in main.c

#include <types.h>

myStruct hello

int main(void){
while(1){
hello.a = 10;
hello.b = 43;
hello.c = 98;
}
}


Then in interrupt.c

#include <types.h>

myStruct hello

int count = 0;

void timer_IRQHandler(void){
if(interrupt != RESET){
switch(count){
case 0:
timerSet(hello.a); // if i just put a number here, it works fine
count++;
break;
case 1:
timerSet(hello.b);
count++;
break;
case 2:
timerSet(hello.c);
count++;
break;
}
resetInterrupt();
}
}


--- SOLUTION ---

Ok I've figured it out, could do with moving things around but otherwise it works like this:

types.h

#ifndef __TYPES_H
#define __TYPES_H

typedef struct { uint32_t a; uint32_t b; uint32_t c;} myStruct;

#endif


Then in main.c

#include <types.h>

myStruct volatile hello = {10,10,10};

int main(void){
while(1){
hello.a = 10;
hello.b = 43;
hello.c = 98;
}
}


Then in interrupt.c

#include <types.h>

extern myStruct hello

int count = 0;

void timer_IRQHandler(void){
if(interrupt != RESET){
switch(count){
case 0:
timerSet(hello.a); // if i just put a number here, it works fine
count++;
break;
case 1:
timerSet(hello.b);
count++;
break;
case 2:
timerSet(hello.c);
count++;
break;
}
resetInterrupt();
}
}


The extern seems to have solved the problem of getting the struct across different files, and the initial value declaration of {10,10,10} has, I think solved some memory allocation problem. The code compiles, but doesn't hold correct values without it. I don't know what volatile does yet, no difference if I remove it. Something I shall read up on.

Answer

It appears to me that your timer_IRQHandler is called in the kernel as an interrupt routine. If true, main is probably never called.

I would try to statically initialize your struct, rather than rely on main to initialize it. For example:

myStruct hello = { 10, 43, 98 };

and yes, if multiple files reference it you should declare it as extern in the header and define/initialize it only once in a source file.

As for volatile, that's for device registers or memory-mapped addresses that might not give the same answer if read twice. It tells the compiler to not try to optimize out multiple reads for that memory location.