[chbot] Synco's reentrant chocolate fish

Col colp42 at gmail.com
Sat Jul 23 01:37:42 BST 2011


On 23/07/11 09:15, Peter Harris wrote:
> Hi Synco
> Welcome to the joys of reentrancy.
> For those not familiar with this problem: The variable 'count' is more
> than 8-bits long and is being dealt with on an 8-bit micro. Assuming
> count is 16 bits long the micro has to read first one byte then the
> other. This problem occurs when count is modified by an interrupt
> between reading the first and second bytes the value read is the first
> byte of the old value of count and the second byte of the new value of
> count E.g. garbage.
>
> The following code works by reading values that may be changed more than
> once and making sure the same value is read twice. When an overflow
> occurs at one or other end of the pulse count may be off by a few ticks.
> If timing is critical you could count the number of times the while
> loops execute, a value greater than 1 indicates that an overflow has
> occurred. The value of count can be increased if there was an overflow
> at the start and decreased if there was one at the end to compensate.
>
>    Peter
>
> #define TIMERWRAP     1024
> static uint number_of_times_the_timer_has_overflowed_during_pulse = 0;
>
> ISR(ExternalInterrupt)  // highest priority
> {
>     if (triggered on +ve edge) {
>        // Start of pulse detected
>        while (number_of_times_the_timer_has_overflowed_during_pulse > 0)
> // The while loop will catch an overflow occurring at the start of the pulse
>        {
>           number_of_times_the_timer_has_overflowed_during_pulse = 0;
>           set to trigger on -ve edge;
>           count = TIMERWRAP - Timer;
>        }
>
>     }
>     else {
>         // end of pulse
>         do
>         {
>            temp_overflow_count =
> number_of_times_the_timer_has_overflowed_during_pulse;
>            set to trigger on +ve edge;
>            count += Timer +(temp_overflow_count * TIMEWRAP);
>         } while (temp_overflow_count !=
> number_of_times_the_timer_has_overflowed_during_pulse); // The while
> loop will catch an overflow occurring at the end of the pulse
>     }
> }
>
> ISR(TimerOverflow)   // overflows at TIMERWRAP ticks
> {
>     number_of_times_the_timer_has_overflowed ++;
>     ....
> }
>
> ISR(other)
> {
>    ...
> }
>

Is number_of_times_the_timer_has_overflowed 8bit? otherwise I figure you 
have just moved the same problem to a different variable.

Also my tutors taught me it was bad practice to put loops in ISR's.



Col.



More information about the Chchrobotics mailing list