Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Can anyone explain me this, why it happens??

Status
Not open for further replies.

xpress_embedo

Advanced Member level 4
Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,154
Helped
161
Reputation
396
Reaction score
189
Trophy points
1,353
Location
India
embeddedlaboratory.blogspot.in
Activity points
10,591
I just started using PIC32 Family and found a very strange thing, maybe it is possible that i did not noticed these things earlier but noticed now.

I am using PIC32MX534F064H Micro-Controller, for Starting PIC 32 Series.
I write a simple bit toggling program.
Here it is


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// PIC32MX534F064H Configuration Bit Settings
 
#include <p32xxxx.h>
 
// DEVCFG3
// USERID = No Setting
#pragma config FSRSSEL = PRIORITY_7     // SRS Select (SRS Priority 7)
#pragma config FCANIO = ON              // CAN I/O Pin Select (Default CAN I/O)
#pragma config FUSBIDIO = ON            // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = OFF          // USB VBUS ON Selection (Controlled by Port Function)
 
// DEVCFG2
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20         // PLL Multiplier (20x Multiplier)
#pragma config UPLLIDIV = DIV_2         // USB PLL Input Divider (2x Divider)
#pragma config UPLLEN = ON              // USB PLL Enable (Enabled)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)
 
// DEVCFG1
#pragma config FNOSC = PRIPLL           // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF            // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF               // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = XT             // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSECME           // Clock Switching and Monitor Selection (Clock Switch Enable, FSCM Enabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
 
// DEVCFG0
#pragma config DEBUG = OFF              // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)
 
////////////////////////////////
#define DATA LATDbits.LATD6
#define STAT LATGbits.LATG6
////////////////////////////////
 
void Delay_ms(unsigned int time)
{
    unsigned int first,second;
    for(first=0;first<time;first++)
        for(second=0;second<11500;second++)
            ;   
}
 
main()
{
 
    [B]unsigned int time = 500;[/B]
    TRISD = 0;
    TRISG = 0;
 
    LATD = 0;
    LATG = 0;
    while(1)
    {
        DATA = ~DATA;
        Delay_ms(time);
        STAT = ~STAT;
        Delay_ms(time);
    }    
}



Just see this variable unsigned int time, in MPLAB C32 Compiler it consumes 4-bytes of memory.
When i see Memory Window it says Zero Why??

1.png

And when i changed the unsigned int time = 500; to outside the main, means global declaration, it consumes memory and also rom gets incremented.

See this
2.png

Even the lines.
unsigned int time;
then time = 500;

Showing different consumption in rom.
I am going to see dis-assembly of this code.
 
Last edited:

I think if it is not a global variable i.e., if declared inside main function or sub functions data is not reserved for the variable but data will be reserved if declared as global variable. I think if variables declared in main() or other functions the data is assigned dynamically when the program runs those functions.
 
I will confirm that.

Declaring it inside the function makes it local to that function so it is created as the function is entered and destroyed afterwards. Declaring it outside of a function makes it available throughout the program (or at least the source file) so it has to be allocated a fixed storage address. The "Memory Usage Guage" is showing the memory used immediately after compiling so at that point it will not have allocated dynamic storage to any local variables.

You would see the same effect if you declared the variable as "static" inside the function so the compiler was forced to allocate somewhere to store it but that could have disastrous effects elsewhere in your program!


Brian.
 
Thanks Very Nice Explanation...

That's great feature of compiler.
With that i can reduce my code size,
Now i will declare as much as possible local variables, to save ram space.
Thanks everyone.
 

The call stack is just the contents of the stack in the order the data was put on it. It gives you some tracability of which routine called another because the return address of each is stored there. As a routine is called, either with a CALL instruction or because an interrupt occurred, the place it has to return to when the routine has finished has to be saved somewhere, this is called the stack. As successive calls or returns (or end of a function) is reached, the last stack entry is where the program has to resume from. It works the opposite way around to normal memory, a register called the "stack pointer" (which cannot be directly accessed in some PICs) holds the currently active position in the stack. As you enter a subroutine/ISR, the program counter value is 'pushed' on to the stack and the pointer is adjusted to it's position, as you return from a subroutine/ISR, the address in the stack being pointed to is copied or 'popped' to the program counter so execution continues from there and the stack pointer is adjusted to the previous entry in the stack. It allows routines to be nested one inside another as many times as there are spaces in the stack to hold the return addresses.

