Stuck after removing unused global variable

Hi, I modify the USB CDC example from Atmel for AVR32 (software pack): FreeRTOS + USB CDC and I add files for serial communication (also from software pack) and keyboard scan example. Everything worked just great. The ISR for keyboard is like: (only one change compare to original file = sendqueue; from global overview: I am trying to change using keypress value as global variable => to store each pressed key like item of queue => the same structure is used in FreeRTOS serial example from SW FRWK to store rx/tx chars) /* * EXT_INT_EXAMPLE_LINE3 interrupt service routine. */ #if __GNUC__     __attribute__((__naked__)) #elif __ICCAVR32__     #pragma shadow_registers = full   // Naked. #endif static void vEIC_int_handler3_ISR( void ) {     /* This ISR can cause a context switch, so the first statement must be a     call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any     variable declarations. */     portENTER_SWITCHING_ISR();     prvEIC_ISR_NonNakedBehaviour( EXT_INT_EXAMPLE_LINE3, 3 );     /* Exit the ISR.  If a task was woken by either a character being received     or transmitted then a context switch will occur. */     portEXIT_SWITCHING_ISR(); }    #if __GNUC__     __attribute__((__noinline__)) #elif __ICCAVR32__     #pragma optimize = no_inline #endif static portBASE_TYPE prvEIC_ISR_NonNakedBehaviour ( const unsigned int line_num, const unsigned int row_num) {     /* Now we can declare the local variables. */           //portBASE_TYPE key_number;           portBASE_TYPE xTaskWokenByKey = pdFALSE;           portBASE_TYPE retstatus;           portBASE_TYPE    line_number;           gpio_tgl_gpio_pin(AVR32_PIN_PA18);           line_number = eic_get_interrupt_pad_scan(&AVR32_EIC);           switch (line_number)           {           case SCAN_COL1_IDX :             key_number = 1;             break;           case SCAN_COL2_IDX :             key_number = 2;             break;           case SCAN_COL3_IDX :             key_number = 3;             break;           case SCAN_COL4_IDX :             key_number = 4;             break;           case SCAN_COL5_IDX :             key_number = 5;             break;           case SCAN_COL6_IDX :             key_number = 6;             break;           case SCAN_COL7_IDX :             key_number = 7;             break;              }           key_number=key_number+row_num*10;           eic_clear_interrupt_line(&AVR32_EIC, line_num);              /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS           calls in a critical section . */           portENTER_CRITICAL();             retstatus = xQueueSendFromISR(xKeyPressed, &key_number, pdFALSE);           portEXIT_CRITICAL();           if( retstatus )           {               xTaskWokenByKey = pdTRUE;           }         /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it         should perform a vTaskSwitchContext(). */         return xTaskWokenByKey; } Variable key_number is global, definition is in the beginning of file and it force to have some value (0). But if I change it to local, queuesendfromisr will not save value properly(nothing is stored to queue, however everything other is running ok) and after calling receive mcu stuck. If I not call Receive interrupt mcu execute without any problem. (But I can still use queuesend from different function and receive just work, but it doesnt get any characters from ISR) Second weird thing is that I am forced to create this global value and put some value in it in the beginning and also use it once in code wherevery I can! Thats it = no useful using in code, it just must be created, otherwise the mcu stuck in totally beginning before the code of keyboard routines go execute or keyboard ISR have chance to run. The stuck will not happen only if I am comment the line with inicialization of keypressed queue. If I do the comment than everything work, I could delete the global variable usage and its definition, but ofcourse I cant read any information about keypress, because the queue doesnt exist (send and receive are in comment too). Summary: key_number global – should be redundant, but still defined and once somewhere! used, otherwise I must comment inicialization of keyboard, especially queuecreate cmd variable in queuesendISR must be global otherwise the data is not put in queue THE PROBLEM SHOULD BE SOMEWHERE IN MEMORY STUFF. Do you know what is the relation between global variables and creating dynamic queue? I tried to change minimal stack size, size of usart queues and keypress queue (its just 3 chars) and I dont thing there is not enough memory. The rest of code which I dont publish is pretty much the same as original example. Hope u understand my issue.. HOW IT IS POSSIBLE THAT IT WORKS ONLY IF I USE THIS USELESS GLOBAL VARIABLE? SOMETIMES I CANT EVEN CHANGE ITS NAME! I tried clean project, delete debug.. portBASE_TYPE init_keyboard(void) {   /* Create the queue used to hold pressed keys. */   vprvKeyboardCreateQueue( KEYPRESSED_QUEUE_LENGHT, &xKeyPressed );   if( ( xKeyPressed == (xQueueHandle) 0 ) ) {       return 0;   }       // Enable edge-triggered interrupt.   eic_options[0].eic_mode  = EIC_MODE_EDGE_TRIGGERED;   // Interrupt will trigger on falling edge (this is a must-do for the keypad scan   // feature if the chosen mode is edge-triggered).   eic_options[0].eic_edge  = EIC_EDGE_FALLING_EDGE;   // Initialize in synchronous mode : interrupt is synchronized to the clock   eic_options[0].eic_async = EIC_SYNCH_MODE;   // Set the interrupt line number.   eic_options[0].eic_line  = EXT_INT_EXAMPLE_LINE1;   // Enable edge-triggered interrupt.   eic_options[1].eic_mode   = EIC_MODE_EDGE_TRIGGERED;   // Interrupt will trigger on falling edge (this is a must-do for the keypad scan   // feature if the chosen mode is edge-triggered).   eic_options[1].eic_edge  = EIC_EDGE_FALLING_EDGE;   // Initialize in synchronous mode : interrupt is synchronized to the clock   eic_options[1].eic_async  = EIC_SYNCH_MODE;   // Set the interrupt line number.   eic_options[1].eic_line   = EXT_INT_EXAMPLE_LINE2;   // Enable edge-triggered interrupt.   eic_options[2].eic_mode   = EIC_MODE_EDGE_TRIGGERED;   // Interrupt will trigger on falling edge (this is a must-do for the keypad scan   // feature if the chosen mode is edge-triggered).   eic_options[2].eic_edge  = EIC_EDGE_FALLING_EDGE;   // Initialize in synchronous mode : interrupt is synchronized to the clock   eic_options[2].eic_async  = EIC_SYNCH_MODE;   // Set the interrupt line number.   eic_options[2].eic_line   = EXT_INT_EXAMPLE_LINE3;   // Activate LED0 & LED1 & LED2 & LED3 pins in GPIO output mode and switch them off.   gpio_tgl_gpio_pin(AVR32_PIN_PA18);   // Map the interrupt lines to the GPIO pins with the right peripheral functions.   static const gpio_map_t EIC_GPIO_MAP =   {     {EXT_INT_EXAMPLE_PIN_LINE1, EXT_INT_EXAMPLE_FUNCTION_LINE1},     {EXT_INT_EXAMPLE_PIN_LINE2, EXT_INT_EXAMPLE_FUNCTION_LINE2},     {EXT_INT_EXAMPLE_PIN_LINE3, EXT_INT_EXAMPLE_FUNCTION_LINE3},     {EXT_SCAN_EXAMPLE_PIN_LINE1, EXT_SCAN_EXAMPLE_FUNCTION_LINE1},     {EXT_SCAN_EXAMPLE_PIN_LINE2, EXT_SCAN_EXAMPLE_FUNCTION_LINE2},     {EXT_SCAN_EXAMPLE_PIN_LINE3, EXT_SCAN_EXAMPLE_FUNCTION_LINE3},     {EXT_SCAN_EXAMPLE_PIN_LINE4, EXT_SCAN_EXAMPLE_FUNCTION_LINE4},     {EXT_SCAN_EXAMPLE_PIN_LINE5, EXT_SCAN_EXAMPLE_FUNCTION_LINE5},     {EXT_SCAN_EXAMPLE_PIN_LINE6, EXT_SCAN_EXAMPLE_FUNCTION_LINE6},     {EXT_SCAN_EXAMPLE_PIN_LINE7, EXT_SCAN_EXAMPLE_FUNCTION_LINE7}   };   gpio_enable_module(EIC_GPIO_MAP, sizeof(EIC_GPIO_MAP) / sizeof(EIC_GPIO_MAP[0]));   // Enable GPIO pullups for the rows.   gpio_enable_pin_pull_up(EXT_INT_EXAMPLE_PIN_LINE1);   gpio_enable_pin_pull_up(EXT_INT_EXAMPLE_PIN_LINE2);   gpio_enable_pin_pull_up(EXT_INT_EXAMPLE_PIN_LINE3);   // Disable all interrupts.   Disable_global_interrupt();   // Initialize interrupt vectors.   INTC_init_interrupts();   // Register the EIC interrupt handler to the interrupt controller.   // eic_int_handler1 and eic_int_handler2 are the interrupt handlers to register.   // EXT_INT_EXAMPLE_IRQ_LINE1 and EXT_INT_EXAMPLE_IRQ_LINE2 are the IRQ of the   // interrupt handlers to register.   // AVR32_INTC_INT0 is the interrupt priority level to assign to the group of this IRQ.   // void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_lev);     INTC_register_interrupt(&vEIC_int_handler1_ISR, EXT_INT_EXAMPLE_IRQ_LINE1, AVR32_INTC_INT2);   INTC_register_interrupt(&vEIC_int_handler2_ISR, EXT_INT_EXAMPLE_IRQ_LINE2, AVR32_INTC_INT2);   INTC_register_interrupt(&vEIC_int_handler3_ISR, EXT_INT_EXAMPLE_IRQ_LINE3, AVR32_INTC_INT2); /*  INTC_register_interrupt(&eic_int_handler1, EXT_INT_EXAMPLE_IRQ_LINE1, AVR32_INTC_INT0);   INTC_register_interrupt(&eic_int_handler2, EXT_INT_EXAMPLE_IRQ_LINE2, AVR32_INTC_INT0);   INTC_register_interrupt(&eic_int_handler3, EXT_INT_EXAMPLE_IRQ_LINE3, AVR32_INTC_INT0); */   // Init the EIC controller with the options   eic_init(&AVR32_EIC, eic_options, 3);   // Enable the EIC lines.   eic_enable_lines(&AVR32_EIC, (1<<eic_options[2].eic_line)|(1<<eic_options[1].eic_line)|(1<<eic_options[0].eic_line));   // Enable the interrupt for each EIC line.   eic_enable_interrupt_lines(&AVR32_EIC, (1<<eic_options[2].eic_line)|(1<<eic_options[1].eic_line)|(1<<eic_options[0].eic_line));   // Enable the keypad scanning feature and configure the scan rate to 18ms (== pow(2,(10+1))*RCOsc).   eic_enable_interrupt_scan(&AVR32_EIC,10);   // Enable all interrupts.   Enable_global_interrupt();   return 1; } /* * Create the keypress queue. */ static void vprvKeyboardCreateQueue(  unsigned portBASE_TYPE uxQueueLength, xQueueHandle *pxKeyPressed ) {     /* Create the queue used to hold keypressed characters. */     xQueueHandle xKeyPressQ = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );     /* Pass back a reference to the queue so the keyboard API file can     post/receive characters. */     *pxKeyPressed = xKeyPressQ; }

Stuck after removing unused global variable

There does not seem to be a logical explanation but if you are using FreeRTOS version 5 or higher then you need to change the call to xQueueSendFromISR() to use the new parameter format. You may also like to try a complete rebuild to ensure the compiler is doing the right thing.