Hi!
You're right, thats what I meant, and I also was in the (now obviously wrong) 
belief that the compiler had to take care of that problem. At first, I thought 
there must be a simple solution, but smarter people than me haven't found one 
;-)
Perhaps one of th cheapest solutions in PICs is like that:
var word changingvar bit change_happened
procedure isrpragma interrupt  changing=new_value  change_happened=trueend 
procedure
...
REPEAT  change_happened=false  value=changingUNTIL ! change_happened
It costs only one bit of RAM, one (or at most three) code words in the 
interrupt and also the reading does not have to compare bytes.
Greets,Kiste   

 Am Samstag, 28. November 2020, 00:24:23 MEZ hat zmafoox 
<[email protected]> Folgendes geschrieben:  
 
 You seem to be confusing a volatile operation from an atomic one - volatile 
means just what it says, the results will not be cached, and a write will 
happen once. Since the PIC is byte oriented, any read of a value greater than a 
byte has to be done in multiple operations. There is no way to make these 
operations atomic, so you need to do this yourself. It's been a while, but if I 
recall the order is:read the LSBread the MSBread the LSB2 (read the LSB again)
if LSB2 < LSB  read MSB
again, I might be wrong. It's been a long time...
On Thursday, November 26, 2020 at 10:51:12 PM UTC-8 Kiste wrote:

Sorry... This isn't in fact the proper list for compiler issues, is it?
This one is probably more severe. I'll start with the example. This is the data 
I've received:
?2807   2808    1?2807   2809    2?2807   2810    2?2807   2811    4?2807   
2812    4?2807   2813    6?2807   2814    7?2807   2815    8?2807   2816    264
It's generated from this part of code, running on an PIC18F27K42. extra_time is 
increased in an interrupt every 16 seconds. It is declared as var volatile 
word, so the compiler should make sure that the bytes of the variable are in a 
consistent state:

  diff=word(extra_time-last_pulse_time_uw)

  if print_debug then
    print_debug=false
    serial="?"
    print_word_dec(serial,last_pulse_time_uw)
    serial="    "
    print_word_dec(serial,extra_time)
    serial="    "
    print_dword_dec(serial,diff)
    print_crlf(serial)
  end if

Let me repeat some of the results above in hex:

AFE-AF7    =7AFF-AF7    =8B00-AF7    =108
So, what has happened? The last line is clearly wrong. The subtraction was done 
just as extra_time was in the process of increasing. The low byte was processed 
before, the high byte was processed after the interrupt fired. So the actual 
subtraction done was BFF-AF7, with the result of 108.
I've had a look at the asm file. Both bytes of the variable are just handled 
one after the other, both in the main program and in the interrupt service 
routine. The "volatile" declaration does not seem to do anything.
Greets,Kiste


-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/d6a6d597-2dd3-4a8c-be00-83d18a45a7a7n%40googlegroups.com.
  

-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/519487440.2271703.1606547339764%40mail.yahoo.com.

Reply via email to