开发环境:
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中运行