EmbeddedRelated.com
Forums

LPC2148 debugging a stack overflow problem - Keil

Started by Sutton Mehaffey June 27, 2012
After 2 days of debugging a possible stack overflow problem, I thought
someone on the forum might have a suggestion for the problem I'm
seeing. I have simplified the code to be a very simple snippet that
still exhibits the problem. Basically,

1. I setup the CPU for 12Mhz operation. This really entails setting
VPBDIV = 1, since I have a 12MHZ crystal input.
2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
for this test, so I let the clock just run.
3. I have a circular 4800 char UART0 buffer. I'm not turning on the
UART for this test. It is a global buffer.

My stack is 4K. My stack pointer starts out well above my data section,
according to the memory map and by looking at the debugger. What
happens is that when the Timer1 interrupt fires, the SP becomes a
location near location 3080 in my circular buffer. Therefore, in my
real system, it locks it up. Obviously, because the SP is corrupted.
In my snippet, when Timer1 gets decremented, and exits the interrupt,
the SP goes back to normal (same location as before it entered the
interrupt). I have not been able to figure out why the SP becomes a
part of my circular buffer during the ISR.

I can put breakpoints at the entry point to the ISR, and when it gets
there, the SP has been changed to a RAM address in my buffer. Below is
my snippet. My memory map looks good. The SP is well above the buffer
placement.
Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
Any ideas on things to look at and double check? I feel as though it's
something simple and I've overlooked it many times over. Thanks.
memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);

// sets up CPU clock speed to 12Mhz

VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
(CCLK)

PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
PLL0CFG = 0;
PLL0FEED = 0xAA;
PLL0FEED = 0x55;

PLL1CON = 0; // not used
PLL1FEED = 0xAA;
PLL1FEED = 0x55;

// Set up Timer Counter 1 and its Interrupt

PCONP |= 0x00000004; // ON by default, but just to be sure
T1CTCR = 0; // puts Timer 1 in timer mode
T1PR = 0; // One increment per PCLK
T1IR = 1; // reset Timer 1 interrupt flag
T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
12Mhz clock
T1MCR = 3; // enable interrupt on match, reset TC

// set up and start Timer1 interrupt

VICVectAddr3 = (unsigned long) timer1_int;
VICVectCntl3 = 0x25;
VICIntEnable |= 0x00000020;
T1TCR = 2; // reset timer
T1TCR = 1; // start timer

for (i = 0; i < 100; i++)
{
serial_input0[3072+i] = 0x66; // data gets written fine, but
then starts getting overwritten by the interrupt at 7 locations 3080-3086
}
for(;;);
******** every second when this interrupt fires, the SP gets corrupted
and 7 bytes of data gets changed in the circular buffer ********

void timer1_int(void) __irq
{
// occurs every 1 sec

delay_timer2--;
delay_timer3--;
delay_timer4--;

T1IR = 1;
VICVectAddr = 0; // Acknowledge interrupt
}
--
Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr. #100
Kennesaw, GA 30144
800-207-6269, 770-514-7999, 770-514-1285 FAX
s...@lookoutportablesecurity.com

An Engineer's Guide to the LPC2100 Series

It seems like you're not setting SP correctly for all operation modes.

You need to set up SP for IRQ mode to an address that is not colliding with
your data or bss sections. When your code enters the ISR most of the
registers (SP included) change because there is another set of registers
used in IRQ mode.

Just set up stack pointer in all modes at startup and your problem is
solved.

At Startup.S you'll need to have something smilar to:

/* Initialize stack pointers for all ARM modes */
MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
*/

MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
*/

MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
*/

MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
*/

MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
LDR sp,=__und_stack_top__ /* set the UND stack pointer
*/

MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
LDR sp,=__c_stack_top__ /* set the C stack pointer
*/

and in your linker script you need to set all those stack top addresses,
something similar to:

IRQ_STACK_SIZE = 512;
FIQ_STACK_SIZE = 256;
SVC_STACK_SIZE = 1K;
ABT_STACK_SIZE = 0;
UND_STACK_SIZE = 0;
C_STACK_SIZE = 1K;

/* set stack end to the end of RAM and stack start to the first unused RAM
address */
__stack_start__ = __end;
__stack_end__ = 0x40000000 + 64K;
/* and set the stacks locations */
__und_stack_top__ = __stack_end__;
__abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
__svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
__fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
__irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
__c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;

Regards,
Bernardo Marques

On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
s...@lookoutportablesecurity.com> wrote:

> **
> After 2 days of debugging a possible stack overflow problem, I thought
> someone on the forum might have a suggestion for the problem I'm
> seeing. I have simplified the code to be a very simple snippet that
> still exhibits the problem. Basically,
>
> 1. I setup the CPU for 12Mhz operation. This really entails setting
> VPBDIV = 1, since I have a 12MHZ crystal input.
> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
> for this test, so I let the clock just run.
> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
> UART for this test. It is a global buffer.
>
> My stack is 4K. My stack pointer starts out well above my data section,
> according to the memory map and by looking at the debugger. What
> happens is that when the Timer1 interrupt fires, the SP becomes a
> location near location 3080 in my circular buffer. Therefore, in my
> real system, it locks it up. Obviously, because the SP is corrupted.
> In my snippet, when Timer1 gets decremented, and exits the interrupt,
> the SP goes back to normal (same location as before it entered the
> interrupt). I have not been able to figure out why the SP becomes a
> part of my circular buffer during the ISR.
>
> I can put breakpoints at the entry point to the ISR, and when it gets
> there, the SP has been changed to a RAM address in my buffer. Below is
> my snippet. My memory map looks good. The SP is well above the buffer
> placement.
>
> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
>
> Any ideas on things to look at and double check? I feel as though it's
> something simple and I've overlooked it many times over. Thanks.
>
> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
>
> // sets up CPU clock speed to 12Mhz
>
> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
> (CCLK)
>
> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
> PLL0CFG = 0;
> PLL0FEED = 0xAA;
> PLL0FEED = 0x55;
>
> PLL1CON = 0; // not used
> PLL1FEED = 0xAA;
> PLL1FEED = 0x55;
>
> // Set up Timer Counter 1 and its Interrupt
>
> PCONP |= 0x00000004; // ON by default, but just to be sure
> T1CTCR = 0; // puts Timer 1 in timer mode
> T1PR = 0; // One increment per PCLK
> T1IR = 1; // reset Timer 1 interrupt flag
> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
> 12Mhz clock
> T1MCR = 3; // enable interrupt on match, reset TC
>
> // set up and start Timer1 interrupt
>
> VICVectAddr3 = (unsigned long) timer1_int;
> VICVectCntl3 = 0x25;
> VICIntEnable |= 0x00000020;
> T1TCR = 2; // reset timer
> T1TCR = 1; // start timer
>
> for (i = 0; i < 100; i++)
> {
> serial_input0[3072+i] = 0x66; // data gets written fine, but
> then starts getting overwritten by the interrupt at 7 locations 3080-3086
> }
> for(;;);
>
> ******** every second when this interrupt fires, the SP gets corrupted
> and 7 bytes of data gets changed in the circular buffer ********
>
> void timer1_int(void) __irq
> {
> // occurs every 1 sec
>
> delay_timer2--;
> delay_timer3--;
> delay_timer4--;
>
> T1IR = 1;
> VICVectAddr = 0; // Acknowledge interrupt
> }
>
> --
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr. #100
> Kennesaw, GA 30144
> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> s...@lookoutportablesecurity.com
>
>
>


That's all done in the 'Startup.s' file. I'll go double check that
again. It looks OK.

Sutton

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com
On 6/28/2012 3:06 AM, Bernardo Marques wrote:
> It seems like you're not setting SP correctly for all operation modes.
>
> You need to set up SP for IRQ mode to an address that is not colliding with
> your data or bss sections. When your code enters the ISR most of the
> registers (SP included) change because there is another set of registers
> used in IRQ mode.
>
> Just set up stack pointer in all modes at startup and your problem is
> solved.
>
> At Startup.S you'll need to have something smilar to:
>
> /* Initialize stack pointers for all ARM modes */
> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
> */
>
> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
> */
>
> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
> */
>
> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
> */
>
> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
> LDR sp,=__und_stack_top__ /* set the UND stack pointer
> */
>
> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
> LDR sp,=__c_stack_top__ /* set the C stack pointer
> */
>
> and in your linker script you need to set all those stack top addresses,
> something similar to:
>
> IRQ_STACK_SIZE = 512;
> FIQ_STACK_SIZE = 256;
> SVC_STACK_SIZE = 1K;
> ABT_STACK_SIZE = 0;
> UND_STACK_SIZE = 0;
> C_STACK_SIZE = 1K;
>
> /* set stack end to the end of RAM and stack start to the first unused RAM
> address */
> __stack_start__ = __end;
> __stack_end__ = 0x40000000 + 64K;
> /* and set the stacks locations */
> __und_stack_top__ = __stack_end__;
> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
>
> Regards,
> Bernardo Marques
>
> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
> s...@lookoutportablesecurity.com> wrote:
>
>> **
>> After 2 days of debugging a possible stack overflow problem, I thought
>> someone on the forum might have a suggestion for the problem I'm
>> seeing. I have simplified the code to be a very simple snippet that
>> still exhibits the problem. Basically,
>>
>> 1. I setup the CPU for 12Mhz operation. This really entails setting
>> VPBDIV = 1, since I have a 12MHZ crystal input.
>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
>> for this test, so I let the clock just run.
>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
>> UART for this test. It is a global buffer.
>>
>> My stack is 4K. My stack pointer starts out well above my data section,
>> according to the memory map and by looking at the debugger. What
>> happens is that when the Timer1 interrupt fires, the SP becomes a
>> location near location 3080 in my circular buffer. Therefore, in my
>> real system, it locks it up. Obviously, because the SP is corrupted.
>> In my snippet, when Timer1 gets decremented, and exits the interrupt,
>> the SP goes back to normal (same location as before it entered the
>> interrupt). I have not been able to figure out why the SP becomes a
>> part of my circular buffer during the ISR.
>>
>> I can put breakpoints at the entry point to the ISR, and when it gets
>> there, the SP has been changed to a RAM address in my buffer. Below is
>> my snippet. My memory map looks good. The SP is well above the buffer
>> placement.
>>
>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
>>
>> Any ideas on things to look at and double check? I feel as though it's
>> something simple and I've overlooked it many times over. Thanks.
>>
>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
>>
>> // sets up CPU clock speed to 12Mhz
>>
>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
>> (CCLK)
>>
>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
>> PLL0CFG = 0;
>> PLL0FEED = 0xAA;
>> PLL0FEED = 0x55;
>>
>> PLL1CON = 0; // not used
>> PLL1FEED = 0xAA;
>> PLL1FEED = 0x55;
>>
>> // Set up Timer Counter 1 and its Interrupt
>>
>> PCONP |= 0x00000004; // ON by default, but just to be sure
>> T1CTCR = 0; // puts Timer 1 in timer mode
>> T1PR = 0; // One increment per PCLK
>> T1IR = 1; // reset Timer 1 interrupt flag
>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
>> 12Mhz clock
>> T1MCR = 3; // enable interrupt on match, reset TC
>>
>> // set up and start Timer1 interrupt
>>
>> VICVectAddr3 = (unsigned long) timer1_int;
>> VICVectCntl3 = 0x25;
>> VICIntEnable |= 0x00000020;
>> T1TCR = 2; // reset timer
>> T1TCR = 1; // start timer
>>
>> for (i = 0; i < 100; i++)
>> {
>> serial_input0[3072+i] = 0x66; // data gets written fine, but
>> then starts getting overwritten by the interrupt at 7 locations 3080-3086
>> }
>> for(;;);
>>
>> ******** every second when this interrupt fires, the SP gets corrupted
>> and 7 bytes of data gets changed in the circular buffer ********
>>
>> void timer1_int(void) __irq
>> {
>> // occurs every 1 sec
>>
>> delay_timer2--;
>> delay_timer3--;
>> delay_timer4--;
>>
>> T1IR = 1;
>> VICVectAddr = 0; // Acknowledge interrupt
>> }
>>
>> --
>> Sutton Mehaffey
>> Lookout Portable Security
>> 4040 Royal Dr. #100
>> Kennesaw, GA 30144
>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
>> s...@lookoutportablesecurity.com
>>
>>
>>
>
>
Check your map file and see what is the base address to which you set the
IRQ SP (in my case the value of __irq_stack_top__).

