Index: fw/core/flash_start_gcc.s
===================================================================
--- /YC3121_SDK/fw/core/flash_start_gcc.s	(revision 633)
+++ /YC3121_SDK/fw/core/flash_start_gcc.s	(working copy)
@@ -1,10 +1,10 @@
 		.org 0x200
-		.global start_flash,hard_fault_handler,svc_handler,pendsv_handler,systick,irq0,irq1,irq2,irq3,irq4,irq5,irq6,irq7,irq8,irq9,irq10,irq11,irq12,irq13,irq14,irq15,irq16,irq17,irq18,irq19,irq20,irq21,irq22,irq23,irq24,irq25,irq26,irq27,irq28,irq29,irq30,irq31
+		.global Reset_Handler,hard_fault_handler,svc_handler,pendsv_handler,systick,irq0,irq1,irq2,irq3,irq4,irq5,irq6,irq7,irq8,irq9,irq10,irq11,irq12,irq13,irq14,irq15,irq16,irq17,irq18,irq19,irq20,irq21,irq22,irq23,irq24,irq25,irq26,irq27,irq28,irq29,irq30,irq31
 		
 		.long
 
 
-start_flash:
+Reset_Handler:
 		ldr r0,=hardware_init
 		bx r0	
 		.thumb_func
@@ -202,9 +202,9 @@
 		.thumb
 		.thumb_func
 hardware_init:
-		ldr	r1, =_sidata
-		ldr	r2, =_sdata
-		ldr	r3, =_edata
+		ldr	r1, =__exidx_start
+		ldr	r2, =__data_start__
+		ldr	r3, =__data_end__
 
 		sub	r3, r2
 		ble	.L_loop1_done
@@ -227,8 +227,8 @@
 	 *
 	 *  Both addresses must be aligned to 4 bytes boundary.
 	 */
-		ldr	r1, =_sbss
-		ldr	r2, =_ebss
+		ldr	r1, =__bss_start__
+		ldr	r2, =__bss_end__
 
 		mov	r0, #0
 
Index: fw/core/misc.h
===================================================================
--- /YC3121_SDK/fw/core/misc.h	(revision 633)
+++ /YC3121_SDK/fw/core/misc.h	(working copy)
@@ -70,7 +70,15 @@
  * @param  none
  * @retval 0:interrupt not masking; 1:interrupt is masking
  */
