[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] generic queue library for AVR GCC?
From: |
gouy yann |
Subject: |
Re: [avr-gcc-list] generic queue library for AVR GCC? |
Date: |
Fri, 12 Nov 2004 11:33:33 +0100 (CET) |
to sum up, I'm a lucky "or a very very carefull" guy
because, up to now, I only have one task that writes
or reads in a fifo and they are all less than 255
chars long. :)
Furthermore, it is constructed in a way if a task
doesn't have the necessary place to put a char in the
fifo, it yields to a background task and the fifo will
be emptied during the task switch.
regards.
Yann
--- Paul Haas <address@hidden> a écrit :
> On Thu, 11 Nov 2004, gouy yann wrote:
>
> > I'm using it with a preemptible multi-tasks kernel
> of
> > my own and I've never notice any problem.
>
> > I have taken care the tests and modifications of
> the
> > number of elements in the fifo to be done in the
> right
> > sequence, up to now it seems sufficient for
> reading
> > and writing characters from the USART or for
> > inter-tasks communication.
>
> It would be safe if all 4 of these conditions were
> true:
> 1. only one task calls FIFO_get()
> 2. only one task calls FIFO_put()
> 3. f->nb++ in FIFO_put() is atomic
> 4. f->nb-- in FIFO_get() is atomic
>
> I wrote a little function:
> typedef struct {
> short val;
> } f;
> void incr(f* fp) {
> fp->val++;
> }
>
> and compiled it with avr-gcc -S -O3 -c incr.c
> .global incr
> .type incr, @function
> incr:
> 1. mov r31,r25
> 2. mov r30,r24
> 3. ld r24,Z
> 4. ldd r25,Z+1
> 5. adiw r24,1
> 6. st Z,r24
> 7. std Z+1,r25
> 8. ret
>
> Imagine that I have one task called plus which calls
> incr() and another
> task called minus that calls the matching decr()
> function. Assume that
> val starts at 2.
>
> If we have the sequence of calls:
> function fp->val
> incr() 3
> decr() 2
> incr() 3
>
> The final value is 3 and everything is cool.
> However if incr() is
> interrupted at line 5, right after it finishes the
> adiw, then we get the
> sequence:
> function fp->val r24,r25
> first half of incr() 2 3
> decr() 1
> second half of incr() 3
> incr() 4
>
> Producing a final value of 4 after two calls to
> incr() and one call to
> decr().
>
> You may not notice a bug like this for a long time.
> The window for
> corruption is only 4 instructions long and the exact
> opposite kind of
> corruption can happen on the decr() side. If you
> are lucky, the lost
> increments will cancel out the lost decrements. Or
> it will look like line
> noise or lost characters, and you'll blame the
> serial port. Very rarely
> will it lead to total failure.
>
> If you're very very carefull and you know what
> you're doing, you can write
> fifo routines that don't require critical sections
> as long as only one
> task reads, only one task writes and the fifo has
> 255 bytes or less.
> Critical sections make it all easier.
>
>
> > bye.
> > Yann
> >
> > --- Geoffrey Wossum <address@hidden> a écrit :
> >> On Thursday 11 November 2004 1:32 pm, gouy yann
> >> wrote:
> >>
> >>> here is my implementation of a fifo.
> >>> I hope this will help you.
> >>
> >> I took a quick look at these routines. I noticed
> >> that they lack any type of
> >> "critical section" around where the queue data
> and
> >> pointers are modified.
> >> Calling these routines as-is from an ISR context
> and
> >> from a non-ISR context
> >> might result in race conditions and odd,
> >> intermittent behavior.
> >>
> >> Here's my critical section routines. The enter
> just
> >> pushes the global
> >> interrupt state and then disables interrupts, the
> >> exit pops the interrupt
> >> state. Observant list readers might note an
> uncanny
> >> resemblance to NutOS's
> >> critical section code...
> >>
> >> extern inline void utos_enter_cs(void)
> >> {
> >> asm volatile(
> >> "in __tmp_reg__, __SREG__" "\n\t"
> >> "push __tmp_reg__" "\n\t"
> >> "cli" "\n\t"
> >> );
> >> }
> >>
> >> extern inline void utos_exit_cs(void)
> >> {
> >> asm volatile(
> >> "pop __tmp_reg__" "\n\t"
> >> "out __SREG__, __tmp_reg__" "\n\t"
> >> );
> >> }
> >>
> >> Since these routines push and pop from the stack,
> >> you have to be careful to
> >> balance them within a function. I'll leave where
> to
> >> insert them into the
> >> code as an exercise to the reader ;)
> >>
> >> Maybe lack of critical sections is the problem
> with
> >> the original posters code?
> >>
> >> ---
> >> Geoffrey Wossum
> >> Long Range Systems - http://www.pager.net
> ---
> Paul Haas
> http://hamjudo.com
=====
Vous manquez despace pour stocker vos mails ?
Yahoo! Mail vous offre GRATUITEMENT 100 Mo !
Créez votre Yahoo! Mail sur http://fr.benefits.yahoo.com/
Le nouveau Yahoo! Messenger est arrivé ! Découvrez toutes les nouveautés pour
dialoguer instantanément avec vos amis. A télécharger gratuitement sur
http://fr.messenger.yahoo.com
- [avr-gcc-list] generic queue library for AVR GCC?, David Morrison, 2004/11/11
- Re: [avr-gcc-list] generic queue library for AVR GCC?, E. Weddington, 2004/11/11
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Ned Konz, 2004/11/11
- Re: [avr-gcc-list] generic queue library for AVR GCC?, gouy yann, 2004/11/11
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Bruce D. Lightner, 2004/11/15
- Re: [avr-gcc-list] generic queue library for AVR GCC?, E. Weddington, 2004/11/15
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Bruce D. Lightner, 2004/11/15
- Re: [avr-gcc-list] generic queue library for AVR GCC?, E. Weddington, 2004/11/15
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Richard Urwin, 2004/11/16
- Re: [avr-gcc-list] generic queue library for AVR GCC?, gouy yann, 2004/11/16
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Bjarne Laursen, 2004/11/16
- Re: [avr-gcc-list] generic queue library for AVR GCC?, David Brown, 2004/11/16
- Re: [avr-gcc-list] generic queue library for AVR GCC?, Ian Caddy, 2004/11/16
- Re: [avr-gcc-list] generic queue library for AVR GCC?, David Brown, 2004/11/16