单片机运行时加载led驱动到RAM中运行

开发环境:

MCU:MPC5606B
IDE:S32 Design Stduio

链接文件修改:

/* Entry Point */
ENTRY(_start)

/* define heap and stack size */
__HEAP_SIZE            = 0 ;
__STACK_SIZE           = 4096 ;

SRAM_SIZE =  80K;    
/* Define SRAM Base Address */
SRAM_BASE_ADDR = 0x40000000;
    
MEMORY
{

    flash_rchw : org = 0x00000000,   len = 0x08
    
    m_min1 :	org = 0x100, len = 0x100
    m_min2 :	org = 0x200, len = 0x100 
	m_min3 :	org = 0x300, len = 0x100
        
    m_text :	org = 0x1000, len = 1020K  
    m_data :	org = 0x40000000,   len = 80K
       
}


SECTIONS
{
    .rchw   : 
    {
        KEEP(*(.rchw))
    } > flash_rchw
    
    .min1	:
    {
    	. = ALIGN(4);
    	KEEP(*(.m_min1))
    } > m_min1
    
    .min2	:
    {
    	. = ALIGN(4);
    	KEEP(*(.m_min2))
    } > m_min2
    
    .min3	:
    {
    	. = ALIGN(4);
    	KEEP(*(.m_min3))
    } > m_min3

    .startup : ALIGN(0x400)
    {
    __start = . ;
    	*(.startup)
    } > m_text
    
    .core_exceptions_table   : ALIGN(0x1000)
    {
      __IVPR_VALUE = . ;
      KEEP(*(.core_exceptions_table))
    } > m_text

    .intc_vector_table   : ALIGN(0x1000)  
    {
      KEEP(*(.intc_vector_table))
    } > m_text
      
    .text_booke :
    { 
      INPUT_SECTION_FLAGS (!SHF_PPC_VLE)
      *(.text*)      
    } > m_text            
           
    .text_vle : 
    { INPUT_SECTION_FLAGS (SHF_PPC_VLE) 
      *(.text.startup)
      *(.text)      
      *(.text.*)
      KEEP (*(.init))
      KEEP (*(.fini))            
      . = ALIGN(16);      
    } > m_text       /* that will force pick VLE .text sections */ 
        
    .ctors :
    {
      __CTOR_LIST__ = .;
      /* gcc uses crtbegin.o to find the start of
         the constructors, so we make sure it is
         first.  Because this is a wildcard, it
         doesn't matter if the user does not
         actually link against crtbegin.o; the
         linker won't look for a file to match a
         wildcard.  The wildcard also means that it
         doesn't matter which directory crtbegin.o
         is in.  */
      KEEP (*crtbegin.o(.ctors))
      KEEP (*crtbegin?.o(.ctors))
      /* We don't want to include the .ctor section from
         from the crtend.o file until after the sorted ctors.
         The .ctor section from the crtend file contains the
         end of ctors marker and it must be last */
      KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
      KEEP (*(SORT(.ctors.*)))
      KEEP (*(.ctors))
      __CTOR_END__ = .;
    } > m_text

    .dtors :
    {
      __DTOR_LIST__ = .;
      KEEP (*crtbegin.o(.dtors))
      KEEP (*crtbegin?.o(.dtors))
      KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
      KEEP (*(SORT(.dtors.*)))
      KEEP (*(.dtors))
      __DTOR_END__ = .;
    } > m_text
        
    .preinit_array :
    {
      PROVIDE_HIDDEN (__preinit_array_start = .);
      KEEP (*(.preinit_array*))
      PROVIDE_HIDDEN (__preinit_array_end = .);
    } > m_text

    .init_array :
    {
      PROVIDE_HIDDEN (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array*))
      PROVIDE_HIDDEN (__init_array_end = .);
    } > m_text

    .fini_array :
    {
      PROVIDE_HIDDEN (__fini_array_start = .);
      KEEP (*(SORT(.fini_array.*)))
      KEEP (*(.fini_array*))
      PROVIDE_HIDDEN (__fini_array_end = .);
    } > m_text
          
    .rodata :
    {
      *(.rodata)
      *(.rodata.*)
    } > m_text
    
    .eh_frame_hdr : { *(.eh_frame_hdr) } > m_text
    .eh_frame     : { KEEP (*(.eh_frame)) } > m_text
    
    .data   : 
    {
      *(.data)
      *(.data.*)
    }  > m_data AT>m_text
    
    .sdata2  :
    {  
      *(.sdata2)
      *(.sdata2.*)
    } > m_data AT>m_text

    .sbss2    (NOLOAD)   :
    {
      /* _SDA2_BASE_ = .; */ 
      *(.sbss2)
      *(.sbss2.*)
    } > m_data
    
    .sdata  :
    {
      *(.sdata)
      *(.sdata.*)
    } > m_data AT>m_text
    
    .bss   (NOLOAD)  :
    {
      __BSS_START = .;
      *(.sbss)
      *(.sbss.*)	
      *(.bss)
      *(.bss.*)
      *(COMMON)
      __BSS_END = .;
    } > m_data
    
    .stack (NOLOAD) : ALIGN(16) 
    {
      __HEAP = . ;
      PROVIDE (_end = . );
      PROVIDE (end = . );            
      . += __HEAP_SIZE ;
      __HEAP_END = . ;
      _stack_end = . ;
      . +=  __STACK_SIZE ;
      _stack_addr = . ;
      __SP_INIT = . ;
      . += 4;
    } > m_data
 
