简体   繁体   中英

Variables randomly changing, extremely odd behavior

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 __enable_irq 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.

I'm about ready to break something.

#include "sam.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "math.h"

#define HEAP_SIZE 0x500
#define STACK_SIZE 0x2500

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);
}


#define RX_buffer_size 1000
#define TX_buffer_size 1000

volatile char UART_rx_buffer[RX_buffer_size];
volatile int UART_rx_buffer_load_index = 0;
volatile int UART_rx_buffer_read_index = RX_buffer_size-1;
volatile int message_ready = 0;

volatile char UART_tx_buffer[TX_buffer_size];
volatile int UART_tx_buffer_load_index = 0;
volatile int UART_tx_buffer_sent_index = TX_buffer_size-1;

volatile int encoder_1_position = 0;
volatile int encoder_2_position = 0;





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

}

To provide concrete example of what is happening, we see one step changes encoder_1_position in debugger view

前 后

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 .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM