PDA

View Full Version : Variable organization



Ioannis
- 11th March 2009, 07:29
This thread is more like a survey as to how you organize your variables in a big program.

My concern is about the waste of variables used all over the program one writes.

I saw the problem mainly in large code with interrupts. If one wants to use a variable inside the interrupt, this must be new. But, if for every task we assign a new variable, at the end we may have a lots that are really not necessary and most of them used once.

In C threre are local variables so there is no waste in memory.

How do you organize your programs in respect of this matter?

Ioannis

Melanie
- 11th March 2009, 20:26
I saw the problem mainly in large code with interrupts. If one wants to use a variable inside the interrupt, this must be new. But, if for every task we assign a new variable, at the end we may have a lots that are really not necessary and most of them used once.

This is new to me - I've not come across this anomally/limitation/requirement before.

I write code in a very structured way... it doesn't mean it's the RIGHT way, it just happens to work for me.

1. At the very top I have the PIC Definitions/Configurations
2. Next I have all the Hardware Assignments and Pin Definitions, LCD and all other Defines.
3. Then EEPROM Data Statements
4. Then RAM Definitions
5. Then Constant Definitions
6. Here sits a jump to step 10.
7. Assembler Routines
8. Interrupt Routines
9. Subroutines
10. Hardware and Register Initialisation sequences
11. Main Program Loop

Wherever possible, Variables, Definitions, Subroutines etc are all in Alphabetical order within their own sections (makes them easy to find subsequently).

The variables (for example at step 4) are all in one spot... if I need Bits, then I define a Byte or a Word and sub-define that into bits.... variables that are used and reused many times throughout the program (like intermediate working variables) are defined to sit in Bank0 (it makes for considerably smaller code)...

Here is a typical example of (a few) variable definitions in a (large) program...



SystemError var Byte Bank0 ' Hardware Fatal Error Flags
Tamper var SystemError.0 ' Main CPU Anti-Tamper
I2CError var SystemError.1 ' I2C Bus Failure
I2CVersion var SystemError.2 ' EEPROM Incompatible
I2CTimeout var SystemError.3 ' I2C Bus Timeout
I2CDevFail var SystemError.4 ' I2C Device Failure
' SystemError.5 - Unused - Reserved
' SystemError.6 - Unused - Reserved
' SystemError.7 - Unused - Reserved
SystemFlags var Byte ' System Operational Flags
' 0=Unused
' 1=Unused
' 2=Unused
' 3=Unused
UECursor var SystemFlags.4 ' 4=User-Entry Field Cursor (0=Invisible, 1=Visible)
UEEntry var SystemFlags.5 ' 5=User-Entry (0=NOT Permitted, 1=Permitted)
UESecure var SystemFlags.6 ' 6=User-Entry Security (0=Unsecure 1=Secure)
' 7=Unused
TempA var Byte ' Temporary Storage Variable
TempBitA var TempA.0 ' Just a Temporary Bit
UEData var Byte Bank0 ' User-Entry EEPROM Data to be Loaded
UEDataReference var Byte ' User-Entry EEPROM Data Reference
UEDisplay var Byte ' User-Entry EEPROM Data being Referenced
UELen var Byte ' User-Entry Field Length (0-16 chars long)
UEMax var Byte ' User-Entry Maximum Field Entry Value
UEMin var Byte ' User-Entry Minimum Field Entry Value
UEPos var Byte ' User-Entry Current Position in Field (0-15)
UEReference var Byte ' User-Entry Display Reference Pointer
UETemp var Byte ' User-Entry Temporary Counter
UETimeOut var Byte Bank0 ' User-Entry Keyboard TimeOut Counter
UEType var Byte Bank0 ' User-Entry Field Type
' 0=Alphanumeric
' 1=LCD Contrast Setting
' 2=LCD BackLight Setting
' 3=Idiot Selection (eg Yes/No)
' 4=Idiot Selection with Reset (eg Hours Counters)
' 5=Idiot Selection with Erase (eg Erase Event Log)
' 6=Date & Time Entry & Validation
' 7=Option Selecting Off/On/Auto Modes
' 10=Numeric (0-255) c/w leading Blank Suppression
' 11=Numeric (0.0-25.5) c/w leading Blank Suppression
' 2x=Option with Menu Skip (preset to x)
' 3x=Option with individual x-Bit manipulation
XDataAddress var Word Bank0 ' External EEPROM 16-bit Address


As you can see, there's noting clever here - it's just all arranged logically, all placed in one section, all documented and done to be easilly maintained.

Ioannis
- 12th March 2009, 08:04
Hi Melanie.

Well, I suppose that most people will without much thinking follow in general that structure too.

But what I tried to express with my limited english was this:

