HammerFet
HammerFet

Reputation: 881

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.

Upvotes: 0

Views: 3713

Answers (4)

BobDoolittle
BobDoolittle

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

Jiminion
Jiminion

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

David Neiss
David Neiss

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

sp2danny
sp2danny

Reputation: 7644

declare it in the header

extern myStruct hello;

and define it in only one cpp

myStruct hello;

Upvotes: 3

Related Questions