Re: TinyOS timer issue when building with mspgcc4.7 with large memory model
Peter Bigot <[email protected]>
| Newsgroups | gmane.comp.hardware.texas-instruments.msp430.gcc.user |
|---|---|
| Message-ID | <CAPOJ94PkTf8dhPNJn-5PcwqbdBX74W3+hZreKDFdGtEoBdZqbA@mail.gmail.com> |
For TinyOS specific issues it'd be best to start by going through TinyOS support. If you can reduce the problem to a standalone C program and report it at the SF mspgcc tracker, it'll be looked at during the normal course of mspgcc maintenance. Peter On Fri, Apr 19, 2013 at 7:44 AM, Wim De Clercq <[email protected]> wrote: > Hello, > > I am building a TinyOS application using mspgcc 4.7.0 (20120911), with > large memory model / 20bit support. > I have experienced severe timer issues (wrong timers being set, causing > crashes in the end), which I could trace back to TinyOS library file > VirtualizeTimerC.nc. It looks to me like a mspgcc compiler bug. > I have no issues with my application when I build & run it with small > memory model options, with the same tool chain. > Here is the original piece of code in VirtualizeTimerC.nc that causes the > failure: > > task void updateFromTimer() > { > /* This code supports a maximum dt of MAXINT. If min_remaining and > remaining were switched to uint32_t, and the logic changed a > little, dt's up to 2^32-1 should work (but at a slightly higher > runtime cost). */ > uint32_t now = call TimerFrom.getNow(); > int32_t min_remaining = (1UL << 31) - 1; /* max int32_t */ > bool min_remaining_isset = FALSE; > uint16_t num; > > call TimerFrom.stop(); > > for (num=0; num<NUM_TIMERS; num++) > { > Timer_t* timer = &m_timers[num]; > > if (timer->isrunning) > { > uint32_t elapsed = now - timer->t0; > int32_t remaining = timer->dt - elapsed; > > if (remaining < min_remaining) > { > min_remaining = remaining; > min_remaining_isset = TRUE; > } > } > } > > if (min_remaining_isset) > { > if (min_remaining <= 0) > fireTimers(now); > else > call TimerFrom.startOneShotAt(now, min_remaining); > } > } > > The failure I saw is that the variable "now" got corrupted inside this > function. > The produced assembler code of this function is as follows: > > .L893: > calla #TransformCounterC__0__Counter__get > mov r14, r8 > mov r15, r9 > and #-17, &898 > mov #13, r14 > mov.b #0, r6 > mov #llo(2147483647), r10 > mov #lhi(2147483647), r11 > mov #0, r15 > .L959: > mov r15, r7 > rlam #1, r7 > mov r15, r13 > rlam #3, r13 > add r13, r7 > adda #VirtualizeTimerC__0__m_timers, r7 > bit.b #2, 8(r7) > jeq .L957 > mov r8, r12 > mov r9, r13 > sub @r7, r12 > subc 2(r7), r13 > mov 4+2(r7), r8 > mov 4(r7), r7 > sub r12, r7 > subc r13, r8 > mov r7, r12 > mov r8, r13 > cmp r11, r13 > jl .L1173 > jne .L957 > cmp r10, r7 > jhs .L957 > .L1173: > mov r12, r10 > mov r13, r11 > mov.b #1, r6 > .L957: > add #1, r15 > add #-1, r14 > jne .L959 > cmp.b #0, r6 > jne 1f > bra #.L884 > 1: > > cmp #0, r11 > jl .L1208 > cmp #1, r11 > jge .L960 > cmp #1, r10 > jhs .L960 > .L1208: > mov r8, r14 > mov r9, r15 > calla #VirtualizeTimerC__0__fireTimers > bra #.L884 > .L960: > ...more code... > > At label L893, the value of variable "now" is stored in registers r8 and > r9. > Later on, "now" is used as a parameter to call function fireTimers (label > L1208), by moving r8 and r9 to r14 and r15 respectively. > However, from the code in between, you can see that register r8 is > overwritten (and not restored afterwards), while "now" is nowhere changed > in the C-code. > > I managed to avoid the problem by changing statement: > > int32_t min_remaining = (1UL << 31) - 1; /* max int32_t */ > > to: > > volatile int32_t min_remaining = (1UL << 31) - 1; /* max int32_t */ > > so, just adding the "volatile" keyword. > Doing so, resulted in following assembler code: > > .L893: > calla #TransformCounterC__0__Counter__get > mov r14, r10 > mov r15, r11 > mov #llo(2147483647), -102(r4) > mov #lhi(2147483647), -102+2(r4) > and #-17, &898 > mov #13, r8 > mov.b #0, r7 > mov #0, r9 > .L959: > mov r9, r14 > rlam #1, r14 > mov r9, r15 > rlam #3, r15 > add r14, r15 > adda #VirtualizeTimerC__0__m_timers, r15 > bit.b #2, 8(r15) > jeq .L957 > mov r10, r12 > mov r11, r13 > sub @r15, r12 > subc 2(r15), r13 > mov 4(r15), r5 > mov 4+2(r15), r6 > sub r12, r5 > subc r13, r6 > mov r5, r12 > mov r6, r13 > mov -102(r4), r14 > mov -102+2(r4), r15 > cmp r15, r13 > jl .L1207 > cmp r13, r15 > jl .L957 > cmp r14, r5 > jhs .L957 > .L1207: > mov r12, -102(r4) > mov r13, -102+2(r4) > mov.b #1, r7 > .L957: > add #1, r9 > add #-1, r8 > jne .L959 > cmp.b #0, r7 > jne 1f > bra #.L884 > 1: > > mov -102(r4), r14 > mov -102+2(r4), r15 > cmp #0, r15 > jl .L1208 > cmp #1, r15 > jge .L960 > cmp #1, r14 > jhs .L960 > .L1208: > mov r10, r14 > mov r11, r15 > calla #VirtualizeTimerC__0__fireTimers > bra #.L884 > .L960: > ...more code... > > This time, at L893, the value of variable "now" is stored in registers r10 > and r11, and variable "min_remaining" is stored on the stack (previously > also in registers). > r10 and r11 register contents are not modified this time, up to the point > "now" is passed to function fireTimers. > > With this modification my TinyOS application runs fine. > Needless to say I am worried... am I just lucky that compilation seems to > be correct by adding this volatile keyword? > Is this a known issue? I cannot imagine that no one in the TinyOS > community has faced this timer issue, even though it only occurs when > building for large memory model. > > Thanks for commenting. > Wim > > > > ------------------------------------------------------------------------------ > Precog is a next-generation analytics platform capable of advanced > analytics on semi-structured data. The platform includes APIs for building > apps and a phenomenal toolset for data science. Developers can use > our toolset for easy data analysis & visualization. Get a free account! > http://www2.precog.com/precogplatform/slashdotnewsletter > _______________________________________________ > Mspgcc-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/mspgcc-users > > ------------------------------------------------------------------------------ Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis & visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter _______________________________________________ Mspgcc-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mspgcc-users