C variable declared and assigned to function call - c

The local variable btmp in the below code is declared with an assignment to a function call. That function is reading the value of a register RegX. The next line writes to another register Reg_ADDR, which is the purpose of these lines of code. The lines thereafter potentially update btmp.
As this function does not return anything, is there any purpose to the last 4 lines of code? Or is there something complicated going on, e.g. btmp is some sort of pointer?
void SetDeviceAddress( uint8_t address, ENUM_MODE AddressMode)
{
uint8_t btmp = DeviceReadReg( RegX ) & ~0x03;
DeviceWriteReg(Reg_ADDR, address);
if ( AddressMode == MODE0 ) {}
else if( AddressMode == MODE1 ) { btmp |= 0x01; }
else if( AddressMode == MODE2 ) { btmp |= 0x02; }
else if( AddressMode == MODE3 ) { btmp |= 0x03; }
}

The 'btmp' variable is the local variable, so any write/change operations related to this are lost while clearing the stack on function return. Moreover, it seems that the first line of this code is useless too - as long as the DeviceReadReg() call has no side effects (if it has, this is really bad coding practice).
So, the real equivalent of the function is:
void SetDeviceAddress(uint8_t address, ENUM_MODE AddressMode)
{
DeviceWriteReg(Reg_ADDR, address);
}
or better:
void SetDeviceAddress(uint8_t address)
{
DeviceWriteReg(Reg_ADDR, address);
}

Related

Pass array that is part of struct as uint8_t pointer to function