/*-------- LABELS USED IN CODE -------------------------------*/
        
/* Labels for Copying Initialised Data from Flash to RAM */
__DATA_SRAM_ADDR  = ADDR(.data);
__SDATA_SRAM_ADDR = ADDR(.sdata);

__DATA_SIZE   = SIZEOF(.data);
__SDATA_SIZE  = SIZEOF(.sdata);

__DATA_ROM_ADDR  = LOADADDR(.data);
__SDATA_ROM_ADDR = LOADADDR(.sdata);
   
/* Labels Used for Initialising SRAM ECC */
__SRAM_SIZE = SRAM_SIZE;
__SRAM_BASE_ADDR = SRAM_BASE_ADDR;
     
__BSS_SIZE    = __BSS_END - __BSS_START;

}

led驱动工程:

/*
 * main implementation: use this 'C' sample to create your own application
 *
 */

#include "derivative.h" /* include peripheral declarations */

#define PORTF_0	80
#define PORTF_1	81

#define PF0_LED_R_CTL	PORTF_0
#define PF1_LED_G_CTL	PORTF_1

void disable_watchdog(void)
{
    SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */
    SWT.SR.R = 0x0000d928;
    SWT.CR.R = 0x8000010A;     /* Clear watchdog enable (WEN) */
}

void system_init(void)
{
	//模式配置: 使能DRUN, RUN0, SAFE, RESET模式
//	ME.MER.R = 0x0000001D;
	ME.MER.R = 0x0000243D;

	//初始化锁相环,
	//外部晶振为8MHz,设置PLL0为64MHz  // 0x05400100: 0000 0101 0100 0000 0000 0001 0000 0000
	//设置IDF=2,ODF=4,NDIV=64;
	//锁相环输出时钟phi=(clkin*NDIV)/(IDF*ODF)=(8*64)/(2*4)=64MHz
//	CGM.FMPLL_CR.R = 0x05400100;
	CGM.FXOSC_CTL.R = 0x00801300;
	CGM.FMPLL_CR.R = 0x0D400000;

    //RUN0配置: 主电压调节器打开,Data Flash处于正常模式。Code Flash处于正常模式。
    //使能锁相环,锁相环输出时钟作为系统时钟。
    ME.RUN[0].R   = 0x001F0074;

    //外设运行配置0: 外设在所有模式下都工作
    ME.RUNPC[0].R = 0x000000FE;

    // SIUL: 选择 ME.RUNPC[0] 的配置
    ME.PCTL[68].R = 0x00;

    // 设置进入RUN0模式
    ME.MCTL.R = 0x40005AF0;               //写入模式和密钥
    ME.MCTL.R = 0x4000A50F;               //写入模式和反密钥

    //等待模式转换完成
    while(ME.GS.B.S_MTRANS) {};
    //验证进入了RUN0模式
    while(ME.GS.B.S_CURRENTMODE != 4) {}
}

__attribute__ ((section(".m_min1"))) void led_init(void);
__attribute__ ((section(".m_min2"))) void led_on(void);
__attribute__ ((section(".m_min3"))) void led_off(void);

void led_init(void)
{
	SIU.PCR[PF0_LED_R_CTL	].R = 0x0200;
}

void led_on(void)
{
	SIU.GPDO[PF0_LED_R_CTL	].B.PDO = 1;
}

void led_off(void)
{
	SIU.GPDO[PF0_LED_R_CTL	].B.PDO = 0;
}

int main(void)
{
	volatile int counter = 0;
	
//	xcptn_xmpl ();              /* Configure and Enable Interrupts */

	disable_watchdog();
	system_init();

	/* Loop forever */
	for(;;) {	   
	   	counter++;
	}
}
59        {
          led_init:
00000100:   e_stwu  r1,-16(r1)
00000104:   se_stw  r31,12(r1)
00000106:   se_mr   r31,r1
60        	SIU.PCR[PF0_LED_R_CTL	].R = 0x0200;
00000108:   e_lis   r7,50169
0000010c:   se_bgeni        r6,22
0000010e:   e_sth   r6,224(r7)
61        }
00000112:   e_addi  r11,r31,16
00000116:   e_lwz   r31,-4(r11)
0000011a:   se_mfar r1,r11
0000011c:   se_blr  


59        {
          led_init:
00000100:   e_stwu  r1,-16(r1)
00000104:   se_stw  r31,12(r1)
00000106:   se_mr   r31,r1
60        	SIU.PCR[PF0_LED_R_CTL	].R = 0x0200;
00000108:   e_lis   r7,50169
0000010c:   se_bgeni        r6,22
0000010e:   e_sth   r6,224(r7)
61        }
00000112:   e_addi  r11,r31,16
00000116:   e_lwz   r31,-4(r11)
0000011a:   se_mfar r1,r11
0000011c:   se_blr  


