Multiple instances of a process
ErNa
Posts: 1,752
I am actually fighting a bug, I do not understand at all, now I made a work around, but I will come back as I finished the task.
First steps to run a TMC260 stepper motor driver are done, this IC can drive currents Ia, Ib, adjustable via SPI through windings a, b of a stepper.
The setup is as follows:
a main program and two instances of SPI :
the main program calls the two instances via different pointers to parameters
That works as it is intended.
Next step:
Now the motion controller (just increasing the angle over time) is separated into another process and main program starts 4 cogs.
If I only enable one of the two motion controllers, it works for both of the motors.
But if I enable both at the same time, the system doesn't start, as I found out, the busy flag of one process changes inadvertently and is set where I expect unset.
There are two separate signal chains: SpiA<->TmcA, SpiB<->TmcB.
But there is some interference, I could not find until now.
So I had to give up and rewrote the driver to handle both motors (no problem for a cog) and so I have a workaround (what I do not like).
Just a first question:
Is it correct that processes can be instantiated multiple times and they do not share any variable if not explicitly done?
- in future I will discuss in more detail, what I done and how it works, this is just a principal question, so there is no code
First steps to run a TMC260 stepper motor driver are done, this IC can drive currents Ia, Ib, adjustable via SPI through windings a, b of a stepper.
The setup is as follows:
a main program and two instances of SPI :
OBJ Ser : "FullDuplexSerial" ''Used in this DEMO for Debug SpiA : "SPI___Asm" ' SPI for linear guide SpiR : "SPI___Asm" ' SPI continuous rotationInstantiation of SPI is done by passing sets of pointers, SPI is triggered by a cmdVariable.
the main program calls the two instances via different pointers to parameters
That works as it is intended.
Next step:
OBJ Ser : "FullDuplexSerial" ''Used in this DEMO for Debug SpiA : "SPI___Asm" ' SPI for linear guide SpiR : "SPI___Asm" ' SPI continuous rotation TmcA : "TMC260" ' Stepper Motor Driver TmcR : "TMC260" ' Stepper Motor Driver
Now the motion controller (just increasing the angle over time) is separated into another process and main program starts 4 cogs.
If I only enable one of the two motion controllers, it works for both of the motors.
But if I enable both at the same time, the system doesn't start, as I found out, the busy flag of one process changes inadvertently and is set where I expect unset.
There are two separate signal chains: SpiA<->TmcA, SpiB<->TmcB.
But there is some interference, I could not find until now.
So I had to give up and rewrote the driver to handle both motors (no problem for a cog) and so I have a workaround (what I do not like).
Just a first question:
Is it correct that processes can be instantiated multiple times and they do not share any variable if not explicitly done?
- in future I will discuss in more detail, what I done and how it works, this is just a principal question, so there is no code
Comments
The compiler prunes out to save space.
To avoid this and have two completely independent objects you need to have 2 different files having at least one byte different in the dat section.
Enjoy!
Mike
This part intrigues me. Does that mean if I have two different spin objects, with different filenames (e.g. obja.spin and objb.spin) but they have identical DAT sections, they'll share the DAT space? Surely not?
When all your objects are compiled into binary and it's time to put it all together into the image of your program the Spin compiler does a binary comparison of all objects and treats any that match each other as the same.
Even if they come from different source files! Weird but true.
So they end up with their own VAR sections but share the DAT section.
It's some kind of weird, undocumented, memory space optimization feature that has tripped up many people over the years. Perhaps it should be called a "compiler bug".
Hence the requirement for at least one byte difference in the DAT section.
As Dave Hein demonstrated above.
It could also be a useful feature - provided one knows and understands it. The question is, can I rely on it always being that way? Should I take advantage of its possibilities, or should I code around it by making sure my DAT sections are always a little different?
Sounds like you have been watching David L. Jones on the EEVBlog. Excellent. Good on ya mate. Normally I would say that if this is undocumented behaviour one should not design it into ones programs.
What I wonder is this: Once you have made that one byte change in the objects DAT section do you the get two copies of all the Spin byte code, which is the same in both. I presume so. Sounds like a disaster.
Anybody tested this? I don't have the means to check just now.
But it's also a smart optimiser to reduce hub space usage. If the code is identical, then one copy in hub will suffice.
So, any DAT PASM used to start more than one cog can be re-used rather than 2+ copies.
Also, any spin code that is identical can be reused instead of more than 1 copy.
The traps are:
1. If that hub pasm code is modified before loading
2. If that hub pasm code reuses its own load space (a few objects do this)
3. If that hub spin code is modified
Any others?
bst was written to be identical to PropTool's output. Neither will be changed.
Perhaps OpenSpin could have an option to turn this feature off ???
This is going to do my head in... If I have two objects in different spin files but with the same DAT space I get a single copy of the DAT space - and that includes code. What if the objects have self-modifying code? Maybe I'll just make sure my DAT spaces are always different.
In the expected run of the mill program PASM code is loaded into a COG and executed there. So if that PASM program gets into self modifying code, for table indexing for example, then the modification is happening to the copy in the COG not the program image in HUB RAM from which it was loaded.
Yes, of course. Phew.
Presumably the entire object, VAR, DAT, PUB etc has to match in order to be "pruned" away. Otherwise it would be chaos.
I presume the idea is that if you use object X from object Y and then use object X again from object Z then only one copy of X is included in the final binary.