Searching \ for '[PIC]: Multibyte words and Interrupts - A challeng' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'Multibyte words and Interrupts - A challeng'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Multibyte words and Interrupts - A challeng'
2000\11\06@133759 by Bob Ammerman

picon face
What if you need to share multibyte data between 'task' and interrupt level
code, and you are not allowed to disable interrupts AT ALL.

Given:

The 2-byte variable 'shared_var'.

Problem 1: We want to guarantee that interrupt level can always get a
'reasonably current' and consistent value of the variable as set by task
level. (ie: value is never written by interrupt level code)

Problem 2: We want to guarantee that task level can always get a 'reasonably
current' and consistent value of the variable as set by interrupt level.
(ie: value is never written by task level code) (hint this is rather easy)

Problem 3: We want interrupt and task level both to be able to write to the
variable, and always get a 'reasonably current' and consistent value of the
variable. (ie: value is written by both task level and interrupt level code)
(this is rather tricky)

Criteria:

Minimum extra RAM locations used.
Minimum amount of code.

Have at it!

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spam_OUTlistservTakeThisOuTspammitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@141057 by Scott Dattalo

face
flavicon
face
On Mon, 6 Nov 2000, Bob Ammerman wrote:

{Quote hidden}

1 word: Semaphore

However, it's not as easy as it sounds.

For example, for case 3 you could do this

  cblock
    SEM_shared_var   ;two bits per variable
    shared_var_hi
    shared_var_lo
  endc



interrupt:

  save W into Wtemp ; this may contain one of the bytes
                    ; protected by the semaphore
  ...

  movf    Wtemp,w
  btfsc   SEM_shared_var,0    ;Is low byte 'in use'?
   movf   shared_var_lo,w     ;no, can use it...

 ;now shared_var_lo can be used.

  comf    shared_var_lo,f     ;here we modify it...



 ;now check if semaphore is set again
  btfss   SEM_shared_var,0
   goto   next_thing

  movf   shared_var_lo,w     ;update W (which is shared_var_lo)
  movwf   Wtemp
  bsf     SEM_shared_var,1   ;tell the main task the interrupt
                             ; has modified the variable

next_thing:

...

  restore W from Wtemp

  retfie




then in the non-interrupt code:

  bsf    SEM_shared_var,0       ;Set the semaphore

  movf   shared_var_lo,w        ;get the shared variable
  movwf  temp_buffer            ;and save a temporary copy

  btfsc  SEM_shared_var,1       ;did the interrupt modify it?
   movwf temp_buffer            ;yep, save new copy

  bcf    SEM_shared_var,0       ;clear semaphore flags
  bcf    SEM_shared_var,1


;use temp_buffer - it has the most recent copy of shared_var_lo


This works for the case when the interrupt can modify in the middle of an
access. Similar logic exists for writing to a variable (instead of just reading
it in the main task). But I agree with Andy K, I'd be inclined to throw DI/EI
around the critical sections.


Scott

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use .....listservKILLspamspam@spam@mitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@150906 by Bob Ammerman

picon face
>
> This works for the case when the interrupt can modify in the middle of an
> access. Similar logic exists for writing to a variable (instead of just
reading
> it in the main task). But I agree with Andy K, I'd be inclined to throw
DI/EI
> around the critical sections.
>
>
> Scott

Ah, but Scott, the whole point is: sometimes you CANNOT disable interrupts
due to real-time requirements (ie: fast response and/or zero jitter) of
interrupt handling code.

> --
> http://www.piclist.com#nomail Going offline? Don't AutoReply us!
> use listservspamKILLspammitvma.mit.edu?body=SET%20PICList%20DIGEST
>
>
>
>

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use .....listservKILLspamspam.....mitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@151539 by David VanHorn

flavicon
face
>Ah, but Scott, the whole point is: sometimes you CANNOT disable interrupts
>due to real-time requirements (ie: fast response and/or zero jitter) of
>interrupt handling code.

