Nick Williams
Nick Williams

Reputation: 253

Embedded C: Able to access some struct members but not others

The Problem

On a personal project of mine, I have a struct defined in a UART abstraction library (let's call it UART.c and UART.h)I made for an AVR.

In UART.h:

typedef struct ST_UARTRX_MESSAGECONTENTS{
 uint8_t u_command[3];          //Command 
 uint32_t u32_value;            //Parameter for Command
 boolean b_newValue;    //Is there new value written here
 boolean b_Error;       //Is there an error with this message
} ST_UARTRX_MESSAGECONTENTS;

volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;

So basically it's a structure that holds a UART message, it has a "b_newValue" that's a flag for when a new message is received. A message is "received" when the AVR receives a new line "\n".

In the header file of another file (let's call "foo.h"): I include my "UART abstraction library" and put this in the header:

extern volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;

But then in foo.c, I try to access the "b_newValue":

if(st_uartRX_MessageContents.b_newValue){
    st_uartRX_MessageContents.b_newValue = TRUE;  
    fsm_state = ST_STOREMACRO;
}

But the "if" is never entered even if my debugger says the struct value is indeed true:

enter image description here

You can see I have breaked at the if statement. If I hit "Step", it just skips over it and doesn't enter!

Boolean typedef for reference:

typedef enum{FALSE, TRUE} boolean;

Some things I've tried

When I look at the compiled ASM code, I see that general purpose register R24 is used to load the b_newValue, but it loads 0x00, not 0x01 like I'd expect.

uartTX_sendArray(st_uartRX_MessageContents.u_command, sizeof st_uartRX_MessageContents.u_command);
delay_ms(2000);
if(st_uartRX_MessageContents.b_newValue){
    st_uartRX_MessageContents.b_newValue = TRUE;  
    fsm_state = ST_STOREMACRO;
}

I used my "UART: send this array" function to send the ascii "command" from the same structure, and it works! I have no idea why my foo.c can see the "command" but not the "b_newValue".

I've been ripping my hair out for hours. Thanks for looking.

Upvotes: 4

Views: 123

Answers (1)

AnT stands with Russia
AnT stands with Russia

Reputation: 320571

Judging by what you posted now, you have your struct object defined in the header file UART.h

volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;

That's formally illegal (if you include UART.h into multiple translation units) and is generally not a good idea even if some compilers accept it as an extension. I would suggest you move the above definition into a UART.c file and place a non-defining declaration

extern volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;

into UART.h.

Upvotes: 1

Related Questions