I am working with the Renesas RA2A1 using their Flexible software package, trying to send data over a uart.
I am sending ints and floats over the uart, so I created a union of a float and a 4 byte uint8_t array, same for ints.
I put a few of these in a struct, and then put that in a union with an array that is the size of all the data contained in the struct.
I can't get it to work by passing the array in the struct to the function.. If I create an array of uint8_t, that passes in and works OK... I'm not sure what's wrong with trying to pass the array as I am.
It is failing an assert in R_SCI_UART_WRITE that checks the size, which is failing because it is 0.
typedef union{
float num_float;
uint32_t num_uint32;
int32_t num_int32;
uint8_t num_array[4];
} comms_data_t;
typedef struct{
comms_data_t a;
comms_data_t b;
comms_data_t c;
comms_data_t d;
comms_data_t e;
uint8_t lr[2];
} packet_data_t;
typedef union{
packet_data_t msg_packet_data;
uint8_t packet_array[22];
}msg_data_t;
/* Works */
uint8_t myData[10] = "Hi Dave!\r\n";
uart_print_main_processor_msg(myData);
/* Doesn't work */
msg_data_t msg_data;
/* code removed that puts data into msg_data,ex below */
msg_data.msg_packet_data.a.num_float = 1.2f;
uart_print_main_processor_msg(msg_data.packet_array);
// Functions below
/****************************************************************************************************************/
fsp_err_t uart_print_main_processor_msg(uint8_t *p_msg)
{
fsp_err_t err = FSP_SUCCESS;
uint8_t msg_len = RESET_VALUE;
uint32_t local_timeout = (DATA_LENGTH * UINT16_MAX);
char *p_temp_ptr = (char *)p_msg;
/* Calculate length of message received */
msg_len = ((uint8_t)(strlen(p_temp_ptr)));
/* Reset callback capture variable */
g_uart_event = RESET_VALUE;
/* Writing to terminal */
err = R_SCI_UART_Write (&g_uartMainProcessor_ctrl, p_msg, msg_len);
if (FSP_SUCCESS != err)
{
APP_ERR_PRINT ("\r\n** R_SCI_UART_Write API Failed **\r\n");
return err;
}
/* Check for event transfer complete */
while ((UART_EVENT_TX_COMPLETE != g_uart_event) && (--local_timeout))
{
/* Check if any error event occurred */
if (UART_ERROR_EVENTS == g_uart_event)
{
APP_ERR_PRINT ("\r\n** UART Error Event Received **\r\n");
return FSP_ERR_TRANSFER_ABORTED;
}
}
if(RESET_VALUE == local_timeout)
{
err = FSP_ERR_TIMEOUT;
}
return err;
}
fsp_err_t R_SCI_UART_Write (uart_ctrl_t * const p_api_ctrl, uint8_t const * const p_src, uint32_t const bytes)
{
#if (SCI_UART_CFG_TX_ENABLE)
sci_uart_instance_ctrl_t * p_ctrl = (sci_uart_instance_ctrl_t *) p_api_ctrl;
#if SCI_UART_CFG_PARAM_CHECKING_ENABLE || SCI_UART_CFG_DTC_SUPPORTED
fsp_err_t err = FSP_SUCCESS;
#endif
#if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
err = r_sci_read_write_param_check(p_ctrl, p_src, bytes);
FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
FSP_ERROR_RETURN(0U == p_ctrl->tx_src_bytes, FSP_ERR_IN_USE);
#endif
/* Transmit interrupts must be disabled to start with. */
p_ctrl->p_reg->SCR &= (uint8_t) ~(SCI_SCR_TIE_MASK | SCI_SCR_TEIE_MASK);
/* If the fifo is not used the first write will be done from this function. Subsequent writes will be done
* from txi_isr. */
#if SCI_UART_CFG_FIFO_SUPPORT
if (p_ctrl->fifo_depth > 0U)
{
p_ctrl->tx_src_bytes = bytes;
p_ctrl->p_tx_src = p_src;
}
else
#endif
{
p_ctrl->tx_src_bytes = bytes - p_ctrl->data_bytes;
p_ctrl->p_tx_src = p_src + p_ctrl->data_bytes;
}
#if SCI_UART_CFG_DTC_SUPPORTED
/* If a transfer instance is used for transmission, reset the transfer instance to transmit the requested
* data. */
if ((NULL != p_ctrl->p_cfg->p_transfer_tx) && p_ctrl->tx_src_bytes)
{
uint32_t data_bytes = p_ctrl->data_bytes;
uint32_t num_transfers = p_ctrl->tx_src_bytes >> (data_bytes - 1);
p_ctrl->tx_src_bytes = 0U;
#if (SCI_UART_CFG_PARAM_CHECKING_ENABLE)
/* Check that the number of transfers is within the 16-bit limit. */
FSP_ASSERT(num_transfers <= SCI_UART_DTC_MAX_TRANSFER);
#endif
err = p_ctrl->p_cfg->p_transfer_tx->p_api->reset(p_ctrl->p_cfg->p_transfer_tx->p_ctrl,
(void const *) p_ctrl->p_tx_src,
NULL,
(uint16_t) num_transfers);
FSP_ERROR_RETURN(FSP_SUCCESS == err, err);
}
#endif
#if SCI_UART_CFG_FLOW_CONTROL_SUPPORT
if ((((sci_uart_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->uart_mode == UART_MODE_RS485_HD) &&
(p_ctrl->flow_pin != SCI_UART_INVALID_16BIT_PARAM))
{
R_BSP_PinAccessEnable();
R_BSP_PinWrite(p_ctrl->flow_pin, BSP_IO_LEVEL_HIGH);
R_BSP_PinAccessDisable();
}
#endif
/* Trigger a TXI interrupt. This triggers the transfer instance or a TXI interrupt if the transfer instance is
* not used. */
p_ctrl->p_reg->SCR |= SCI_SCR_TIE_MASK;
#if SCI_UART_CFG_FIFO_SUPPORT
if (p_ctrl->fifo_depth == 0U)
#endif
{
/* On channels with no FIFO, the first byte is sent from this function to trigger the first TXI event. This
* method is used instead of setting TE and TIE at the same time as recommended in the hardware manual to avoid
* the one frame delay that occurs when the TE bit is set. */
if (2U == p_ctrl->data_bytes)
{
p_ctrl->p_reg->FTDRHL = *((uint16_t *) (p_src)) | (uint16_t) ~(SCI_UART_FIFO_DAT_MASK);
}
else
{
p_ctrl->p_reg->TDR = *(p_src);
}
}
return FSP_SUCCESS;
#else
FSP_PARAMETER_NOT_USED(p_api_ctrl);
FSP_PARAMETER_NOT_USED(p_src);
FSP_PARAMETER_NOT_USED(bytes);
return FSP_ERR_UNSUPPORTED;
#endif
}
There are several issues with this program. A large part of this code relies on undefined behavior. Unions are also UB if used for aliasing, even if pretty much all C compilers tend to allow it, but if you are using a union I would still prefer using a char[] for the array used for aliasing. As mentioned in the comments, "Hi Dave!\r\n"; actually takes up 11 bytes with the null-character. It's safer to use uint8_t myData[] = "Hi Dave!\r\n"; or const * uint8_t = "Hi Dave!\r\n"; and spare yourself the trouble.
Second problem is that strlen cannot work correctly for binary data. strlen works by searching for the first occurrence of the null-character in the string, so it's not applicable for binary data. If you pass a floating point value which has a single zero byte in its IEEE 754 representation, it will mark the end of this "string".
Plain and simple, your function should be declared as fsp_err_t uart_write(const char * msg, size_t msg_len); and be called using uart_write(data_array, sizeof data_array);. If you want to transmit messages of variable size over the UART, you will also have to define a certain communication protocol, i.e. create a message that can be unambiguously parsed. This will likely mean: 1) some cookie at the beginning, 2) length of the transmitted data, 3) actual data, 4) crc -- but this is outside the scope of this question.
So, strlen won't tell you the length of the data, you will pass it to the function yourself, and you don't need unions at all. If you choose not to properly serialize the data (e.g. using protobuf or some other protocol), you can simply pass the pointer to the struct to the function, i.e. call the above mentioned uart_write((char*)&some_struct, sizeof some_struct); and it will work as if you passed an array.
Note that char in this case doesn't mean "ascii character", or "character in a string". The point with using the char* is that it's the only pointer which is legally allowed to alias other pointers. So, you acquire a pointer to your struct (&str), cast it to a char*, and pass it to a function which can then read its representation in memory. I am aware that R_SCI_UART_Write is likely generated by your IDE, and unfortunately these blocks often use uint8_t* instead of char*, so you will probably have to cast to uint8_t* at some point.