Bernardo.
On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
s...@lookoutportablesecurity.com> wrote:

> **
> That's all done in the 'Startup.s' file. I'll go double check that
> again. It looks OK.
>
> Sutton
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr.
> Kennesaw, GA 30144
> 770-514-7999, 800-207-6269
> Fax: 770-514-1285
> http://www.lookoutportablesecurity.com
> s...@lookoutportablesecurity.com
>
> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
> > It seems like you're not setting SP correctly for all operation modes.
> >
> > You need to set up SP for IRQ mode to an address that is not colliding
> with
> > your data or bss sections. When your code enters the ISR most of the
> > registers (SP included) change because there is another set of registers
> > used in IRQ mode.
> >
> > Just set up stack pointer in all modes at startup and your problem is
> > solved.
> >
> > At Startup.S you'll need to have something smilar to:
> >
> > /* Initialize stack pointers for all ARM modes */
> > MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
> > LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
> > */
> >
> > MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
> > LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
> > */
> >
> > MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
> > LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
> > */
> >
> > MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
> > LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
> > */
> >
> > MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
> > LDR sp,=__und_stack_top__ /* set the UND stack pointer
> > */
> >
> > MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
> > LDR sp,=__c_stack_top__ /* set the C stack pointer
> > */
> >
> > and in your linker script you need to set all those stack top addresses,
> > something similar to:
> >
> > IRQ_STACK_SIZE = 512;
> > FIQ_STACK_SIZE = 256;
> > SVC_STACK_SIZE = 1K;
> > ABT_STACK_SIZE = 0;
> > UND_STACK_SIZE = 0;
> > C_STACK_SIZE = 1K;
> >
> > /* set stack end to the end of RAM and stack start to the first unused
> RAM
> > address */
> > __stack_start__ = __end;
> > __stack_end__ = 0x40000000 + 64K;
> > /* and set the stacks locations */
> > __und_stack_top__ = __stack_end__;
> > __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
> > __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
> > __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
> > __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
> > __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
> >
> > Regards,
> > Bernardo Marques
> >
> >
> >
> > On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
> > s...@lookoutportablesecurity.com> wrote:
> >
> >> **
>
> >>
> >>
> >> After 2 days of debugging a possible stack overflow problem, I thought
> >> someone on the forum might have a suggestion for the problem I'm
> >> seeing. I have simplified the code to be a very simple snippet that
> >> still exhibits the problem. Basically,
> >>
> >> 1. I setup the CPU for 12Mhz operation. This really entails setting
> >> VPBDIV = 1, since I have a 12MHZ crystal input.
> >> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
> >> for this test, so I let the clock just run.
> >> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
> >> UART for this test. It is a global buffer.
> >>
> >> My stack is 4K. My stack pointer starts out well above my data section,
> >> according to the memory map and by looking at the debugger. What
> >> happens is that when the Timer1 interrupt fires, the SP becomes a
> >> location near location 3080 in my circular buffer. Therefore, in my
> >> real system, it locks it up. Obviously, because the SP is corrupted.
> >> In my snippet, when Timer1 gets decremented, and exits the interrupt,
> >> the SP goes back to normal (same location as before it entered the
> >> interrupt). I have not been able to figure out why the SP becomes a
> >> part of my circular buffer during the ISR.
> >>
> >> I can put breakpoints at the entry point to the ISR, and when it gets
> >> there, the SP has been changed to a RAM address in my buffer. Below is
> >> my snippet. My memory map looks good. The SP is well above the buffer
> >> placement.
> >>
> >> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
> >> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
> >> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
> >>
> >> Any ideas on things to look at and double check? I feel as though it's
> >> something simple and I've overlooked it many times over. Thanks.
> >>
> >> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
> >>
> >> // sets up CPU clock speed to 12Mhz
> >>
> >> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
> >> (CCLK)
> >>
> >> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
> >> PLL0CFG = 0;
> >> PLL0FEED = 0xAA;
> >> PLL0FEED = 0x55;
> >>
> >> PLL1CON = 0; // not used
> >> PLL1FEED = 0xAA;
> >> PLL1FEED = 0x55;
> >>
> >> // Set up Timer Counter 1 and its Interrupt
> >>
> >> PCONP |= 0x00000004; // ON by default, but just to be sure
> >> T1CTCR = 0; // puts Timer 1 in timer mode
> >> T1PR = 0; // One increment per PCLK
> >> T1IR = 1; // reset Timer 1 interrupt flag
> >> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
> >> 12Mhz clock
> >> T1MCR = 3; // enable interrupt on match, reset TC
> >>
> >> // set up and start Timer1 interrupt
> >>
> >> VICVectAddr3 = (unsigned long) timer1_int;
> >> VICVectCntl3 = 0x25;
> >> VICIntEnable |= 0x00000020;
> >> T1TCR = 2; // reset timer
> >> T1TCR = 1; // start timer
> >>
> >> for (i = 0; i < 100; i++)
> >> {
> >> serial_input0[3072+i] = 0x66; // data gets written fine, but
> >> then starts getting overwritten by the interrupt at 7 locations
> 3080-3086
> >> }
> >> for(;;);
> >>
> >> ******** every second when this interrupt fires, the SP gets corrupted
> >> and 7 bytes of data gets changed in the circular buffer ********
> >>
> >> void timer1_int(void) __irq
> >> {
> >> // occurs every 1 sec
> >>
> >> delay_timer2--;
> >> delay_timer3--;
> >> delay_timer4--;
> >>
> >> T1IR = 1;
> >> VICVectAddr = 0; // Acknowledge interrupt
> >> }
> >>
> >> --
> >> Sutton Mehaffey
> >> Lookout Portable Security
> >> 4040 Royal Dr. #100
> >> Kennesaw, GA 30144
> >> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> >> s...@lookoutportablesecurity.com
> >>
> >>
> >>
> >
> >
> >
> >
> >
> >
> >
> >
Not exactly sure what you mean. I'm using Keil's provided startup.s file
for LPC21xx (see below stack portions) and I changed the USR stack to 4K
from 2K. That's all I've changed from the default.

UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000008
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00001000

ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)

AREA STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size

Stack_Top

; Setup Stack for each mode

LDR R0, =Stack_Top

; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size

; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size

; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size

; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size

; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size

; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB

EXPORT __initial_sp

ELSE

MOV SP, R0
SUB SL, SP, #USR_Stack_Size

