Problem writing bytes not along long boundaries
Here is a min repo of the problem
PUB start | ptr DIRA[0] := 1 OUTA[0] := 1 ptr := @Shared byte[ptr] := 1 cognew(@SetPASM, ptr) repeat while (byte[ptr] == 1) OUTA[0] := 0 DAT org 0 SetPASM mov Value, #2 wrbyte Value, PAR Loop jmp #Loop Value res 1 not_used byte 0 Shared byte 0
This app does the following
1. Turns on the debug LED
2. Obtains the address of a byte from within the DAT
section
3. Set the byte at that location to 1
4. Start a new Cog that will run some PASM
5. Loop while the byte at that location is 1
6. Turn off the LED
7. End
The problem appears to be in the PASM, it does the following
1. Fills a temp registry with value 2
2. Writes that value to the byte at the location passed via PAR
3. Enters an endless loop jumping back to the Loop
label
I would expect that when you run this the LED would flash for just a moment and then go out.
However that is not what I'm observing. The LED turns on, and then stays on.
This indicates that the while
condition on the repeat
loop stays fulfilled and ultimately that Shared
still holds the value 1
The strange thing is that seemingly "unrelated" changes will effect the outcome.
Here are a few that will "fix" the problem
1. Move the byte writes to always occur on long boundaries by doing any of the following
- Remove the line
not_used byte 0
- Add 3 more bytes after
not_used
and beforeShared
like this
not_used byte 0, 0, 0, 0 Shared byte 0
- Change all the references from 'byte' to 'long' (note: swapping to 'word' will reproduce the problem)
-or-
2. Do the work in Spin by
- Adding
VAR long Stack[128] PRI SetSpin(ptr) byte[ptr] := 2 repeat
- Change
cognew(@SetPASM, ptr)
tocognew(SetSpin(ptr), @Stack)
I have done some additional debugging and found that when this misbehaves it does look like a write is occurring, I have seen cases where it appears to corrupt other data in the DAT
section. I also did a little double checking by changing all of my references from byte[ptr]
to Shared
and that seams to indicate that those are equivalent
But I'm clearly missing something if you know what it is I'll all ears. Thanks in advance.
Comments
Yes, you missed to read the Propeller manual, before you have done a lot of debugging. For example on page 82 it says:
Andy
You're not the first to miss this important aspect of the par register.
I had similar issues when I was first learning PASM. I've seen this issue mentioned many many times on the forum.
Try out this simple one
As Andy and Duane have pointed out, the par register (that many call the mailbox") must contain a long address (because the two low bits are cleared). Here's a work-around that works in your situation. I happened to have a board with and LED on P8, so I added a constant for that (which is a good idea, anyway).
Thank you very much for the quick response!