Why can't I read interrupt flag from my main loop?

I'm writing code for stm32l011 MCU and it have to do one basic task for now - wait for a specific byte(predefined by me) from the UART and following "\r\n" or "\n\r" sequence. If it receives that, it set's a null pointer to the address of the predefined char, which is read and handled in the main loop.
volatile uint8_t uart_buff[UART_BUFF_LEN] = {'\0'};
volatile uint8_t *uart_data = NULL;
volatile uint8_t *uart_stack = uart_buff+2;
void USART2_IRQHandler(void){
if(LL_USART_IsActiveFlag_RXNE(USART2)){
*uart_stack = LL_USART_ReceiveData8(USART2);
user_uart_send_byte(*uart_stack);
//same as if(!(strcmp((uart_stack-1), "\r\n") || strcmp((uart_stack-1), "\n\r")))
if((*uart_stack == '\r' || *uart_stack == '\n') && (*(uart_stack-1) == '\r' || *(uart_stack-1) == '\n'))
{
uart_data = uart_stack - 2;
uart_stack = uart_buff+2;
}
uart_stack++;
}
}
and main:
extern volatile uint32_t systick_counter_ms;
extern volatile uint8_t *uart_data;
int main(void){
init();
while(1)
{
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_3);
//delay_ms(1); //without that it doesn't want to work
if(uart_data)
{
adc_transmit_reading(*uart_data);
uart_data = NULL;
}
}
}
I wrote the C program above and it didn't seem to work. But when I introduced delay in the main loop it just magically sprang to life. Why is that? Key things to note:
There's echo from the UART so I'm sure that it handles the interrupt properly in both cases, also I tried to remove optimizations of the compiler(which optimizes for size(Os)) by using volatile variables. Also the delay is made by while loop, which waits interrupt which increments variable every millisecond.
My layman's guess is that because I'm only looping around that uart_data pointer, somehow the synchronization between the interrupt and main loop isn't happening.
Thanks in advance :)
The problem is that you have indicated that your uart_data points to volatile data. But in your loop, you are testing the pointer and not the data.
So you must indicate that your pointer is volatile as well:
extern volatile uint8_t * volatile uart_data;
You can find more information in this post: Why is a point-to-volatile pointer, like "volatile int * p", useful?

Passing PIN status as a function parameter