ENDIF
Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com
On 6/28/2012 10:04 AM, Bernardo Marques wrote:
> Check your map file and see what is the base address to which you set the
> IRQ SP (in my case the value of __irq_stack_top__).
>
> Bernardo.
> On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
> s...@lookoutportablesecurity.com> wrote:
>
>> **
>> That's all done in the 'Startup.s' file. I'll go double check that
>> again. It looks OK.
>>
>> Sutton
>> Sutton Mehaffey
>> Lookout Portable Security
>> 4040 Royal Dr.
>> Kennesaw, GA 30144
>> 770-514-7999, 800-207-6269
>> Fax: 770-514-1285
>> http://www.lookoutportablesecurity.com
>> s...@lookoutportablesecurity.com
>>
>> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
>>> It seems like you're not setting SP correctly for all operation modes.
>>>
>>> You need to set up SP for IRQ mode to an address that is not colliding
>> with
>>> your data or bss sections. When your code enters the ISR most of the
>>> registers (SP included) change because there is another set of registers
>>> used in IRQ mode.
>>>
>>> Just set up stack pointer in all modes at startup and your problem is
>>> solved.
>>>
>>> At Startup.S you'll need to have something smilar to:
>>>
>>> /* Initialize stack pointers for all ARM modes */
>>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
>>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
>>> */
>>>
>>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
>>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
>>> */
>>>
>>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
>>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
>>> */
>>>
>>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
>>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
>>> */
>>>
>>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
>>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
>>> */
>>>
>>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
>>> LDR sp,=__c_stack_top__ /* set the C stack pointer
>>> */
>>>
>>> and in your linker script you need to set all those stack top addresses,
>>> something similar to:
>>>
>>> IRQ_STACK_SIZE = 512;
>>> FIQ_STACK_SIZE = 256;
>>> SVC_STACK_SIZE = 1K;
>>> ABT_STACK_SIZE = 0;
>>> UND_STACK_SIZE = 0;
>>> C_STACK_SIZE = 1K;
>>>
>>> /* set stack end to the end of RAM and stack start to the first unused
>> RAM
>>> address */
>>> __stack_start__ = __end;
>>> __stack_end__ = 0x40000000 + 64K;
>>> /* and set the stacks locations */
>>> __und_stack_top__ = __stack_end__;
>>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
>>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
>>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
>>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
>>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
>>>
>>> Regards,
>>> Bernardo Marques
>>>
>>>
>>>
>>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
>>> s...@lookoutportablesecurity.com> wrote:
>>>
>>>> **
>>>>
>>>> After 2 days of debugging a possible stack overflow problem, I thought
>>>> someone on the forum might have a suggestion for the problem I'm
>>>> seeing. I have simplified the code to be a very simple snippet that
>>>> still exhibits the problem. Basically,
>>>>
>>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
>>>> VPBDIV = 1, since I have a 12MHZ crystal input.
>>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
>>>> for this test, so I let the clock just run.
>>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
>>>> UART for this test. It is a global buffer.
>>>>
>>>> My stack is 4K. My stack pointer starts out well above my data section,
>>>> according to the memory map and by looking at the debugger. What
>>>> happens is that when the Timer1 interrupt fires, the SP becomes a
>>>> location near location 3080 in my circular buffer. Therefore, in my
>>>> real system, it locks it up. Obviously, because the SP is corrupted.
>>>> In my snippet, when Timer1 gets decremented, and exits the interrupt,
>>>> the SP goes back to normal (same location as before it entered the
>>>> interrupt). I have not been able to figure out why the SP becomes a
>>>> part of my circular buffer during the ISR.
>>>>
>>>> I can put breakpoints at the entry point to the ISR, and when it gets
>>>> there, the SP has been changed to a RAM address in my buffer. Below is
>>>> my snippet. My memory map looks good. The SP is well above the buffer
>>>> placement.
>>>>
>>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
>>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
>>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
>>>>
>>>> Any ideas on things to look at and double check? I feel as though it's
>>>> something simple and I've overlooked it many times over. Thanks.
>>>>
>>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
>>>>
>>>> // sets up CPU clock speed to 12Mhz
>>>>
>>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
>>>> (CCLK)
>>>>
>>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
>>>> PLL0CFG = 0;
>>>> PLL0FEED = 0xAA;
>>>> PLL0FEED = 0x55;
>>>>
>>>> PLL1CON = 0; // not used
>>>> PLL1FEED = 0xAA;
>>>> PLL1FEED = 0x55;
>>>>
>>>> // Set up Timer Counter 1 and its Interrupt
>>>>
>>>> PCONP |= 0x00000004; // ON by default, but just to be sure
>>>> T1CTCR = 0; // puts Timer 1 in timer mode
>>>> T1PR = 0; // One increment per PCLK
>>>> T1IR = 1; // reset Timer 1 interrupt flag
>>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
>>>> 12Mhz clock
>>>> T1MCR = 3; // enable interrupt on match, reset TC
>>>>
>>>> // set up and start Timer1 interrupt
>>>>
>>>> VICVectAddr3 = (unsigned long) timer1_int;
>>>> VICVectCntl3 = 0x25;
>>>> VICIntEnable |= 0x00000020;
>>>> T1TCR = 2; // reset timer
>>>> T1TCR = 1; // start timer
>>>>
>>>> for (i = 0; i < 100; i++)
>>>> {
>>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
>>>> then starts getting overwritten by the interrupt at 7 locations
>> 3080-3086
>>>> }
>>>> for(;;);
>>>>
>>>> ******** every second when this interrupt fires, the SP gets corrupted
>>>> and 7 bytes of data gets changed in the circular buffer ********
>>>>
>>>> void timer1_int(void) __irq
>>>> {
>>>> // occurs every 1 sec
>>>>
>>>> delay_timer2--;
>>>> delay_timer3--;
>>>> delay_timer4--;
>>>>
>>>> T1IR = 1;
>>>> VICVectAddr = 0; // Acknowledge interrupt
>>>> }
>>>>
>>>> --
>>>> Sutton Mehaffey
>>>> Lookout Portable Security
>>>> 4040 Royal Dr. #100
>>>> Kennesaw, GA 30144
>>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
>>>> s...@lookoutportablesecurity.com
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
So, your ISR stack size is 0x88 (0+8+0+0+80) bytes = 34 words. Are you sure that is enough?
--- In l..., Sutton Mehaffey wrote:
>
> Not exactly sure what you mean. I'm using Keil's provided startup.s file
> for LPC21xx (see below stack portions) and I changed the USR stack to 4K
> from 2K. That's all I've changed from the default.
>
> UND_Stack_Size EQU 0x00000000
> SVC_Stack_Size EQU 0x00000008
> ABT_Stack_Size EQU 0x00000000
> FIQ_Stack_Size EQU 0x00000000
> IRQ_Stack_Size EQU 0x00000080
> USR_Stack_Size EQU 0x00001000
>
> ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
> ABT_Stack_Size + \
> FIQ_Stack_Size + IRQ_Stack_Size)
>
> AREA STACK, NOINIT, READWRITE, ALIGN=3
>
> Stack_Mem SPACE USR_Stack_Size
> __initial_sp SPACE ISR_Stack_Size
>
> Stack_Top
> ; Setup Stack for each mode
>
> LDR R0, =Stack_Top
>
> ; Enter Undefined Instruction Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #UND_Stack_Size
>
> ; Enter Abort Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #ABT_Stack_Size
>
> ; Enter FIQ Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #FIQ_Stack_Size
>
> ; Enter IRQ Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #IRQ_Stack_Size
>
> ; Enter Supervisor Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #SVC_Stack_Size
>
> ; Enter User Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_USR
> IF :DEF:__MICROLIB
>
> EXPORT __initial_sp
>
> ELSE
>
> MOV SP, R0
> SUB SL, SP, #USR_Stack_Size
>
> ENDIF
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr.
> Kennesaw, GA 30144
> 770-514-7999, 800-207-6269
> Fax: 770-514-1285
> http://www.lookoutportablesecurity.com
> sutton@...
> On 6/28/2012 10:04 AM, Bernardo Marques wrote:
> > Check your map file and see what is the base address to which you set the
> > IRQ SP (in my case the value of __irq_stack_top__).
> >
> > Bernardo.
> >
> >
> > On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
> > sutton@...> wrote:
> >
> >> **
> >>
> >>
> >> That's all done in the 'Startup.s' file. I'll go double check that
> >> again. It looks OK.
> >>
> >> Sutton
> >>
> >>
> >> Sutton Mehaffey
> >> Lookout Portable Security
> >> 4040 Royal Dr.
> >> Kennesaw, GA 30144
> >> 770-514-7999, 800-207-6269
> >> Fax: 770-514-1285
> >> http://www.lookoutportablesecurity.com
> >> sutton@...
> >>
> >> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
> >>> It seems like you're not setting SP correctly for all operation modes.
> >>>
> >>> You need to set up SP for IRQ mode to an address that is not colliding
> >> with
> >>> your data or bss sections. When your code enters the ISR most of the
> >>> registers (SP included) change because there is another set of registers
> >>> used in IRQ mode.
> >>>
> >>> Just set up stack pointer in all modes at startup and your problem is
> >>> solved.
> >>>
> >>> At Startup.S you'll need to have something smilar to:
> >>>
> >>> /* Initialize stack pointers for all ARM modes */
> >>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__c_stack_top__ /* set the C stack pointer
> >>> */
> >>>
> >>> and in your linker script you need to set all those stack top addresses,
> >>> something similar to:
> >>>
> >>> IRQ_STACK_SIZE = 512;
> >>> FIQ_STACK_SIZE = 256;
> >>> SVC_STACK_SIZE = 1K;
> >>> ABT_STACK_SIZE = 0;
> >>> UND_STACK_SIZE = 0;
> >>> C_STACK_SIZE = 1K;
> >>>
> >>> /* set stack end to the end of RAM and stack start to the first unused
> >> RAM
> >>> address */
> >>> __stack_start__ = __end;
> >>> __stack_end__ = 0x40000000 + 64K;
> >>> /* and set the stacks locations */
> >>> __und_stack_top__ = __stack_end__;
> >>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
> >>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
> >>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
> >>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
> >>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
> >>>
> >>> Regards,
> >>> Bernardo Marques
> >>>
> >>>
> >>>
> >>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
> >>> sutton@...> wrote:
> >>>
> >>>> **
> >>>>
> >>>> After 2 days of debugging a possible stack overflow problem, I thought
> >>>> someone on the forum might have a suggestion for the problem I'm
> >>>> seeing. I have simplified the code to be a very simple snippet that
> >>>> still exhibits the problem. Basically,
> >>>>
> >>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
> >>>> VPBDIV = 1, since I have a 12MHZ crystal input.
> >>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
> >>>> for this test, so I let the clock just run.
> >>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
> >>>> UART for this test. It is a global buffer.
> >>>>
> >>>> My stack is 4K. My stack pointer starts out well above my data section,
> >>>> according to the memory map and by looking at the debugger. What
> >>>> happens is that when the Timer1 interrupt fires, the SP becomes a
> >>>> location near location 3080 in my circular buffer. Therefore, in my
> >>>> real system, it locks it up. Obviously, because the SP is corrupted.
> >>>> In my snippet, when Timer1 gets decremented, and exits the interrupt,
> >>>> the SP goes back to normal (same location as before it entered the
> >>>> interrupt). I have not been able to figure out why the SP becomes a
> >>>> part of my circular buffer during the ISR.
> >>>>
> >>>> I can put breakpoints at the entry point to the ISR, and when it gets
> >>>> there, the SP has been changed to a RAM address in my buffer. Below is
> >>>> my snippet. My memory map looks good. The SP is well above the buffer
> >>>> placement.
> >>>>
> >>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
> >>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
> >>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
> >>>>
> >>>> Any ideas on things to look at and double check? I feel as though it's
> >>>> something simple and I've overlooked it many times over. Thanks.
> >>>>
> >>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
> >>>>
> >>>> // sets up CPU clock speed to 12Mhz
> >>>>
> >>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
> >>>> (CCLK)
> >>>>
> >>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
> >>>> PLL0CFG = 0;
> >>>> PLL0FEED = 0xAA;
> >>>> PLL0FEED = 0x55;
> >>>>
> >>>> PLL1CON = 0; // not used
> >>>> PLL1FEED = 0xAA;
> >>>> PLL1FEED = 0x55;
> >>>>
> >>>> // Set up Timer Counter 1 and its Interrupt
> >>>>
> >>>> PCONP |= 0x00000004; // ON by default, but just to be sure
> >>>> T1CTCR = 0; // puts Timer 1 in timer mode
> >>>> T1PR = 0; // One increment per PCLK
> >>>> T1IR = 1; // reset Timer 1 interrupt flag
> >>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
> >>>> 12Mhz clock
> >>>> T1MCR = 3; // enable interrupt on match, reset TC
> >>>>
> >>>> // set up and start Timer1 interrupt
> >>>>
> >>>> VICVectAddr3 = (unsigned long) timer1_int;
> >>>> VICVectCntl3 = 0x25;
> >>>> VICIntEnable |= 0x00000020;
> >>>> T1TCR = 2; // reset timer
> >>>> T1TCR = 1; // start timer
> >>>>
> >>>> for (i = 0; i < 100; i++)
> >>>> {
> >>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
> >>>> then starts getting overwritten by the interrupt at 7 locations
> >> 3080-3086
> >>>> }
> >>>> for(;;);
> >>>>
> >>>> ******** every second when this interrupt fires, the SP gets corrupted
> >>>> and 7 bytes of data gets changed in the circular buffer ********
> >>>>
> >>>> void timer1_int(void) __irq
> >>>> {
> >>>> // occurs every 1 sec
> >>>>
> >>>> delay_timer2--;
> >>>> delay_timer3--;
> >>>> delay_timer4--;
> >>>>
> >>>> T1IR = 1;
> >>>> VICVectAddr = 0; // Acknowledge interrupt
> >>>> }
> >>>>
> >>>> --
> >>>> Sutton Mehaffey
> >>>> Lookout Portable Security
> >>>> 4040 Royal Dr. #100
> >>>> Kennesaw, GA 30144
> >>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> >>>> sutton@...
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
All seems ok in here... you're setting IRQ SP to 'Stack_Top - 8' and after
your IRQ stack is the USR stack, if there was a stack overflow in IRQ mode
you'd most probably overwrite the USR stack (and your program would
behave unpredictably after the return from ISR) than variables in your
code. As long as you don't use FIQ, ABT, UND and SVC modes your stacks seem
to be just fine.
Can you show me the part in your .map file with the addresses given
to 'Stack_Mem', '__initial_sp', 'Stack_Top' and for the 'serial_input0'
variable?

