avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] generic queue library for AVR GCC?


From: Geoffrey Wossum
Subject: Re: [avr-gcc-list] generic queue library for AVR GCC?
Date: Tue, 16 Nov 2004 13:36:14 -0600
User-agent: KMail/1.7.1

On Tuesday 16 November 2004 11:53 am, Richard Urwin wrote:

> But you still have to declare a variable to hold the return value, and
> that was what broke the #define version.

That's actually the main thing I like about the NutOS critical sections that 
push and pop directly from the stack.  No need to declare a variable to go 
along with it.

> typedef enum {cs_start, cs_end} cs_enum;
>
> static inline unsigned char critical_section(cs_enum dir)
> {
>         static unsigned char s;
>
>  switch(dir)
>  {
>  case cs_start:
>   s = SREG;
>          cli();
>   break;
>  case cs_end:
>   SREG = s;
>  }
> }

This doesn't look like it would handle nested critical sections.  I actually 
do that quite a lot.  For instance, in my FIFO routines I use a critical 
section to protect access to the FIFO counters and pointers.  Sometimes I 
want multiple elements to be enqueued/dequeued from the FIFO as an atomic 
unit.  For this, I'll wrap a critical section around all the 
enqueues/dequeues.  That type of use would break this, I believe.  You could 
probably fix it in the majority of usages by adding a counter, though.  You 
only store SREG in s when the counter is 0, and you only restore SREG when 
counter is being decremented back to 0.

If you didn't want to declare a variable to hold SREG, and you didn't want to 
manipulate the stack directly, you could probably do something like this:

#define CRITICAL_SECTION(_stmts) \
    do { \
        uint8_t sreg_save = SREG;  \
        cli();  \
        { _stmts }  \
        SREG = sreg_save;  \
    } while (0);

To use it would look something like:

    CRITICAL_SECTION((    // notice the double paranthesis
        fifo_push(&fifo, c1);
        fifo_push(&fifo, c2);
    ));

I think that would work.  I'm not really sure I'd like to use it, though.  
Plus, you still have the problem of what if you put a return in statements.  
You'd leave the critical section without restoring interrupts.  Your stack 
would be fine, however, unlike if you did that with the NutOS version. 

---
Geoffrey Wossum
Long Range Systems - http://www.pager.net





reply via email to

[Prev in Thread] Current Thread [Next in Thread]