69        {
          led_off:
00000300:   e_stwu  r1,-16(r1)
00000304:   se_stw  r31,12(r1)
00000306:   se_mr   r31,r1
70        	SIU.GPDO[PF0_LED_R_CTL	].B.PDO = 0;
00000308:   e_lis   r7,50169
0000030c:   e_lbz   r6,1616(r7)
00000310:   se_bclri        r6,31
00000312:   e_stb   r6,1616(r7)
71        }
00000316:   e_addi  r11,r31,16
0000031a:   e_lwz   r31,-4(r11)
0000031e:   se_mfar r1,r11
00000320:   se_blr 

查看map文件中相关函数信息
将led_init/led_on/led_off从bin文件中拷贝出来放到数组里

APP工程:

/*
 * main implementation: use this 'C' sample to create your own application
 *
 */

#include "derivative.h" /* include peripheral declarations */

extern void xcptn_xmpl(void);

unsigned char __attribute__((aligned(4))) led_init[] = { 0x18, 0x21, 0x06, 0xF0, 0xD3, 0xF1, 0x01, 0x1F, 0x70, 0xF8, 0xE3, 0xF9, 0x63, 0x66, 0x5C, 0xC7, 0x00, 0xE0, 0x19, 0x7F, 0x80, 0x10, 0x53, 0xEB, 0xFF, 0xFC, 0x03, 0x31, 0x00, 0x04, 0x00, 0x00 };
unsigned char __attribute__((aligned(4))) led_on  [] = { 0x18, 0x21, 0x06, 0xF0, 0xD3, 0xF1, 0x01, 0x1F, 0x70, 0xF8, 0xE3, 0xF9, 0x30, 0xC7, 0x06, 0x50, 0x65, 0xF6, 0x34, 0xC7, 0x06, 0x50, 0x19, 0x7F, 0x80, 0x10, 0x53, 0xEB, 0xFF, 0xFC, 0x03, 0x31, 0x00, 0x04, 0x00, 0x00 };
unsigned char __attribute__((aligned(4))) led_off [] = { 0x18, 0x21, 0x06, 0xF0, 0xD3, 0xF1, 0x01, 0x1F, 0x70, 0xF8, 0xE3, 0xF9, 0x30, 0xC7, 0x06, 0x50, 0x61, 0xF6, 0x34, 0xC7, 0x06, 0x50, 0x19, 0x7F, 0x80, 0x10, 0x53, 0xEB, 0xFF, 0xFC, 0x03, 0x31, 0x00, 0x04, 0x00, 0x00 };

typedef void (*fun)(void);

fun fun_led_init = (fun)(led_init + 1);
fun fun_led_on   = (fun)(led_on   + 1);
fun fun_led_off  = (fun)(led_off  + 1);

int main(void)
{
	volatile int counter = 0;
	
//	xcptn_xmpl ();              /* Configure and Enable Interrupts */

	disable_watchdog();
	system_init();

	fun_led_init();
	fun_led_on();

	/* Loop forever */
	for(;;) {
	   	counter++;
	}
}

void disable_watchdog(void)
{
    SWT.SR.R = 0x0000c520;     /* Write keys to clear soft lock bit */
    SWT.SR.R = 0x0000d928;
    SWT.CR.R = 0x8000010A;     /* Clear watchdog enable (WEN) */
}

void system_init(void)
{
	//模式配置: 使能DRUN, RUN0, SAFE, RESET模式
//	ME.MER.R = 0x0000001D;
	ME.MER.R = 0x0000243D;

	//初始化锁相环,
	//外部晶振为8MHz,设置PLL0为64MHz  // 0x05400100: 0000 0101 0100 0000 0000 0001 0000 0000
	//设置IDF=2,ODF=4,NDIV=64;
	//锁相环输出时钟phi=(clkin*NDIV)/(IDF*ODF)=(8*64)/(2*4)=64MHz
//	CGM.FMPLL_CR.R = 0x05400100;
	CGM.FXOSC_CTL.R = 0x00801300;
	CGM.FMPLL_CR.R = 0x0D400000;

    //RUN0配置: 主电压调节器打开,Data Flash处于正常模式。Code Flash处于正常模式。
    //使能锁相环,锁相环输出时钟作为系统时钟。
    ME.RUN[0].R   = 0x001F0074;

    //外设运行配置0: 外设在所有模式下都工作
    ME.RUNPC[0].R = 0x000000FE;

    // SIUL: 选择 ME.RUNPC[0] 的配置
    ME.PCTL[68].R = 0x00;

    // 设置进入RUN0模式
    ME.MCTL.R = 0x40005AF0;               //写入模式和密钥
    ME.MCTL.R = 0x4000A50F;               //写入模式和反密钥

    //等待模式转换完成
    while(ME.GS.B.S_MTRANS) {};
    //验证进入了RUN0模式
    while(ME.GS.B.S_CURRENTMODE != 4) {}
}

参考:
常量固定地址-S32 Design Studio for ARM
Bootloader升级方式一————擦、写flash在RAM中运行

你可能感兴趣的:(MPC56xx)