Regards,
Bernardo Marques.

On Thu, Jun 28, 2012 at 3:45 PM, Sutton Mehaffey <
s...@lookoutportablesecurity.com> wrote:

> **
> Not exactly sure what you mean. I'm using Keil's provided startup.s file
> for LPC21xx (see below stack portions) and I changed the USR stack to 4K
> from 2K. That's all I've changed from the default.
>
> UND_Stack_Size EQU 0x00000000
> SVC_Stack_Size EQU 0x00000008
> ABT_Stack_Size EQU 0x00000000
> FIQ_Stack_Size EQU 0x00000000
> IRQ_Stack_Size EQU 0x00000080
> USR_Stack_Size EQU 0x00001000
>
> ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
> ABT_Stack_Size + \
> FIQ_Stack_Size + IRQ_Stack_Size)
>
> AREA STACK, NOINIT, READWRITE, ALIGN=3
>
> Stack_Mem SPACE USR_Stack_Size
> __initial_sp SPACE ISR_Stack_Size
>
> Stack_Top
>
> ; Setup Stack for each mode
>
> LDR R0, =Stack_Top
>
> ; Enter Undefined Instruction Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #UND_Stack_Size
>
> ; Enter Abort Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #ABT_Stack_Size
>
> ; Enter FIQ Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #FIQ_Stack_Size
>
> ; Enter IRQ Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #IRQ_Stack_Size
>
> ; Enter Supervisor Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
> MOV SP, R0
> SUB R0, R0, #SVC_Stack_Size
>
> ; Enter User Mode and set its Stack Pointer
> MSR CPSR_c, #Mode_USR
> IF :DEF:__MICROLIB
>
> EXPORT __initial_sp
>
> ELSE
>
> MOV SP, R0
> SUB SL, SP, #USR_Stack_Size
>
> ENDIF
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr.
> Kennesaw, GA 30144
> 770-514-7999, 800-207-6269
> Fax: 770-514-1285
> http://www.lookoutportablesecurity.com
> s...@lookoutportablesecurity.com
> On 6/28/2012 10:04 AM, Bernardo Marques wrote:
> > Check your map file and see what is the base address to which you set the
> > IRQ SP (in my case the value of __irq_stack_top__).
> >
> > Bernardo.
> >
> >
> > On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
> > s...@lookoutportablesecurity.com> wrote:
> >
> >> **
>
> >>
> >>
> >> That's all done in the 'Startup.s' file. I'll go double check that
> >> again. It looks OK.
> >>
> >> Sutton
> >>
> >>
> >> Sutton Mehaffey
> >> Lookout Portable Security
> >> 4040 Royal Dr.
> >> Kennesaw, GA 30144
> >> 770-514-7999, 800-207-6269
> >> Fax: 770-514-1285
> >> http://www.lookoutportablesecurity.com
> >> s...@lookoutportablesecurity.com
> >>
> >> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
> >>> It seems like you're not setting SP correctly for all operation modes.
> >>>
> >>> You need to set up SP for IRQ mode to an address that is not colliding
> >> with
> >>> your data or bss sections. When your code enters the ISR most of the
> >>> registers (SP included) change because there is another set of
> registers
> >>> used in IRQ mode.
> >>>
> >>> Just set up stack pointer in all modes at startup and your problem is
> >>> solved.
> >>>
> >>> At Startup.S you'll need to have something smilar to:
> >>>
> >>> /* Initialize stack pointers for all ARM modes */
> >>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
> >>> */
> >>>
> >>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
> >>> LDR sp,=__c_stack_top__ /* set the C stack pointer
> >>> */
> >>>
> >>> and in your linker script you need to set all those stack top
> addresses,
> >>> something similar to:
> >>>
> >>> IRQ_STACK_SIZE = 512;
> >>> FIQ_STACK_SIZE = 256;
> >>> SVC_STACK_SIZE = 1K;
> >>> ABT_STACK_SIZE = 0;
> >>> UND_STACK_SIZE = 0;
> >>> C_STACK_SIZE = 1K;
> >>>
> >>> /* set stack end to the end of RAM and stack start to the first unused
> >> RAM
> >>> address */
> >>> __stack_start__ = __end;
> >>> __stack_end__ = 0x40000000 + 64K;
> >>> /* and set the stacks locations */
> >>> __und_stack_top__ = __stack_end__;
> >>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
> >>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
> >>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
> >>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
> >>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
> >>>
> >>> Regards,
> >>> Bernardo Marques
> >>>
> >>>
> >>>
> >>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
> >>> s...@lookoutportablesecurity.com> wrote:
> >>>
> >>>> **
> >>>>
> >>>> After 2 days of debugging a possible stack overflow problem, I thought
> >>>> someone on the forum might have a suggestion for the problem I'm
> >>>> seeing. I have simplified the code to be a very simple snippet that
> >>>> still exhibits the problem. Basically,
> >>>>
> >>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
> >>>> VPBDIV = 1, since I have a 12MHZ crystal input.
> >>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
> >>>> for this test, so I let the clock just run.
> >>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
> >>>> UART for this test. It is a global buffer.
> >>>>
> >>>> My stack is 4K. My stack pointer starts out well above my data
> section,
> >>>> according to the memory map and by looking at the debugger. What
> >>>> happens is that when the Timer1 interrupt fires, the SP becomes a
> >>>> location near location 3080 in my circular buffer. Therefore, in my
> >>>> real system, it locks it up. Obviously, because the SP is corrupted.
> >>>> In my snippet, when Timer1 gets decremented, and exits the interrupt,
> >>>> the SP goes back to normal (same location as before it entered the
> >>>> interrupt). I have not been able to figure out why the SP becomes a
> >>>> part of my circular buffer during the ISR.
> >>>>
> >>>> I can put breakpoints at the entry point to the ISR, and when it gets
> >>>> there, the SP has been changed to a RAM address in my buffer. Below is
> >>>> my snippet. My memory map looks good. The SP is well above the buffer
> >>>> placement.
> >>>>
> >>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
> >>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
> >>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
> >>>>
> >>>> Any ideas on things to look at and double check? I feel as though it's
> >>>> something simple and I've overlooked it many times over. Thanks.
> >>>>
> >>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
> >>>>
> >>>> // sets up CPU clock speed to 12Mhz
> >>>>
> >>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
> >>>> (CCLK)
> >>>>
> >>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
> >>>> PLL0CFG = 0;
> >>>> PLL0FEED = 0xAA;
> >>>> PLL0FEED = 0x55;
> >>>>
> >>>> PLL1CON = 0; // not used
> >>>> PLL1FEED = 0xAA;
> >>>> PLL1FEED = 0x55;
> >>>>
> >>>> // Set up Timer Counter 1 and its Interrupt
> >>>>
> >>>> PCONP |= 0x00000004; // ON by default, but just to be sure
> >>>> T1CTCR = 0; // puts Timer 1 in timer mode
> >>>> T1PR = 0; // One increment per PCLK
> >>>> T1IR = 1; // reset Timer 1 interrupt flag
> >>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
> >>>> 12Mhz clock
> >>>> T1MCR = 3; // enable interrupt on match, reset TC
> >>>>
> >>>> // set up and start Timer1 interrupt
> >>>>
> >>>> VICVectAddr3 = (unsigned long) timer1_int;
> >>>> VICVectCntl3 = 0x25;
> >>>> VICIntEnable |= 0x00000020;
> >>>> T1TCR = 2; // reset timer
> >>>> T1TCR = 1; // start timer
> >>>>
> >>>> for (i = 0; i < 100; i++)
> >>>> {
> >>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
> >>>> then starts getting overwritten by the interrupt at 7 locations
> >> 3080-3086
> >>>> }
> >>>> for(;;);
> >>>>
> >>>> ******** every second when this interrupt fires, the SP gets corrupted
> >>>> and 7 bytes of data gets changed in the circular buffer ********
> >>>>
> >>>> void timer1_int(void) __irq
> >>>> {
> >>>> // occurs every 1 sec
> >>>>
> >>>> delay_timer2--;
> >>>> delay_timer3--;
> >>>> delay_timer4--;
> >>>>
> >>>> T1IR = 1;
> >>>> VICVectAddr = 0; // Acknowledge interrupt
> >>>> }
> >>>>
> >>>> --
> >>>> Sutton Mehaffey
> >>>> Lookout Portable Security
> >>>> 4040 Royal Dr. #100
> >>>> Kennesaw, GA 30144
> >>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> >>>> s...@lookoutportablesecurity.com
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
.data 0x40000800 Section 11
en4200.o(.data)
.data 0x40000810 Section
156 lookout.o(.data)
.data 0x400008ac Section
20 rtc.o(.data)

