cortex-m3,基于qemu(lm3s6965evb)模拟器(第一篇)

1.前言

    让我们先来了解一下cortex-m3和stm32、lm3s之间的关系。arm是一家只设计cpu的公司,所以会授权硬件公司开发具体的处理器,arm设计的是处理器的核心部件,之后的一些核心外围的部件由具体的硬件公司自己添加(按约定的规则),arm设计了cortex-m的架构,而cortex-m3是一个型号的内核,stm32是意法半导体基于cortex-m设计的一系列具体的微控制器。lm3s与之类似,lm3s之前的公司现在已经被TI(德州仪器)收购。

    嵌入式微控制器涉及软硬件设计,初学者一般先用现成的开发板学习基本知识。软件开发就涉及一个编译器的问题,cortex-m3的开发有很多工具,著名的由ARMCC(arm公司自己开发的工具),keil(学过51单片机的同学应该会知道),gcc。这里我个人偏向于使用gcc,所以在这里会说明如何编译gcc。

    硬件我先使用了qemu模拟器模拟的一块cortex-m3开发板(lm3s6965evb),用于学习cortex-m3的基础知识。


2.构建gcc和qemu(操作系统为linux)

    现从网上下载binutils2.24,gcc4.9.1,newlib-nano1.0,qemu2.1,gdb7.7源代码。

    binutils配置(一般我们会建立一个文件夹用于编译,而不在源代码目录编译):

../binutils-2.24/configure --target=arm-none-eabi \
	--prefix=/opt/cross-cortex-m3 \     //指定路径
        --with-sysroot=/opt/cross-cortex-m3/arm-none-eabi \
	--enable-nls --enable-gold \
        --enable-plugins --enable-lto --disable-werror \
	--enable-multilib --enable-interwork

    编译安装

make -j8
	make install(我用的是ubuntu所以需要前面加sudo)

    gcc配置(libgmp,libmpfr,libmpc, libzip)(打补丁patch -N ${GCC_VERSION}/gcc/config/arm/t-arm-elf gcc-multilib.patch):

