Hi.
I have a program for an MSP133. It works fine without optimizations (-O0), but
it crashes with optimization (-O1). Well it doesn't really crash, the machine
gets resetted. I narrowed down the location of the crash (by printf debugging,
because I have no debugger available). It looks like the problem has got to do
with a function pointer call.
Here's the relevant source code. The problematic line is marked XXXX.
It is called like this:
SpiSequence(SPI_DEV_FLASH, "wwr",
pCmd, sizeof(pCmd), // write command
(char*)0, 4, // 32 dummy bits
pBuf, nBuf); // read data
and the crash happens when SpiSequence processes the first "w".
Further down is the disassembly (with -O1).
Thanks for helping!
Heiko
typedef void (*spicb)(unsigned char* tmpbuf, int idx, void* userdata);
//------------------------------------------------------------------------------
static void _dummycb(unsigned char* tmpbuf, int idx, void* userdata)
{
// printf("Dummy callback!\n\r");
}
//------------------------------------------------------------------------------
int SpiSequence(int device, char* fmt, ...)
{ unsigned long i;
unsigned char tmp;
va_list ap;
char* pBuf= 0;
unsigned long nBuf= 0;
spicb cb= _dummycb;
void* userdata=0;
if(!SpiLock()) return 1;
//----- start sequence, assert chip select
SpiByte(device, SPI_DONT_CARE, 0);
va_start(ap, fmt);
while (*fmt) {
switch(*fmt) {
//----- transmit buffer, exec callback *before* every byte
case 'w':
pBuf= va_arg(ap, char*);
nBuf= va_arg(ap, int);
for (i= 0; i< nBuf; i++) {
if (pBuf) tmp= pBuf[i];
else tmp= 0x00;
XXXX cb(&tmp, i, userdata);
SpiByte(device, tmp, 0);
}
cb= _dummycb; // clear callback after
transaction
nBuf= 0; // clear nBuf MSBs!
break;
0000f112 <_dummycb>:
//------------------------------------------------------------------------------
static void _dummycb(unsigned char* tmpbuf, int idx, void* userdata)
{
// printf("Dummy callback!\n\r");
}
f112: 30 41 ret
f114: 53 70 .word 0x7053; ????
f116: 69 53 incd.b r9 ;
f118: 65 71 subc.b @r1, r5 ;
f11a: 75 65 addc.b @r5+, r5 ;
f11c: 6e 63 addc.b #2, r14 ;r3 As==10
f11e: 65 28 jnc $+204 ;abs 0xf1ea
f120: 29 20 jnz $+84 ;abs 0xf174
f122: 75 6e addc.b @r14+, r5 ;
f124: 73 65 .word 0x6573; ????
f126: 6c 65 addc.b @r5, r12 ;
f128: 63 74 .word 0x7463; ????
f12a: 20 53 incd r0 ;
f12c: 50 49 0a 0d br 3338(r9) ;
f130: 00 53 add #0, r0 ;r3 As==00
f132: 70 69 addc.b @r9+, r0 ;
f134: 53 65 .word 0x6553; ????
f136: 71 75 subc.b @r5+, r1 ;
f138: 65 6e addc.b @r14, r5 ;
f13a: 63 65 .word 0x6563; ????
f13c: 28 29 jnc $+594 ;abs 0xf38e
f13e: 20 72 subc #4, r0 ;r2 As==10
f140: 65 6c addc.b @r12, r5 ;
f142: 65 61 addc.b @r1, r5 ;
f144: 73 65 .word 0x6573; ????
f146: 20 53 incd r0 ;
f148: 50 49 0a 0d br 3338(r9) ;
...
0000f14e <SpiSequence>:
//------------------------------------------------------------------------------
int SpiSequence(int device, char* fmt, ...)
{ unsigned long i;
f14e: 0b 12 push r11 ;
f150: 0a 12 push r10 ;
f152: 09 12 push r9 ;
f154: 08 12 push r8 ;
f156: 07 12 push r7 ;
f158: 06 12 push r6 ;
f15a: 05 12 push r5 ;
f15c: 04 12 push r4 ;
f15e: 31 80 06 00 sub #6, r1 ;#0x0006
f162: 3b 40 18 00 mov #24, r11 ;#0x0018
f166: 0b 51 add r1, r11 ;
f168: 24 4b mov @r11, r4 ;
f16a: 16 4b 02 00 mov 2(r11), r6 ;
unsigned char tmp;
va_list ap;
char* pBuf= 0;
unsigned long nBuf= 0;
f16e: 07 43 clr r7 ;
f170: 08 43 clr r8 ;
spicb cb= _dummycb;
f172: b1 40 12 f1 mov #-3822, 2(r1) ;#0xf112
f176: 02 00
void* userdata=0;
f178: 81 43 04 00 mov #0, 4(r1) ;r3 As==00
if(!SpiLock()) return 1;
f17c: b0 12 dc f3 call #-3108 ;#0xf3dc
f180: 0f 93 cmp #0, r15 ;r3 As==00
f182: 02 20 jnz $+6 ;abs 0xf188
f184: 1f 43 mov #1, r15 ;r3 As==01
f186: a0 3c jmp $+322 ;abs 0xf2c8
//printf("SpiSequence()\n\r");
//----- start sequence, assert chip select
SpiByte(device, SPI_DONT_CARE, 0);
f188: 0d 43 clr r13 ;
f18a: 4e 43 clr.b r14 ;
f18c: 0f 44 mov r4, r15 ;
f18e: b0 12 ec f2 call #-3348 ;#0xf2ec
//printf("SpiSequence() - got SPI\n\r");
va_start(ap, fmt);
f192: 09 4b mov r11, r9 ;
f194: 29 52 add #4, r9 ;r2 As==10
while (*fmt) {
f196: c6 93 00 00 cmp.b #0, 0(r6) ;r3 As==00
f19a: 85 24 jz $+268 ;abs 0xf2a6
//printf("SpiSequence() process format '%c'\n\r", *fmt);
switch(*fmt) {
f19c: 6f 46 mov.b @r6, r15 ;
f19e: 8f 11 sxt r15 ;
f1a0: 3f 90 63 00 cmp #99, r15 ;#0x0063
f1a4: 74 24 jz $+234 ;abs 0xf28e
f1a6: 3f 90 64 00 cmp #100, r15 ;#0x0064
f1aa: 04 34 jge $+10 ;abs 0xf1b4
f1ac: 3f 90 52 00 cmp #82, r15 ;#0x0052
f1b0: 34 24 jz $+106 ;abs 0xf21a
f1b2: 75 3c jmp $+236 ;abs 0xf29e
f1b4: 3f 90 72 00 cmp #114, r15 ;#0x0072
f1b8: 3a 24 jz $+118 ;abs 0xf22e
f1ba: 3f 90 77 00 cmp #119, r15 ;#0x0077
f1be: 6f 20 jnz $+224 ;abs 0xf29e
//----- transmit buffer, exec callback *before* every byte
case 'w':
pBuf= va_arg(ap, char*);
f1c0: 0f 49 mov r9, r15 ;
f1c2: 29 53 incd r9 ;
f1c4: 25 4f mov @r15, r5 ;
nBuf= va_arg(ap, int);
f1c6: 0f 49 mov r9, r15 ;
f1c8: 29 53 incd r9 ;
f1ca: 27 4f mov @r15, r7 ;
f1cc: 08 47 mov r7, r8 ;
f1ce: 08 58 rla r8 ;
f1d0: 08 78 subc r8, r8 ;
f1d2: 38 e3 inv r8 ;
for (i= 0; i< nBuf; i++) {
f1d4: 0a 43 clr r10 ;
f1d6: 0b 43 clr r11 ;
f1d8: 0e 43 clr r14 ;
f1da: 0f 43 clr r15 ;
f1dc: 0e 87 sub r7, r14 ;
f1de: 0f 78 subc r8, r15 ;
f1e0: 50 2c jc $+162 ;abs 0xf282
if (pBuf) tmp= pBuf[i];
f1e2: 05 93 cmp #0, r5 ;r3 As==00
f1e4: 05 24 jz $+12 ;abs 0xf1f0
f1e6: 0f 45 mov r5, r15 ;
f1e8: 0f 5a add r10, r15 ;
f1ea: e1 4f 00 00 mov.b @r15, 0(r1) ;
f1ee: 02 3c jmp $+6 ;abs 0xf1f4
else tmp= 0x00;
f1f0: c1 43 00 00 mov.b #0, 0(r1) ;r3 As==00
//printf("cb=%x\n\r", cb);
cb(&tmp, i, userdata);
f1f4: 1d 41 04 00 mov 4(r1), r13 ;
f1f8: 0e 4a mov r10, r14 ;
f1fa: 0f 41 mov r1, r15 ;
f1fc: 91 12 02 00 call 2(r1) ;
SpiByte(device, tmp, 0);
f200: 0d 43 clr r13 ;
f202: 6e 41 mov.b @r1, r14 ;
f204: 0f 44 mov r4, r15 ;
f206: b0 12 ec f2 call #-3348 ;#0xf2ec
f20a: 1a 53 inc r10 ;
f20c: 0b 63 adc r11 ;
f20e: 0e 4a mov r10, r14 ;
f210: 0f 4b mov r11, r15 ;
f212: 0e 87 sub r7, r14 ;
f214: 0f 78 subc r8, r15 ;
f216: e5 2b jnc $-52 ;abs 0xf1e2
}
cb= _dummycb; // clear callback after
transaction
nBuf= 0; // clear nBuf MSBs!
// printf("SpiSequence() 'w' finished\n\r");
break;
f218: 34 3c jmp $+106 ;abs 0xf282