HEAP 0x40004580 Section
0 startup.o(HEAP)
STACK 0x40004580 Section
4232 startup.o(STACK)
Heap_Mem 0x40004580 Data
0 startup.o(HEAP)
Stack_Mem 0x40004580 Data
4096 startup.o(STACK)
Stack_Top 0x40005608 Data
0 startup.o(STACK)

serial_input0 0x40001162 Data
4800 lookout.o(.bss)
serial_input1 0x40002422 Data
256 lookout.o(.bss)
serial_output0 0x40002522 Data
128 lookout.o(.bss)
serial_output1 0x400025a2 Data
128 lookout.o(.bss)

When the Timer1 interrupt fires, SP becomes 0x40001D70, which is in the
middle of my serial_input0 buffer. If I reduce the size of the buffer
to 3000, SP still becomes 1D70, which does seem to indicate it is stack
related.

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com
On 6/28/2012 11:41 AM, Bernardo Marques wrote:
> All seems ok in here... you're setting IRQ SP to 'Stack_Top - 8' and after
> your IRQ stack is the USR stack, if there was a stack overflow in IRQ mode
> you'd most probably overwrite the USR stack (and your program would
> behave unpredictably after the return from ISR) than variables in your
> code. As long as you don't use FIQ, ABT, UND and SVC modes your stacks seem
> to be just fine.
> Can you show me the part in your .map file with the addresses given
> to 'Stack_Mem', '__initial_sp', 'Stack_Top' and for the 'serial_input0'
> variable?
>
> Regards,
> Bernardo Marques.
>
> On Thu, Jun 28, 2012 at 3:45 PM, Sutton Mehaffey <
> s...@lookoutportablesecurity.com> wrote:
>
>> **
>> Not exactly sure what you mean. I'm using Keil's provided startup.s file
>> for LPC21xx (see below stack portions) and I changed the USR stack to 4K
>> from 2K. That's all I've changed from the default.
>>
>> UND_Stack_Size EQU 0x00000000
>> SVC_Stack_Size EQU 0x00000008
>> ABT_Stack_Size EQU 0x00000000
>> FIQ_Stack_Size EQU 0x00000000
>> IRQ_Stack_Size EQU 0x00000080
>> USR_Stack_Size EQU 0x00001000
>>
>> ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
>> ABT_Stack_Size + \
>> FIQ_Stack_Size + IRQ_Stack_Size)
>>
>> AREA STACK, NOINIT, READWRITE, ALIGN=3
>>
>> Stack_Mem SPACE USR_Stack_Size
>> __initial_sp SPACE ISR_Stack_Size
>>
>> Stack_Top
>>
>> ; Setup Stack for each mode
>>
>> LDR R0, =Stack_Top
>>
>> ; Enter Undefined Instruction Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
>> MOV SP, R0
>> SUB R0, R0, #UND_Stack_Size
>>
>> ; Enter Abort Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
>> MOV SP, R0
>> SUB R0, R0, #ABT_Stack_Size
>>
>> ; Enter FIQ Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
>> MOV SP, R0
>> SUB R0, R0, #FIQ_Stack_Size
>>
>> ; Enter IRQ Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
>> MOV SP, R0
>> SUB R0, R0, #IRQ_Stack_Size
>>
>> ; Enter Supervisor Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
>> MOV SP, R0
>> SUB R0, R0, #SVC_Stack_Size
>>
>> ; Enter User Mode and set its Stack Pointer
>> MSR CPSR_c, #Mode_USR
>> IF :DEF:__MICROLIB
>>
>> EXPORT __initial_sp
>>
>> ELSE
>>
>> MOV SP, R0
>> SUB SL, SP, #USR_Stack_Size
>>
>> ENDIF
>> Sutton Mehaffey
>> Lookout Portable Security
>> 4040 Royal Dr.
>> Kennesaw, GA 30144
>> 770-514-7999, 800-207-6269
>> Fax: 770-514-1285
>> http://www.lookoutportablesecurity.com
>> s...@lookoutportablesecurity.com
>> On 6/28/2012 10:04 AM, Bernardo Marques wrote:
>>> Check your map file and see what is the base address to which you set the
>>> IRQ SP (in my case the value of __irq_stack_top__).
>>>
>>> Bernardo.
>>>
>>>
>>> On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
>>> s...@lookoutportablesecurity.com> wrote:
>>>
>>>> **
>>>>
>>>> That's all done in the 'Startup.s' file. I'll go double check that
>>>> again. It looks OK.
>>>>
>>>> Sutton
>>>>
>>>>
>>>> Sutton Mehaffey
>>>> Lookout Portable Security
>>>> 4040 Royal Dr.
>>>> Kennesaw, GA 30144
>>>> 770-514-7999, 800-207-6269
>>>> Fax: 770-514-1285
>>>> http://www.lookoutportablesecurity.com
>>>> s...@lookoutportablesecurity.com
>>>>
>>>> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
>>>>> It seems like you're not setting SP correctly for all operation modes.
>>>>>
>>>>> You need to set up SP for IRQ mode to an address that is not colliding
>>>> with
>>>>> your data or bss sections. When your code enters the ISR most of the
>>>>> registers (SP included) change because there is another set of
>> registers
>>>>> used in IRQ mode.
>>>>>
>>>>> Just set up stack pointer in all modes at startup and your problem is
>>>>> solved.
>>>>>
>>>>> At Startup.S you'll need to have something smilar to:
>>>>>
>>>>> /* Initialize stack pointers for all ARM modes */
>>>>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
>>>>> */
>>>>>
>>>>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
>>>>> */
>>>>>
>>>>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
>>>>> */
>>>>>
>>>>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
>>>>> */
>>>>>
>>>>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
>>>>> */
>>>>>
>>>>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
>>>>> LDR sp,=__c_stack_top__ /* set the C stack pointer
>>>>> */
>>>>>
>>>>> and in your linker script you need to set all those stack top
>> addresses,
>>>>> something similar to:
>>>>>
>>>>> IRQ_STACK_SIZE = 512;
>>>>> FIQ_STACK_SIZE = 256;
>>>>> SVC_STACK_SIZE = 1K;
>>>>> ABT_STACK_SIZE = 0;
>>>>> UND_STACK_SIZE = 0;
>>>>> C_STACK_SIZE = 1K;
>>>>>
>>>>> /* set stack end to the end of RAM and stack start to the first unused
>>>> RAM
>>>>> address */
>>>>> __stack_start__ = __end;
>>>>> __stack_end__ = 0x40000000 + 64K;
>>>>> /* and set the stacks locations */
>>>>> __und_stack_top__ = __stack_end__;
>>>>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
>>>>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
>>>>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
>>>>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
>>>>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
>>>>>
>>>>> Regards,
>>>>> Bernardo Marques
>>>>>
>>>>>
>>>>>
>>>>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
>>>>> s...@lookoutportablesecurity.com> wrote:
>>>>>
>>>>>> **
>>>>>>
>>>>>> After 2 days of debugging a possible stack overflow problem, I thought
>>>>>> someone on the forum might have a suggestion for the problem I'm
>>>>>> seeing. I have simplified the code to be a very simple snippet that
>>>>>> still exhibits the problem. Basically,
>>>>>>
>>>>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
>>>>>> VPBDIV = 1, since I have a 12MHZ crystal input.
>>>>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
>>>>>> for this test, so I let the clock just run.
>>>>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
>>>>>> UART for this test. It is a global buffer.
>>>>>>
>>>>>> My stack is 4K. My stack pointer starts out well above my data
>> section,
>>>>>> according to the memory map and by looking at the debugger. What
>>>>>> happens is that when the Timer1 interrupt fires, the SP becomes a
>>>>>> location near location 3080 in my circular buffer. Therefore, in my
>>>>>> real system, it locks it up. Obviously, because the SP is corrupted.
>>>>>> In my snippet, when Timer1 gets decremented, and exits the interrupt,
>>>>>> the SP goes back to normal (same location as before it entered the
>>>>>> interrupt). I have not been able to figure out why the SP becomes a
>>>>>> part of my circular buffer during the ISR.
>>>>>>
>>>>>> I can put breakpoints at the entry point to the ISR, and when it gets
>>>>>> there, the SP has been changed to a RAM address in my buffer. Below is
>>>>>> my snippet. My memory map looks good. The SP is well above the buffer
>>>>>> placement.
>>>>>>
>>>>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
>>>>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND LOCATION
>>>>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
>>>>>>
>>>>>> Any ideas on things to look at and double check? I feel as though it's
>>>>>> something simple and I've overlooked it many times over. Thanks.
>>>>>>
>>>>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
>>>>>>
>>>>>> // sets up CPU clock speed to 12Mhz
>>>>>>
>>>>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
>>>>>> (CCLK)
>>>>>>
>>>>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock = 12MHz
>>>>>> PLL0CFG = 0;
>>>>>> PLL0FEED = 0xAA;
>>>>>> PLL0FEED = 0x55;
>>>>>>
>>>>>> PLL1CON = 0; // not used
>>>>>> PLL1FEED = 0xAA;
>>>>>> PLL1FEED = 0x55;
>>>>>>
>>>>>> // Set up Timer Counter 1 and its Interrupt
>>>>>>
>>>>>> PCONP |= 0x00000004; // ON by default, but just to be sure
>>>>>> T1CTCR = 0; // puts Timer 1 in timer mode
>>>>>> T1PR = 0; // One increment per PCLK
>>>>>> T1IR = 1; // reset Timer 1 interrupt flag
>>>>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
>>>>>> 12Mhz clock
>>>>>> T1MCR = 3; // enable interrupt on match, reset TC
>>>>>>
>>>>>> // set up and start Timer1 interrupt
>>>>>>
>>>>>> VICVectAddr3 = (unsigned long) timer1_int;
>>>>>> VICVectCntl3 = 0x25;
>>>>>> VICIntEnable |= 0x00000020;
>>>>>> T1TCR = 2; // reset timer
>>>>>> T1TCR = 1; // start timer
>>>>>>
>>>>>> for (i = 0; i < 100; i++)
>>>>>> {
>>>>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
>>>>>> then starts getting overwritten by the interrupt at 7 locations
>>>> 3080-3086
>>>>>> }
>>>>>> for(;;);
>>>>>>
>>>>>> ******** every second when this interrupt fires, the SP gets corrupted
>>>>>> and 7 bytes of data gets changed in the circular buffer ********
>>>>>>
>>>>>> void timer1_int(void) __irq
>>>>>> {
>>>>>> // occurs every 1 sec
>>>>>>
>>>>>> delay_timer2--;
>>>>>> delay_timer3--;
>>>>>> delay_timer4--;
>>>>>>
>>>>>> T1IR = 1;
>>>>>> VICVectAddr = 0; // Acknowledge interrupt
>>>>>> }
>>>>>>
>>>>>> --
>>>>>> Sutton Mehaffey
>>>>>> Lookout Portable Security
>>>>>> 4040 Royal Dr. #100
>>>>>> Kennesaw, GA 30144
>>>>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
>>>>>> s...@lookoutportablesecurity.com
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
That's weird. If you're setting IRQ SP to 0x40005600 in your start up code
I don't know how it is possible for it to be 0x40001D70 when entering the
ISR, unless your ISR uses 14Kb of stack :/ (that would be very very wrong)
... strange though that 0x5600 - 0x1D70 is exactly 14Kb.

