Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
problem child for msp430-gcc 4.6.3 with patches
/**
* signedtest.c - this fails to output int8_t values properly when optimized with -Os
*
* Compiled like this:
*
* $ msp430-gcc -mmcu=msp430g2553 -DF_CPU=16000000 -Os -Wall \
* -Wno-main -g -mdisable-watchdog -fdata-sections -ffunction-sections \
* -Wl,--gc-sections signedtest.c
*
* $ mspdebug rf2500 "prog a.out"
*
* compiling with -O1 produces proper output, as does changing the
* int8_t to volatile int8_t
*
*/
#include <msp430.h>
#include <stdint.h>
#include <stdlib.h>
/**
* serial output routines
*/
void printc(const char c) {
while(!(IFG2 & UCA0TXIFG));
IFG2 &= ~UCA0TXIFG;
UCA0TXBUF = c;
}
void prints(const char *s) {
while(*s)
printc(*s++);
}
void printi(int8_t i) {
char buff[8];
#if 1
if ( i < 0 ) {
printc('-');
i=-i;
}
utoa((i & 0xff),buff,10);
#else
itoa((int8_t)i,buff,10); /* also tried this, also failed */
#endif
prints(buff);
}
void printu(uint8_t i) {
char buff[8];
utoa((i & 0xff),buff,10);
prints(buff);
}
void println() {
printc('\n');
}
static const uint32_t brd = (F_CPU + (9600 >> 1)) / 9600; // Bit rate divisor
int main(void) {
uint16_t indx;
#define BAD
#if defined(GOOD)
volatile int8_t i8; // test2 produces valid results
#elif defined(BAD)
int8_t i8; // broken for test2 unless marked volatile or you use -O1
#endif
uint8_t u8;
WDTCTL = WDTPW + WDTHOLD; // No watchdog reset
//
DCOCTL = 0; // Run at 16 MHz
BCSCTL1 = CALBC1_16MHZ; //
DCOCTL = CALDCO_16MHZ; //
//P1DIR |= BIT0 | BIT4; P1SEL |= BIT4;
// GPIO Configuration ; // Set alternate function I/O for UART & SPI
P1SEL |= BIT2; // UART P1.2(tx)
P1SEL2 |= BIT2;
// Serial Config
UCA0CTL1 = UCSWRST; // Hold USCI in reset to allow configuration
UCA0CTL0 = 0; // No parity, LSB first, 8 bits, one stop bit, UART (async)
UCA0BR1 = (brd >> 12) & 0xFF; // High byte of whole divisor
UCA0BR0 = (brd >> 4) & 0xFF; // Low byte of whole divisor
UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16; // Fractional divisor, oversampling mode
UCA0CTL1 = UCSSEL_2; // Use SMCLK for bit rate generator, release reset
prints("-test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary rollover\n RESULTS: always succeeds\n");
i8=125; u8=125;
for(indx=0; indx < 5; indx++, i8++, u8++) {
printi(i8);
prints(", ");
printu(u8);
println();
}
prints("-test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary rollover\n RESULTS: fails unless volatile\n");
i8=126; u8=126;
for(indx=0; indx < 4; indx++, i8++, u8++) {
printi(i8);
prints(", ");
printu(u8);
println();
}
prints("-test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary rollover\n RESULTS: always ok\n");
i8=127; u8=127;
for(indx=0; indx < 3; indx++, i8++, u8++) {
printi(i8);
prints(", ");
printu(u8);
println();
}
while(1);
}
#if 0
>>> Bad results when int8_t not volatile
-test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary rollover
RESULTS: always succeeds
125, 125
126, 126
127, 127
-128, 128
-127, 129
-test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary rollover
RESULTS: fails unless volatile
126, 126
127, 127
127, 128 << fail this is the wrong result
127, 129 << fail this is the wrong result
-test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary rollover
RESULTS: always ok
127, 127
-128, 128
-127, 129
>>> Good results when using volatile int8_t
-test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary rollover
RESULTS: always succeeds
125, 125
126, 126
127, 127
-128, 128
-127, 129
-test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary rollover
RESULTS: fails unless volatile
126, 126
127, 127
-128, 128
-127, 129
-test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary rollover
RESULTS: always ok
127, 127
-128, 128
-127, 129
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.