I think Batang is warning you that the stack can be used to carry variables into and out of functions as well so the stack can fill up quickly. Certainly in conventional C/C++, all function parameters are carried on the stack but in the case of PIC microcontrollers I'm not sure that's true. To save space and time. I would guess the stack only holds addresses and data is held in a reserved block of conventional memory instead. Someone with better knowledge of the inner workings of C32 can advise you better than me.

Brian.
 
The call stack is just the contents of the stack in the order the data was put on it. It gives you some tracability of which routine called another because the return address of each is stored there. As a routine is called, either with a CALL instruction or because an interrupt occurred, the place it has to return to when the routine has finished has to be saved somewhere, this is called the stack. As successive calls or returns (or end of a function) is reached, the last stack entry is where the program has to resume from. It works the opposite way around to normal memory, a register called the "stack pointer" (which cannot be directly accessed in some PICs) holds the currently active position in the stack. As you enter a subroutine/ISR, the program counter value is 'pushed' on to the stack and the pointer is adjusted to it's position, as you return from a subroutine/ISR, the address in the stack being pointed to is copied or 'popped' to the program counter so execution continues from there and the stack pointer is adjusted to the previous entry in the stack. It allows routines to be nested one inside another as many times as there are spaces in the stack to hold the return addresses.

I think Batang is warning you that the stack can be used to carry variables into and out of functions as well so the stack can fill up quickly. Certainly in conventional C/C++, all function parameters are carried on the stack but in the case of PIC microcontrollers I'm not sure that's true. To save space and time. I would guess the stack only holds addresses and data is held in a reserved block of conventional memory instead. Someone with better knowledge of the inner workings of C32 can advise you better than me.

Brian.

I had read some where that, in pic address are passed to Stack Pointer, i had read all these things when reading books never know what it means in reality, today i came to know this.

Declaring two many local variable, will increase the stack size (Is it true, as i thinking calling functions inside a function will increase the stack size ) and what is best Declaring global or local variables.

- - - Updated - - -

Hi Arun,

Read this link for details https://en.wikipedia.org/wiki/Call_stack

Cheers.

@Brian, Likewise I have never used Pics and yes that was the warning.

Thanks i reading that.
 

As I mentioned earlier I have never used the C32 etc.

However here is some info (edited) for the ARM C/C++ compiler that can be used as a general guide.

Stack use in C and C++

C and C++ both use the stack intensively. For example, the stack holds:

The return address of functions.

Registers that must be preserved, for instance, when register contents are saved on entry into subroutines.

Local variables, including local arrays, structures, unions, and in C++, classes.

Some stack usage is not obvious, such as:

Local integer or floating point variables are allocated stack memory if they are spilled (that is, not allocated to a register).

Structures are normally allocated to the stack.

Arrays are always allocated to the stack.

Optimizations can introduce new temporary variables to hold intermediate results.

Stack use is difficult to estimate because it is code dependent, and can vary between runs depending on the code path that the program takes on execution.

In general, you can lower the stack requirements of your program by:

Writing small functions that only require a small number of variables.

Avoiding the use of large local structures or arrays.

Avoiding recursion, for example, by using an alternative algorithm.

Minimizing the number of variables that are in use at any given time at each point in a function.

Cheers.
 

Local variables are not held on the stack, the compiler will allocate a temporary address for them and when you leave the routine it will free the address for other parts of the program to use. So you are free to use as many local variables as you want without the stack size changing.

What we were referring to is passing variables in to a routine which *may* use stack space but I doubt it. For example, in conventional C on a PC if you called "myFunction(a,b,c,d);" it would put the return address on the stack and also the values of a, b, c and d. Inside "myFunction", it would extract the values of a, b, c and d from the stack for the function to use. In the case of a PIC that may not be the case, I suspect that only the return address is put on the stack and any variables are instead saved into a reserved block of normal memory.

You should be able to do a test - I do not have C32 here at the moment so I can't try it for you. Create a function with no parameters and make a call to it, look on the stack with the stack viewer and you should see it's return address appear in the list. Then change the function so it passes some variables and call it again, if the variables appear in the stack viewer they are being passed on the stack, if it looks like before with only one entry on the stack, they are being passed in memory. Try it with different numbers of variables and see what happens.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top