SPIN/ASM Driver lock up on code size greater than 480 longs?
Timothy D. Swieter
Posts: 1,613
Alright - same commercial project I am working through (i.e. can only post small portions of code). I have an object setup with several SPIN routines, then a data table in a DAT block, then an ASM routine in another DAT block. The SPIN code is for starting, stopping and sending commands to the ASM driver. The core of the driver is working and proven. However I started adding some additional SPIN code and commands. I am at a point where the driver appears to be locking up or isn't running properly, here is what I am seeing.
In the SPIN section is where the code was added. After review, commenting, uncommenting, etc I think what I am seeing is that the driver is locking up with the code size over a certain amount - 480 total longs. Now, again, remember the code I am adding is in the SPIN section, not the ASM section. When the driver is locking up and I get the Object Info - just the object (F8) I see the program is 471 longs, variables are 20 longs. When I comment out code (doesn't matter which SPIN code - any SPIN code - new code or old code - code that is being called or code that isn't implemented in the calling routines yet) and the program size drops to 460 longs or lower with 20 variable longs then the program/driver works fine. Futhermore, if I leave all the code in the SPIN section uncommented and take out portions of the data table to drop the size to 460 longs, 20 variables, the driver will still lockup, so it is as if the problem is in the SPIN section.
Again, it hasn't mattered which code I comment out or leave in. It appears to be the size. Am I barking up the wrong tree? What is happening here? Is this a symptom of a different problem?
FYI: In the ASM DAT section the status bar at the bottom of the Propeller Tool is telling me it is 491 bytes. So, I don't think it is a code size limit on a cog.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
In the SPIN section is where the code was added. After review, commenting, uncommenting, etc I think what I am seeing is that the driver is locking up with the code size over a certain amount - 480 total longs. Now, again, remember the code I am adding is in the SPIN section, not the ASM section. When the driver is locking up and I get the Object Info - just the object (F8) I see the program is 471 longs, variables are 20 longs. When I comment out code (doesn't matter which SPIN code - any SPIN code - new code or old code - code that is being called or code that isn't implemented in the calling routines yet) and the program size drops to 460 longs or lower with 20 variable longs then the program/driver works fine. Futhermore, if I leave all the code in the SPIN section uncommented and take out portions of the data table to drop the size to 460 longs, 20 variables, the driver will still lockup, so it is as if the problem is in the SPIN section.
Again, it hasn't mattered which code I comment out or leave in. It appears to be the size. Am I barking up the wrong tree? What is happening here? Is this a symptom of a different problem?
FYI: In the ASM DAT section the status bar at the bottom of the Propeller Tool is telling me it is 491 bytes. So, I don't think it is a code size limit on a cog.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
Comments
Other ideas?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
just a thought
The SPIN code isn't making any assumptions on memory or space for variables that I can see. There are a couple buffers declared as variables and those variables are strictly used with clear definitions (usually with variable[noparse][[/noparse]x] := value). There are various SPIN routines, and it hasn't mattered which ones are commented out or which lines are commented out - as long as the 460 longs program space isn't violated.
Kevin101 - good thought. The ASM driver reads configurations as the beginning of the driver initialization. Then, when a command is passed to the driver it reads the command plus four parameters. This is the same template idea that I have seen used in other drivers like graphics and float, and also in the LM9033A LCD driver I created. This new code works, I have tested and used it extensively, and it worked until I added SPIN code. There is one variable that is written to the HUB RAM an it is a value of zero written to the PAR address (clears the command after execution).
Here are more details after a little more investigation based on the above probing which triggers my thinking. Commenting or uncommenting the lines of SPIN are causing the ASM driver to function or not function properly. What I mean is, the ASM driver (with some lines commented out of SPIN) behaves as it should (it transmits and massages data - I am getting the data at the device that uses the data). I get great results and the driver is working. With those SPIN lines uncomments, it is like the ASM COG is locked up - not the calling COG or other cogs because I can still navigate on a menu structure (the calling COG), but the data sending isn't happening. So, the SPIN code isn't locking up, but the inclusion or exclusion of SPIN code is causing the ASM driver to function or not function.
So, why would commenting/uncommenting and size have to do with if the ASM code works properly or not? I will try and desensitize portions of the ASM code and publish that, but my thinking isn't that the problem is there.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
After the above code is sub-routines for the various commands and sending data out. The behavour that I see when the driver behaves improperly is that no data is being sent and the LED I/O is stuck on.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
CON
VAR
OBJ - not used
PUBs/PRIs
DAT - table of values - Propeller Tool status bar says this section is 765 bytes
DAT - ASM routine (part of which is shown in the post above)
Are you suggesting moving the DAT(table) section above the PUBs/PRIs? I can certainly try it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
That looks odd. par holds the address of the command (Entry line). Then in CmdWait you actually load the command into t0 and then treat t0 as an address again (last quoted line)? Shouldn't that last line read mov t1,par?
This may be intentional if the command holds a pointer to its parameters but I just thought I point it out anyway.
Post Edited (kuroneko) : 3/17/2009 6:57:22 AM GMT
Then, the CMDWait section reads the CONTENTs of par into t0. So t0 is now the value of what par is pointing to in HUB RAM. If the value is zero, then the code checks again. If the value is non-zero then it moves on. t0 is copied to t1 for processing, because later I use t0 again - this avoids reading par and syncing with the HUB RAM again. The comments are confusing, I suppose you would have to see the spin code. The contents of PAR is a variable called Command. Command is then made up of a pointer and value in the upper 16 bits.
See Graphics.spin or Float32 (I think) or LM9033A LCD driver for more examples (complete with SPIN code) to see how the passing of a command and parameters are done in this method. It is sort of tricky until you write it out (or rewrite it and debug it) but boy is it a nice technique for creating drivers.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
Another thing I know is that the commands are being executed. Most of the SPIN code is structured to wait for the commands to be done before returning to the calling cog. Something like this, where 'a' is the start of four variables with parameters. You can see in the ASM code I posted that the par is written with zero after the command is processed, so the code waits for the command. The parameters are read near the start of the ASM.
I know this is working because it is not causing the calling cog to hang. Hmmm....maybe I can do more testing in this area because I would think that it should be hanging if the ASM cog is really walking off a cliff. Hmmm...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
Post Edited (Timothy D. Swieter) : 3/17/2009 7:33:19 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
But in your case in the command buffer you can have what ever you want without a problem. Because in your exit you always set the command back to zero and every waiting SPIN code will continue. Thats some kind of robust programming, but it's a program with Alzheimer as it simply forgets that there was an error.
In this case I'd place a errorbeat ;o) which is only executed in case of an erroneous command.
Isn't it a nice challenge to find those kind of bugs. I really miss my java debugger in these times. Step through the code, do code changes on the fly .... ;o)
Oh - I guess I also have an LED that gives some feedback under certain commands. I only have four commands right now, one sets/clears a flag, another changes a parameter for the other commands. yet another only forces I/O for testing purposes and finally there is the one command that does all the heavy lifting and sending of data. In the future this may be expanded to be multiple commands. First, get the SPIn processing and cog dysfunction working properly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
Do you have a spare cog and 2 IO pins to communicate with the pc?
If so, you could use my debugger to trace the code, particularly if it occurs quickly. See my signature for link to the thread.
If you dont follow my debugger PM me and I'll give you my msn address.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, SixBladeProp, website (Multiple propeller pcbs)
· Prop Tools under Development or Completed (Index)
· Emulators (Micros eg Altair, and Terminals eg VT100) - index
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
You may already be doing this but do you ever check that the assembly cog actually starts either by checking the return value from the cognew or a led set in the asm cog?
"Command is then made up of a pointer and value in the upper 16 bits. "
Don't forget not all of the PAR variable actually gets passed into the cog.
Object table
Method Table
DAT section
PUB methods
PRI methods
VAR section
In this section
should t0 be t1? t0 just holds the contents of the PAR register.
Post Edited (stevenmess2004) : 3/17/2009 11:43:48 AM GMT
Good news is.......I think I found the problem. Bad news is......I don't understand why.
First, last night I was really getting bogged down thinking through this problem. I get like that after trying and trying and getting no where. Therefore I stopped working on the problem, that is why my posting stopped. I have gotten bogged down before and the lesson I learn is that I just need to walk away and stop thinking about it. I need to clear my head. After some time I return with a fresh mind - like I did this morning. I have a fresh mind and I start to reread everything I posted. I start to test assumptions. I review what I know and what I don't know. I retest to prove the problem or not. (of course I complicated matters yesterday by troubleshooting multiple bugs in multiple locations - which didn't help my focus).
So - this morning I think I found the problem. There is a piece of code I haven't posted yet. It is ASM code that has a flag and if the flag is set (non-zero) it branches to one direction and if the flag is not set (zero) it takes another path. The default, I was assuming, is not set and taking the "main path". The flag is reserved space at the end of the ASM routine. The flag was not initialized by the ASM code (I assumed this should be default to zero - no?). With all my SPIN code included (more than 460 longs), it appears that the flag was non-zero as it was getting stuck in that other path (a future feature half written). But, with some of my SPIN code commented out (doesn't matter which code, just as long as I am below 460) then the flag would be zero. Mind you, none of the commands/parameters at this time are manipulating the flag, it is only a reserved variable in ASM.
So, I am guessing that when I write something like:
That it isn't always initiated to zero - or at least doesn't appear to me to be that way based on my testing. Of course maybe there is some other bug that is clobbering the flag and I am looking for that now too. I also have my ASM routine initialized the flag to zero just after the I/O is initialized.
So - all of this to find a flag that is sometimes initialized as non-zero and other times is zero and the only way I can change between the two was how much SPIN code was present. Surely there is some thing else I haven't found yet.
So - all this talk here has helped me narrow down on the problem. Now if only I do why - I can spend sometime figuring it out, but I also need to move to the next coding task.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
periodicTXfg long 0
to define it at start up.
res reserves space for assembly code but that space is still available for spin or assembly code from other locations.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Need to make your prop design easier or secure? Get a PropMod has crystal, eeprom, and programing header in a 40 pin dip 0.7" pitch module with uSD reader, and RTC options.
I just checked the Propeller Manual regarding RES and it didn't mention that it is initialized to an indeterminante state. If this is true (and makes sense because there is also the other way of intializing a vriable) then it should get mentioned.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
The advantage of using res is the space gets reused over. very useful if your code is nearng the 32k limit. i almost always use the long, byte, or word opcode so I know for sure the start value.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Need to make your prop design easier or secure? Get a PropMod has crystal, eeprom, and programing header in a 40 pin dip 0.7" pitch module with uSD reader, and RTC options.