Raspberry Pi 3 bare metal: unexpected behaviour from arrays and switch statements

0

I currently have a simple program that sets up a framebuffer that can be written to.

I am encountering behaviour where values stored i arrays, once retrieved, come back as seemingly random values, with no relation to the originals. I have also noticed some similarly strange and.unexpected behaviour from switch statements - I suspect this has something to do with how both arrays and switch statements are statically allocated in memory.

As an example, here I have some code that should draw a hardcoded number, followed by 7 other hardcoded numbers that have been stored in an array:

unsigned int cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
drawNum(&display, 0x1234ABCD);
for (int i=0; i<7; i++)
  drawNum(&display, cols[i]);

The first drawNum() call with the hardcoded value works fine, but all of the calls with array accesses give seemingly random results.

Assigning the array values at runtime doesn't have this problem, like so:

unsigned int cols[7];
cols[0] = 0xFFFF0000;
cols[1] = 0xFFFF7F00;
cols[2] = 0xFFFFFF00;
cols[3] = 0xFF00FF00;
cols[4] = 0xFF0000FF;
cols[5] = 0xFF4B0082;
cols[6] = 0xFF9400D3;
drawNum(&display, 0x1234ABCD);
drawNum(&display, (int)cols);
for (int i=0; i<7; i++)
  drawNum(&display, cols[i]);

I've also experienced similarly unpredictable behaviour when returning values from switch statements.

I cannot say for sure, but this leads me to believe that this is a problem with the compiler or linker being used - I am using arm-none-eabi.

c
raspberry-pi
raspberry-pi3
asked on Stack Overflow Jun 16, 2019 by Nat Karmios

2 Answers

0

Just a shot in the dark, but you may want to try a different value in your array where the highest bit is 0 instead of 1 like in your hardcoded example.

unsigned int cols[7] = { 0x7FFF0000, 0x7FFF7F00, 0x7FFFFF00, 0x7F00FF00, 0x7F0000FF, 0x7F4B0082, 0x7F9400D3 };

This is assuming that drawNum takes an int instead of an unsigned int. You might just have a conversion problem. Without seeing what drawNum does it's hard to say.

answered on Stack Overflow Jun 17, 2019 by Adam VZ
0

And here my shot in the dark. You have a memory overwrite anywhere and this kills cols[]. If you move the variable from global scope to local scope the outcome varies. Add some 'detector' code:

volatile unsigned int cols[7] = { 0xFFFF0000, 0xFFFF7F00, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFF4B0082, 0xFF9400D3 };
drawNum(&display, 0x1234ABCD);

//test code
drawNum(&display, cols[0]==0xFFFF0000);    
drawNum(&display, cols[1]==0xFFFF7F00);

for (int i=0; i<7; i++)
  drawNum(&display, cols[i]);      

//test code
drawNum(&display, cols[0]==0xFFFF0000);    
drawNum(&display, cols[1]==0xFFFF7F00);

I added the volatile keyword to avoid optimizations by the compiler. It shouldn't mask away the observed wrong output.

answered on Stack Overflow Jun 20, 2019 by user5329483

User contributions licensed under CC BY-SA 3.0