--- t-arm-elf.orig	2012-09-09 21:18:49.000000000 +0200
+++ gcc-linaro-4.7-2012.08/gcc/config/arm/t-arm-elf	2012-09-11 17:00:04.000000000 +0200
@@ -17,75 +17,29 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS     = marm/mthumb
-MULTILIB_DIRNAMES    = arm thumb
-MULTILIB_EXCEPTIONS  = 
-MULTILIB_MATCHES     =
-
-#MULTILIB_OPTIONS     += mcpu=fa526/mcpu=fa626/mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te
-#MULTILIB_DIRNAMES    += fa526 fa626 fa606te fa626te fmp626 fa726te
-#MULTILIB_EXCEPTIONS  += *mthumb*/*mcpu=fa526 *mthumb*/*mcpu=fa626
-
-#MULTILIB_OPTIONS      += march=armv7
-#MULTILIB_DIRNAMES     += thumb2
-#MULTILIB_EXCEPTIONS   += march=armv7* marm/*march=armv7*
-#MULTILIB_MATCHES      += march?armv7=march?armv7-a
-#MULTILIB_MATCHES      += march?armv7=march?armv7-r
-#MULTILIB_MATCHES      += march?armv7=march?armv7-m
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
-
-# Not quite true.  We can support hard-vfp calling in Thumb2, but how do we
-# express that here?  Also, we really need architecture v5e or later
-# (mcrr etc).
-MULTILIB_OPTIONS       += mfloat-abi=hard
-MULTILIB_DIRNAMES      += fpu
-MULTILIB_EXCEPTIONS    += *mthumb/*mfloat-abi=hard*
-#MULTILIB_EXCEPTIONS    += *mcpu=fa526/*mfloat-abi=hard*
-#MULTILIB_EXCEPTIONS    += *mcpu=fa626/*mfloat-abi=hard*
-
-# MULTILIB_OPTIONS    += mcpu=ep9312
-# MULTILIB_DIRNAMES   += ep9312
-# MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
-# 	
-# MULTILIB_OPTIONS     += mlittle-endian/mbig-endian
-# MULTILIB_DIRNAMES    += le be
-# MULTILIB_MATCHES     += mbig-endian=mbe mlittle-endian=mle
-# 
-# MULTILIB_OPTIONS    += mfloat-abi=hard/mfloat-abi=soft
-# MULTILIB_DIRNAMES   += fpu soft
-# MULTILIB_EXCEPTIONS += *mthumb/*mfloat-abi=hard*
-# 
-# MULTILIB_OPTIONS    += mno-thumb-interwork/mthumb-interwork
-# MULTILIB_DIRNAMES   += normal interwork
-# 
-# MULTILIB_OPTIONS    += fno-leading-underscore/fleading-underscore
-# MULTILIB_DIRNAMES   += elf under
-# 
-# MULTILIB_OPTIONS    += mcpu=arm7
-# MULTILIB_DIRNAMES   += nofmult
-# MULTILIB_EXCEPTIONS += *mthumb*/*mcpu=arm7*
-# # Note: the multilib_exceptions matches both -mthumb and
-# # -mthumb-interwork
-# #
-# # We have to match all the arm cpu variants which do not have the
-# # multiply instruction and treat them as if the user had specified
-# # -mcpu=arm7.  Note that in the following the ? is interpreted as
-# # an = for the purposes of matching command line options.
-# # FIXME: There ought to be a better way to do this.
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7d
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7di
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm70
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700i
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710c
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7100
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500fe
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm6
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm60
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm600
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm610
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm620
+MULTILIB_MATCHES      += march?armv6s-m=mcpu?cortex-m0
+MULTILIB_MATCHES      += march?armv6s-m=mcpu?cortex-m1
+MULTILIB_MATCHES      += march?armv7-m=mcpu?cortex-m3
+MULTILIB_MATCHES      += march?armv7e-m=mcpu?cortex-m4
+MULTILIB_MATCHES      += march?armv7e-m=mcpu?cortex-m4f
+
+MULTILIB_OPTIONS      += mthumb
+MULTILIB_DIRNAMES     += thumb
+MULTILIB_EXCEPTIONS   += *
+
+MULTILIB_OPTIONS      += march=armv6s-m/march=armv7-m/march=armv7e-m
+MULTILIB_DIRNAMES     += armv6s-m armv7-m armv7e-m
+MULTILIB_EXCEPTIONS   += *
+
+MULTILIB_OPTIONS      += mfloat-abi=hard
+MULTILIB_DIRNAMES     += fpu
+MULTILIB_EXCEPTIONS   += *
+
+MULTILIB_OPTIONS      += mfpu=fpv4-sp-d16
+MULTILIB_DIRNAMES     += fpv4-sp-d16
+MULTILIB_EXCEPTIONS   += *
+
+MULTILIB_REQUIRED +=  mthumb/march=armv6s-m
+MULTILIB_REQUIRED +=  mthumb/march=armv7-m
+MULTILIB_REQUIRED +=  mthumb/march=armv7e-m
+MULTILIB_REQUIRED +=  mthumb/march=armv7e-m/mfloat-abi=hard/mfpu=fpv4-sp-d16

../gcc-4.9.1/configure --target=arm-none-eabi \
	--prefix=/opt/cross-cortex-m3 \
	--with-newlib \
	--with-build-time-tools=/opt/cross-cortex-m3/arm-none-eabi/bin \
	--with-sysroot=/opt/cross-cortex-m3/arm-none-eabi \
	--disable-shared \
	--enable-interwork \
	--enable-nls \
	--enable-poison-system-directories \
	--enable-lto \
	--enable-gold \
	--disable-libmudflap \
	--disable-libgomp \
	--disable-libstdcxx-pch \
	--disable-libssp \
	--disable-tls \
	--disable-threads \
	--disable-libunwind-exceptions \
	--enable-checking=release --without-headers --enable-languages=c

    编译安装gcc

        make all-gcc -j8 CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize" LDFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize"
	
        make install-gcc

    newlib配置(打补丁patch -N ${NEWLIB_VERSION}/libgloss/arm/linux-crt0.c newlib-optimize.patch):

