From 6d9100da2e6deb09d72c892fc5f376828f1d81bd Mon Sep 17 00:00:00 2001 From: qiuyiuestc Date: Sat, 26 Dec 2009 10:10:50 +0000 Subject: support GCC compiler for LM3S platform git-svn-id: https://rt-thread.googlecode.com/svn/trunk@233 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- libcpu/arm/lm3s/context_gcc.S | 164 ++++++++++++++++++++++++++++ libcpu/arm/lm3s/start_gcc.c | 242 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 libcpu/arm/lm3s/context_gcc.S create mode 100644 libcpu/arm/lm3s/start_gcc.c (limited to 'libcpu') diff --git a/libcpu/arm/lm3s/context_gcc.S b/libcpu/arm/lm3s/context_gcc.S new file mode 100644 index 0000000000..04d45c1327 --- /dev/null +++ b/libcpu/arm/lm3s/context_gcc.S @@ -0,0 +1,164 @@ +/* + * File : context_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-10-11 Bernard first version + */ + +/** + * @addtogroup STM32 + */ +/*@{*/ + +.cpu cortex-m3 +.fpu softvfp +.syntax unified +.thumb +.text + +.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */ +.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */ +.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */ +.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */ + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.global rt_hw_interrupt_disable +.type rt_hw_interrupt_disable, %function +rt_hw_interrupt_disable: + MRS r0, PRIMASK + CPSID I + BX LR + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.global rt_hw_interrupt_enable +.type rt_hw_interrupt_enable, %function +rt_hw_interrupt_enable: + MSR PRIMASK, r0 + BX LR + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.global rt_hw_context_switch_interrupt +.type rt_hw_context_switch_interrupt, %function +.global rt_hw_context_switch +.type rt_hw_context_switch, %function + +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + /* set rt_thread_switch_interrput_flag to 1 */ + LDR r2, =rt_thread_switch_interrput_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOV r3, #1 + STR r3, [r2] + + LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ + STR r0, [r2] + +_reswitch: + LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ + STR r1, [r2] + + LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + BX LR + +/* r0 --> swith from thread stack + * r1 --> swith to thread stack + * psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack + */ +.global rt_hw_pend_sv +.type rt_hw_pend_sv, %function +rt_hw_pend_sv: + /* disable interrupt to protect context switch */ + MRS r2, PRIMASK + CPSID I + + /* get rt_thread_switch_interrupt_flag */ + LDR r0, =rt_thread_switch_interrput_flag + LDR r1, [r0] + CBZ r1, pendsv_exit /* pendsv already handled */ + + /* clear rt_thread_switch_interrput_flag to 0 */ + MOV r1, #0x00 + STR r1, [r0] + + LDR r0, =rt_interrupt_from_thread + LDR r1, [r0] + CBZ r1, swtich_to_thread /* skip register save at the first time */ + + MRS r1, psp /* get from thread stack pointer */ + STMFD r1!, {r4 - r11} /* push r4 - r11 register */ + LDR r0, [r0] + STR r1, [r0] /* update from thread stack pointer */ + +swtich_to_thread: + LDR r1, =rt_interrupt_to_thread + LDR r1, [r1] + LDR r1, [r1] /* load thread stack pointer */ + + LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */ + MSR psp, r1 /* update stack pointer */ + +pendsv_exit: + /* restore interrupt */ + MSR PRIMASK, r2 + + ORR lr, lr, #0x04 + BX lr + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.global rt_hw_context_switch_to +.type rt_hw_context_switch_to, %function +rt_hw_context_switch_to: + LDR r1, =rt_interrupt_to_thread + STR r0, [r1] + + /* set from thread to 0 */ + LDR r1, =rt_interrupt_from_thread + MOV r0, #0x0 + STR r0, [r1] + + /* set interrupt flag to 1 */ + LDR r1, =rt_thread_switch_interrput_flag + MOV r0, #1 + STR r0, [r1] + + /* set the PendSV exception priority */ + LDR r0, =NVIC_SYSPRI2 + LDR r1, =NVIC_PENDSV_PRI + STR r1, [r0] + + LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + + CPSIE I /* enable interrupts at processor level */ + + /* never reach here! */ + +/* compatible with old version */ +.global rt_hw_interrupt_thread_switch +.type rt_hw_interrupt_thread_switch, %function +rt_hw_interrupt_thread_switch: + BX lr + NOP diff --git a/libcpu/arm/lm3s/start_gcc.c b/libcpu/arm/lm3s/start_gcc.c new file mode 100644 index 0000000000..fa1398e35c --- /dev/null +++ b/libcpu/arm/lm3s/start_gcc.c @@ -0,0 +1,242 @@ +//***************************************************************************** +// +// startup.c - Boot code for Stellaris. +// +// Copyright (c) 2005-2008 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. You may not combine +// this software with "viral" open-source software in order to form a larger +// program. Any use in violation of the foregoing restrictions may subject +// the user to criminal sanctions under applicable laws, as well as to civil +// liability for the breach of the terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2752 of the Stellaris Peripheral Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +#ifndef STACK_SIZE +#define STACK_SIZE 64 +#endif +static unsigned long pulStack[STACK_SIZE]; + +//***************************************************************************** +// +// The minimal vector table for a Cortex M3. Note that the proper constructs +// must be placed on this to ensure that it ends up at physical address +// 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + IntDefaultHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + IntDefaultHandler, // The PendSV handler + IntDefaultHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI Rx and Tx + IntDefaultHandler, // I2C Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder + IntDefaultHandler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + IntDefaultHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + IntDefaultHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler, // FLASH Control + IntDefaultHandler, // GPIO Port F + IntDefaultHandler, // GPIO Port G + IntDefaultHandler, // GPIO Port H + IntDefaultHandler, // UART2 Rx and Tx + IntDefaultHandler, // SSI1 Rx and Tx + IntDefaultHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + IntDefaultHandler, // I2C1 Master and Slave + IntDefaultHandler, // Quadrature Encoder 1 + IntDefaultHandler, // CAN0 + IntDefaultHandler, // CAN1 + IntDefaultHandler, // CAN2 + IntDefaultHandler, // Ethernet + IntDefaultHandler, // Hibernate + IntDefaultHandler, // USB0 + IntDefaultHandler, // PWM Generator 3 + IntDefaultHandler, // uDMA Software Transfer + IntDefaultHandler // uDMA Error +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern unsigned long _etext; +extern unsigned long _sdata; +extern unsigned long _edata; +extern unsigned long _sbss; +extern unsigned long _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied main() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + unsigned long *pulSrc, *pulDest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pulSrc = &_etext; + for(pulDest = &_sdata; pulDest < &_edata; ) + { + *pulDest++ = *pulSrc++; + } + + // + // Zero fill the bss segment. This is done with inline assembly since this + // will clear the value of pulDest if it is not kept in a register. + // + __asm(" ldr r0, =_sbss\n" + " ldr r1, =_ebss\n" + " mov r2, #0\n" + " .thumb_func\n" + "zero_loop:\n" + " cmp r0, r1\n" + " it lt\n" + " strlt r2, [r0], #4\n" + " blt zero_loop"); + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + } +} -- cgit v1.3.1