Say you have a long program with many variable, some of them common to most routines like the CounterA, CounterB etc. As these are used for counting purposes, they are present in many subroutines and For-Next loops.

Lets suppose now that an interrupt occurs in the middle of a subroutine and a counter variable is necessary for the interrupt itself.

We need now a new variable, exclusively for this iterrupt,used only once.

If accidentally one uses the, say, CounterA variable,which is at this particular time used in a subroutine, sure the program will go to the La-La-Land!

I feel a little Skroutz with the blind use of variables.

Ioannis

Melanie
- 12th March 2009, 08:20
Duhhhh.... Yes, I use CounterA, CounterB... DataA, DataB in my subroutines, but INTERRUPTS by their very nature will INTERRUPT the flow of things, so you wouldn't use the same variables within those routines unless the interrupt is supposed to change the way the main program works - I would have thought that was obvious!

In the same way, if you nest subroutines within subroutines for a particular task... you can't have the same variables in each of those subroutines as they'll mess with each other.

It doesn't mean that every subroutine has to have it's own exclusive variables, but you do need to keep track of what is being used where - and to that end, when you list your subroutine, have a header which simply reminds you what's used inside it...



'
' Subroutine Displays Message on LCD from Program CodeSpace
' ---------------------------------------------------------
' CounterA - General Byte Variable
' CounterC - General Word Variable
' DataA - General Byte variable
' Message - ID of Message to Display
' MessageLen - Number of characters to Output
' MessageSupport - Beginning of Message Table in Codespace
' XDataAddress - 16-bit Address in Codespace
DisplayExternal:
@ GetAddress _MessageSupport, _XDataAddress ' Get Start address of Message Support Table
XDataAddress=XDataAddress+(Message*18)
ReadCode XDataAddress,MessageLen
XDataAddress=XDataAddress+1
ReadCode XDataAddress,DataA
If DataA>0 then LCDOut $FE,DataA
If MessageLen>0 then
For CounterA=1 to MessageLen
CounterC=XDataAddress+CounterA
ReadCode CounterC,DataA
LCDOut DataA
Next CounterA
endif
Return

Acetronics2
- 12th March 2009, 08:40
Hi, Ioannis

I believe PBP Variables are GLOBAL Variables ... and You'd better turn to "C" if you want LOCAL variables.

or "another Basiç " ... Booooooooooooooo.




Identifier is declared in the function or procedure Scope extends from the point where it is declared to the end of the current routine. These identifiers are referred to as locals.




Now, let's say I do not understand clearly what you mean ...

You simply could add a memo to the variable name like "Count_inter" or " Count_LCD "for your example ...

I do not think RAM is THE problem ... as you have to preserve the "eventually overwritten" Variables !!!


BTW ... I didn't find the Max. Variable Length in the Holy Manual ... ( 32 Characters ??? )

Alain

PS: Tell me You won't implement a " Variable Stack " ... tell me you won't ... lol

Melanie
- 12th March 2009, 08:49
Actually, I assumed the maximum variable length to be 65534 bytes (though I've never gone beyond about 8k personally - after all you gotta leave some space for your actual program too!!!)...

Word variable minus 2 (because you can't have 65536) and it has to be an even number because the way 18F parts store stuff in Program Codespace.

Acetronics2
- 12th March 2009, 08:57
Actually, I assumed the maximum variable length to be 65534 bytes (though I've never gone beyond about 8k personally - after all you gotta leave some space for your actual program too!!!)...

Word variable minus 2 (because you can't have 65536) and it has to be an even number because the way 18F parts store stuff in Program Codespace.

Hi, Mel ..

I meant the Max Variable NAME length ....

Alain

Ioannis
- 12th March 2009, 13:01
PS: Tell me You won't implement a " Variable Stack " ... tell me you won't ... lol

No, not yet Alain. I think Darrel did this a while back?

As for the C i do not feel very comfort... That += and =- get me on my nerves!

Melanie:

I usually name the variable in a way that is obvious as to what they are doing. But I don't like the CounterA, B, C, D, ... Z variables all to be used for the same task in different places. But I see no other way as the meaning of Local in PBP is not defined.

Thanks for the talking.

Ioannis

Melanie
- 12th March 2009, 22:07
If you're writing large complex programs, then your chosen PIC probably has so much RAM you're never going to use it all anyway... so why not have a dedicated set of variables for every subroutine and ISR... after all, that's what C does with it's local declarations.

Ioannis
- 13th March 2009, 07:05
Yes Melanie. That is what in practice I am doing. It would be nice though, if there was a way of recycling variables!

Ioannis

mackrackit
- 13th March 2009, 09:13
Maybe the Aliases idea is what you are looking for?

Ioannis
- 13th March 2009, 10:00
Absolutely No, Grandpa!

This will mess up all the variables for sure.

Ioannis