I need help understanding memory on the prop...
Chris_D
Posts: 305
Hi folks,
On my project that I have been working on for a couple of years, it is reaching the point where memory is becomming a problem on the prop. Up until now I have not looked at the memory and how to work with it because it has not been a problem. After thinking about ways to utilize what is there, I realized there is more than I originally thought.
First with the basic data.. there are 8192 longs of global memory (RAM), each cog has 512 Longs. If all COGs were fully loaded, you would still have 4096 longs left over of global ram. At this point I am making some assumptions because there has to be some code space for the spin interpreter etc.
Anyway, assuming I have more memory space than what can fit in all the COGs at once, I then started thinking about how I could use that. I then realized that COGs can be started, stopped, and re-used. Assuming I am correct on that, it appears that I could use one COG (or more) to run 2 or more different programs, just not at the same time.
Specifically to my application, I have two different modes of operation when it comes to motion control: Automatic and manual. I cannot get both sets of logic to fit in one COG but they do not run at the same time. If all other assumptions are correct, I could start a COG as MANUAL MOTION and later when the machine goes into automatic motion, I would stop the COG, restart it with AUTOMATIC MOTION and continue switching back and forth at will. The speed at which this changeover would happen is not a major concern because it is a user driven event.
Am I ontrack with this whole concept?
Sorry if this is all basic common sense stuff, I just never took the time to consider this capability and now that I did, I have to re-think everything I have done with the Prop so far because it adds a whole new level of performance.
Chris
On my project that I have been working on for a couple of years, it is reaching the point where memory is becomming a problem on the prop. Up until now I have not looked at the memory and how to work with it because it has not been a problem. After thinking about ways to utilize what is there, I realized there is more than I originally thought.
First with the basic data.. there are 8192 longs of global memory (RAM), each cog has 512 Longs. If all COGs were fully loaded, you would still have 4096 longs left over of global ram. At this point I am making some assumptions because there has to be some code space for the spin interpreter etc.
Anyway, assuming I have more memory space than what can fit in all the COGs at once, I then started thinking about how I could use that. I then realized that COGs can be started, stopped, and re-used. Assuming I am correct on that, it appears that I could use one COG (or more) to run 2 or more different programs, just not at the same time.
Specifically to my application, I have two different modes of operation when it comes to motion control: Automatic and manual. I cannot get both sets of logic to fit in one COG but they do not run at the same time. If all other assumptions are correct, I could start a COG as MANUAL MOTION and later when the machine goes into automatic motion, I would stop the COG, restart it with AUTOMATIC MOTION and continue switching back and forth at will. The speed at which this changeover would happen is not a major concern because it is a user driven event.
Am I ontrack with this whole concept?
Sorry if this is all basic common sense stuff, I just never took the time to consider this capability and now that I did, I have to re-think everything I have done with the Prop so far because it adds a whole new level of performance.
Chris
Comments
Whenever you start SPIN-Code in a new cog. The COMPLETE COG-RAM is occupied by the SPIN-interpreter.
The interpreter starts working and does fetching SPIN-bytecode and values of variables from HUB-RAM all the time.
If you start PASM-Code the PASM-code will be transferred from HUB-RAM to Cog-RAM and then the cog starts
executing YOUR PASM-Code. (Remember PASM is written inside a DAT-section which means store DATA in HUB-RAM.)
With SPIN-code the SPIN-interpreter-code is transferred from HUB-ROM (Read-Only-Memory) to Cog-RAM
and the cog starts executing the SPIN-interpreter-PASM-code.
So without using special hard- and software all the CODE still has to fit into the 32kB of the HUB-RAM.
If you use PASM and your PASM-code does NOT fill the complete Cog-RAM you can use the left Cog-RAM
for PASM-variables that are exclusive for THIS PASM-code.
If you want to make left Cog-RAM accesibble for other cogs you would have to implement a software-mechanism
how to request for COG-RAM-values. Therefore you need some HUB-RAM and the involved cogs would have to have
a loop that polls for handshaking commands and values that should be transferred.
Regarding all this I think it will be easier to use external RAM or a bigger EEPROM.
For variable values this will be quite easy. For code I'm not familiar with it.
Maybe the memory-extension-users can explain more about that and provide easy to use demo-code that shows how
extra-SPIN or PASM-code can be loaded from an EEPROM or external RAM or SD-card.
best regards
Stefan
For clarification in my particular example. The COGs that I would be doing this with are written in PASM and I am already sharing variables through the hub using rdlong/wrlong statements.
I don't do too much in SPIN for this project as performance is very critical and the performance is only critical once the COG is up an running. The time to unload/load - Stop/Start a COG wouldn't be a concern (assuming this happens in a few milliseconds).
Chris
It looks like my blog entries are specially for you ;o)
If you have two different COG programs, you could have only one in your application code (the one which is most propable loaded) and the other code you can put into upper part of EEPROM or save it on an SD card. Of course you'd have both codes, the manual and the automatic mode code there. When a switch occurs you simply load the version you want to switch to into the place where the included module is and start it.
As kuroneko already mentioned you have to take care of the hardware that's driven by your code. Especially if the code runs independent. If the user then forces a COGSTOP in the middle of something, that's propably not what you want. So, you could maybe think of an interface to your main application. If your COG reads the command KILL it first cleans up and makes sure that COGSTOP won't harm the hardware. Easy way which does not need code is to use resistors to have the pins in a defined state. Other way would be to let the main application drive the pins for the short while of reloading. And another way is to let the COG reload itself. Then you would not send a KILL command, but a RELOAD command.
Thanks for chiming in. As I stated this whole concept is new to me (even though I have been using the prop for a couple years). Anyway, I am not sure if I actually need to load the cog program from EEPROM. I suspect all the COG programs could fit in the global memory. What I was thinking of doing is within my OBJ section, specify all the objects for the whole application.
Then Start and stop the ones specificly needed. I assume what happens is that the stop unloads the COG, then the start loads the specified object and runs the code. As these objects are PASM they should all fit within the RAM of the core (The 8192 longs).
As for the hardware part of this, the way the system is currently configured, I don't think there is anyway that the pins could be damaged. Nor do I think it is possilbe to be able to kill a COG while that COG is doing something - although I have to check all the other code to make sure.
I read through your blog after you mentioned it above and it will take me a few more read-throughs to grasp it.
Chris
It is, actually, using cogstop with the cog's id from outside said cog. Depending on how your cogs work they may be able to set an "I'm not busy" flag for the master control application which could then [safely] unload the cog.
we all know to little about your current system. That's why everybody throws in whatever comes into mind. I think in another thread you talked about a CNC. So, when your COG is driving the steppers and then you stop this COG your outputs driven by this COG will be free floating if your setup does not use pullup/down resistors. Anything can happen then.
So, the concerns were not going in the direction "destroy a propeller pin"
There are pull downs on these outputs so that the inputs to the stepper drives are not floating. That part is safe and I have never had the thing run away on me.
As for killing the cog (or swapping the logic in my case), this should be safe the way the software is setup. The only time it would switch is when the user tells it to do so by switching modes (Automatic or Manual). When that activity happens, I run the "reset" routine in the software which clears all activity, then I switch mode which would now also swap out the logic in the COG. I know the logic is in my program from the Automatic to Manual switch now, but I have to double check the manual to automatic switch.
Chris
If you have a loop at the beginning of the cog-RAM that is "looping" if the logic is in idle-mode this loop could be expanded a little bit
to load other code "behind" this loop. So the cog would not have to stop at all.
Of course this requires VERY careful coding of all parts of the code that nothing important gets overwritten and that offsets for jumps and loops are setup correctly,
even after "overloading" the other part of the code.
By the way: did anybody already realise something like this, with some clever coding that does recalculating the offsets correct?
best regards
Stefan
A Hi Ray!