-uint32_t get_primask();
+uint32_t get_primask(void);
+
+
+/**
+ * @brief  get cortex M0 msp REG value
+ * @param  none
+ * @retval msp REG value
+ */
+uint32_t get_msp(void);
 
 /**
  * @brief  set MSP
Index: fw/core/misc.c
===================================================================
--- /YC3121_SDK/fw/core/misc.c	(revision 633)
+++ /YC3121_SDK/fw/core/misc.c	(working copy)
@@ -28,16 +28,28 @@
 	while(1);
 }
 
-
-__asm uint32_t get_primask(void)
+uint32_t get_primask(void)
 {
-	mrs r0, primask
-	bx lr
+	__asm volatile("mrs r0, primask");
 }
 
+uint32_t get_msp(void)
+{
+	__asm volatile("mrs r0, msp");
+}
 
-__asm void set_msp(uint32_t mainStackPointer)
+#if defined ( __CC_ARM   )	//MDK
+void set_msp(uint32_t mainStackPointer)
+{
+	__asm volatile("msr msp,mainStackPointer");
+}
+#else
+void set_msp(uint32_t mainStackPointer)
 {
-	msr msp, r0
-	bx lr
+	__asm volatile("msr msp,r0");
 }
+#endif
+
+
+
+
Index: fw/main.c
===================================================================
--- /YC3121_SDK/fw/main.c	(revision 633)
+++ /YC3121_SDK/fw/main.c	(working copy)
@@ -2,6 +2,7 @@
 #include<string.h>
 #include "core\bt_code.h"
 #include "core\system.h"
+#include "core\misc.h"
 #include "sdk\yc_uart.h"
 #include "sdk\yc_sysctrl.h"
 #include "sdk\yc_systick.h"
@@ -36,37 +37,6 @@
 }
 
 
-int lpm_read(volatile int *addr)
-{
-	#if (HARDWAER==M0_FPGA)
-		if((int)addr<=0xf740B)
-			return LPMREG_FPGABuf[((int)addr-0xf7404)/4];
-		else
-			return LPMREG_FPGABuf[2+((int)addr-0xf7480)/4];
-
-	#elif (HARDWAER==POS_FPGA||HARDWAER==POS_CHIP)
-		int i = *addr;
-	//	MyPrintf("lpm_read i=%x\r\n",i);//编译器会忽略上面那句话，但是硬件没有上面一句话，程序会一直死在这里
-		while(SYSCTRL_STATUS & 0x10000);
-		return SYSCTRL_LPM_RDATA;
-	#endif
-	
-}
-
-void lpm_write(volatile int *addr, int val)
-{
-	#if (HARDWAER==M0_FPGA)
-		if((int)addr<=0xf740B)
-			LPMREG_FPGABuf[((int)addr-0xf7404)/4] = val;
-		else
-			LPMREG_FPGABuf[2+((int)addr-0xf7480)/4] = val;
-	#elif (HARDWAER==POS_FPGA||HARDWAER==POS_CHIP)
-		*addr = val;
-		while(SYSCTRL_STATUS & 0x10000);
-	#endif
-}
-
-
 void wdt_test()
 {
 	MyPrintf("\r\nwdt test");
@@ -164,7 +134,7 @@
 	static uint32_t times = 0;
 	times++;
 
-	if(times>0x10000)
+	if(times>0x100000)
 	{
 		times = 0;
 		GPIO_CONFIG(2) = (GPIO_CONFIG(2)==GPCFG_OUTPUT_HIGH)? GPCFG_OUTPUT_LOW: GPCFG_OUTPUT_HIGH;
@@ -303,32 +273,7 @@
 
 void main()
 {
-	#ifndef __USEKEILCOMPILE__
-	unsigned long *src, *dest;
-	extern unsigned long  _sdata, _edata, _sidata;
-	extern char _ebss, _sbss;
-
-	
-	for(register unsigned int i = 0x20000;i<0x30000;i++)
-	{
-		*(volatile unsigned char*)i = 0;
-	}
-
-
-	for (src = &_sidata, dest = &_sdata; dest < &_edata;)
-		*(dest++) = *(src++);
 
-	memset((void*)&_sbss, 0, &_ebss - &_sbss);
-	#endif
-	
-
-	
-	SYSCTRL_HCLK_CON = 0;
-	
-	for(int i = 0;i<32;i++)
-		disable_intr(i);
-
-	delay_ms(500);
 
 	SYSCTRL_AHBPeriphClockCmd(SYSCTRL_AHBPeriph_UART,ENABLE);
 	printf_uart_init(UART0);
@@ -339,6 +284,13 @@
 	MyPrintf("\r\nData:%s-%s",__DATE__,__TIME__);
 	MyPrintf("\r\nchip power");
 
+	MyPrintf("\nprimask=%x",get_primask());
+	__asm("CPSID i");
+	MyPrintf("\nprimask=%x",get_primask());
+	__asm("CPSIE i");
+	MyPrintf("\nprimask=%x",get_primask());
+	MyPrintf("\nmsp=%x",get_msp());
+
 //	bt_test();
 //	qspi_test();
 	#ifdef USB_CCID_DEMO
@@ -347,7 +299,7 @@
 	//test_usb();
 #endif
 	uart0_init(UART1);
-	UartCmd_Init();
+//	UartCmd_Init();
     
 
 //	RAND_Init();
@@ -355,7 +307,7 @@
 	
 	while(1)
 	{	
-	 	UartCmd_Process();
+//	 	UartCmd_Process();
 //		WDTTEST();
 		LED_Run();
 	} 
Index: fw/makefile
===================================================================
--- /YC3121_SDK/fw/makefile	(revision 633)
+++ /YC3121_SDK/fw/makefile	(working copy)
@@ -16,43 +16,50 @@
 all : output/out.hex
 
 
-CORE_OBJS = core/flash_start_gcc \
+CORE_OBJS = core/misc \
+			core/flash_start_gcc \
             core/system \
-						crypt\yc_aes \
-						crypt\yc_des \
-						crypt\yc_rsa \
-						crypt\yc_sha \
-						crypt\yc_sm3 \
-						crypt\yc_sm4 \
-						crypt\yc_sm2 \
-						crypt\yc_ecc \
-						crypt\yc_calc \
-						crypt\yc_crc16 \
-						sdk\yc_rand \
-						sdk\yc_spi \
-						sdk\yc_trng \
-						sdk\yc_systick \
-						sdk\yc_sysctrl \
-						sdk\yc_uart \
-						sdk\yc_timer \
-						sdk\yc_iic \
-						sdk\yc_it \
-						sdk\yc_gpio \
-						sdk\yc_msr\yc_msr \
-						sdk\yc_wdt \
-						sdk\yc_dma \
-						sdk\yc_exti \
-						sdk\yc_bt \
-						sdk\yc_ipc \
-						Example\Func_assist \
-						Example\Uart_cmd \
-						Example\UART_Test\Uart_Test \
-						Example\SPI_Test\SPI_Test \
-						Example\TIMER_PWM_Test\TIMER_PWM_Test \
-						Example\IIC_Test\IIC_Test \
-						Example\TRNG_Test\TRNG_Test \
-#						Example\MSR_Test\MSR_Test \
-						Example\Algorithm
+			crypt/yc_aes \
+			crypt/yc_calc \
+			crypt/yc_crc16 \
+			crypt/yc_des \
+			crypt/yc_ecc \
+			crypt/yc_rsa \
+			crypt/yc_sha \
+			crypt/yc_sm2 \
+			crypt/yc_sm3 \
+			crypt/yc_sm4 \
+			sdk/yc_7816/yc_7816 \
+			sdk/yc_7816/yc_7816_T0 \
+			sdk/yc_7816/yc_7816_T1 \
+			sdk/yc_msr/yc_msr \
+			sdk/yc_nfc/yc_emv_contactless_l1 \
+			sdk/yc_nfc/yc_nfc_common \
+			sdk/yc_adc \
+			sdk/yc_bt \
+			sdk/yc_chrg \
+			sdk/yc_dma \
+			sdk/yc_DTM \
+			sdk/yc_exti \
+			sdk/yc_gpio \
+			sdk/yc_iic \
+			sdk/yc_ipc \
+			sdk/yc_kscan \
+			sdk/yc_lcd \
+			sdk/yc_lpm \
+			sdk/yc_otp \
+			sdk/yc_power \
+			sdk/yc_qspi \
+			sdk/yc_rand \
+			sdk/yc_rtc \
+			sdk/yc_spi \
+			sdk/yc_ssc \
+			sdk/yc_sysctrl \
+			sdk/yc_systick \
+			sdk/yc_timer \
+			sdk/yc_trng \
+			sdk/yc_uart \
+			sdk/yc_wdt
 
 
              
@@ -62,26 +69,176 @@
 OBJS = $(CORE_OBJS) $(USER_OBJS)
 
 INC_DIR = -I core \
+		  -I crypt \
           -I sdk \
-          -I sdk\yc_msr
+          -I sdk/yc_7816 \
+		  -I sdk/yc_msr \
+		  -I sdk/yc_nfc \
+		  -I sdk/yc_usb
 
 
-CFLAG =  -mthumb -mcpu=cortex-m0 -c -g -Os $(INC_DIR) $(DEF) -fno-toplevel-reorder
+CFLAG =  -mthumb -mcpu=cortex-m0 -c -g -Os $(INC_DIR) $(DEF) -fno-toplevel-reorder  -ffunction-sections -fdata-sections
 LDFLAG = -T output/ld.script -Map=output/memmap -lc -lm -lgcc -L "$(DIR)/lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m"  -L "$(DIR)/arm-none-eabi/lib/thumb/v6-m"
 
 define ldscript = 
+/* Linker script to configure memory regions. 
+ * Need modifying for a specific board. 
+ *   FLASH.ORIGIN: starting address of flash
+ *   FLASH.LENGTH: length of flash
+ *   RAM.ORIGIN: starting address of RAM bank 0
+ *   RAM.LENGTH: length of RAM bank 0
+ */
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x1000000, LENGTH = 0x80000 /* 512K */
+  RAM (rwx) : ORIGIN = 0x20000, LENGTH = 0x10000 /* 64K */
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ * 
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ */
+ENTRY(Reset_Handler)
+
 SECTIONS
