Variables randomly changing, extremely odd behavior

587 Views Asked by At

I am experiencing extremely bizarre behavior where variables are randomly changing.

I have distilled it to the simplest example, encoder_1_position and encoder_2_position get updated with randomly values inside the NVIC_SetPriority(UART_IRQn,2); function. I have reordered declarations of the global variables in the file and I noticed it makes a difference as to what/if garbage gets added to them. I since disabled "remove unused sections" in the linker command and it seemed to fix the problem(apparently the BSS section was being tossed out) but I don't understand why particularly since every global variable I have is declared with volatile.

Reducing the buffer size from 1000 to 100 seems to correct the random change to the encoder variables, but I'm not confident it's an actual fix nor should it be required. The SAM3X8E has 65kbytes of ram - the stack shouldn't overflow regardless.

#include "sam.h"

#define HEAP_SIZE 0x500
#define STACK_SIZE 0x3500

int encoder_1_position = 0;
int encoder_2_position = 0;

void IntializeWatchdogTimer(void)
{
    // disable watchdog timer
    WDT->WDT_MR =  WDT_MR_WDDIS;
}

void InitializeUart(void)
{
    PMC->PMC_PCER0 = PMC_PCER0_PID8;// ID_UART 8
    // baud rate is 84Mhz/(16*45) = 116667
    UART->UART_BRGR = uint32_t(45);
    // set to no parity
    UART->UART_MR = UART_MR_PAR_NO;
    // Enable transmit and receive
    UART->UART_CR = UART_CR_TXEN|UART_CR_RXEN;
    // Enable UART control of port A pin 8, 9
    PIOA->PIO_PDR = PIO_PER_P8|PIO_PER_P9;
    // Enable UART interrupt on RX RDY
    UART->UART_IER = UART_IER_RXRDY;
    
    // Set priority
    NVIC_SetPriority(UART_IRQn,2);
    NVIC_EnableIRQ(UART_IRQn);
}




int main(void)
{
    __disable_irq();
    IntializeWatchdogTimer();
    SystemInit();
    InitializeUart();
    __enable_irq();
    /* Initialize the SAM system */
    
    //char* RX_message;
    char TX_message[1000];
    
    while (true)
    {
        int a = encoder_1_position;
        int b = encoder_2_position;
    }

}

readelf output:

Elf file type is EXEC (Executable file)
Entry point 0x80000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00080000 0x00080000 0x02a58 0x02a58 R E 0x10000
  LOAD           0x020000 0x20000000 0x00082a58 0x001d4 0x00808 RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text
   01     .relocate .bss .stack .heap
1

There are 1 best solutions below

1
On

I since disabled "remove unused sections" in the linker command and it seemed to fix the problem(apparently the BSS section was being tossed out)

This is just a guess, but that could mean that your program loader is not processing the BSS section correctly. It is supposed to allocate and zero the memory region the linker assigned to the BSS, even if there are no bits to copy from the executable image to that range. (It's a little more complicated than that, but unless you are stuck writing the loader yourself, that should give you enough of an idea.)

but I don't understand why particularly since every global variable I have is declared with volatile.

volatile doesn't do what you think it does. (More detail.)