On Thu, Jun 28, 2012 at 4:56 PM, Sutton Mehaffey <
s...@lookoutportablesecurity.com> wrote:

> **
> .data 0x40000800 Section 11
> en4200.o(.data)
> .data 0x40000810 Section
> 156 lookout.o(.data)
> .data 0x400008ac Section
> 20 rtc.o(.data)
>
> HEAP 0x40004580 Section
> 0 startup.o(HEAP)
> STACK 0x40004580 Section
> 4232 startup.o(STACK)
> Heap_Mem 0x40004580 Data
> 0 startup.o(HEAP)
> Stack_Mem 0x40004580 Data
> 4096 startup.o(STACK)
> Stack_Top 0x40005608 Data
> 0 startup.o(STACK)
>
> serial_input0 0x40001162 Data
> 4800 lookout.o(.bss)
> serial_input1 0x40002422 Data
> 256 lookout.o(.bss)
> serial_output0 0x40002522 Data
> 128 lookout.o(.bss)
> serial_output1 0x400025a2 Data
> 128 lookout.o(.bss)
>
> When the Timer1 interrupt fires, SP becomes 0x40001D70, which is in the
> middle of my serial_input0 buffer. If I reduce the size of the buffer
> to 3000, SP still becomes 1D70, which does seem to indicate it is stack
> related.
> Sutton Mehaffey
> Lookout Portable Security
> 4040 Royal Dr.
> Kennesaw, GA 30144
> 770-514-7999, 800-207-6269
> Fax: 770-514-1285
> http://www.lookoutportablesecurity.com
> s...@lookoutportablesecurity.com
> On 6/28/2012 11:41 AM, Bernardo Marques wrote:
> > All seems ok in here... you're setting IRQ SP to 'Stack_Top - 8' and
> after
> > your IRQ stack is the USR stack, if there was a stack overflow in IRQ
> mode
> > you'd most probably overwrite the USR stack (and your program would
> > behave unpredictably after the return from ISR) than variables in your
> > code. As long as you don't use FIQ, ABT, UND and SVC modes your stacks
> seem
> > to be just fine.
> > Can you show me the part in your .map file with the addresses given
> > to 'Stack_Mem', '__initial_sp', 'Stack_Top' and for the 'serial_input0'
> > variable?
> >
> > Regards,
> > Bernardo Marques.
> >
> > On Thu, Jun 28, 2012 at 3:45 PM, Sutton Mehaffey <
> > s...@lookoutportablesecurity.com> wrote:
> >
> >> **
>
> >>
> >>
> >> Not exactly sure what you mean. I'm using Keil's provided startup.s file
> >> for LPC21xx (see below stack portions) and I changed the USR stack to 4K
> >> from 2K. That's all I've changed from the default.
> >>
> >> UND_Stack_Size EQU 0x00000000
> >> SVC_Stack_Size EQU 0x00000008
> >> ABT_Stack_Size EQU 0x00000000
> >> FIQ_Stack_Size EQU 0x00000000
> >> IRQ_Stack_Size EQU 0x00000080
> >> USR_Stack_Size EQU 0x00001000
> >>
> >> ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
> >> ABT_Stack_Size + \
> >> FIQ_Stack_Size + IRQ_Stack_Size)
> >>
> >> AREA STACK, NOINIT, READWRITE, ALIGN=3
> >>
> >> Stack_Mem SPACE USR_Stack_Size
> >> __initial_sp SPACE ISR_Stack_Size
> >>
> >> Stack_Top
> >>
> >> ; Setup Stack for each mode
> >>
> >> LDR R0, =Stack_Top
> >>
> >> ; Enter Undefined Instruction Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
> >> MOV SP, R0
> >> SUB R0, R0, #UND_Stack_Size
> >>
> >> ; Enter Abort Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
> >> MOV SP, R0
> >> SUB R0, R0, #ABT_Stack_Size
> >>
> >> ; Enter FIQ Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
> >> MOV SP, R0
> >> SUB R0, R0, #FIQ_Stack_Size
> >>
> >> ; Enter IRQ Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
> >> MOV SP, R0
> >> SUB R0, R0, #IRQ_Stack_Size
> >>
> >> ; Enter Supervisor Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
> >> MOV SP, R0
> >> SUB R0, R0, #SVC_Stack_Size
> >>
> >> ; Enter User Mode and set its Stack Pointer
> >> MSR CPSR_c, #Mode_USR
> >> IF :DEF:__MICROLIB
> >>
> >> EXPORT __initial_sp
> >>
> >> ELSE
> >>
> >> MOV SP, R0
> >> SUB SL, SP, #USR_Stack_Size
> >>
> >> ENDIF
> >>
> >>
> >> Sutton Mehaffey
> >> Lookout Portable Security
> >> 4040 Royal Dr.
> >> Kennesaw, GA 30144
> >> 770-514-7999, 800-207-6269
> >> Fax: 770-514-1285
> >> http://www.lookoutportablesecurity.com
> >> s...@lookoutportablesecurity.com
> >> On 6/28/2012 10:04 AM, Bernardo Marques wrote:
> >>> Check your map file and see what is the base address to which you set
> the
> >>> IRQ SP (in my case the value of __irq_stack_top__).
> >>>
> >>> Bernardo.
> >>>
> >>>
> >>> On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey <
> >>> s...@lookoutportablesecurity.com> wrote:
> >>>
> >>>> **
> >>>>
> >>>> That's all done in the 'Startup.s' file. I'll go double check that
> >>>> again. It looks OK.
> >>>>
> >>>> Sutton
> >>>>
> >>>>
> >>>> Sutton Mehaffey
> >>>> Lookout Portable Security
> >>>> 4040 Royal Dr.
> >>>> Kennesaw, GA 30144
> >>>> 770-514-7999, 800-207-6269
> >>>> Fax: 770-514-1285
> >>>> http://www.lookoutportablesecurity.com
> >>>> s...@lookoutportablesecurity.com
> >>>>
> >>>> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
> >>>>> It seems like you're not setting SP correctly for all operation
> modes.
> >>>>>
> >>>>> You need to set up SP for IRQ mode to an address that is not
> colliding
> >>>> with
> >>>>> your data or bss sections. When your code enters the ISR most of the
> >>>>> registers (SP included) change because there is another set of
> >> registers
> >>>>> used in IRQ mode.
> >>>>>
> >>>>> Just set up stack pointer in all modes at startup and your problem is
> >>>>> solved.
> >>>>>
> >>>>> At Startup.S you'll need to have something smilar to:
> >>>>>
> >>>>> /* Initialize stack pointers for all ARM modes */
> >>>>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
> >>>>> */
> >>>>>
> >>>>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
> >>>>> */
> >>>>>
> >>>>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
> >>>>> */
> >>>>>
> >>>>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
> >>>>> */
> >>>>>
> >>>>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
> >>>>> */
> >>>>>
> >>>>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
> >>>>> LDR sp,=__c_stack_top__ /* set the C stack pointer
> >>>>> */
> >>>>>
> >>>>> and in your linker script you need to set all those stack top
> >> addresses,
> >>>>> something similar to:
> >>>>>
> >>>>> IRQ_STACK_SIZE = 512;
> >>>>> FIQ_STACK_SIZE = 256;
> >>>>> SVC_STACK_SIZE = 1K;
> >>>>> ABT_STACK_SIZE = 0;
> >>>>> UND_STACK_SIZE = 0;
> >>>>> C_STACK_SIZE = 1K;
> >>>>>
> >>>>> /* set stack end to the end of RAM and stack start to the first
> unused
> >>>> RAM
> >>>>> address */
> >>>>> __stack_start__ = __end;
> >>>>> __stack_end__ = 0x40000000 + 64K;
> >>>>> /* and set the stacks locations */
> >>>>> __und_stack_top__ = __stack_end__;
> >>>>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
> >>>>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
> >>>>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
> >>>>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
> >>>>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
> >>>>>
> >>>>> Regards,
> >>>>> Bernardo Marques
> >>>>>
> >>>>>
> >>>>>
> >>>>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey <
> >>>>> s...@lookoutportablesecurity.com> wrote:
> >>>>>
> >>>>>> **
> >>>>>>
> >>>>>> After 2 days of debugging a possible stack overflow problem, I
> thought
> >>>>>> someone on the forum might have a suggestion for the problem I'm
> >>>>>> seeing. I have simplified the code to be a very simple snippet that
> >>>>>> still exhibits the problem. Basically,
> >>>>>>
> >>>>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
> >>>>>> VPBDIV = 1, since I have a 12MHZ crystal input.
> >>>>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
> >>>>>> for this test, so I let the clock just run.
> >>>>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
> >>>>>> UART for this test. It is a global buffer.
> >>>>>>
> >>>>>> My stack is 4K. My stack pointer starts out well above my data
> >> section,
> >>>>>> according to the memory map and by looking at the debugger. What
> >>>>>> happens is that when the Timer1 interrupt fires, the SP becomes a
> >>>>>> location near location 3080 in my circular buffer. Therefore, in my
> >>>>>> real system, it locks it up. Obviously, because the SP is corrupted.
> >>>>>> In my snippet, when Timer1 gets decremented, and exits the
> interrupt,
> >>>>>> the SP goes back to normal (same location as before it entered the
> >>>>>> interrupt). I have not been able to figure out why the SP becomes a
> >>>>>> part of my circular buffer during the ISR.
> >>>>>>
> >>>>>> I can put breakpoints at the entry point to the ISR, and when it
> gets
> >>>>>> there, the SP has been changed to a RAM address in my buffer. Below
> is
> >>>>>> my snippet. My memory map looks good. The SP is well above the
> buffer
> >>>>>> placement.
> >>>>>>
> >>>>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
> >>>>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND
> LOCATION
> >>>>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
> >>>>>>
> >>>>>> Any ideas on things to look at and double check? I feel as though
> it's
> >>>>>> something simple and I've overlooked it many times over. Thanks.
> >>>>>>
> >>>>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
> >>>>>>
> >>>>>> // sets up CPU clock speed to 12Mhz
> >>>>>>
> >>>>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
> >>>>>> (CCLK)
> >>>>>>
> >>>>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock > 12MHz
> >>>>>> PLL0CFG = 0;
> >>>>>> PLL0FEED = 0xAA;
> >>>>>> PLL0FEED = 0x55;
> >>>>>>
> >>>>>> PLL1CON = 0; // not used
> >>>>>> PLL1FEED = 0xAA;
> >>>>>> PLL1FEED = 0x55;
> >>>>>>
> >>>>>> // Set up Timer Counter 1 and its Interrupt
> >>>>>>
> >>>>>> PCONP |= 0x00000004; // ON by default, but just to be sure
> >>>>>> T1CTCR = 0; // puts Timer 1 in timer mode
> >>>>>> T1PR = 0; // One increment per PCLK
> >>>>>> T1IR = 1; // reset Timer 1 interrupt flag
> >>>>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
> >>>>>> 12Mhz clock
> >>>>>> T1MCR = 3; // enable interrupt on match, reset TC
> >>>>>>
> >>>>>> // set up and start Timer1 interrupt
> >>>>>>
> >>>>>> VICVectAddr3 = (unsigned long) timer1_int;
> >>>>>> VICVectCntl3 = 0x25;
> >>>>>> VICIntEnable |= 0x00000020;
> >>>>>> T1TCR = 2; // reset timer
> >>>>>> T1TCR = 1; // start timer
> >>>>>>
> >>>>>> for (i = 0; i < 100; i++)
> >>>>>> {
> >>>>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
> >>>>>> then starts getting overwritten by the interrupt at 7 locations
> >>>> 3080-3086
> >>>>>> }
> >>>>>> for(;;);
> >>>>>>
> >>>>>> ******** every second when this interrupt fires, the SP gets
> corrupted
> >>>>>> and 7 bytes of data gets changed in the circular buffer ********
> >>>>>>
> >>>>>> void timer1_int(void) __irq
> >>>>>> {
> >>>>>> // occurs every 1 sec
> >>>>>>
> >>>>>> delay_timer2--;
> >>>>>> delay_timer3--;
> >>>>>> delay_timer4--;
> >>>>>>
> >>>>>> T1IR = 1;
> >>>>>> VICVectAddr = 0; // Acknowledge interrupt
> >>>>>> }
> >>>>>>
> >>>>>> --
> >>>>>> Sutton Mehaffey
> >>>>>> Lookout Portable Security
> >>>>>> 4040 Royal Dr. #100
> >>>>>> Kennesaw, GA 30144
> >>>>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
> >>>>>> s...@lookoutportablesecurity.com
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
Not when the ISR has 3 lines of code in it. All decrementing shorts.
And, with no other interrupts running.