-{ 
-        . = 0x1000000;
-        .text : { *flash_start.o *(.text*) *(.rodata*) }
-        _sidata = ALIGN(4);
-        . = 0x20000;
-        .data : AT (_sidata) { _sdata = .; *(.data) _edata = .; }
-        .bss : { _sbss = .;     *(*.bss) *(*.scommon*) }
-        _ebss = .;
-        . = 0x30000;
-        _stack = .;
-        ASSERT(_ebss < _stack, "data size overflow")
+{
+	.text :
+	{
+		*flash_start*.o
+		*(.text*)
+
+		KEEP(*(.init))
+		KEEP(*(.fini))
+
+		/* .ctors */
+		*crtbegin.o(.ctors)
+		*crtbegin?.o(.ctors)
+		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+		*(SORT(.ctors.*))
+		*(.ctors)
+
+		/* .dtors */
+ 		*crtbegin.o(.dtors)
+ 		*crtbegin?.o(.dtors)
+ 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ 		*(SORT(.dtors.*))
+ 		*(.dtors)
+
+		*(.rodata*)
+
+		KEEP(*(.eh_frame*))
+	} > FLASH
+	
+	.ARM.extab : 
+	{
+		*(.ARM.extab* .gnu.linkonce.armextab.*)
+	} > FLASH
+
+	 . = ALIGN(4);
+	__exidx_start = .;
+	.ARM.exidx :
+	{
+		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
+	} > FLASH
+	__exidx_end = .;
+
+	
+	__etext = .;
+		
+	.data : AT (__etext)
+	{
+		__data_start__ = .;
+		*(vtable)
+		*(.data*)
+
+		. = ALIGN(4);
+		/* preinit data */
+		PROVIDE_HIDDEN (__preinit_array_start = .);
+		KEEP(*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+
+		. = ALIGN(4);
+		/* init data */
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP(*(SORT(.init_array.*)))
+		KEEP(*(.init_array))
+		PROVIDE_HIDDEN (__init_array_end = .);
+
+
+		. = ALIGN(4);
+		/* finit data */
+		PROVIDE_HIDDEN (__fini_array_start = .);
+		KEEP(*(SORT(.fini_array.*)))
+		KEEP(*(.fini_array))
+		PROVIDE_HIDDEN (__fini_array_end = .);
+
+		KEEP(*(.jcr*))
+		. = ALIGN(4);
+		/* All data end */
+		__data_end__ = .;
+
+	} > RAM
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start__ = .;
+		*(.bss*)
+		*(COMMON)
+		. = ALIGN(4);
+		__bss_end__ = .;
+	} > RAM
+	
+	.heap (COPY):
+	{
+		__end__ = .;
+		PROVIDE(end = .);
+		*(.heap*)
+		__HeapLimit = .;
+	} > RAM
+
+	/* .stack_dummy section doesn't contains any symbols. It is only
+	 * used for linker to calculate size of stack sections, and assign
+	 * values to stack symbols later */
+	.stack_dummy (COPY):
+	{
+		*(.stack*)
+	} > RAM
+
+	/* Set stack top to end of RAM, and stack limit move down by
+	 * size of stack_dummy section */
+	__StackTop = ORIGIN(RAM) + LENGTH(RAM);
+	__StackLimit = __StackTop - SIZEOF(.stack_dummy);
+	PROVIDE(__stack = __StackTop);
+	
+	/* Check if data + heap + stack exceeds RAM limit */
+	ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
 }
 endef
 
Index: fw/makefile_lib
===================================================================
--- /YC3121_SDK/fw/makefile_lib	(revision 634)
+++ /YC3121_SDK/fw/makefile_lib	(working copy)
@@ -30,6 +30,7 @@
 			sdk/yc_7816/yc_7816_T0 \
 			sdk/yc_7816/yc_7816_T1 \
 			core/flash_start_gcc \
+			core/misc \
 			sdk/yc_rand \
 			sdk/yc_trng \
 			core/system \
@@ -52,18 +53,164 @@
 LDFLAG = -T output/ld.script -Map=output/memmap -lc -lm -lgcc -L "$(DIR)/lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m"  -L "$(DIR)/arm-none-eabi/lib/thumb/v6-m"
 
 define ldscript = 
+/* Linker script to configure memory regions. 
+ * Need modifying for a specific board. 
+ *   FLASH.ORIGIN: starting address of flash
+ *   FLASH.LENGTH: length of flash
+ *   RAM.ORIGIN: starting address of RAM bank 0
+ *   RAM.LENGTH: length of RAM bank 0
+ */
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x1000000, LENGTH = 0x80000 /* 512K */
+  RAM (rwx) : ORIGIN = 0x20000, LENGTH = 0x10000 /* 64K */
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ * 
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ */
+ENTRY(Reset_Handler)
+
 SECTIONS
-{ 
-        . = 0x1000000;
-        .text : { *flash_start.o *(.text*) *(.rodata*) }
-        _sidata = ALIGN(4);
-        . = 0x20000;
-        .data : AT (_sidata) { _sdata = .; *(.data) _edata = .; }
-        .bss : { _sbss = .;     *(*.bss) *(*.scommon*) }
-        _ebss = .;
-        . = 0x30000;
-        _stack = .;
-        ASSERT(_ebss < _stack, "data size overflow")
+{
+	.text :
+	{
+		*flash_start*.o
+		*(.text*)
+
+		KEEP(*(.init))
+		KEEP(*(.fini))
+
+		/* .ctors */
+		*crtbegin.o(.ctors)
+		*crtbegin?.o(.ctors)
+		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+		*(SORT(.ctors.*))
+		*(.ctors)
+
+		/* .dtors */
+ 		*crtbegin.o(.dtors)
+ 		*crtbegin?.o(.dtors)
+ 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ 		*(SORT(.dtors.*))
+ 		*(.dtors)
+
+		*(.rodata*)
+
+		KEEP(*(.eh_frame*))
+	} > FLASH
+	
+	.ARM.extab : 
+	{
+		*(.ARM.extab* .gnu.linkonce.armextab.*)
+	} > FLASH
+
+	 . = ALIGN(4);
+	__exidx_start = .;
+	.ARM.exidx :
+	{
+		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
+	} > FLASH
+	__exidx_end = .;
+
+	
+	__etext = .;
+		
+	.data : AT (__etext)
+	{
+		__data_start__ = .;
+		*(vtable)
+		*(.data*)
+
+		. = ALIGN(4);
+		/* preinit data */
+		PROVIDE_HIDDEN (__preinit_array_start = .);
+		KEEP(*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+
+		. = ALIGN(4);
+		/* init data */
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP(*(SORT(.init_array.*)))
+		KEEP(*(.init_array))
+		PROVIDE_HIDDEN (__init_array_end = .);
+
+
+		. = ALIGN(4);
+		/* finit data */
+		PROVIDE_HIDDEN (__fini_array_start = .);
+		KEEP(*(SORT(.fini_array.*)))
+		KEEP(*(.fini_array))
+		PROVIDE_HIDDEN (__fini_array_end = .);
+
+		KEEP(*(.jcr*))
+		. = ALIGN(4);
+		/* All data end */
+		__data_end__ = .;
+
+	} > RAM
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start__ = .;
+		*(.bss*)
+		*(COMMON)
+		. = ALIGN(4);
+		__bss_end__ = .;
+	} > RAM
+	
+	.heap (COPY):
+	{
+		__end__ = .;
+		PROVIDE(end = .);
+		*(.heap*)
+		__HeapLimit = .;
+	} > RAM
+
+	/* .stack_dummy section doesn't contains any symbols. It is only
+	 * used for linker to calculate size of stack sections, and assign
+	 * values to stack symbols later */
+	.stack_dummy (COPY):
+	{
+		*(.stack*)
+	} > RAM
+
+	/* Set stack top to end of RAM, and stack limit move down by
+	 * size of stack_dummy section */
+	__StackTop = ORIGIN(RAM) + LENGTH(RAM);
+	__StackLimit = __StackTop - SIZEOF(.stack_dummy);
+	PROVIDE(__stack = __StackTop);
+	
+	/* Check if data + heap + stack exceeds RAM limit */
+	ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
 }
 endef
 
Index: fw/output/ld.script
===================================================================
--- /YC3121_SDK/fw/output/ld.script	(revision 633)
+++ /YC3121_SDK/fw/output/ld.script	(working copy)
@@ -1,13 +1,159 @@
- SECTIONS
-{ 
-        . = 0x1000000;
-        .text : { *flash_start.o *(.text*) *(.rodata*) }
-        _sidata = ALIGN(4);
-        . = 0x20000;
-        .data : AT (_sidata) { _sdata = .; *(.data) _edata = .; }
-        .bss : { _sbss = .;     *(*.bss) *(*.scommon*) }
-        _ebss = .;
-        . = 0x30000;
-        _stack = .;
-        ASSERT(_ebss < _stack, "data size overflow")
+ /* Linker script to configure memory regions. 
+ * Need modifying for a specific board. 
+ *   FLASH.ORIGIN: starting address of flash
+ *   FLASH.LENGTH: length of flash
+ *   RAM.ORIGIN: starting address of RAM bank 0
+ *   RAM.LENGTH: length of RAM bank 0
+ */
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x1000000, LENGTH = 0x80000 /* 512K */
+  RAM (rwx) : ORIGIN = 0x20000, LENGTH = 0x10000 /* 64K */
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ * 
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+	.text :
+	{
+		*flash_start*.o
+		*(.text*)
+
+		KEEP(*(.init))
+		KEEP(*(.fini))
+
+		/* .ctors */
+		*crtbegin.o(.ctors)
+		*crtbegin?.o(.ctors)
+		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+		*(SORT(.ctors.*))
+		*(.ctors)
+
+		/* .dtors */
+ 		*crtbegin.o(.dtors)
+ 		*crtbegin?.o(.dtors)
+ 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ 		*(SORT(.dtors.*))
+ 		*(.dtors)
+
+		*(.rodata*)
+
+		KEEP(*(.eh_frame*))
+	} > FLASH
+	
+	.ARM.extab : 
+	{
+		*(.ARM.extab* .gnu.linkonce.armextab.*)
+	} > FLASH
+
+	 . = ALIGN(4);
+	__exidx_start = .;
+	.ARM.exidx :
+	{
+		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
+	} > FLASH
+	__exidx_end = .;
+
+	
+	__etext = .;
+		
+	.data : AT (__etext)
+	{
+		__data_start__ = .;
+		*(vtable)
+		*(.data*)
+
+		. = ALIGN(4);
+		/* preinit data */
+		PROVIDE_HIDDEN (__preinit_array_start = .);
+		KEEP(*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+
+		. = ALIGN(4);
+		/* init data */
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP(*(SORT(.init_array.*)))
+		KEEP(*(.init_array))
+		PROVIDE_HIDDEN (__init_array_end = .);
+
+
+		. = ALIGN(4);
+		/* finit data */
+		PROVIDE_HIDDEN (__fini_array_start = .);
+		KEEP(*(SORT(.fini_array.*)))
+		KEEP(*(.fini_array))
+		PROVIDE_HIDDEN (__fini_array_end = .);
+
+		KEEP(*(.jcr*))
+		. = ALIGN(4);
+		/* All data end */
+		__data_end__ = .;
+
+	} > RAM
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start__ = .;
+		*(.bss*)
+		*(COMMON)
+		. = ALIGN(4);
+		__bss_end__ = .;
+	} > RAM
+	
+	.heap (COPY):
+	{
+		__end__ = .;
+		PROVIDE(end = .);
+		*(.heap*)
+		__HeapLimit = .;
+	} > RAM
+
+	/* .stack_dummy section doesn't contains any symbols. It is only
+	 * used for linker to calculate size of stack sections, and assign
+	 * values to stack symbols later */
+	.stack_dummy (COPY):
+	{
+		*(.stack*)
+	} > RAM
+
+	/* Set stack top to end of RAM, and stack limit move down by
+	 * size of stack_dummy section */
+	__StackTop = ORIGIN(RAM) + LENGTH(RAM);
+	__StackLimit = __StackTop - SIZEOF(.stack_dummy);
+	PROVIDE(__stack = __StackTop);
+	
+	/* Check if data + heap + stack exceeds RAM limit */
+	ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
 }
Index: fw/sdk/yc_DTM.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_DTM.c	(revision 635)
+++ /YC3121_SDK/fw/sdk/yc_DTM.c	(working copy)
@@ -1,6 +1,8 @@
 
 #include "yc_dtm.h"
 extern uint8_t BT_Wake;
+extern void erase_memory(void);
+extern void _download_btcode(const byte *btcode);
 void DTMTestInit(void)
 {
 	disable_intr(INTR_BT);
Index: fw/sdk/yc_lcd.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_lcd.c	(revision 635)
+++ /YC3121_SDK/fw/sdk/yc_lcd.c	(working copy)
@@ -7,9 +7,6 @@
 */
 #include "yc_lcd.h"
 
-void clr_a0(void);
-void set_a0(void);
-void spi_write_data(unsigned char data);
 
 SPIx_TypeDef LCDSPI  = SPI0;
 uint16_t LCD_SDA_PIN = GPIO_Pin_2;
