Strange Compiler Behavior

10 Apr 2014

void get_sample() {
    if (buffer_index < BUFFER_SIZE) {
        buffer[buffer_index] = (ain.read_u16() >> 8);
        buffer_index++;
    }
    else {
        led2 = 1;
        tick.detach();
    }
}

tick.attach_us(get_sample, sample_interval);
        while (1) {
            dout = !dout;
            if (buffer_index >= BUFFER_SIZE)
                break;
        }
        led3 = 1;

I'm seeing some weird behavior with the online mbed compiler. Above are two snippets of code. The first is a function named get_sample() that is called repeatedly by Ticker at a rate of 44.1kHz. The seconds is a section of the main function where get_sample() gets attached to Ticker and a while loops spins as it waits for a buffer to get filled.

The odd part is when I removed the line "dout = !dout;" from the second chunk of code, that while loop never breaks out. I know that in spite of this, the get_sample() function does fill up the buffer and subsequently detach itself from ticker. Why does this while loop need that useless line of code?

10 Apr 2014

First guess: buffer_index is not defined as volatile? It must be volatile, otherwise the compiler applies some optimisations because it does not know it can change in the interrupt. Volatile definition prevents this from happening.

That dout changes it is most likely that it simply applies different optimisations when that is present.