I know. It's a weird one.

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr. #100
Kennesaw, GA 30144
800-207-6269, 770-514-7999, 770-514-1285 FAX
s...@lookoutportablesecurity.com
On 6/28/2012 12:50 PM, Bernardo Marques wrote:
> That's weird. If you're setting IRQ SP to 0x40005600 in your start up code
> I don't know how it is possible for it to be 0x40001D70 when entering the
> ISR, unless your ISR uses 14Kb of stack :/ (that would be very very wrong)
> ... strange though that 0x5600 - 0x1D70 is exactly 14Kb.
>
> On Thu, Jun 28, 2012 at 4:56 PM, Sutton Mehaffey<
> s...@lookoutportablesecurity.com> wrote:
>
>> **
>> .data 0x40000800 Section 11
>> en4200.o(.data)
>> .data 0x40000810 Section
>> 156 lookout.o(.data)
>> .data 0x400008ac Section
>> 20 rtc.o(.data)
>>
>> HEAP 0x40004580 Section
>> 0 startup.o(HEAP)
>> STACK 0x40004580 Section
>> 4232 startup.o(STACK)
>> Heap_Mem 0x40004580 Data
>> 0 startup.o(HEAP)
>> Stack_Mem 0x40004580 Data
>> 4096 startup.o(STACK)
>> Stack_Top 0x40005608 Data
>> 0 startup.o(STACK)
>>
>> serial_input0 0x40001162 Data
>> 4800 lookout.o(.bss)
>> serial_input1 0x40002422 Data
>> 256 lookout.o(.bss)
>> serial_output0 0x40002522 Data
>> 128 lookout.o(.bss)
>> serial_output1 0x400025a2 Data
>> 128 lookout.o(.bss)
>>
>> When the Timer1 interrupt fires, SP becomes 0x40001D70, which is in the
>> middle of my serial_input0 buffer. If I reduce the size of the buffer
>> to 3000, SP still becomes 1D70, which does seem to indicate it is stack
>> related.
>> Sutton Mehaffey
>> Lookout Portable Security
>> 4040 Royal Dr.
>> Kennesaw, GA 30144
>> 770-514-7999, 800-207-6269
>> Fax: 770-514-1285
>> http://www.lookoutportablesecurity.com
>> s...@lookoutportablesecurity.com
>> On 6/28/2012 11:41 AM, Bernardo Marques wrote:
>>> All seems ok in here... you're setting IRQ SP to 'Stack_Top - 8' and
>> after
>>> your IRQ stack is the USR stack, if there was a stack overflow in IRQ
>> mode
>>> you'd most probably overwrite the USR stack (and your program would
>>> behave unpredictably after the return from ISR) than variables in your
>>> code. As long as you don't use FIQ, ABT, UND and SVC modes your stacks
>> seem
>>> to be just fine.
>>> Can you show me the part in your .map file with the addresses given
>>> to 'Stack_Mem', '__initial_sp', 'Stack_Top' and for the 'serial_input0'
>>> variable?
>>>
>>> Regards,
>>> Bernardo Marques.
>>>
>>> On Thu, Jun 28, 2012 at 3:45 PM, Sutton Mehaffey<
>>> s...@lookoutportablesecurity.com> wrote:
>>>
>>>> **
>>>>
>>>> Not exactly sure what you mean. I'm using Keil's provided startup.s file
>>>> for LPC21xx (see below stack portions) and I changed the USR stack to 4K
>>>> from 2K. That's all I've changed from the default.
>>>>
>>>> UND_Stack_Size EQU 0x00000000
>>>> SVC_Stack_Size EQU 0x00000008
>>>> ABT_Stack_Size EQU 0x00000000
>>>> FIQ_Stack_Size EQU 0x00000000
>>>> IRQ_Stack_Size EQU 0x00000080
>>>> USR_Stack_Size EQU 0x00001000
>>>>
>>>> ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size +
>>>> ABT_Stack_Size + \
>>>> FIQ_Stack_Size + IRQ_Stack_Size)
>>>>
>>>> AREA STACK, NOINIT, READWRITE, ALIGN=3
>>>>
>>>> Stack_Mem SPACE USR_Stack_Size
>>>> __initial_sp SPACE ISR_Stack_Size
>>>>
>>>> Stack_Top
>>>>
>>>> ; Setup Stack for each mode
>>>>
>>>> LDR R0, =Stack_Top
>>>>
>>>> ; Enter Undefined Instruction Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
>>>> MOV SP, R0
>>>> SUB R0, R0, #UND_Stack_Size
>>>>
>>>> ; Enter Abort Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
>>>> MOV SP, R0
>>>> SUB R0, R0, #ABT_Stack_Size
>>>>
>>>> ; Enter FIQ Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
>>>> MOV SP, R0
>>>> SUB R0, R0, #FIQ_Stack_Size
>>>>
>>>> ; Enter IRQ Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
>>>> MOV SP, R0
>>>> SUB R0, R0, #IRQ_Stack_Size
>>>>
>>>> ; Enter Supervisor Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
>>>> MOV SP, R0
>>>> SUB R0, R0, #SVC_Stack_Size
>>>>
>>>> ; Enter User Mode and set its Stack Pointer
>>>> MSR CPSR_c, #Mode_USR
>>>> IF :DEF:__MICROLIB
>>>>
>>>> EXPORT __initial_sp
>>>>
>>>> ELSE
>>>>
>>>> MOV SP, R0
>>>> SUB SL, SP, #USR_Stack_Size
>>>>
>>>> ENDIF
>>>>
>>>>
>>>> Sutton Mehaffey
>>>> Lookout Portable Security
>>>> 4040 Royal Dr.
>>>> Kennesaw, GA 30144
>>>> 770-514-7999, 800-207-6269
>>>> Fax: 770-514-1285
>>>> http://www.lookoutportablesecurity.com
>>>> s...@lookoutportablesecurity.com
>>>> On 6/28/2012 10:04 AM, Bernardo Marques wrote:
>>>>> Check your map file and see what is the base address to which you set
>> the
>>>>> IRQ SP (in my case the value of __irq_stack_top__).
>>>>>
>>>>> Bernardo.
>>>>>
>>>>>
>>>>> On Thu, Jun 28, 2012 at 2:10 PM, Sutton Mehaffey<
>>>>> s...@lookoutportablesecurity.com> wrote:
>>>>>
>>>>>> **
>>>>>>
>>>>>> That's all done in the 'Startup.s' file. I'll go double check that
>>>>>> again. It looks OK.
>>>>>>
>>>>>> Sutton
>>>>>>
>>>>>>
>>>>>> Sutton Mehaffey
>>>>>> Lookout Portable Security
>>>>>> 4040 Royal Dr.
>>>>>> Kennesaw, GA 30144
>>>>>> 770-514-7999, 800-207-6269
>>>>>> Fax: 770-514-1285
>>>>>> http://www.lookoutportablesecurity.com
>>>>>> s...@lookoutportablesecurity.com
>>>>>>
>>>>>> On 6/28/2012 3:06 AM, Bernardo Marques wrote:
>>>>>>> It seems like you're not setting SP correctly for all operation
>> modes.
>>>>>>> You need to set up SP for IRQ mode to an address that is not
>> colliding
>>>>>> with
>>>>>>> your data or bss sections. When your code enters the ISR most of the
>>>>>>> registers (SP included) change because there is another set of
>>>> registers
>>>>>>> used in IRQ mode.
>>>>>>>
>>>>>>> Just set up stack pointer in all modes at startup and your problem is
>>>>>>> solved.
>>>>>>>
>>>>>>> At Startup.S you'll need to have something smilar to:
>>>>>>>
>>>>>>> /* Initialize stack pointers for all ARM modes */
>>>>>>> MSR CPSR_c,#(IRQ_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__irq_stack_top__ /* set the IRQ stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> MSR CPSR_c,#(FIQ_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__fiq_stack_top__ /* set the FIQ stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> MSR CPSR_c,#(SVC_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__svc_stack_top__ /* set the SVC stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> MSR CPSR_c,#(ABT_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__abt_stack_top__ /* set the ABT stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> MSR CPSR_c,#(UND_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__und_stack_top__ /* set the UND stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> MSR CPSR_c,#(SYS_MODE | I_BIT | F_BIT)
>>>>>>> LDR sp,=__c_stack_top__ /* set the C stack pointer
>>>>>>> */
>>>>>>>
>>>>>>> and in your linker script you need to set all those stack top
>>>> addresses,
>>>>>>> something similar to:
>>>>>>>
>>>>>>> IRQ_STACK_SIZE = 512;
>>>>>>> FIQ_STACK_SIZE = 256;
>>>>>>> SVC_STACK_SIZE = 1K;
>>>>>>> ABT_STACK_SIZE = 0;
>>>>>>> UND_STACK_SIZE = 0;
>>>>>>> C_STACK_SIZE = 1K;
>>>>>>>
>>>>>>> /* set stack end to the end of RAM and stack start to the first
>> unused
>>>>>> RAM
>>>>>>> address */
>>>>>>> __stack_start__ = __end;
>>>>>>> __stack_end__ = 0x40000000 + 64K;
>>>>>>> /* and set the stacks locations */
>>>>>>> __und_stack_top__ = __stack_end__;
>>>>>>> __abt_stack_top__ = __und_stack_top__ - UND_STACK_SIZE;
>>>>>>> __svc_stack_top__ = __abt_stack_top__ - ABT_STACK_SIZE;
>>>>>>> __fiq_stack_top__ = __svc_stack_top__ - SVC_STACK_SIZE;
>>>>>>> __irq_stack_top__ = __fiq_stack_top__ - FIQ_STACK_SIZE;
>>>>>>> __c_stack_top__ = __irq_stack_top__ - IRQ_STACK_SIZE;
>>>>>>>
>>>>>>> Regards,
>>>>>>> Bernardo Marques
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Jun 28, 2012 at 2:49 AM, Sutton Mehaffey<
>>>>>>> s...@lookoutportablesecurity.com> wrote:
>>>>>>>
>>>>>>>> **
>>>>>>>>
>>>>>>>> After 2 days of debugging a possible stack overflow problem, I
>> thought
>>>>>>>> someone on the forum might have a suggestion for the problem I'm
>>>>>>>> seeing. I have simplified the code to be a very simple snippet that
>>>>>>>> still exhibits the problem. Basically,
>>>>>>>>
>>>>>>>> 1. I setup the CPU for 12Mhz operation. This really entails setting
>>>>>>>> VPBDIV = 1, since I have a 12MHZ crystal input.
>>>>>>>> 2. I setup Timer 1 to generate a 1 second interrupt. I don't use it
>>>>>>>> for this test, so I let the clock just run.
>>>>>>>> 3. I have a circular 4800 char UART0 buffer. I'm not turning on the
>>>>>>>> UART for this test. It is a global buffer.
>>>>>>>>
>>>>>>>> My stack is 4K. My stack pointer starts out well above my data
>>>> section,
>>>>>>>> according to the memory map and by looking at the debugger. What
>>>>>>>> happens is that when the Timer1 interrupt fires, the SP becomes a
>>>>>>>> location near location 3080 in my circular buffer. Therefore, in my
>>>>>>>> real system, it locks it up. Obviously, because the SP is corrupted.
>>>>>>>> In my snippet, when Timer1 gets decremented, and exits the
>> interrupt,
>>>>>>>> the SP goes back to normal (same location as before it entered the
>>>>>>>> interrupt). I have not been able to figure out why the SP becomes a
>>>>>>>> part of my circular buffer during the ISR.
>>>>>>>>
>>>>>>>> I can put breakpoints at the entry point to the ISR, and when it
>> gets
>>>>>>>> there, the SP has been changed to a RAM address in my buffer. Below
>> is
>>>>>>>> my snippet. My memory map looks good. The SP is well above the
>> buffer
>>>>>>>> placement.
>>>>>>>>
>>>>>>>> Note: THE SYSTEM WAS RUNNING PERFECTLY, BUT WHEN I RAISED THE BUFFER
>>>>>>>> SIZE TO 4800 FROM 2400, THE PROBLEM STARTED OCCURRING AROUND
>> LOCATION
>>>>>>>> 3080 OF THE BUFFER AND LOCKING UP THE SYSTEM.
>>>>>>>>
>>>>>>>> Any ideas on things to look at and double check? I feel as though
>> it's
>>>>>>>> something simple and I've overlooked it many times over. Thanks.
>>>>>>>>
>>>>>>>> memset(serial_input0,0,SERIAL_INPUT_BUFSIZE);
>>>>>>>>
>>>>>>>> // sets up CPU clock speed to 12Mhz
>>>>>>>>
>>>>>>>> VPBDIV = 1; // VPB clock (PCLK) is same as the processor clock
>>>>>>>> (CCLK)
>>>>>>>>
>>>>>>>> PLL0CON = 0; // not using PLL0, since PCLK = oscillator clock >> 12MHz
>>>>>>>> PLL0CFG = 0;
>>>>>>>> PLL0FEED = 0xAA;
>>>>>>>> PLL0FEED = 0x55;
>>>>>>>>
>>>>>>>> PLL1CON = 0; // not used
>>>>>>>> PLL1FEED = 0xAA;
>>>>>>>> PLL1FEED = 0x55;
>>>>>>>>
>>>>>>>> // Set up Timer Counter 1 and its Interrupt
>>>>>>>>
>>>>>>>> PCONP |= 0x00000004; // ON by default, but just to be sure
>>>>>>>> T1CTCR = 0; // puts Timer 1 in timer mode
>>>>>>>> T1PR = 0; // One increment per PCLK
>>>>>>>> T1IR = 1; // reset Timer 1 interrupt flag
>>>>>>>> T1MR0 = 11999999; // 1 sec - 0xb71b00 - 1 = 11999999 for
>>>>>>>> 12Mhz clock
>>>>>>>> T1MCR = 3; // enable interrupt on match, reset TC
>>>>>>>>
>>>>>>>> // set up and start Timer1 interrupt
>>>>>>>>
>>>>>>>> VICVectAddr3 = (unsigned long) timer1_int;
>>>>>>>> VICVectCntl3 = 0x25;
>>>>>>>> VICIntEnable |= 0x00000020;
>>>>>>>> T1TCR = 2; // reset timer
>>>>>>>> T1TCR = 1; // start timer
>>>>>>>>
>>>>>>>> for (i = 0; i< 100; i++)
>>>>>>>> {
>>>>>>>> serial_input0[3072+i] = 0x66; // data gets written fine, but
>>>>>>>> then starts getting overwritten by the interrupt at 7 locations
>>>>>> 3080-3086
>>>>>>>> }
>>>>>>>> for(;;);
>>>>>>>>
>>>>>>>> ******** every second when this interrupt fires, the SP gets
>> corrupted
>>>>>>>> and 7 bytes of data gets changed in the circular buffer ********
>>>>>>>>
>>>>>>>> void timer1_int(void) __irq
>>>>>>>> {
>>>>>>>> // occurs every 1 sec
>>>>>>>>
>>>>>>>> delay_timer2--;
>>>>>>>> delay_timer3--;
>>>>>>>> delay_timer4--;
>>>>>>>>
>>>>>>>> T1IR = 1;
>>>>>>>> VICVectAddr = 0; // Acknowledge interrupt
>>>>>>>> }
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sutton Mehaffey
>>>>>>>> Lookout Portable Security
>>>>>>>> 4040 Royal Dr. #100
>>>>>>>> Kennesaw, GA 30144
>>>>>>>> 800-207-6269, 770-514-7999, 770-514-1285 FAX
>>>>>>>> s...@lookoutportablesecurity.com
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>