I want to write a function for my AVR ATmega328 that debounces switches using state space to confirm a switch press. After finishing it I wanted to generalize my function so that I may reuse it in the future with little work, but that involves passing the pin I want to use as a function parameter, and I just can't get that to work.
This is what I have now:
int debounceSwitch(unsigned char *port, uint8_t mask)
{
int n = 0;
while (1)
{
switch (n)
{
case 0: //NoPush State
_delay_ms(30);
if(!(*port & (1<<mask))){n = n + 1;}
else {return 0;}
break;
case 1: //MaybePush State
_delay_ms(30);
if(!(*port & (1<<mask))){n = n + 1;}
else {n = n - 1;}
break;
case 2: //YesPush State
_delay_ms(30);
if(!(*port & (1<<mask))){return 1;}
else {n = n - 1;}
break;
}
}
}
I have a hunch my issue is with the data type I'm using as the parameter, and I seem to have gotten different answers online.
Any help would be appreciated!
Well in AVR ports are special IO registers and they are accessed using IN and OUT instructions. Not like memory using LDR etc.
From the port definition you can see that you need to make the port pointer volatile. which the compiler would have also told you as a warning when you would had tried to pass PORT to the function.
#define PORTB _SFR_IO8(0x05)
which maps to
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
Various issues:
The function should be void debounceSwitch(volatile uint8_t* port, uint8_t pin). Pointers to hardware registers must always be volatile. It doesn't make sense to return anything.
Never use 1 signed int literals when bit-shifting. Should be 1u << n or your program will bug out when n is larger than 8.
Burning away 30ms several times over in a busy-delay is horrible practice. It will lock your CPU at 100% doing nothing meaningful, for an eternity.
There are many ways to debounce buttons. The simplest professional form is probably to have a periodic timer running with interrupt every 10ms (should be enough, if in doubt measure debounce spikes of your button with a scope). It will look something like the following pseudo code:
volatile bool button_pressed = false;
void timer_interrupt (void)
{
uint8_t button = port & mask;
button_pressed = button && prev;
prev = button;
}
This assuming that buttons use active high logic.
What I dislike on your implementation is the pure dependency on PORT/IO handling and the actual filter/debouncing logic. What are you doing then, when the switch input comes over a signal e.g. from CAN?
Also, it can be handled much easier, if you think in configurable/parameterizable filters. You implement the logic once, and then just create proper configs and pass separate state variables into the filter.
// Structure to keep state
typedef struct {
boolean state;
uint8 cnt;
} deb_state_t;
// Structure to configure the filters debounce values
typedef struct {
uint8 cnt[2]; // [0] = H->L transition, [1] = L->H transition
} deb_config_t;
boolean debounce(boolean in, deb_state_t *state, const deb_config_t *cfg)
{
if (state->state != in) {
state->cnt++;
if (state->cnt >= cfg->cnt[in]) {
state->state = in;
state->cnt = 0;
}
} else {
state->cnt = 0;
}
return state->state;
}
static const deb_config_t debcfg_pin = { {3,4} };
static const deb_config_t debcfg_can = { {2,1} };
int main(void)
{
boolean in1, in2, out1, out2;
deb_state_t debstate_pin = {0, 0};
deb_state_t debstate_can = {0, 0};
while(1) {
// read pin and convert to 0/1
in1 = READ_PORT(PORTx, PINxy); // however this is defined on this architecture
out1 = debounce(in1, &debstate_pin, &debcfg_pin);
// same handling, but input from CAN
in2 = READ_CAN(MSGx, SIGxy); // however this is defined on this architecture
out2 = debounce(in2, &debstate_can, &debcfg_can);
// out1 & out2 are now debounced
}

--fill command on PIC32MX boot flash memory

I have been trying for the last few weeks to find out why this isn't working. I have tried reading all the documentation I could find on my PIC32 MCU (PIC32MX795F512L) and the XC32 compiler I am using (v1.34) but with no success as of yet.
I need a special constant value written to the physical boot flash address 0x1FC02FEC (Virtual address: 0x9FC02FEC). This constant is 0x3BDFED92.
I have managed to successfully do this on my main program (If I program my pic32 directly using Real ICE) by means of the following command line (Which I put in xc32-ld under "Additional options" under the Project Properties):
--fill=0x3bdfed92#0x9FC02FEC
I am then able to check (Inside my main program) if this address indeed does have the correct value stored inside it, and this works too. I use the following code for that:
if(*(int *)(0x9fc02fec) == 0x3bdfed92)
My problem is the following. I do not want my main program hex file to write the constant into that location. I want my bootloader hex file to do this and my main program must just be able to read that location and see if that constant is there. If I use the --fill command inside the xc32-ld of my bootloader program, it successfully writes the constant just like the main program did (I have tested this by running my bootloader program with the same --fill command in debug mode and checking the 0x1FC02FEC address for the constant). Problem is, when my bootloader reads in a new main program via the MicroSD, and then jumps to the new main program, everything doesn't work. Seems like, before it jumps to the new main program, something bad happens and everything crashes. Almost like writing a value to the 1FC02FEC location is a problem when the program jumps from boot loader to main program.
Is there a reason for this? I hope my explanation is ok, if not then please let me know and I will try reword it in a more understandable way.
I am using the example code provided by Microchip to do the bootloader using the MicroSD card. The following is the code:
int main(void)
{
volatile UINT i;
volatile BYTE led = 0;
// Setup configuration
(void)SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
InitLED();
TRISBbits.TRISB14 = 0;
LATBbits.LATB14 = 0;
ClrWdt();
// Create a startup delay to resolve trigger switch bouncing issues
unsigned char x;
WORD ms = 500;
DWORD dwCount = 25;
while(ms--)
{
ClrWdt();
x=4;
while(x--)
{
volatile DWORD _dcnt;
_dcnt = dwCount*((DWORD)(0.00001/(1.0/GetInstructionClock())/10));
while(_dcnt--)
{
#if defined(__C32__)
Nop();
Nop();
Nop();
#endif
}
}
}
if(!CheckTrigger() && ValidAppPresent())
{
// This means the switch is not pressed. Jump
// directly to the application
JumpToApp();
}
else if(CheckTrigger() && ValidAppPresent()){
if(MDD_MediaDetect()){
if(FSInit()){
myFile = FSfopen("image.hex","r");
if(myFile == NULL){
JumpToApp();
}
}
else{
JumpToApp();
}
}
else{
JumpToApp();
}
}
//Initialize the media
while (!MDD_MediaDetect())
{
// Waiting for media to be inserted.
BlinkLED();
}
// Initialize the File System
if(!FSInit())
{
//Indicate error and stay in while loop.
Error();
while(1);
}
myFile = FSfopen("image.hex","r");
if(myFile == NULL)// Make sure the file is present.
{
//Indicate error and stay in while loop.
Error();
while(1);
}
// Erase Flash (Block Erase the program Flash)
EraseFlash();
// Initialize the state-machine to read the records.
record.status = REC_NOT_FOUND;
while(1)
{
ClrWdt();
// For a faster read, read 512 bytes at a time and buffer it.
readBytes = FSfread((void *)&asciiBuffer[pointer],1,512,myFile);
if(readBytes == 0)
{
// Nothing to read. Come out of this loop
// break;
FSfclose(myFile);
// Something fishy. The hex file has ended abruptly, looks like there was no "end of hex record".
//Indicate error and stay in while loop.
Error();
while(1);
}
for(i = 0; i < (readBytes + pointer); i ++)
{
// This state machine seperates-out the valid hex records from the read 512 bytes.
switch(record.status)
{
case REC_FLASHED:
case REC_NOT_FOUND:
if(asciiBuffer[i] == ':')
{
// We have a record found in the 512 bytes of data in the buffer.
record.start = &asciiBuffer[i];
record.len = 0;
record.status = REC_FOUND_BUT_NOT_FLASHED;
}
break;
case REC_FOUND_BUT_NOT_FLASHED:
if((asciiBuffer[i] == 0x0A) || (asciiBuffer[i] == 0xFF))
{
// We have got a complete record. (0x0A is new line feed and 0xFF is End of file)
// Start the hex conversion from element
// 1. This will discard the ':' which is
// the start of the hex record.
ConvertAsciiToHex(&record.start[1],hexRec);
WriteHexRecord2Flash(hexRec);
record.status = REC_FLASHED;
}
break;
}
// Move to next byte in the buffer.
record.len ++;
}
if(record.status == REC_FOUND_BUT_NOT_FLASHED)
{
// We still have a half read record in the buffer. The next half part of the record is read
// when we read 512 bytes of data from the next file read.
memcpy(asciiBuffer, record.start, record.len);
pointer = record.len;
record.status = REC_NOT_FOUND;
}
else
{
pointer = 0;
}
// Blink LED at Faster rate to indicate programming is in progress.
led += 3;
mLED = ((led & 0x80) == 0);
}//while(1)
return 0;
}
If I remember well (very long time ago I used PIC32) you can add into your linker script:
MEMORY
{
//... other stuff
signature (RX) : ORIGIN = 0x9FC02FEC, length 0x4
}
then
SECTIONS
{
.signature_section:
{
BYTE(0x3b);
BYTE(0xdf);
BYTE(0xed);
BYTE(0x92);
}>signature
}
Googling around I also found out, that you could do that in your source code, I hope...
const int __attribute__((space(prog), address(0x9FC02FEC))) signature = 0x3bdfed92;
In my program I use an attribute to place a certain value at a certain location in memory space. My bootloader and App can read this location. This may be a simpler way for you to do this. This is using xc16 and a smaller part but I've done it on a PIC32 as well.
#define CHECK_SUM 0x45FB
#define CH_HIGH ((CHECK_SUM & 0xFF00) >> 8)
#define CH_LOW ((CHECK_SUM & 0x00FF) >> 0)
const char __attribute__((space(prog), address(APP_CS_LOC))) CHKSUM[2] = {CH_LOW,CH_HIGH};
Just a note, when you read it, it will be in the right format: HIGH->LOW

Pragma and Interrupt Vector Table : TI MSP430

My program contains few global variables , whose values are set during the interrupt service routine (USCI_A0_ISR()) execution.
Once the execution of USCI_A0_ISR() is done , will the global variables hold the value assigned or will be set back to void/0.????
//Global variables
int ptr = 0;
char rxBuffer[16];
int flag = -1;
int check[2];
void __set_flag(void)
{
if (strcmp(rxBuffer,"OK") == 0) flag = 0;
else if (strcmp(rxBuffer,"CONNECT") == 0) flag = 1;
else if (strcmp(rxBuffer,"NO CARRIER") == 0) flag = 3;
else if (strcmp(rxBuffer,"ERROR") == 0) flag = 4;
}
void __GSM_client(void)
{
while (flag == -1);
if (flag == 0) check[0] = buflen(rxBuffer);
}
void main(void)
{
__Buffer_init();
__low_level_init(); //WDT
__UART0_init(); //UART
__bis_SR_register(GIE); //interrupts enabled
__delay_cycles(1000); // wait till UART intial
__GSM_client();
__no_operation(); // For debugger
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
char byte;
while (!(UCA0IFG&UCTXIFG));
byte= UCA0RXBUF;
UCA0TXBUF = byte;
if (byte == '\r') {
//push_char(byte);
ptr = 0;
__set_flag();
//__Buffer_init();
}
else{
push_char(byte);
}
}
Here is the code snippet of what I am doing. I am setting the "flag" based on the response obtained . When I see the register view in Code Composer Studio , the "flag" value is set correctly , but if try using the value of "flag" elsewhere the value of "flag " is not reflected.
Any pointers over concepts of the interrupt service routine or when loopholes in my coding method appreciated
Thanks in Advance
AK
Within the interrupt, you are directly or indirectly changing several global variables, e.g. ptr, flag, and I'm assuming rxBuffer[?]. They are not declared "volatile" so their value may or may not change when you return from the interrupt. This is a bug because the behavior can change based on where in the execution of the code the interrupt occurs and what the level of optimization is. As a rule of thumb, any variable modified by an interrupt routine should always be declared volatile.
If you're sure that making the shared variables volatile isn't working then I'd suspect you have redefined a global variable as a local variable somewhere. Check the address of the flag variable when you are debugging and make sure it is the same in __set_flag() and outwith the interrupt, where you think it has not been updated.
I also think that the polling loop in your ISR is poor code and you should find a better way to wait for the transmitter to be ready for the next character.
Thanks to all the feedback i got from the members. Well the idea of declaring all the "variables volatile" did the trick . strcmp() uses const var* so i couldn't use it . I had to write my own custom string compare function. All this minor things solved my problems.

Resources