Bug with GCC compiler (for STM32F030C6)
We encountered what appears to be a compiler bug as rewriting the code slightly by adding intermediate variables solved the issue.
Relevant code :
#define HT16K33_DISPLAY_NB_COLUMNS (8)
#define HT16K33_DISPLAY_NB_ROWS (16)
#define HT16K33_DISPLAY_NB_COLUMN_BYTES (HT16K33_DISPLAY_NB_ROWS/8)
class HT16K33_SevenSegment {
void writeASCII(const uint8_t ledPos, const char character);
private:
uint8_t screen[HT16K33_DISPLAY_NB_COLUMNS*HT16K33_DISPLAY_NB_COLUMN_BYTES];
}
const char AlphaNum[] = { /* ... list of bytes ... */ };
void
HT16K33_SevenSegment::writeASCII(const uint8_t ledPos, const char character) {
assert(ledPos<3);
assert(character<100);
#if 1
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES] = AlphaNum[character-'0'-7];
#else
{
int charIdx=character-'0'-7;
char charVal=AlphaNum[charIdx];
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES]=charVal;
}
#endif
}In the above extract, the code in the first leg of the preprocessor "if" does not work - "screen" does not get the correct data value. The evaluation of the right hand expression by the debugger shows "0x39" or 57, but the value that is actually written is 0x40 which is not in the AlphaNum table.
With the code in the "else" part, we do get the correct value.
I think that the cause can be detemined by examining the generated code:
Dysfunctionnal code with assembly:
/**
* Write a 1 ASCII Character from position 0.
*/
void
HT16K33_SevenSegment::writeASCII(const uint8_t ledPos, const char character) {
8003470: b580 push {r7, lr}
8003472: b082 sub sp, #8
8003474: af00 add r7, sp, #0
8003476: 6078 str r0, [r7, #4]
8003478: 0008 movs r0, r1
800347a: 0011 movs r1, r2
800347c: 1cfb adds r3, r7, #3
800347e: 1c02 adds r2, r0, #0
8003480: 701a strb r2, [r3, #0]
8003482: 1cbb adds r3, r7, #2
8003484: 1c0a adds r2, r1, #0
8003486: 701a strb r2, [r3, #0]
assert(ledPos<3);
8003488: 1cfb adds r3, r7, #3
800348a: 781b ldrb r3, [r3, #0]
800348c: 2b02 cmp r3, #2
800348e: d905 bls.n 800349c <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x2c>
8003490: 4b10 ldr r3, [pc, #64] ; (80034d4 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x64>)
8003492: 4a11 ldr r2, [pc, #68] ; (80034d8 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x68>)
8003494: 4811 ldr r0, [pc, #68] ; (80034dc <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x6c>)
8003496: 21e0 movs r1, #224 ; 0xe0
8003498: f001 f9fa bl 8004890 <__assert_func>
assert(character<100);
800349c: 1cbb adds r3, r7, #2
800349e: 781b ldrb r3, [r3, #0]
80034a0: 2b63 cmp r3, #99 ; 0x63
80034a2: d905 bls.n 80034b0 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x40>
80034a4: 4b0e ldr r3, [pc, #56] ; (80034e0 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x70>)
80034a6: 4a0c ldr r2, [pc, #48] ; (80034d8 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x68>)
80034a8: 480c ldr r0, [pc, #48] ; (80034dc <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x6c>)
80034aa: 21e1 movs r1, #225 ; 0xe1
80034ac: f001 f9f0 bl 8004890 <__assert_func>
#if 1
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES] = AlphaNum[character-'0'-7];
80034b0: 1cbb adds r3, r7, #2
80034b2: 781b ldrb r3, [r3, #0]
80034b4: 3b37 subs r3, #55 ; 0x37
80034b6: 001a movs r2, r3
80034b8: 1cfb adds r3, r7, #3
80034ba: 781b ldrb r3, [r3, #0]
80034bc: 005b lsls r3, r3, #1
80034be: 4909 ldr r1, [pc, #36] ; (80034e4 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x74>)
80034c0: 5c89 ldrb r1, [r1, r2]
80034c2: 687a ldr r2, [r7, #4]
80034c4: 18d3 adds r3, r2, r3
80034c6: 1c0a adds r2, r1, #0
80034c8: 72da strb r2, [r3, #11]
int charIdx=character-'0'-7;
char charVal=AlphaNum[charIdx];
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES]=charVal;
}
#endif
}Working code with assembly:
/**
* Write a 1 ASCII Character from position 0.
*/
void
HT16K33_SevenSegment::writeASCII(const uint8_t ledPos, const char character) {
8003470: b580 push {r7, lr}
8003472: b084 sub sp, #16
8003474: af00 add r7, sp, #0
8003476: 6078 str r0, [r7, #4]
8003478: 0008 movs r0, r1
800347a: 0011 movs r1, r2
800347c: 1cfb adds r3, r7, #3
800347e: 1c02 adds r2, r0, #0
8003480: 701a strb r2, [r3, #0]
8003482: 1cbb adds r3, r7, #2
8003484: 1c0a adds r2, r1, #0
8003486: 701a strb r2, [r3, #0]
assert(ledPos<3);
8003488: 1cfb adds r3, r7, #3
800348a: 781b ldrb r3, [r3, #0]
800348c: 2b02 cmp r3, #2
800348e: d905 bls.n 800349c <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x2c>
8003490: 4b13 ldr r3, [pc, #76] ; (80034e0 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x70>)
8003492: 4a14 ldr r2, [pc, #80] ; (80034e4 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x74>)
8003494: 4814 ldr r0, [pc, #80] ; (80034e8 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x78>)
8003496: 21e0 movs r1, #224 ; 0xe0
8003498: f001 fa00 bl 800489c <__assert_func>
assert(character<100);
800349c: 1cbb adds r3, r7, #2
800349e: 781b ldrb r3, [r3, #0]
80034a0: 2b63 cmp r3, #99 ; 0x63
80034a2: d905 bls.n 80034b0 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x40>
80034a4: 4b11 ldr r3, [pc, #68] ; (80034ec <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x7c>)
80034a6: 4a0f ldr r2, [pc, #60] ; (80034e4 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x74>)
80034a8: 480f ldr r0, [pc, #60] ; (80034e8 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x78>)
80034aa: 21e1 movs r1, #225 ; 0xe1
80034ac: f001 f9f6 bl 800489c <__assert_func>
#if 0
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES] = AlphaNum[character-'0'-7];
#else
{
int charIdx=character-'0'-7;
80034b0: 1cbb adds r3, r7, #2
80034b2: 781b ldrb r3, [r3, #0]
80034b4: 3b37 subs r3, #55 ; 0x37
80034b6: 60fb str r3, [r7, #12]
char charVal=AlphaNum[charIdx];
80034b8: 200b movs r0, #11
80034ba: 183b adds r3, r7, r0
80034bc: 490c ldr r1, [pc, #48] ; (80034f0 <_ZN20HT16K33_SevenSegment10writeASCIIEhc+0x80>)
80034be: 68fa ldr r2, [r7, #12]
80034c0: 188a adds r2, r1, r2
80034c2: 7812 ldrb r2, [r2, #0]
80034c4: 701a strb r2, [r3, #0]
screen[ledPos*HT16K33_DISPLAY_NB_COLUMN_BYTES]=charVal;
80034c6: 1cfb adds r3, r7, #3
80034c8: 781b ldrb r3, [r3, #0]
80034ca: 005b lsls r3, r3, #1
80034cc: 687a ldr r2, [r7, #4]
80034ce: 18d3 adds r3, r2, r3
80034d0: 183a adds r2, r7, r0
80034d2: 7812 ldrb r2, [r2, #0]
80034d4: 72da strb r2, [r3, #11]
}
#endif
}Where should we report this?
We're using STMCubeIDE V1.0.2 and "com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610" for the compiler which comes with the IDE.