STM32L052 - weird crash
Posted: Mon Jul 11, 2016 3:37 pm
Hello.
I'm trying to run ChibiOS on custom board based on STM32L052K8 chip.
For start, i'm trying to run this code, based on RT-STM32L053R8-NUCLEO demo:
And I've faced problem even with this example. MCU "crashes" on chThdSleepMilliseconds either in main thread or blinker thread. Moreover, crash looks quite weird. MCU is falling into system memory, and starting code from address 0x1FF0xxxx o_O.
To get trace, I've used gdb script:
And here's most interesting part of crash (whole trace - http://pastebin.com/fvhX5cBw):
As you can see, mcu accidentaly jumps to 0x60412106 (WTF?! according to RM, 0x6xxxxxxx - External RAM / FSMC).
Also I've tried to debug in Eclipse, and noticed, that jump occurs right after "cpsie i" instruction in _port_thread_start (os/rt/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s:95), so, maybe some interrupt occurs and IRQ table is broken?
I'm trying to run ChibiOS on custom board based on STM32L052K8 chip.
For start, i'm trying to run this code, based on RT-STM32L053R8-NUCLEO demo:
Code: Select all
#include "ch.h"
#include "hal.h"
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
(void)arg;
chRegSetThreadName("blinker");
while (true) {
palClearPad(GPIOA, GPIOA_LED_GREEN);
chThdSleepMilliseconds(500);
palSetPad(GPIOA, GPIOA_LED_GREEN);
chThdSleepMilliseconds(500);
}
}
int main(void) {
halInit();
chSysInit();
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
while (true) {
chThdSleepMilliseconds(500);
}
}
And I've faced problem even with this example. MCU "crashes" on chThdSleepMilliseconds either in main thread or blinker thread. Moreover, crash looks quite weird. MCU is falling into system memory, and starting code from address 0x1FF0xxxx o_O.
To get trace, I've used gdb script:
Code: Select all
set $i=0
target remote localhost:4242
monitor reset halt
load
break Reset_Handler
continue
while ($i<100000)
si
set $i = $i + 1
end
quit
And here's most interesting part of crash (whole trace - http://pastebin.com/fvhX5cBw):
Code: Select all
Thread1 (arg=0x0) at main.c:5
5 static THD_FUNCTION(Thread1, arg) {
0x080001f2 5 static THD_FUNCTION(Thread1, arg) {
0x080001f4 5 static THD_FUNCTION(Thread1, arg) {
8 chRegSetThreadName("blinker");
0x080001f8 8 chRegSetThreadName("blinker");
0x080001fa 8 chRegSetThreadName("blinker");
chRegSetThreadName (name=0x80001f1 <Thread1> "\265\203\260\001\220\vK\030") at ../../../os/rt/include/chregistry.h:132
132 static inline void chRegSetThreadName(const char *name) {
0x080001d2 132 static inline void chRegSetThreadName(const char *name) {
135 ch.rlist.r_current->p_name = name;
0x080001d6 135 ch.rlist.r_current->p_name = name;
0x080001d8 135 ch.rlist.r_current->p_name = name;
0x080001da 135 ch.rlist.r_current->p_name = name;
139 }
0x080001de in chRegSetThreadName (name=0x0) at ../../../os/rt/include/chregistry.h:139
139 }
Thread1 (arg=0x0) at main.c:10
10 palClearPad(GPIOA, GPIOA_LED_GREEN);
0x08000200 10 palClearPad(GPIOA, GPIOA_LED_GREEN);
0x08000202 10 palClearPad(GPIOA, GPIOA_LED_GREEN);
0x08000204 10 palClearPad(GPIOA, GPIOA_LED_GREEN);
11 chThdSleepMilliseconds(500);
0x08000208 11 chThdSleepMilliseconds(500);
0x0800020a 11 chThdSleepMilliseconds(500);
0x0800020c 11 chThdSleepMilliseconds(500);
chThdSleep (time=0) at ../../../os/rt/src/chthreads.c:311
311 void chThdSleep(systime_t time) {
0x080016f2 311 void chThdSleep(systime_t time) {
0x080016f4 311 void chThdSleep(systime_t time) {
0x080016f6 311 void chThdSleep(systime_t time) {
0x080016f8 311 void chThdSleep(systime_t time) {
0x080016fa 311 void chThdSleep(systime_t time) {
313 chSysLock();
chSysLock () at ../../../os/rt/include/chsys.h:346
346 static inline void chSysLock(void) {
348 port_lock();
__disable_irq () at ../../../os/ext/CMSIS/include/core_cmFunc.h:344
344 __ASM volatile ("cpsid i" : : : "memory");
port_lock () at ../../../os/rt/ports/ARMCMx/chcore_v6m.h:333
333 }
chSysLock () at ../../../os/rt/include/chsys.h:351
351 }
chThdSleep (time=500) at ../../../os/rt/src/chthreads.c:314
314 chThdSleepS(time);
0x08001702 314 chThdSleepS(time);
0x08001704 314 chThdSleepS(time);
0x08001706 314 chThdSleepS(time);
0x08001708 314 chThdSleepS(time);
chThdSleepS (time=0) at ../../../os/rt/include/chthreads.h:264
264 static inline void chThdSleepS(systime_t time) {
0x080015c2 264 static inline void chThdSleepS(systime_t time) {
0x080015c4 264 static inline void chThdSleepS(systime_t time) {
0x080015c6 264 static inline void chThdSleepS(systime_t time) {
0x080015c8 264 static inline void chThdSleepS(systime_t time) {
0x080015ca 264 static inline void chThdSleepS(systime_t time) {
268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
0x080015ce 268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
0x080015d0 268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
0x080015d2 268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
0x080015d4 268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
0x080015d6 268 (void) chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time);
chSchGoSleepTimeoutS (newstate=0 '\000', time=0) at ../../../os/rt/src/chschd.c:330
330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x08001382 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x08001384 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x08001386 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x08001388 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x0800138a 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x0800138c 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x0800138e 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
0x08001390 330 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
334 if (TIME_INFINITE != time) {
0x08001394 334 if (TIME_INFINITE != time) {
0x08001396 334 if (TIME_INFINITE != time) {
0x08001398 334 if (TIME_INFINITE != time) {
0x0800139a 334 if (TIME_INFINITE != time) {
337 chVTDoSetI(&vt, time, wakeup, currp);
0x0800139e 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013a0 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013a2 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013a4 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013a6 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013a8 337 chVTDoSetI(&vt, time, wakeup, currp);
0x080013aa 337 chVTDoSetI(&vt, time, wakeup, currp);
chVTDoSetI (vtp=0x0, delay=0, vtfunc=0x0, par=0x0) at ../../../os/rt/src/chvt.c:96
96 vtfunc_t vtfunc, void *par) {
0x08000f02 96 vtfunc_t vtfunc, void *par) {
0x08000f04 96 vtfunc_t vtfunc, void *par) {
0x08000f06 96 vtfunc_t vtfunc, void *par) {
0x08000f08 96 vtfunc_t vtfunc, void *par) {
0x08000f0a 96 vtfunc_t vtfunc, void *par) {
0x08000f0c 96 vtfunc_t vtfunc, void *par) {
0x08000f0e 96 vtfunc_t vtfunc, void *par) {
0x08000f10 96 vtfunc_t vtfunc, void *par) {
103 vtp->vt_par = par;
0x08000f14 103 vtp->vt_par = par;
0x08000f16 103 vtp->vt_par = par;
104 vtp->vt_func = vtfunc;
0x08000f1a 104 vtp->vt_func = vtfunc;
0x08000f1c 104 vtp->vt_func = vtfunc;
108 systime_t now = chVTGetSystemTimeX();
0x08000f20 108 systime_t now = chVTGetSystemTimeX();
chVTGetSystemTimeX () at ../../../os/rt/include/chvt.h:228
228 static inline systime_t chVTGetSystemTimeX(void) {
233 return port_timer_get_time();
port_timer_get_time () at ../../../os/rt/ports/ARMCMx/chcore_timer.h:105
105 static inline systime_t port_timer_get_time(void) {
107 return stGetCounter();
st_lld_get_counter () at ../../../os/hal/ports/STM32/LLD/TIMv1/st_lld.h:141
141 return (systime_t)STM32_ST_TIM->CNT;
0x08000e52 141 return (systime_t)STM32_ST_TIM->CNT;
0x08000e54 141 return (systime_t)STM32_ST_TIM->CNT;
142 }
0x08000e58 142 }
0x08000eb6 in port_timer_get_time () at ../../../os/rt/ports/ARMCMx/chcore_timer.h:107
107 return stGetCounter();
108 }
0x08000eba 108 }
0x08000ec6 in chVTGetSystemTimeX () at ../../../os/rt/include/chvt.h:233
233 return port_timer_get_time();
235 }
0x08000eca 235 }
0x08000f24 in chVTDoSetI (vtp=0x2000086c <waThread1+252>, delay=500, vtfunc=0x8001321 <wakeup>, par=0x20000770 <waThread1>) at ../../../os/rt/src/chvt.c:108
108 systime_t now = chVTGetSystemTimeX();
0x08000f26 108 systime_t now = chVTGetSystemTimeX();
112 if (delay < (systime_t)CH_CFG_ST_TIMEDELTA) {
0x08000f2a 112 if (delay < (systime_t)CH_CFG_ST_TIMEDELTA) {
0x08000f2c 112 if (delay < (systime_t)CH_CFG_ST_TIMEDELTA) {
0x08000f2e 112 if (delay < (systime_t)CH_CFG_ST_TIMEDELTA) {
0x08000f30 112 if (delay < (systime_t)CH_CFG_ST_TIMEDELTA) {
117 if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
0x08000f3c 117 if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
0x08000f3e 117 if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
0x08000f40 117 if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
0x08000f42 117 if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f86 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f88 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f8a 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f8c 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f8e 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f90 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f92 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f94 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f96 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f98 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f9a 136 delta = now + delay - ch.vtlist.vt_lasttime;
0x08000f9c 136 delta = now + delay - ch.vtlist.vt_lasttime;
137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fa0 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fa2 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fa4 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fa6 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fa8 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000faa 137 if (delta < ch.vtlist.vt_next->vt_delta) {
0x08000fac 137 if (delta < ch.vtlist.vt_next->vt_delta) {
150 p = ch.vtlist.vt_next;
0x08000fc4 150 p = ch.vtlist.vt_next;
0x08000fc6 150 p = ch.vtlist.vt_next;
0x08000fc8 150 p = ch.vtlist.vt_next;
151 while (p->vt_delta < delta) {
0x08000fe4 151 while (p->vt_delta < delta) {
0x08000fe6 151 while (p->vt_delta < delta) {
0x08000fe8 151 while (p->vt_delta < delta) {
0x08000fea 151 while (p->vt_delta < delta) {
0x08000fec 151 while (p->vt_delta < delta) {
0x08000fee 151 while (p->vt_delta < delta) {
152 delta -= p->vt_delta;
0x08000fcc 152 delta -= p->vt_delta;
0x08000fce 152 delta -= p->vt_delta;
0x08000fd0 152 delta -= p->vt_delta;
0x08000fd2 152 delta -= p->vt_delta;
0x08000fd4 152 delta -= p->vt_delta;
0x08000fd6 152 delta -= p->vt_delta;
0x08000fd8 152 delta -= p->vt_delta;
0x08000fda 152 delta -= p->vt_delta;
153 p = p->vt_next;
0x08000fde 153 p = p->vt_next;
0x08000fe0 153 p = p->vt_next;
151 while (p->vt_delta < delta) {
0x08000fe4 151 while (p->vt_delta < delta) {
0x08000fe6 151 while (p->vt_delta < delta) {
0x08000fe8 151 while (p->vt_delta < delta) {
0x08000fea 151 while (p->vt_delta < delta) {
0x08000fec 151 while (p->vt_delta < delta) {
0x08000fee 151 while (p->vt_delta < delta) {
157 vtp->vt_next = p;
0x08000ff2 157 vtp->vt_next = p;
0x08000ff4 157 vtp->vt_next = p;
158 vtp->vt_prev = vtp->vt_next->vt_prev;
0x08000ff8 158 vtp->vt_prev = vtp->vt_next->vt_prev;
0x08000ffa 158 vtp->vt_prev = vtp->vt_next->vt_prev;
0x08000ffc 158 vtp->vt_prev = vtp->vt_next->vt_prev;
0x08000ffe 158 vtp->vt_prev = vtp->vt_next->vt_prev;
159 vtp->vt_prev->vt_next = vtp;
0x08001002 159 vtp->vt_prev->vt_next = vtp;
0x08001004 159 vtp->vt_prev->vt_next = vtp;
0x08001006 159 vtp->vt_prev->vt_next = vtp;
160 p->vt_prev = vtp;
0x0800100a 160 p->vt_prev = vtp;
0x0800100c 160 p->vt_prev = vtp;
161 vtp->vt_delta = delta
0x08001010 161 vtp->vt_delta = delta
0x08001012 161 vtp->vt_delta = delta
0x08001014 161 vtp->vt_delta = delta
0x08001016 161 vtp->vt_delta = delta
165 p->vt_delta -= delta;
0x0800101a 165 p->vt_delta -= delta;
0x0800101c 165 p->vt_delta -= delta;
0x0800101e 165 p->vt_delta -= delta;
0x08001020 165 p->vt_delta -= delta;
0x08001022 165 p->vt_delta -= delta;
0x08001024 165 p->vt_delta -= delta;
0x08001026 165 p->vt_delta -= delta;
0x08001028 165 p->vt_delta -= delta;
166 ch.vtlist.vt_delta = (systime_t)-1;
0x0800102c 166 ch.vtlist.vt_delta = (systime_t)-1;
0x0800102e 166 ch.vtlist.vt_delta = (systime_t)-1;
0x08001030 166 ch.vtlist.vt_delta = (systime_t)-1;
167 }
0x08001034 in chVTDoSetI (vtp=0x80001f4 <Thread1+4>, delay=0, vtfunc=0x80013af <chSchGoSleepTimeoutS+46>, par=0x20000770 <waThread1>) at ../../../os/rt/src/chvt.c:167
167 }
chSchGoSleepTimeoutS (newstate=8 '\b', time=500) at ../../../os/rt/src/chschd.c:338
338 chSchGoSleepS(newstate);
0x080013b0 338 chSchGoSleepS(newstate);
0x080013b2 338 chSchGoSleepS(newstate);
0x080013b4 338 chSchGoSleepS(newstate);
0x080013b6 338 chSchGoSleepS(newstate);
chSchGoSleepS (newstate=32 ' ') at ../../../os/rt/src/chschd.c:250
250 void chSchGoSleepS(tstate_t newstate) {
0x080012d2 250 void chSchGoSleepS(tstate_t newstate) {
0x080012d4 250 void chSchGoSleepS(tstate_t newstate) {
0x080012d6 250 void chSchGoSleepS(tstate_t newstate) {
0x080012d8 250 void chSchGoSleepS(tstate_t newstate) {
0x080012da 250 void chSchGoSleepS(tstate_t newstate) {
255 otp = currp;
0x080012de 255 otp = currp;
0x080012e0 255 otp = currp;
256 otp->p_state = newstate;
0x080012e4 256 otp->p_state = newstate;
0x080012e6 256 otp->p_state = newstate;
0x080012e8 256 otp->p_state = newstate;
0x080012ea 256 otp->p_state = newstate;
262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
0x080012ee 262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
0x080012f0 262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
queue_fifo_remove (tqp=0x8000f25 <chVTDoSetI+36>) at ../../../os/rt/include/chschd.h:671
671 static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
0x080011a2 671 static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
672 thread_t *tp = tqp->p_next;
0x080011a6 672 thread_t *tp = tqp->p_next;
0x080011a8 672 thread_t *tp = tqp->p_next;
674 tqp->p_next = tp->p_next;
0x080011ac 674 tqp->p_next = tp->p_next;
0x080011ae 674 tqp->p_next = tp->p_next;
0x080011b0 674 tqp->p_next = tp->p_next;
675 tqp->p_next->p_prev = (thread_t *)tqp;
0x080011b4 675 tqp->p_next->p_prev = (thread_t *)tqp;
0x080011b6 675 tqp->p_next->p_prev = (thread_t *)tqp;
0x080011b8 675 tqp->p_next->p_prev = (thread_t *)tqp;
677 return tp;
678 }
0x080011be 678 }
0x080011c0 in queue_fifo_remove (tqp=0x800086c) at ../../../os/rt/include/chschd.h:678
678 }
0x080012f4 in chSchGoSleepS (newstate=8 '\b') at ../../../os/rt/src/chschd.c:262
262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
0x080012f6 262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
0x080012f8 262 setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
268 currp->p_state = CH_STATE_CURRENT;
0x080012fc 268 currp->p_state = CH_STATE_CURRENT;
0x080012fe 268 currp->p_state = CH_STATE_CURRENT;
0x08001300 268 currp->p_state = CH_STATE_CURRENT;
269 chSysSwitch(currp, otp);
0x08001304 269 chSysSwitch(currp, otp);
0x08001306 269 chSysSwitch(currp, otp);
0x08001308 269 chSysSwitch(currp, otp);
0x0800130a 269 chSysSwitch(currp, otp);
0x0800130c 269 chSysSwitch(currp, otp);
0x08000190 in _port_switch ()
0x08000192 in _port_switch ()
0x08000194 in _port_switch ()
0x08000196 in _port_switch ()
0x08000198 in _port_switch ()
0x0800019a in _port_switch ()
0x0800019c in _port_switch ()
0x0800019e in _port_switch ()
0x080001a0 in _port_switch ()
0x080001a2 in _port_switch ()
0x080001a4 in _port_switch ()
0x080001a6 in _port_switch ()
0x080001a8 in _port_switch ()
0x080001aa in _port_switch ()
0x080001ac in _port_switch ()
0x080001ae in _port_switch ()
0x080001b0 in _port_thread_start ()
0x60412106 in ?? ()
0x1ff00230 in ?? ()
As you can see, mcu accidentaly jumps to 0x60412106 (WTF?! according to RM, 0x6xxxxxxx - External RAM / FSMC).
Also I've tried to debug in Eclipse, and noticed, that jump occurs right after "cpsie i" instruction in _port_thread_start (os/rt/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s:95), so, maybe some interrupt occurs and IRQ table is broken?