cogs calling cogs
steprog
Posts: 227
Hello Everyone,
I have a question. My main program calls and creates several methods in different cogs. How do you get one of these method (or cogs) to be able to use another method or cog also called by the main program.
For instance, I am calling a 2 TEC drivers, each uses the PWM_32_V2 method. To use just one cog I call it from the main or cog 0. How am I able to use the PWM_32_V2 from my TEC driver cogs?
Any Ideas?
I have a question. My main program calls and creates several methods in different cogs. How do you get one of these method (or cogs) to be able to use another method or cog also called by the main program.
For instance, I am calling a 2 TEC drivers, each uses the PWM_32_V2 method. To use just one cog I call it from the main or cog 0. How am I able to use the PWM_32_V2 from my TEC driver cogs?
Any Ideas?
Comments
Can't be done directly. You can have a memory location in the hub where one cog [cog 1] leaves a command or data for another cog [cog 2]. Cog 2 would check that hub location and execute that command or read that data and perform whatever function was required.
Consider the TV.spin and Graphics.spin objects authored by Chip. TV.spin is used by graphics_demo.spin, and TVtext.spin, unchanged! The same goes for VGA objects, many capable of using graphics.spin. (all about screen formatting really)
If one wants multiple displays, just launch a few of them, allocate some RAM to communicate to them, and then use just ONE graphics.spin to serve images to all of them.
It's just a different way of thinking, that's all. It's only awkward because these kinds of things are more difficult on other kinds of processors, making it unfamiliar.
If you use one object in 2 different .SPIN-files
1. the code is not duplicated
2. DAT sections are not duplicated
3. only the VAR section is duplicated
Some drivers - propably like the PWM-driver - are designed to allow COGs to run them independently. That's why it's easy to set up several serial interfaces with FullDuplexSerial.
Other drivers, like the graphics-driver are designed to run only once and allow usage from more than one other COG.
The difference is that the first kind of drivers uses VARs, the second kind of drivers uses DAT or some memory directly.
So, if you have a driver of one kind you can also convert it to the other.
Using Object B and Object C
Object B:
Using Object C
In this constellation both, object A and object B have access to the functions of object C. Please note, that the code is not duplicated in the available RAM. It's there only once. Same is true for the DAT variables. Only VAR variables are duplicated.
The implementation of object C makes the difference. If C makes use of VAR, each instance of the object is functioning independent - because each instance has it's own state. If C only uses DAT (or memory directly) it's more like one global object.
If C is a global object you have to be carefull when running the C functions in parallel (from several COGs at the same time). Depending on what the object is doing you might want to use LOCKs for synchronizing.
Object A -->PWM
--> TEC control (where each wants to use PWM)
--> TEC control (where each wants to use PWM)
solution (not desirable, uses 2 cogs when only one is needed)
Object A
--> TEC control --> PWM
--> TEC control--> PWM
It would be nice to only use 1 cog instead of 2 here.
I believe you have two choices here:
1. As others have mentioned, some objects are already designed to be called from multiple cogs. Assuming that the PWM object allows for this, your solution would be correct but only one of the TEC control objects would need to call pwm.start - or you could do it in Object A before getting into TEC control (so pwm is only running in one cog, the other TEC control object shares that same instance).
2. If you define everything in one object file, then the different cogs can access the variables and objects declared in that file (like your first diagram, if TEC control and Object A are merged into the same file).
#1 would probably be considered best practise, and would result in cleaner and more re-usable code (though may require more coding). #2 can be done though (you will of course still have to ensure that having multiple cogs calling a single instance does not cause any problems).
Note that this does not mean that it is using a cog - calling the start() method (or similar, provided it is following good coding practise) is where it launches off another cog (if the object needs one).
Put another way: If you only call start() on the pwm object once, then it will only be using one cog, no matter how often it is listed in OBJ blocks in your other objects.
Thanks