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 <w...@track4c.com> 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
> Mspgcc-users@lists.sourceforge.net
> 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
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to