Using locks for multi-cog sensor inputs
lyons5959
Posts: 13
During one of my projects I found the need to learn about locks. I have a prop that is reading two speed signals(w/ timeout), two thermocouples(via DS2760), and two ADC(Max1202). I have the startup cog initializing everything, then working with fullduplexserial to send the data out to a separate display unit. The main cog specifies the address of 16 word variables, and passes this address on each new cog. two cogs for reading speed, a cog for reading the thermocouples, and a two cogs for reading the two ADCs. However, I keep running into problems. I have tested the code and the program works if I only start up one cog, but when I add another, it goes haywire. How should I use the locks to fix this. I was thinking one lock for each cog representing access to memory. No cog could read from or write to memory while any lock was set. However, i'm not really sure how to do this, and which commands to use. any help is appricated.
Comments
Basically, you need a single value that means "not ready yet". It could be zero or all one bits or some other value that will never occur with the sensor. The variable associated with the sensor is initialized with this value. The "producer" (the routine that reads the sensor) sits in a loop waiting for the variable to have this "not ready yet" value. When it does, the routine reads the sensor and stores its value in the variable. The "consumer" (the routine that processes the sensor value) sits in a loop waiting for the variable to not have the "not ready yet" value. When it does, the routine does whatever it needs to with the value, then sets the variable to "not ready yet". If the "consumer" routine is designed to handle several sensors, it just checks each variable in turn, processes the value if not "not ready yet", then goes on to the next variable (in an overall loop).
For writing sensor data...
repeat until (var) == $FFFF
(var) := (data)
For reading sensor data...
repeat until not (var) == $FFFF
...send out data
(var) := $FFFF
Will this work if the reading and writing occur on separate cogs?
2) Yes.· It's assumed that these are in separate cogs that are executing simultaneously.· This type of inter-process communication is very common and very useful (one process generating data and another consuming it).
·3) These are actually special forms of locks that don't require any special hardware·or instructions to do.· The only requirement is that the assignment operation and the data fetch operation are each indivisible.· In other words, the act of storing a 32-bit long word can not be interrupted by another processor and the act of fetching a 32-bit value from the shared memory can not be interrupted by another processor, both of which are true for the Propeller.
Post Edited (Mike Green) : 6/27/2007 1:13:06 AM GMT
I am building a controller that will activate two solenoids based on two variables: RPM and MAP. Since I have been going through the Objects lab and found an exercise that checks the status of two variables that are passed on from a parent object, I decided to tweak it and try to make it work for my application.
The first object (parent) will start another object (child) in a different cog that will monitor the two variables (RPM, MAP)that are updated in the parent object.
I have implemented a loop that will check the value of the variables, and if it is noticed that it changes to $FFFF, then the parent object will get the value with the Measure method in the parent object and update.
Since the child object is in a loop until the RPM value is not equal to $FFFF, then it should carry out the case loops that follow.
However, it doesn't. The terminal freezes at a measurement and no more measurements are made. I believe it is stuck at the 1st repeat loop in the child object. I even tried to set the two outputs before the repeat loop in the PRI NoidControl Method, in order to turn on the solenoids, but they do not turn on. I also tried beefing up the number of longs for the Method stack from 10 to 1000, no dice. Why isn't the second cog running the child method? NOTE: The post will not show the number four on the outa settings throughout the post. I am using pin four and pin nine as outputs.
Parent Object:
Child Object:
In the child object, you're setting RPM to $FFFF to signal that the child wants a new measurement. Unfortunately,
this RPM is the one declared local to the child object, not the one in the main object. You should use long[noparse][[/noparse]RPMAddress].
You have the same naming problem in the REPEAT loop at the beginning where you use RPM.
I'd suggest you simply use long[noparse][[/noparse]RPMAddress] and long[noparse][[/noparse]MAPAddress] throughout the child object. These don't take that
much more space or time than using a local copy, particularly since they're only used in a few places and this will avoid
any confusion over which copy you're using at what time.
and outa[noparse][[/noparse]9] high, that the solenoids do not switch on?
In the child object:
I am using LEDs in place of the solenoids. The LEDs are switched on with a high output on pins 4 and 9. What the program does is take the last measurement,
then halts as if the child object is not running. Why does it halt?
You must set.
dira~~ ''Clear Pin 4
dira[noparse][[/noparse]9]~~ ''Clear Pin 9
In same COG proces.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nothing is impossible, there are only different degrees of difficulty.
For every stuipid question there is atleast one inteligent answer
If you dont ask you wont know
Sapieha
Each cog has its own DIR and OUT registers and, as is shown in several diagrams on the Propeller webpages and manual, they're all OR'd together. If any cog sets its DIR register bit to a one, that pin becomes an output regardless of what any other cog does. If any cog with its DIR bit set to one also sets its OUT bit to one, that I/O pin becomes an high output regardless of what any other cog does.
the LED would light up. It didn't. For some reason, the Parent Object is not starting up the new object in the new cog.
I will test to see if the NoidControl Method starts via the cognew command.
Thanks for everyone's help.
Not give up.
I wanted Yours post.
Place You code for Child proces I have one mistake but must see you code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nothing is impossible, there are only different degrees of difficulty.
For every stuipid question there is atleast one inteligent answer
If you dont ask you wont know
Sapieha
Sorry.
I mean you EDITED Child
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nothing is impossible, there are only different degrees of difficulty.
For every stuipid question there is atleast one inteligent answer
If you dont ask you wont know
Sapieha
When I introduce the Child Object and the repeat until <> and == $FFFF loops in their respective places in the objects, that is when the program hangs, I only get the initial measured value from the pots and then it is waiting for the child object to cycle through. This is why I think something is wrong with the child object.
This is not a big deal since I can use one cog for this operation, it is not as time critical to warrant two cogs slaving over it.
However, I do appreciate the assistance from you, Mike and Sapieha.