All_those#constants
Erlend
Posts: 612
I take pleasure in writing code in a style where it is as self explanatory as possible, even to the non-Spin enabled, almost like pseudo code. With this goes a verbouse style with full naming of varables and constants. Yeah, I know, some call it bloated code. Fortunately compilers often take care of that and leave the excess fat behind in the source code. I guess that is basically true for Spin too, but I am not sure to what extent.
For instance, the result of concistantly having full-named constants is that I end up with a large amount of constant definitions. To keep the top level code lean and legible I would like to move most CON definitions to a dedicated Object, such that they can be used by means of Cdefs#a_constant. But, to do this every Method using these constants need to include the 'Cdefs' in their OBJ declaration. How does this end up affecting code size?
Btw, I wish there was a similar way to do this for Varables too.
Erlend
For instance, the result of concistantly having full-named constants is that I end up with a large amount of constant definitions. To keep the top level code lean and legible I would like to move most CON definitions to a dedicated Object, such that they can be used by means of Cdefs#a_constant. But, to do this every Method using these constants need to include the 'Cdefs' in their OBJ declaration. How does this end up affecting code size?
Btw, I wish there was a similar way to do this for Varables too.
Erlend
Comments
Meaningful function/variable/constant names is a good idea. When that becomes "verbose" is subjective I guess.
I did this and it is working without memory overhead at all. Almost. Including the object cost a couple of longs.
If you reduce your 'common' object just to contain a CON section you can include it wherever and as often you want. CONstants get resolved at compile time.
Putting 'common' used things besides CCONstant definitions into a 'common' object is a little bit more trickier, but doable.
If you include the same object in multiple other (sub)objects in your project the spin compiler will sort of prune it.
It will reduce it to ONE code section and ONE data section. each objet will have its own VAR section.
So code and all references to DAT sections are shared or common to all 'instances' of the same object. VARiables are bound to the instance of the object.
So as long as you avoid VAR sections, you can include your object as often as you want and it will just be ONE time in the created binary. But each instance has its own VAR section. Keeping that in mind you can build some nice helper/common objects.
This is a pretty neat feature of spin.
Enjoy!
Mike
I also can call a procedure/method/function or whatever you call it by SER.whatever(parameters)
what I can not do is referencing the address of something in the (sub)object.
example:
now I have to do
PUB getVarAdr
return @myVar
assuming myVar is a label inside the sub object. Either in DAT or VAR section
to use this in my main program I need to do something like this:
current := long[SER.getVarAdr]
wouldn't it be nicer to have direct access to the address and skipping the procedure getVarAdr?
current:=long[SER@myVar]
could do the same and you do not need a function/method/procedure to access the address.
Anyways!
Mike
Erlend
Personally I have no problem with constant definitions in an object that does nothing but hold constant definitions. Global constant definitions as it were.
We might ask though, "why do that?". Presumably those constants are describing the nature of something and that something is probably related to some functionality, subsystem, of your program. And presumably that functionality/subsystem is itself implemented in an object. So why not put the constant definitions in the object they relate to? Why have them "globally" defined?
I can think if some cases where this is not the case though:
1) Truly global constants that potentially span all other objects. Things like mathematical constants, PI, E, and so on.
2) Constants that relate to things external to the Propeller in your project. Things like, well I don't know, perhaps the baud rate used by some external gadget, Basically constant that describe objects external to the Propeller and in Spin program and hence don't have a natural place to live in your code.
3) Cross cutting concerns. Perhaps you have one pin dedicated as an emergency stop output that any other object can raise when it gets into an error situation. (Not a good example as I imagine it's better to create an emergency stop object here and include that in all the other objects.
One can make an argument that all the constants that define the interface between the Prop and the outside world should be defined in a global constant object rather than being spread around other objects. So for example a single configuration object would contain all the definitions of which pins are used by which interface, UART, PWM, ect, etc. This way you have a single place to look to when moving code from platform to platform or rearranging hardware on your bread board. I think Cluso is a big fan of this.
Can anyone suggest other use cases for global constants?
Heater,
In this particular project I have organized it such that many of the cogs are dedicted to reading and writing to the outside world, e.g. ADC, LCD, switches, etc., and they all operate around one single 'real-time database' for storing and retrieving. This 'database' is owned by the top level Main and is nothing more than a set of global variables that are accessed by means of LONG[] from the various cogs. This is going on sort of in the background, whereas algorithms/logic/sequencing is executing in the Main and a few other cogs, and they do not have to worry about I/O, its taken care of. I am kind of emulating the use of true global variables. Often constants go hand-in-hand with variables, e.g. together with Value goes RangeMin and RangeMax, and EngineeringUnit. So when I need global variables I need global constants. I could implement this as an object-based real-time database and cover the physical I/O functionality quite well in that way, but I also experience the need for global constans in other respects, such as with user interfaces.
I guess this is an answer to your 3), and for 2) and 1) my answer is simply yes.
My rudimentary coding background is with ObjectPascal for the office, and with various object-based propriretory SCADA and Supervisory systems for the real-time world. It's a long time ago, but I probably still want to structure the code the way I am used to. Maybe I am pushing Spin out of her comfort zone.
Erlend