--- linux-crt0.c
+++ linux-crt0.c
@@ -22,7 +22,10 @@ asm("\n"
 	"\tbx r0\n"
 	".size _start, .-_start\n");
 
-__attribute__((naked, used))
+/* Force _start_thumb in the .text section so this will still compile when
+ * enabling -ffunction-sections.
+ */
+__attribute__((naked, used)) __attribute__((section(".text")))
 static void _start_thumb(void)
 #else
 __attribute__((naked))

../newlib-nano-1.0/configure \
	--target=arm-none-eabi \
	--prefix=/opt/cross-cortex-m3 \
	--enable-target-optspace \
        --enable-newlib-reent-small \
	--with-build-time-tools=/opt/cross-cortex-m3/bin \
	--with-sysroot=/opt/cross-cortex-m3/arm-none-eabi \
	--disable-shared \
	--disable-newlib-supplied-syscalls \
	--enable-multilib \
	--enable-interwork \
	--enable-newlib-nano-malloc \
       	--enable-newlib-io-c99-formats \
	--enable-newlib-io-long-long \
       	--enable-lto

    编译安装newlib-nano

make -j8 CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize" LDFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize"
	
	make install

    libgcc编译(回到刚刚编译gcc的目录)

make all-target-libgcc -j8 CFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize" LDFLAGS_FOR_TARGET="-ffunction-sections -fdata-sections -mabi=aapcs -Os -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -D__BUFSIZ__=64 -D_REENT_SMALL -fno-unroll-loops -DSMALL_MEMORY -ffast-math -ftree-vectorize"
	
	make install-target-libgcc

    gdb配置编译:

../gdb-7.7/configure --enable-multilib \
	--enable-interwork --enable-sim \
	--enable-sim-stdio --target=arm-none-eabi \
	--prefix=/opt/cross-cortex-m3

	make -j8
	make install

    qemu配置编译(libsdl-dev):

./configure --prefix=/opt/qemu \
	--target-list=arm-softmmu \
	--enable-sdl --enable-debug

	make -j8
	make install


    

3.结尾

    到这里工具包已经编译好了,可以使用本文章自带的hello代码测试下(记得在编译gcc之前添加PATH)(make QEMU)验证(第一个cortex-m3 hello,world程序留到下一篇解说)

lm3s6965.h

#ifndef LM3S6965_H

#define UART_DR(baseaddr) (*(unsigned int *)(baseaddr))
#define UART_FR(baseaddr) (*(((unsigned int *)(baseaddr))+6))

enum {
  UART_FR_RXFE = 0x10,
  UART_FR_TXFF = 0x20,
  UART0_ADDR = 0x4000C000,
};

#endif

lm3s6965.ld

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data : AT(ADDR(.text) + SIZEOF(.text))
    {
        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > SRAM

    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > SRAM

    . = ALIGN(32);           /*Not sure if this needs to be done, but why not.*/
    _stack_bottom = .;       /*Address of the bottom of the stack.*/
    . = . + 0x1000;          /*Allocate 4K for the Stack.*/
    _stack_top = .;          /*Address of the top of the stack.*/
    _heap_bottom = .;        /*Address of the bottom of the heap.*/
    _heap_top = 0x20008000;  /*Address of the top of the heap, also end of RAM.*/
}

syscalls.c

