RicE
09-08-2007, 06:00 PM
Hello,
I'm a complete newcomer to Propeller (I started my first experiments last week-end). However I have almost 30 years of programming and IT background, and plays for fun with µC (mainly ATMELs) since a few years now. OK, that was for my profile. Enough said now http://forums.parallax.com/images/smilies/wink.gif A last detail : English is not my mother language, since I'm French. So apologizes in advance for approximative grammar and vocabulary....
First of all, I'm deeply amazed by the Propeller, and how it makes multi-thread programming on µC easy. Hats off for the Propeller creators.
To attempt fully understanding the inners of the beast (at SPIN level for the moment), I made several test with respect to data sharing between objects, COGs,... and the relation with declaring stuff using VAR or DAT.
As far as I could see with my tests, data declared in VAR section are "instantiated" for each reference to an object. In OO terms, I would qualify them as "instance data". On the opposite, data declared in DAT section are allocated once only. To re-use the OO parallel, they are like "static (or class leveol) data". Apart from that, from the inside of the object itself both can be used the same way (in terms of access)
My conclusion as a Propeller newbie, is that variables declared in DAT sections can be used to communicate between several instances of objects (accessing them from outside of the object with PUB methods of course), or to define values to be shared by all instances.
Here is a concrete example of this, based on one of my experiments :
- I wrote an object to interface an I2C LCD (same as the serial one used in several samples, but using I2C instead of serial com). This object references Basic_I2C_Driver provided in the libraries. Since all methods of Basic_I2C_Driver have a parameter specifying the pin driving the I2C SCL signal, I stored it in my I2C LCD object, so that callers of I2C LCD methods do not need to care with this, apart when invoking the LCD object initialization method
- from the top-level object running in COG0, I display periodic messages on it, using a reference to the LCD object
- another COG runs a code monitoring a push-button, to toggle the backlight of the LCD. Thus the button monitor object uses also the I2CLCD object.
To summarize, there are 2 instances of I2CLCD, one because of the reference from the top-level object, and the other because of the reference in the push-button monitor one.
I think that you start understanding where I'm going now. If the scl_pin variable is declared in the VAR section of I2CLCD, it will not work, since there will be 2 different "memory cells" for it, and it will not be initialized in the instance created via the reference from the button monitor object. I this variable is declared in DAT section, it works fine, so it seems to be shared between all object instances.
There is however something that remains not clear for me. From what I understood, the DAT part of an object is uploaded to the COG when cognew is invoked. Which is logic, since ASM code is executed directly from the COG RAM. But in this case, since the variables declared in DAT section are allocated in the COG RAM too, how can the sharing effect I could observe be possible ? Or maybe I've not understood correctly the mechanism, and what is uploaded to COGs is only the executable code. But this sounds me false, since it would then no be possible to have variables local to COGs.
The example is a bit artificial, but it is the prelude of a real prototype I am about to start. There will be several I2C devices in it, and the idea is to develop an object for each device, each of one referencing the I2C driver object. So I need to be sure that I2C level data will really be shared between all device objects.
Related to this project, I suspect I will have trouble if I2C device objects run in different COGs, since they will then manipulate the I2C signals in a non synchronized way. I understand that I need some mechanism to serialize I2C access, to be sure that each transaction is sane. What would be the right approach in such a situation ?
A last question now. I've seen in many example that the method commonly used to share data between COGs or objects was to pass a pointer of a memory area when initializing the object. So how does what I've noticed with DAT variable behaviors compare to this one ? Is my DAT variable technic just a "false good idea", working in my examples just because a hidden side effect I didn't realize, or can it be consider as valid ?
Many thanks in advance for any feedback.
Best regards
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Eric
More about my robotics related activities on : www.pobot.org (http://www.pobot.org)
Post Edited (RicE) : 9/8/2007 11:15:09 AM GMT
I'm a complete newcomer to Propeller (I started my first experiments last week-end). However I have almost 30 years of programming and IT background, and plays for fun with µC (mainly ATMELs) since a few years now. OK, that was for my profile. Enough said now http://forums.parallax.com/images/smilies/wink.gif A last detail : English is not my mother language, since I'm French. So apologizes in advance for approximative grammar and vocabulary....
First of all, I'm deeply amazed by the Propeller, and how it makes multi-thread programming on µC easy. Hats off for the Propeller creators.
To attempt fully understanding the inners of the beast (at SPIN level for the moment), I made several test with respect to data sharing between objects, COGs,... and the relation with declaring stuff using VAR or DAT.
As far as I could see with my tests, data declared in VAR section are "instantiated" for each reference to an object. In OO terms, I would qualify them as "instance data". On the opposite, data declared in DAT section are allocated once only. To re-use the OO parallel, they are like "static (or class leveol) data". Apart from that, from the inside of the object itself both can be used the same way (in terms of access)
My conclusion as a Propeller newbie, is that variables declared in DAT sections can be used to communicate between several instances of objects (accessing them from outside of the object with PUB methods of course), or to define values to be shared by all instances.
Here is a concrete example of this, based on one of my experiments :
- I wrote an object to interface an I2C LCD (same as the serial one used in several samples, but using I2C instead of serial com). This object references Basic_I2C_Driver provided in the libraries. Since all methods of Basic_I2C_Driver have a parameter specifying the pin driving the I2C SCL signal, I stored it in my I2C LCD object, so that callers of I2C LCD methods do not need to care with this, apart when invoking the LCD object initialization method
- from the top-level object running in COG0, I display periodic messages on it, using a reference to the LCD object
- another COG runs a code monitoring a push-button, to toggle the backlight of the LCD. Thus the button monitor object uses also the I2CLCD object.
To summarize, there are 2 instances of I2CLCD, one because of the reference from the top-level object, and the other because of the reference in the push-button monitor one.
I think that you start understanding where I'm going now. If the scl_pin variable is declared in the VAR section of I2CLCD, it will not work, since there will be 2 different "memory cells" for it, and it will not be initialized in the instance created via the reference from the button monitor object. I this variable is declared in DAT section, it works fine, so it seems to be shared between all object instances.
There is however something that remains not clear for me. From what I understood, the DAT part of an object is uploaded to the COG when cognew is invoked. Which is logic, since ASM code is executed directly from the COG RAM. But in this case, since the variables declared in DAT section are allocated in the COG RAM too, how can the sharing effect I could observe be possible ? Or maybe I've not understood correctly the mechanism, and what is uploaded to COGs is only the executable code. But this sounds me false, since it would then no be possible to have variables local to COGs.
The example is a bit artificial, but it is the prelude of a real prototype I am about to start. There will be several I2C devices in it, and the idea is to develop an object for each device, each of one referencing the I2C driver object. So I need to be sure that I2C level data will really be shared between all device objects.
Related to this project, I suspect I will have trouble if I2C device objects run in different COGs, since they will then manipulate the I2C signals in a non synchronized way. I understand that I need some mechanism to serialize I2C access, to be sure that each transaction is sane. What would be the right approach in such a situation ?
A last question now. I've seen in many example that the method commonly used to share data between COGs or objects was to pass a pointer of a memory area when initializing the object. So how does what I've noticed with DAT variable behaviors compare to this one ? Is my DAT variable technic just a "false good idea", working in my examples just because a hidden side effect I didn't realize, or can it be consider as valid ?
Many thanks in advance for any feedback.
Best regards
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Eric
More about my robotics related activities on : www.pobot.org (http://www.pobot.org)
Post Edited (RicE) : 9/8/2007 11:15:09 AM GMT