Reputation: 881
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.
Upvotes: 0
Views: 3713
Reputation: 1750
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.
Upvotes: 0
Reputation: 5168
You are in effect declaring the struct twice (with the same name) which is why your code is not working. Define it once (say in main) and then use extern to reference it in your other files.
extern myStruct hello;
Upvotes: 1
Reputation: 8237
Are you having a problem with the compiler optimizing the accesses in the while loop? Since the compiler doesn't know that another thread of execution is looking at the values of hello, maybe its just not writing them? Try to add volatile to your "extern myStruct hello" or look at the mixed assembly output and see if its writing through to the hello struct.
See here
Upvotes: 1
Reputation: 7644
declare it in the header
extern myStruct hello;
and define it in only one cpp
myStruct hello;
Upvotes: 3