So update the working copy DURING the interrupts.

--
Where's dave? http://www.findu.com/cgi-bin/find.cgi?kc6ete-9

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@151725 by Scott Dattalo
face
flavicon
face
On Mon, 6 Nov 2000, Bob Ammerman wrote:

> >
> > This works for the case when the interrupt can modify in the middle of an
> > access. Similar logic exists for writing to a variable (instead of just
> reading
> > it in the main task). But I agree with Andy K, I'd be inclined to throw
> DI/EI
> > around the critical sections.
> >
> >
> > Scott
>
> Ah, but Scott, the whole point is: sometimes you CANNOT disable interrupts
> due to real-time requirements (ie: fast response and/or zero jitter) of
> interrupt handling code.

Okay. btw, there's an error in my code. It's very subtle... But there's a race
condition (that's easily fixed)

Scott

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use listservspamspam_OUTmitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\06@160544 by Don Hyde

flavicon
face
Here's a trick I have used to accomplish this.

Simplifying conditions:

1) The interrupt has a more-or-less constant rate, which means that if one
has just happened, it will  reliably be "a while" before another one happens
(examples are a timer, UART, or possibly I2C.)

2) The background is not in a very big hurry, and doesn't need to access the
shared data very often.

3) Interrupt routines never even come close to using up all the CPU cycles.

How it goes:
When the background task wants to access the shared data, it sets a one-bit
flag, then loops until the flag gets reset by the interrupt routine.

Every time the interrupt routine runs, it clears the flag.

When the background task exits from its wait loop, it is guaranteed to have
some number of cpu cycles during which it has exclusive access to the shared
variables.

The interrupt routine never has to worry about integrity of the shared
variables.

Gotchas:
At startup, the first couple of interrupts for some devices (such as UART
transmit) may not be quite so regularly timed.   (Though UART transmitters
usually make their second interrupt immediately, so they still work OK
without needing any extra logic.)

You may need some more flags if the interrupt is not always active, etc.
which will complify this approach, but you may still be able to get it to
work.

> {Original Message removed}

2000\11\06@160756 by Bob Ammerman

picon face
----- Original Message -----
From: David VanHorn <@spam@dvanhornKILLspamspamCEDAR.NET>
To: <KILLspamPICLISTKILLspamspamMITVMA.MIT.EDU>
Sent: Monday, November 06, 2000 3:15 PM
Subject: Re: [PIC]: Multibyte words and Interrupts - A challenge


> >Ah, but Scott, the whole point is: sometimes you CANNOT disable
interrupts
> >due to real-time requirements (ie: fast response and/or zero jitter) of
> >interrupt handling code.
>
> So update the working copy DURING the interrupts.

That's problem #2, which I said was easy.

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

{Quote hidden}

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spamBeGonelistservspamBeGonespammitvma.mit.edu?body=SET%20PICList%20DIGEST




2000\11\07@095617 by Thomas McGahee

flavicon
face
One method that I have used involves the use of three flag bits.
One flag bit is called main_wants_new, one is called isr_wants_new,
one is called allow_data_in_isr, and the last is called data_ready.

How many of these bits you need depends on what kind of data problem
you are faced with. See details below.

***** Answer to Problem 1:

> Problem 1: We want to guarantee that interrupt level can always get a
> 'reasonably current' and consistent value of the variable as set by task
> level. (ie: value is never written by interrupt level code)
>

Isr polls allow_data_in_isr. If that flag is high, then it polls
data_ready each time isr executes. When it finds data_ready
is high, it uses the data and clears data_ready.

When the main program has new data it clears allow_data_in_isr
(this prevents isr from using data while it is being loaded).
New data is loaded into the shared data variable(s),data_ready is
set high, and allow_data_in_isr is set high.