#ifdef __cplusplus
extern "C" {
#endif


#include "lm3s6965.h"
#include <sys/types.h>

static char *heap_end = 0;
extern unsigned long _heap_bottom;
extern unsigned long _heap_top;
extern unsigned long g_ulBase;

int _close(int file){
    return -1;
}

int _fstat(int file){
    return 0;
}

int _isatty(int file){
    return 1;
}

int _lseek(int file, int ptr, int dir){
    return 0;
}

int _open(const char *name, int flags, int mode){
    return -1;
}

int _read(int file, char *ptr, int len){
//	int todo;
//	char ch;
//	for (todo = 0; todo < len; todo++, ptr++){
//		while(UART_FR(UART0_ADDR) & UART_FR_RXFE)
//		;
//		*ptr = UART_DR(UART0_ADDR); //获取字符
//		UART_DR(UART0_ADDR) = *ptr; //回显
//		if(UART_FR(UART0_ADDR) & UART_FR_RXFE){
// 			break;
//		}
//	}
 	return len;
}

int _write(int file, char *ptr, int len){
	int todo;
 
	for (todo = 0; todo < len; todo++){
		UART_DR(UART0_ADDR) = *ptr++;
	}
	return len;
}

caddr_t _sbrk(unsigned int incr){
    char *prev_heap_end;

    if (heap_end == 0){
        heap_end = (caddr_t)&_heap_bottom;
    }

    prev_heap_end = heap_end;

    if (heap_end + incr > (caddr_t)&_heap_top){
        return (caddr_t)0;
    }

    heap_end += incr;

    return (caddr_t) prev_heap_end;
}

#ifdef __cplusplus
}
#endif

startup.c

// 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);

// Symbols Created by the Linker
extern unsigned long _etext;
extern unsigned long _data;
extern unsigned long _edata;
extern unsigned long _bss;
extern unsigned long _ebss;
extern unsigned long _stack_bottom;
extern unsigned long _stack_top;
extern unsigned long _heap_bottom;
extern unsigned long _heap_top;

// The vector table.  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) =
{
    0,                                      // StackPtr, set in RestetISR
    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,                      // SSI0 Rx and Tx
    IntDefaultHandler,                      // I2C0 Master and Slave
    IntDefaultHandler,                      // PWM Fault
    IntDefaultHandler,                      // PWM Generator 0
    IntDefaultHandler,                      // PWM Generator 1
    IntDefaultHandler,                      // PWM Generator 2
    IntDefaultHandler,                      // Quadrature Encoder 0
    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
    IntDefaultHandler,                      // ADC1 Sequence 0
    IntDefaultHandler,                      // ADC1 Sequence 1
    IntDefaultHandler,                      // ADC1 Sequence 2
    IntDefaultHandler,                      // ADC1 Sequence 3
    IntDefaultHandler,                      // I2S0
    IntDefaultHandler,                      // External Bus Interface 0
    IntDefaultHandler,                      // GPIO Port J
    IntDefaultHandler,                      // GPIO Port K
    IntDefaultHandler,                      // GPIO Port L
    IntDefaultHandler,                      // SSI2 Rx and Tx
    IntDefaultHandler,                      // SSI3 Rx and Tx
    IntDefaultHandler,                      // UART3 Rx and Tx
    IntDefaultHandler,                      // UART4 Rx and Tx
    IntDefaultHandler,                      // UART5 Rx and Tx
    IntDefaultHandler,                      // UART6 Rx and Tx
    IntDefaultHandler,                      // UART7 Rx and Tx
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // I2C2 Master and Slave
    IntDefaultHandler,                      // I2C3 Master and Slave
    IntDefaultHandler,                      // Timer 4 subtimer A
    IntDefaultHandler,                      // Timer 4 subtimer B
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // Timer 5 subtimer A
    IntDefaultHandler,                      // Timer 5 subtimer B
    IntDefaultHandler,                      // Wide Timer 0 subtimer A
    IntDefaultHandler,                      // Wide Timer 0 subtimer B
    IntDefaultHandler,                      // Wide Timer 1 subtimer A
    IntDefaultHandler,                      // Wide Timer 1 subtimer B
    IntDefaultHandler,                      // Wide Timer 2 subtimer A
    IntDefaultHandler,                      // Wide Timer 2 subtimer B
    IntDefaultHandler,                      // Wide Timer 3 subtimer A
    IntDefaultHandler,                      // Wide Timer 3 subtimer B
    IntDefaultHandler,                      // Wide Timer 4 subtimer A
    IntDefaultHandler,                      // Wide Timer 4 subtimer B
    IntDefaultHandler,                      // Wide Timer 5 subtimer A
    IntDefaultHandler,                      // Wide Timer 5 subtimer B
    IntDefaultHandler,                      // FPU
    IntDefaultHandler,                      // PECI 0
    IntDefaultHandler,                      // LPC 0
    IntDefaultHandler,                      // I2C4 Master and Slave
    IntDefaultHandler,                      // I2C5 Master and Slave
    IntDefaultHandler,                      // GPIO Port M
    IntDefaultHandler,                      // GPIO Port N
    IntDefaultHandler,                      // Quadrature Encoder 2
    IntDefaultHandler,                      // Fan 0
    0,                                      // Reserved
    IntDefaultHandler,                      // GPIO Port P (Summary or P0)
    IntDefaultHandler,                      // GPIO Port P1
    IntDefaultHandler,                      // GPIO Port P2
    IntDefaultHandler,                      // GPIO Port P3
    IntDefaultHandler,                      // GPIO Port P4
    IntDefaultHandler,                      // GPIO Port P5
    IntDefaultHandler,                      // GPIO Port P6
    IntDefaultHandler,                      // GPIO Port P7
    IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
    IntDefaultHandler,                      // GPIO Port Q1
    IntDefaultHandler,                      // GPIO Port Q2
    IntDefaultHandler,                      // GPIO Port Q3
    IntDefaultHandler,                      // GPIO Port Q4
    IntDefaultHandler,                      // GPIO Port Q5
    IntDefaultHandler,                      // GPIO Port Q6
    IntDefaultHandler,                      // GPIO Port Q7
    IntDefaultHandler,                      // GPIO Port R
    IntDefaultHandler,                      // GPIO Port S
    IntDefaultHandler,                      // PWM 1 Generator 0
    IntDefaultHandler,                      // PWM 1 Generator 1
    IntDefaultHandler,                      // PWM 1 Generator 2
    IntDefaultHandler,                      // PWM 1 Generator 3
    IntDefaultHandler                       // PWM 1 Fault
};

