Help with using locks
Penguin-fach
Posts: 11
I have been trying to get the Propeller locks to work for me but so far no luck. From what I have read this should all be straightforward.
1. Check out a new lock with the locknew command
2. Use a helper method to pass the lock ID between objects
3. Use the lockset command to set the lock (or test if it is set)
4. Use the lockclr command to clear the lock (or test if it is clear)
5. Use the lockret command to return the lock when it is no longer required
I have used the attached files to play with a lock that will be used eventually to signal that an EEPROM is busy. However when I run my simple little top object, Test_EEPROM.spin, the lock always seems to be set no matter what. I have been working with the education kit to breadboard this but just can't get the locks to do anyhting sensible
What am I doing wrong?
Test_EEPROM.spin
I2C_EEPROM_Dummy.spin
1. Check out a new lock with the locknew command
2. Use a helper method to pass the lock ID between objects
3. Use the lockset command to set the lock (or test if it is set)
4. Use the lockclr command to clear the lock (or test if it is clear)
5. Use the lockret command to return the lock when it is no longer required
I have used the attached files to play with a lock that will be used eventually to signal that an EEPROM is busy. However when I run my simple little top object, Test_EEPROM.spin, the lock always seems to be set no matter what. I have been working with the education kit to breadboard this but just can't get the locks to do anyhting sensible
What am I doing wrong?
Test_EEPROM.spin
I2C_EEPROM_Dummy.spin
Comments
I think your problem is that the "EepromLockID" is set from inside the "InitEEPROM" method, which is launched from a COGNEW. You need to set the EepromLockID number from your main method otherwise you can't control the lock from outside the "InitEEPROM" method.
Have a look at my object 74C92Xbuffer2.0.spin, and you will see that the method that launches the COGNEW actually passes the value of the Lock SemID to the cognew. This allows the object launched with the Cognew to have the SemID as well as any other methods that need it to control access to certain memory locations.
Regards,
As a possible sugestion, take a look at how the FullDuplexSerial passes data via cyclic buffers (ignore the rest of the code because its quite complex). I cannot think offhand other good examples, so perhaps someone will chime in with some.
I have written a little more code to try and make sense of the locks and to be honest, the fact that testing the lock status also sets or clears the lock really cripples them in my view. There needs to be some sort of 'locktest' command that returns the lock state without modification.
I can use 'If...else' to test the lock status and clear or set as needed - that all works fine. However there are many circumstances where you would want code to simply hold until a lock is clear. A simple single-line repeat would seem to be the best way to do this but that just will not work with the lockset and lockclr commands. As soon as they are used in this way the temporal relationship is lost and the repeat statement essentially assumes control of the lock.
Any chance that a locktest function might appear in the command set? In my opinion it would transform the locks into a truly useful feature rather than something that seems to be underutilised and, I suspect, even actively avoided by many.
Far simpler than checking out locks IMO. The only thing is that is multiple cogs are accessing the same eeprom, you need to share the address of the variable when launching cogs so they have the pointers available to access. The same var can be used in other instances of code that need to access the eeprom, with the same result.
@Penguin, a test instruction would be nice. Currently, you need to use a hub location and a lock to implement the type of function you are describing.
@T Chap, your method could fail if two cogs are calling AccessEeprom at about the same time. Both cogs will take control of the EEPROM. You may not have seen any problems in your applications, but this method will not work for all applications.
In fact you can easily simulate a locktest by lockset directly followed by lockclear.
If you only want to test that a COG is doing something, a normal variable is enough.
The lockset is totally fine, because it does not wait for the lock, so a COG can decide to do something else in case it did not get the lock.
I have to say that I also never have used a lock so far, but each kind of application that needs consistent read/modify/write access from more than one COG to more complex data-structures than one byte, one word or one long will benefit from locking.