Ordering res and other data in your DAT section (not urgent, looking for some documentation)
I likely missed this in the documentation but I can't seem to find it....
I was having trouble accessing declarer data in my DAT sections. I found the problem but I can't seem to find where this behavior is explained. Here is some sample code that shows the problem
PUB start DIRA[0] := 1 OUTA[0] := 1 flag := 0 cognew(@SetPASM, @flag) repeat while (flag == 0) OUTA[0] := 0 DAT org 0 SetPASM mov value, #1 mov time, delay add time, cnt waitcnt time, #0 wrlong value, PAR Loop jmp #Loop delay long 6_000 ' With this line the program works as expected value res 1 time res 1 flag long 0 'delay long 6_000 ' With that line commented out and this line included, the program appears to hang
The program should turn the LED on, start a cog running the PASM, and wait for it to set the flag then turn the LED off. I was finding that this only works with delay
is defined before any of the res
items. When it is declared after, the program just hangs. From some debugging I can see that once loaded in PASM delay
does have a non-zero value, but I think it is so small that by the time it calls waitcnt
the counter register is already holding a higher value than time, so program is effectively waiting counter register to roll over, making it looks like it is hung.
Comments
The RES must come at the end after all other long declarations as the RES does not actually take space in the binary.
So FLAG must come before VALUE and also you should move 'DELAY before VALUE too in case you uncomment it later.
As a tip, unless you are pushed for space, RES can cause more problems than it is worth. In drivers/objects you will find we use RES because you never know where/who is using it.
res typically needs to be at the very end to be useful in reducing the amount of memory a given cog program takes in the hub. That's its only reason for existing.
Your cog program exists in the hub at first, before being copied into a cog. You can cheat the memory footprint a little smaller by telling the assembler that the data values at res aren't important to the cog, only the label's cog address is.
res intentionally causes overlap.
For your program example in the bad case, 'flag' is occupying the same memory location as 'value', and 'time' and 'delay' are referencing the same place as well.
Thanks for the information!