stack addr align to 8byte.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2509 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
wuyangyong 2012-12-23 07:40:31 +00:00
parent 728064a45b
commit 5be0c53dd8
3 changed files with 196 additions and 159 deletions

View File

@ -1,111 +1,118 @@
/* /*
* File : cpu.c * File : cpuport.c
* This file is part of RT-Thread RTOS * This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE * http://www.rt-thread.org/license/LICENSE
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2010-01-25 Bernard first version * 2010-01-25 Bernard first version
* 2012-05-31 aozima Merge all of the C source code into cpuport.c * 2012-05-31 aozima Merge all of the C source code into cpuport.c
* 2012-08-17 aozima fixed bug: store r8 - r11. * 2012-08-17 aozima fixed bug: store r8 - r11.
*/ * 2012-12-23 aozima stack addr align to 8byte.
*/
#include <rtthread.h>
#include <rtthread.h>
struct exception_stack_frame
{ struct exception_stack_frame
rt_uint32_t r0; {
rt_uint32_t r1; rt_uint32_t r0;
rt_uint32_t r2; rt_uint32_t r1;
rt_uint32_t r3; rt_uint32_t r2;
rt_uint32_t r12; rt_uint32_t r3;
rt_uint32_t lr; rt_uint32_t r12;
rt_uint32_t pc; rt_uint32_t lr;
rt_uint32_t psr; rt_uint32_t pc;
}; rt_uint32_t psr;
};
struct stack_frame
{ struct stack_frame
/* r4 ~ r7 low register */ {
rt_uint32_t r4; /* r4 ~ r7 low register */
rt_uint32_t r5; rt_uint32_t r4;
rt_uint32_t r6; rt_uint32_t r5;
rt_uint32_t r7; rt_uint32_t r6;
rt_uint32_t r7;
/* r8 ~ r11 high register */
rt_uint32_t r8; /* r8 ~ r11 high register */
rt_uint32_t r9; rt_uint32_t r8;
rt_uint32_t r10; rt_uint32_t r9;
rt_uint32_t r11; rt_uint32_t r10;
rt_uint32_t r11;
struct exception_stack_frame exception_stack_frame;
}; struct exception_stack_frame exception_stack_frame;
};
/* flag in interrupt handling */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; /* flag in interrupt handling */
rt_uint32_t rt_thread_switch_interrupt_flag; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/**
* This function will initialize thread stack /**
* * This function will initialize thread stack
* @param tentry the entry of thread *
* @param parameter the parameter of entry * @param tentry the entry of thread
* @param stack_addr the beginning stack address * @param parameter the parameter of entry
* @param texit the function will be called when thread exit * @param stack_addr the beginning stack address
* * @param texit the function will be called when thread exit
* @return stack address *
*/ * @return stack address
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, */
rt_uint8_t *stack_addr, void *texit) rt_uint8_t *rt_hw_stack_init(void *tentry,
{ void *parameter,
struct stack_frame * stack_frame; rt_uint8_t *stack_addr,
rt_uint8_t * stk; void *texit)
unsigned long i; {
struct stack_frame * stack_frame;
stk = stack_addr + sizeof(rt_uint32_t); rt_uint8_t * stk;
unsigned long i;
stk -= sizeof(struct stack_frame);
stack_frame = (struct stack_frame *)stk; stk = stack_addr + sizeof(rt_uint32_t);
stk = (rt_uint8_t*)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
/* init all register */ stk -= sizeof(struct stack_frame);
for(i=0; i<sizeof(struct stack_frame)/sizeof(rt_uint32_t); i++)
{ stack_frame = (struct stack_frame *)stk;
((rt_uint32_t*)stack_frame)[i] = 0xdeadbeef;
} /* init all register */
for(i=0; i<sizeof(struct stack_frame)/sizeof(rt_uint32_t); i++)
stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ {
stack_frame->exception_stack_frame.r1 = 0; /* r1 */ ((rt_uint32_t*)stack_frame)[i] = 0xdeadbeef;
stack_frame->exception_stack_frame.r2 = 0; /* r2 */ }
stack_frame->exception_stack_frame.r3 = 0; /* r3 */
stack_frame->exception_stack_frame.r12 = 0; /* r12 */ stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */
stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */ stack_frame->exception_stack_frame.r1 = 0; /* r1 */
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */ stack_frame->exception_stack_frame.r2 = 0; /* r2 */
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */ stack_frame->exception_stack_frame.r3 = 0; /* r3 */
stack_frame->exception_stack_frame.r12 = 0; /* r12 */
/* return task's current stack address */ stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */
return stk; stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
} stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
extern long list_thread(void); /* return task's current stack address */
extern rt_thread_t rt_current_thread; return stk;
void rt_hw_hard_fault_exception(struct exception_stack_frame* contex) }
{
rt_kprintf("psr: 0x%08x\n", contex->psr); extern long list_thread(void);
rt_kprintf(" pc: 0x%08x\n", contex->pc); extern rt_thread_t rt_current_thread;
rt_kprintf(" lr: 0x%08x\n", contex->lr); /**
rt_kprintf("r12: 0x%08x\n", contex->r12); * fault exception handling
rt_kprintf("r03: 0x%08x\n", contex->r3); */
rt_kprintf("r02: 0x%08x\n", contex->r2); void rt_hw_hard_fault_exception(struct exception_stack_frame* contex)
rt_kprintf("r01: 0x%08x\n", contex->r1); {
rt_kprintf("r00: 0x%08x\n", contex->r0); rt_kprintf("psr: 0x%08x\n", contex->psr);
rt_kprintf(" pc: 0x%08x\n", contex->pc);
rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); rt_kprintf(" lr: 0x%08x\n", contex->lr);
#ifdef RT_USING_FINSH rt_kprintf("r12: 0x%08x\n", contex->r12);
list_thread(); rt_kprintf("r03: 0x%08x\n", contex->r3);
#endif rt_kprintf("r02: 0x%08x\n", contex->r2);
while (1); rt_kprintf("r01: 0x%08x\n", contex->r1);
} rt_kprintf("r00: 0x%08x\n", contex->r0);
rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
while (1);
}