****** Answer to Problem 2:
>
> Problem 2: We want to guarantee that task level can always get a 'reasonably
> current' and consistent value of the variable as set by interrupt level.
> (ie: value is never written by task level code) (hint this is rather easy)
>

Isr polls allow_data_in_isr. If it is low, it skips loading new data.
If it is high, it loads new data and sets data_ready.

Main program clears allow_data_in_isr to ensure no updating occurs
while it looks at data. If data_ready is high it now processes
data and clears data_ready. If it is low it skips data processing.
Allow_data_in_isr is set high to re-enable updating of data by isr
in the background.

The above main program segment may be in the form of a loop, if that is
desired.

***** Answer to Problem 3;
>
> Problem 3: We want interrupt and task level both to be able to write to the
> variable, and always get a 'reasonably current' and consistent value of the
> variable. (ie: value is written by both task level and interrupt level code)
> (this is rather tricky)
>

Two solutions. The first involves direct requests for new data:

Main:
clear allow_data_in_isr
It may now either read data or write data
  If writing data, write, then set data_ready
  If reading data, read, then clear data_ready and clears main_wants_new
Set allow_data_in_isr.

The main program can specifically request the isr to provide new data
by:
clearing allow_data_in_isr
clearing data_ready
setting main_wants_new
setting allow_data_in_isr

Main responds to isr_wants_new by:
clearing allow_data_in_isr
loading data
setting data_ready
setting main_wants_new
setting allow_data_in_isr

Isr:
if allow_data_in_isr is set:
  then if main_wants_new is set:
      update data
      clear main_wants_data
      set data_ready
  endif
endif

Sometimes the isr wants to request new data from main:
set isr_wants_new
clear data_ready

It is the isr's responsibility to clear isr_wants_new
once it has gotten the requested data.

Make sure that the initialization routine initializes all
the flags properly for first-time operation, and has
proper dummy values loaded into variable(s).

**** second solution

Main and isr can each update variables whenever they have valid data.
No specific data request required.

Main:
clear allow_data_in_isr
It may now either read data or write data
  If writing data, write, then set data_ready
  If reading data, read, then clear data_ready
Set allow_data_in_isr.

Isr:
if allow_data_in_isr is set:
  update data
  set data_ready
  endif
endif

in the case of reading data, if data_ready is set, read
data and clear data_ready. No need to check allow_data_in_isr
when just reading data, as this flag is used to prevent
updating of the variable(s) by the isr during the short
time that the main routine has this flag high.

Make sure that the initialization routine initializes all
the flags properly for first-time operation, and has
proper dummy values loaded into variable(s).

Fr. Thomas McGahee

{Original Message removed}

2000\11\07@120632 by Olin Lathrop

flavicon
face
> One method that I have used involves the use of three flag bits.
> One flag bit is called main_wants_new, one is called isr_wants_new,
> one is called allow_data_in_isr, and the last is called data_ready.

That's pretty clever, saving 4 flags in 3 bits ;-)


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, TakeThisOuTolinEraseMEspamspam_OUTcognivis.com, http://www.cognivis.com

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestspamTakeThisOuTmitvma.mit.edu




2000\11\07@175938 by Michael Rigby-Jones

flavicon
face
> -----Original Message-----
> From: Olin Lathrop [SMTP:olin_piclistEraseMEspam.....COGNIVIS.COM]
> Sent: Tuesday, November 07, 2000 3:45 PM
> To:   EraseMEPICLISTspamMITVMA.MIT.EDU
> Subject:      Re: [PIC]: Multibyte words and Interrupts - A challenge
>
> > One method that I have used involves the use of three flag bits.
> > One flag bit is called main_wants_new, one is called isr_wants_new,
> > one is called allow_data_in_isr, and the last is called data_ready.
>
> That's pretty clever, saving 4 flags in 3 bits ;-)
>
>
Data compression is marvellous thing :o)

Mike

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestEraseMEspamEraseMEmitvma.mit.edu




More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...