void ResetISR(void){
    unsigned long *pulSrc, *pulDest;

    // Copy the data segment initializers from flash to SRAM.
    pulSrc = &_etext;
    for(pulDest = &_data; pulDest < &_edata; ){
        *pulDest++ = *pulSrc++;
    }

    //Load the Stack Pointer
    __asm("    ldr     sp, = _stack_top\n");

    // Zero fill the bss segment.
    __asm("    ldr     r0, =_bss\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();
    while(1){;}
}

static void NmiSR(void){
    while(1);
}

static void FaultISR(void){
    while(1);
}

static void IntDefaultHandler(void){
    while(1);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lm3s6965.h"

void ResetISR(void);

int main(){

	printf("\nResetISR:%x\n", ResetISR);
	printf("testing lm3s6965...\nAddress\n");

	char * p = NULL;
	p = (char *) malloc(sizeof(char)*100);
	if(p == NULL){
		printf("malloc error!!!\n");
		while(1){;}
	}

	strcpy(p, "!!!Hello, World!!!");
	for(;*p != 0;p++){
		printf("0x%x	%c\n",p,*p);
	}

	printf("\nDead cycle...\n");
	
	while(1){;}
	
	return 0;
}

Makefile

CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
OBJDUMP = arm-none-eabi-objdump
ARM = qemu-system-arm

main.bin:main.c syscalls.c startup.c
	$(CC) -std=c11 -g -mcpu=cortex-m3 -mthumb -nostartfiles -T lm3s6965.ld syscalls.c startup.c main.c -o main
	$(OBJCOPY) -O binary -S -R .note -R .comment main main.bin
	$(OBJDUMP) -S main > main.list

QEMU: main.bin
	$(ARM) -M lm3s6965evb --kernel main.bin --serial stdio #-nographic
DEBUG: main.bin
	$(ARM) -M lm3s6965evb -nographic -monitor null -serial null -semihosting  -kernel main.bin  -S  -gdb tcp::123456

clean: main.bin
	rm main.bin main main.list

cortex-m3,基于qemu(lm3s6965evb)模拟器(第一篇)_第1张图片   

              作者:不一样的四季

                email:[email protected]

                发表于:2014.10.15


你可能感兴趣的:(Cortex-M3,lm3s)