View File

@ -1,7 +1,7 @@
/* /*
* File : cpuport.c * File : cpuport.c
* This file is part of RT-Thread RTOS * This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2011, RT-Thread Development Team * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at * found in the file LICENSE in this distribution or at
@ -12,21 +12,36 @@
* 2009-01-05 Bernard first version * 2009-01-05 Bernard first version
* 2011-02-14 onelife Modify for EFM32 * 2011-02-14 onelife Modify for EFM32
* 2011-06-17 onelife Merge all of the C source code into cpuport.c * 2011-06-17 onelife Merge all of the C source code into cpuport.c
* 2012-12-23 aozima stack addr align to 8byte.
*/ */
#include <rtthread.h> #include <rtthread.h>
/* stack context */ struct exception_stack_frame
struct stack_context
{ {
rt_uint32_t r0; rt_uint32_t r0;
rt_uint32_t r1; rt_uint32_t r1;
rt_uint32_t r2; rt_uint32_t r2;
rt_uint32_t r3; rt_uint32_t r3;
rt_uint32_t r12; rt_uint32_t r12;
rt_uint32_t lr; rt_uint32_t lr;
rt_uint32_t pc; rt_uint32_t pc;
rt_uint32_t psr; rt_uint32_t psr;
};
struct stack_frame
{
/* r4 ~ r11 register */
rt_uint32_t r4;
rt_uint32_t r5;
rt_uint32_t r6;
rt_uint32_t r7;
rt_uint32_t r8;
rt_uint32_t r9;
rt_uint32_t r10;
rt_uint32_t r11;
struct exception_stack_frame exception_stack_frame;
}; };
/* flag in interrupt handling */ /* flag in interrupt handling */
@ -34,34 +49,47 @@ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag; rt_uint32_t rt_thread_switch_interrupt_flag;
/** /**
* initializes stack of thread * This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/ */
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *rt_hw_stack_init(void *tentry,
rt_uint8_t *stack_addr, void *texit) void *parameter,
rt_uint8_t *stack_addr,
void *texit)
{ {
unsigned long *stk; struct stack_frame *stack_frame;
rt_uint8_t *stk;
unsigned long i;
stk = (unsigned long *)stack_addr; stk = stack_addr + sizeof(rt_uint32_t);
*(stk) = 0x01000000L; /* PSR */ stk = (rt_uint8_t*)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
*(--stk) = (unsigned long)tentry; /* entry point, pc */ stk -= sizeof(struct stack_frame);
*(--stk) = (unsigned long)texit; /* lr */
*(--stk) = 0; /* r12 */
*(--stk) = 0; /* r3 */
*(--stk) = 0; /* r2 */
*(--stk) = 0; /* r1 */
*(--stk) = (unsigned long)parameter; /* r0 : argument */
*(--stk) = 0; /* r11 */ stack_frame = (struct stack_frame *)stk;
*(--stk) = 0; /* r10 */
*(--stk) = 0; /* r9 */
*(--stk) = 0; /* r8 */
*(--stk) = 0; /* r7 */
*(--stk) = 0; /* r6 */
*(--stk) = 0; /* r5 */
*(--stk) = 0; /* r4 */
/* return task's current stack address */ /* init all register */
return (rt_uint8_t *)stk; for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
{
((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
}
stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */
stack_frame->exception_stack_frame.r1 = 0; /* r1 */
stack_frame->exception_stack_frame.r2 = 0; /* r2 */
stack_frame->exception_stack_frame.r3 = 0; /* r3 */
stack_frame->exception_stack_frame.r12 = 0; /* r12 */
stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */
stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
/* return task's current stack address */
return stk;
} }
extern long list_thread(void); extern long list_thread(void);
@ -69,22 +97,22 @@ extern rt_thread_t rt_current_thread;
/** /**
* fault exception handling * fault exception handling
*/ */
void rt_hw_hard_fault_exception(struct stack_context* contex) void rt_hw_hard_fault_exception(struct exception_stack_frame* contex)
{ {
rt_kprintf("psr: 0x%08x\n", contex->psr); rt_kprintf("psr: 0x%08x\n", contex->psr);
rt_kprintf(" pc: 0x%08x\n", contex->pc); rt_kprintf(" pc: 0x%08x\n", contex->pc);
rt_kprintf(" lr: 0x%08x\n", contex->lr); rt_kprintf(" lr: 0x%08x\n", contex->lr);
rt_kprintf("r12: 0x%08x\n", contex->r12); rt_kprintf("r12: 0x%08x\n", contex->r12);
rt_kprintf("r03: 0x%08x\n", contex->r3); rt_kprintf("r03: 0x%08x\n", contex->r3);
rt_kprintf("r02: 0x%08x\n", contex->r2); rt_kprintf("r02: 0x%08x\n", contex->r2);
rt_kprintf("r01: 0x%08x\n", contex->r1); rt_kprintf("r01: 0x%08x\n", contex->r1);
rt_kprintf("r00: 0x%08x\n", contex->r0); rt_kprintf("r00: 0x%08x\n", contex->r0);
rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
#ifdef RT_USING_FINSH #ifdef RT_USING_FINSH
list_thread(); list_thread();
#endif #endif
while (1); while (1);
} }
/** /**
@ -92,7 +120,7 @@ void rt_hw_hard_fault_exception(struct stack_context* contex)
*/ */
void rt_hw_cpu_shutdown() void rt_hw_cpu_shutdown()
{ {
rt_kprintf("shutdown...\n"); rt_kprintf("shutdown...\n");
RT_ASSERT(0); RT_ASSERT(0);
} }

View File

@ -14,6 +14,7 @@
* 2011-12-31 aozima fixed stack align issues. * 2011-12-31 aozima fixed stack align issues.
* 2012-01-01 aozima support context switch load/store FPU register. * 2012-01-01 aozima support context switch load/store FPU register.
* 2012-12-11 lgnq fixed the coding style. * 2012-12-11 lgnq fixed the coding style.
* 2012-12-23 aozima stack addr align to 8byte.
*/ */
#include <rtthread.h> #include <rtthread.h>
@ -106,6 +107,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
unsigned long i; unsigned long i;
stk = stack_addr + sizeof(rt_uint32_t); stk = stack_addr + sizeof(rt_uint32_t);
stk = (rt_uint8_t*)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
stk -= sizeof(struct stack_frame); stk -= sizeof(struct stack_frame);
stack_frame = (struct stack_frame *)stk; stack_frame = (struct stack_frame *)stk;