Reputation: 253
thank you for taking the time to read.
Problem I'm seeing
I have:
main.h
that declares:
uint8_t u_newVar
I also have
foo.h
that writes:
extern uint8_t u_newVar
The application sits in a infinite while loop in main.c until an ISR occurs.
In the foo.c, said ISR calls a function within foo.c.
In that function (foo_function() if you will): 0x01 is written to the u_newVar.
Finally, after returning from the interrupt and back into the infinite while, there is a single "if" statement:
while(1){
if(u_newVar == 0x01){
uartTX_sendArray(st_uartRX_MessageContents->u_command, (sizeof st_uartRX_MessageContents->u_command));
uartTX_sendButtonPressData(st_uartRX_MessageContents->u32_value);
u_newVar = 0x00;
}
}
However, the application never enters the if. This "if" block will work if it is in foo.c, after the
u_newVar = 0x01;
line.
Stuff I tried
I looked at the compiled assembly, and what I found kind of stumps me.
If I look at the "if" in main, this is what I see:
So it loads the value from address: 0x011D from SRAM, which I can confirm is 0x01.
Then "CPI" to compare R24 directly to 0x01, which should obviously work.
Then "BREQ", branch if equal, and increment program counter twice to the uart function below. Also makes sense.
However this part is weird. Otherwise, use "RJMP" to jump to the instruction which it is currently at. Unless I'm mistaken, this would lock here for eternity?
So, remember when I mentioned that when I put the if block into the foo.c after the write to u_newVar? Yeah, that's not too interesting:
The "if" is supposed to be after "u_newVar = 0x01", but the compiler is too smart and optimizes it how. Which is why it always works there.
Upvotes: 0
Views: 76
Reputation: 16540
what your looking at is the output from the assembler, not the linked code.
The linker has info in the relocation table for that offset in the code (the data byte(s) of the instruction and what the actual target offset is. during the linking process (or for certain environments during the load processing) those data bytes will be updated to contain the correct value
Upvotes: -1
Reputation: 798814
You forgot to tell the compiler that the variable might be modified asynchronously. Such as in a ISR.
volatile uint8_t u_newVar;
Upvotes: 8