/************************************************************************************************ 
* RomToRam_Kinetis
* 将部分ROM中的数据转移至RAM中
************************************************************************************************/
static void RomToRam_Kinetis(void)
{
  K_int32u_t n = (K_int32u_t)__section_end(".data_init") - (K_int32u_t)__section_begin(".data_init");
  K_int8u_t *ptr1 = __section_begin(".data"), *ptr2 = __section_begin(".data_init");
  
  K_int8u_t* code_relocate_ram = __section_begin("CodeRelocateRam");
  K_int8u_t* code_relocate = __section_begin("CodeRelocate");
  K_int8u_t* code_relocate_end = __section_end("CodeRelocate");
  
  if(n != 0)
  {
    do
    {
      *ptr1++ = *ptr2++;  
    } while(--n);  
  } 
  
  /* Copy functions from ROM to RAM */
  n = (K_int32u_t)code_relocate_end - (K_int32u_t)code_relocate;
  if(n != 0)
  {
    while (n--)
    {
      *code_relocate_ram++ = *code_relocate++;
    }
  }
}
Exemple #2
0
void __iar_program_start(void)
{
    /* the calls below are normally made in IAR cstartup */
    __iar_init_core();
    __iar_init_vfp();

    /* the calls below are normally made in IAR cmain
     *
     * The function "__low_level_init" is a user overrideable hook
     * that does nothing by default. Returning zero means that
     * ram initialization should be skipped. Skipping ram initialization
     * is not allowed by mbed.
     *
     * The function "__iar_data_init3" is an IAR function which
     * initializes ram.
     *
     */
    __low_level_init();
    __iar_data_init3();

    /* mbed specific code */
    mbed_heap_start = (unsigned char *)__section_begin("HEAP");
    mbed_heap_size = (uint32_t)__section_size("HEAP");

    mbed_stack_isr_start = (unsigned char *)__section_begin("CSTACK");
    mbed_stack_isr_size = (uint32_t)__section_size("CSTACK");

    mbed_init();
    mbed_rtos_start();
}
Exemple #3
0
void SwitchToOverlay2(void)
{
char * from = __section_begin("MYOVERLAY2_init");
char * to = __section_begin("MYOVERLAY");
long size      = __section_size ("MYOVERLAY2_init");
memcpy(to, from, size);//__section_size("MYOVERLAY2_init"));
}
Exemple #4
0
int nvm_save(void)
{
	char *src, *dest, *bak;
	int magic = NVM_MAGIC;
	int sz_ram, pages;

	src = __section_begin(".nvm.ram");
	sz_ram = (int)__section_end(".nvm.ram") - (int)__section_begin(".nvm.ram");
	if(sz_ram == 0)
		return 0;
	sz_ram = align(sz_ram, 4);
	pages = align(sz_ram + 8, FLASH_PAGE_SZ) / FLASH_PAGE_SZ;
	dest = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages); //rom 1
	bak = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages - pages); // rom 2

	//ram -> rom 1
	flash_Write(dest + 4, &sz_ram, 4);
	flash_Write(dest + 8, src, sz_ram);
	flash_Write(dest + 0, &magic, 4);

	//ram -> rom 2
	flash_Erase(bak, pages);
	flash_Write(bak + 4, &sz_ram, 4);
	flash_Write(bak + 8, src, sz_ram);
	flash_Write(bak + 0, &magic, 4);

	//erase rom 1
	flash_Erase(dest, pages);
	return 0;
}
Exemple #5
0
void VECTableInit(void)
{
 
    /* Declare a counter we'll use in all of the copy loops */
    ULONG n;
 
 
    /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */  
    extern ULONG __VECTOR_TABLE[];
    extern ULONG __VECTOR_RAM[];

    /* Copy the vector table to RAM */
    if (__VECTOR_RAM != __VECTOR_TABLE)
    {
        for (n = 0; n < 0x410; n++)
            __VECTOR_RAM[n] = __VECTOR_TABLE[n];
    }
    /* Point the VTOR to the new copy of the vector table */
    //write_vtor((uint32)__VECTOR_RAM);  
    
    SCB_VTOR = (ULONG)__VECTOR_RAM;
    
    /* Get the addresses for the .data section (initialized data section) */
    U8* data_ram = __section_begin(".data");
    U8* data_rom = __section_begin(".data_init");
    U8* data_rom_end = __section_end(".data_init");
    
    /* Copy initialized data from ROM to RAM */
    n = data_rom_end - data_rom;
    while (n--)
      *data_ram++ = *data_rom++;
 
 
    /* Get the addresses for the .bss section (zero-initialized data) */
    U8* bss_start = __section_begin(".bss");
    U8* bss_end = __section_end(".bss");
    
    /* Clear the zero-initialized data section */
    n = bss_end - bss_start;
    while(n--)
      *bss_start++ = 0;    
    
    /* Get addresses for any code sections that need to be copied from ROM to RAM.
     * The IAR tools have a predefined keyword that can be used to mark individual
     * functions for execution from RAM. Add "__ramfunc" before the return type in
     * the function prototype for any routines you need to execute from RAM instead 
     * of ROM. ex: __ramfunc void foo(void);
     */
    U8* code_relocate_ram = __section_begin("CodeRelocateRam");
    U8* code_relocate = __section_begin("CodeRelocate");
    U8* code_relocate_end = __section_end("CodeRelocate");
    
    /* Copy functions from ROM to RAM */
    n = code_relocate_end - code_relocate;
    while (n--)
      *code_relocate_ram++ = *code_relocate++;
    
}
Exemple #6
0
void __iar_data_init_app(void)
{
    __bss_sram_start__ = (uint8_t *)__section_begin(".bss.sram");
    __bss_sram_end__   = (uint8_t *)__section_end(".bss.sram");
    __bss_dtcm_start__ = (uint8_t *)__section_begin(".bss.dtcm");
    __bss_dtcm_end__   = (uint8_t *)__section_end(".bss.dtcm");
    __bss_dram_start__ = (uint8_t *)__section_begin(".bss.dram");
    __bss_dram_end__   = (uint8_t *)__section_end(".bss.dram");
}
Exemple #7
0
int nvm_init(void)
{
	char *src, *dst, *bak;
	int sz_ram, magic, sz_nvm, pages;

	dst = __section_begin(".nvm.ram");
	sz_ram = (int)__section_end(".nvm.ram") - (int)__section_begin(".nvm.ram");
	if(sz_ram == 0) { //no nvm var is used
		nvm_flag_null = 0;
		return 0;
	}

	sz_ram = align(sz_ram, 4);
	pages = align(sz_ram + 8, FLASH_PAGE_SZ) / FLASH_PAGE_SZ;
	src = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages); //rom 1
	bak = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages - pages); // rom 2

	//rom 1 -> ram, always read & erase rom 1 in case of "rom1 not null!!!"
	flash_Read(&magic, src, 4);
	flash_Read(&sz_nvm, src + 4, 4);

	if(magic == NVM_MAGIC && sz_nvm == sz_ram) {
		flash_Read(dst, src + 8, sz_ram);

		//rom1 data is ok, rom1 -> rom 2
		flash_Erase(bak, pages);
		flash_Write(bak + 4, &sz_nvm, 4);
		flash_Write(bak + 8, dst, sz_ram);
		flash_Write(bak + 0, &magic, 4);
		flash_Erase(src, pages); //erase rom 1
		nvm_flag_null = 0;
		return 0;
	}

	//to avoid one more time erase op on an empty flash page
	if(sz_nvm != -1) {
		flash_Erase(src, pages); //erase rom 1
	}

	//rom 2 -> ram
	src = bak;
	flash_Read(&magic, src, 4);
	flash_Read(&sz_nvm, src + 4, 4);
	if(magic == NVM_MAGIC && sz_nvm == sz_ram) {
		flash_Read(dst, src + 8, sz_ram);
		nvm_flag_null = 0;
		return 0;
	}

	//fail ...
	nvm_flag_null = 1;
	return -1;
}
Exemple #8
0
/*
 * @ingroup finsh
 *
 * This function will initialize finsh shell
 */
void finsh_system_init(void)
{
	rt_err_t result;

#ifdef FINSH_USING_SYMTAB
#ifdef __CC_ARM                 /* ARM C Compiler */
    extern const int FSymTab$$Base;
    extern const int FSymTab$$Limit;
    extern const int VSymTab$$Base;
    extern const int VSymTab$$Limit;
	finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
	finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
#elif defined (__ICCARM__)      /* for IAR Compiler */
    finsh_system_function_init(__section_begin("FSymTab"),
                               __section_end("FSymTab"));
    finsh_system_var_init(__section_begin("VSymTab"),
                          __section_end("VSymTab"));
#elif defined (__GNUC__)        /* GNU GCC Compiler */
	extern const int __fsymtab_start;
	extern const int __fsymtab_end;
	extern const int __vsymtab_start;
	extern const int __vsymtab_end;
	finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
	finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#endif
#endif

	/* create or set shell structure */
#ifdef RT_USING_HEAP
	shell = (struct finsh_shell*)rt_malloc(sizeof(struct finsh_shell));
#else
	shell = &_shell;
#endif
	if (shell == RT_NULL)
	{
		rt_kprintf("no memory for shell\n");
		return;
	}
	
	memset(shell, 0, sizeof(struct finsh_shell));

	rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
	result = rt_thread_init(&finsh_thread,
		"tshell",
		finsh_thread_entry, RT_NULL,
		&finsh_thread_stack[0], sizeof(finsh_thread_stack),
		FINSH_THREAD_PRIORITY, 10);

	if (result == RT_EOK)
		rt_thread_startup(&finsh_thread);
}
/* Called from cstartup.s before the kernel is started. */
void LowLevelInitialisation(void)
{
	/* Chip configuration functions from IAR. ********************************/
	/* Disable MMU, enable ICache */
	CP15_Mmu(FALSE);
	CP15_ICache(FALSE);
	CP15_SetVectorBase( (uint32_t )__section_begin( ".intvec" ) );

	/* Set Low vectors mode in CP15 Control Register */
	CP15_SetHighVectors(FALSE);


	/* Chip and board specific configuration functions from Renesas. *********/
	Peripheral_BasicInit();
	STB_Init();
	PORT_Init();
    R_BSC_Init( ( uint8_t ) ( BSC_AREA_CS2 | BSC_AREA_CS3 ) );
    R_INTC_Init();


	CP15_ICache(TRUE);

	/* Start with interrupts enabled. */
    __enable_irq();
    __enable_fiq();
}
void help(uint8_t argc, char** argv)
{
    struct COMMAND_ENTRY* entry_seek;
    struct COMMAND_ENTRY* entry_tail;

    entry_seek = __section_begin("COMMAND_ENTRY");
    entry_tail = __section_end("COMMAND_ENTRY");

    if(argc == 0)
    {// show all
        for(; entry_seek < entry_tail; ++entry_seek)
        {
            showHelp(entry_seek);
        }
    }
    else
    {
        for(; entry_seek < entry_tail; ++entry_seek)
        {
            if( strcmp(argv[0], entry_seek->name) == 0 )
            {
                showHelp(entry_seek);
                break;
            }
        }
    }
}
/*************************************************************************
 * Function Name: __low_level_init
 * Parameters: none
 *
 * Return: 1 - continue with data initialization
 *         0 - skip data initialization and go to main
 *
 * Description: Low-level initialization.
 *              Initializes vector table register and tunes EMC.
 *              Configures EMC address lines A14-A22
 *
 *************************************************************************/
int __low_level_init(void)
{
  VTOR = (uint32_t)__section_begin(".intvec");
#if ((!__RAM_MODE__) && (!__SPIFI_MODE__))
  /* Enable Buffer for External Flash */
  EMC_STATICCONFIG0_bit.B = 1;
  /* Configure delay from CS to Read Access */
  EMC_STATICWAITRD0_bit.WAITRD = 13;
  /* Configure Address Lines A14-A22 */
  /* Configure P6.8 as EMC_A14 */
  SCU_SFSP6_8 = 0xD1;
  /* Configure P6.7 as EMC_A15 */
  SCU_SFSP6_7 = 0xD1;
  /* Configure PD.16 as EMC_A16 */
  SCU_SFSPD_16 = 0xD2;
  /* Configure PD.15 as EMC_A17 */
  SCU_SFSPD_15 = 0xD2;
  /* Configure PE.0 as EMC_A18 */
  SCU_SFSPE_0 = 0xD3;
  /* Configure PE.1 as EMC_A19 */
  SCU_SFSPE_1 = 0xD3;
  /* Configure PE.2 as EMC_A20 */
  SCU_SFSPE_2 = 0xD3;
  /* Configure PE.3 as EMC_A21 */
  SCU_SFSPE_3 = 0xD3;
  /* Configure PE.4 as EMC_A22 */
  SCU_SFSPE_4 = 0xD3;
#endif
  return 1;
}
Exemple #12
0
void *
malloc (unsigned nbytes)
{
    /* Get addresses for the HEAP start and end */
    #if defined(CW)  
      //extern char __HEAP_START[];
      //extern char __HEAP_END[];
	  extern char __heap_addr[];
	  extern char __heap_size;
	  char *__HEAP_START = __heap_addr;
	  char *__HEAP_END = __heap_addr + __heap_size;
    #elif defined(IAR)
      char* __HEAP_START = __section_begin("HEAP");
      char* __HEAP_END = __section_end("HEAP");
    #elif defined(KEIL)
	  extern uint32_t HEAP$$Base;
	  extern uint32_t HEAP$$Limit;
	  uint32_t __HEAP_START = (uint32_t)&HEAP$$Base;
	  uint32_t __HEAP_END = (uint32_t)&HEAP$$Limit;
    #endif
   
    ALLOC_HDR *p, *prevp;
    unsigned nunits;

    nunits = ((nbytes+sizeof(ALLOC_HDR)-1) / sizeof(ALLOC_HDR)) + 1;

    if ((prevp = freep) == NULL)
    {
        p = (ALLOC_HDR *)__HEAP_START;
        p->s.size = ( ((uint32)__HEAP_END - (uint32)__HEAP_START)
            / sizeof(ALLOC_HDR) );
        p->s.ptr = &base;
        base.s.ptr = p;
        base.s.size = 0;
        prevp = freep = &base;
    }

    for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
    {
        if (p->s.size >= nunits)
        {
            if (p->s.size == nunits)
            {
                prevp->s.ptr = p->s.ptr;
            }
            else
            {
                p->s.size -= nunits;
                p += p->s.size;
                p->s.size = nunits;
            }
            freep = prevp;
            return (void *)(p + 1);
        }

        if (p == freep)
            return NULL;
    }
}
//------------------------------------------------------------------------------
/// This is the code that gets called on processor reset. To initialize the
/// device.
//------------------------------------------------------------------------------
int __low_level_init( void )
{
    unsigned int * src = __section_begin(".intvec");

    AT91C_BASE_NVIC->NVIC_VTOFFR = ((unsigned int)(src)) | (0x0 << 7);
    
    return 1; // if return 0, the data sections will not be initialized.
}
Exemple #14
0
/**------------------------------------------------------------------------------
 * This is the code that gets called on processor reset. To initialize the
 * device.
 *------------------------------------------------------------------------------*/
int __low_level_init(void)
{
        uint32_t *pSrc = __section_begin(".intvec");

        SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

        return 1; /* if return 0, the data sections will not be initialized */
}
Exemple #15
0
/**------------------------------------------------------------------------------
 * This is the code that gets called on processor reset. To initialize the
 * device.
 *------------------------------------------------------------------------------*/
int __low_level_init(void)
{
	uint32_t *pSrc = __section_begin(".intvec");

	SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);

	if (((uint32_t) pSrc >= IRAM_ADDR) && ((uint32_t) pSrc < (uint32_t) IRAM_ADDR + (uint32_t) IRAM_SIZE)) {
		SCB->VTOR |= (uint32_t) (1 << SCB_VTOR_TBLBASE_Pos);
	}

	return 1; /* if return 0, the data sections will not be initialized */
}
Exemple #16
0
/*clear nvm strorage to default state*/
int nvm_clear(void)
{
	char *src, *dest, *bak;
	int sz_ram, pages;

	src = __section_begin(".nvm.ram");
	sz_ram = (int)__section_end(".nvm.ram") - (int)__section_begin(".nvm.ram");
	if(sz_ram == 0)
		return 0;
	sz_ram = align(sz_ram, 4);
	pages = align(sz_ram + 8, FLASH_PAGE_SZ) / FLASH_PAGE_SZ;
	dest = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages); //rom 1
	bak = (char *)FLASH_ADDR(FLASH_PAGE_NR - pages - pages); // rom 2

	//erase rom 2
	flash_Erase(bak, pages);

	//erase rom 1
	flash_Erase(dest, pages);
	return 0;
}
void __iar_data_init3(void)
{
  char const * p = __section_begin("Region$$Table");
  uint32_t const * pe = __section_end("Region$$Table");
  uint32_t const * pi = (uint32_t const *)(p);
  while (pi != pe)
  {
    init_fun_t * fun = (init_fun_t *)((char *)pi + *(int32_t *)pi);
    pi++;
    pi = fun(pi);
  }
}
Exemple #18
0
void * malloc (unsigned nbytes)
{
    /* Get addresses for the HEAP start and end */
    #if defined(__IAR_SYSTEMS_ICC__)
      char* __HEAP_START = __section_begin("HEAP");
      char* __HEAP_END = __section_end("HEAP");
    #else
      #warning 非IAR编译器需确定HEAP起始结束地址
      extern char __HEAP_START;
      extern char __HEAP_END[];
    #endif
   
    ALLOC_HDR *p, *prevp;
    unsigned nunits;

    nunits = ((nbytes+sizeof(ALLOC_HDR)-1) / sizeof(ALLOC_HDR)) + 1;

    if ((prevp = freep) == NULL)
    {
        p = (ALLOC_HDR *)__HEAP_START;
        p->s.size = ( ((uint32)__HEAP_END - (uint32)__HEAP_START)
            / sizeof(ALLOC_HDR) );
        p->s.ptr = &base;
        base.s.ptr = p;
        base.s.size = 0;
        prevp = freep = &base;
    }

    for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
    {
        if (p->s.size >= nunits)
        {
            if (p->s.size == nunits)
            {
                prevp->s.ptr = p->s.ptr;
            }
            else
            {
                p->s.size -= nunits;
                p += p->s.size;
                p->s.size = nunits;
            }
            freep = prevp;
            return (void *)(p + 1);
        }

        if (p == freep)
            return NULL;
    }
}
Exemple #19
0
long StartTest(void) 
{
unsigned int i;
funcp_t f_p = (funcp_t) 
        ((char*) __section_begin("MYOVERLAY") + 0); /* +1 for Thumb instr */
		//StartTestRom2();
		SwitchToOverlay1();
		//f_p();
		SwitchToOverlay2();
		f_p();
		//StartTestRam
		//StartTestRom2();
return 0;		
}
/************************************************************************************************ 
* FillBss_0_Kinetis
* 将"BSS"数据区初始化为0
************************************************************************************************/
static void FillBss_0_Kinetis(void)
{ 
  K_int8u_t *bss_start = __section_begin(".bss");
  K_int8u_t *bss_end   = __section_end(".bss");
  K_int32u_t n = (K_int32u_t)bss_end - (K_int32u_t)bss_start;;
  
  if(n != 0)
  {
    while(n--)
    {
      *bss_start++ = 0;
    }
  }
}
Exemple #21
0
static  void  AppMemCreate(void)
{
    OS_ERR  error = OS_ERR_NONE;

    void        *p_addr;
    void        *p_addr_end;
    OS_MEM_QTY  n_blks;
    OS_MEM_SIZE blk_size;

    p_addr = __section_begin("OS_4K_MEM_POOL");
    p_addr_end = __section_end("OS_4K_MEM_POOL");
    n_blks = ((OS_MEM_SIZE)p_addr_end - (OS_MEM_SIZE)p_addr)/(4*1024);
    blk_size = (4*1024);


    OSMemCreate(&AppMem4KB,
                "4KB memory for app",
                p_addr,
                n_blks,
                blk_size,
                &error );


    p_addr = __section_begin("OS_2M_MEM_POOL");
    p_addr_end = __section_end("OS_2M_MEM_POOL");
    n_blks = ((OS_MEM_SIZE)p_addr_end - (OS_MEM_SIZE)p_addr) / (2*1024*1024);
    blk_size = (2*1024*1024);

    OSMemCreate(&AppMem2MB,
                "2MB memory for app",
                p_addr,
                n_blks,
                blk_size,
                &error );

}
Exemple #22
0
void shell_init(void)
{
#ifdef __CC_ARM                 /* ARM C Compiler */
    extern const int FSymTab$$Base;
    extern const int FSymTab$$Limit;
    _system_function_section_init(&FSymTab$$Base, &FSymTab$$Limit);
    
#elif defined (__ICCARM__)      /* for IAR Compiler */
    #pragma section="FSymTab"
    _system_function_section_init(__section_begin("FSymTab"),
                               __section_end("FSymTab"));

#endif
    
}
__stackless void HardFault_Handler(void)
{
    __ASM volatile(
    "   ldr   r0, 100f                         \n"
    "   cmp   r0, lr                           \n"
    "   bne   1f                               \n"
    /* Reading PSP into R0 */
    "   mrs   r0, PSP                          \n"
    "   b     3f                               \n"
    "1:                                        \n"
    /* Reading MSP into R0 */
    "   mrs   r0, MSP                          \n"
    /* -----------------------------------------------------------------
     * If we have selected MSP check if we may use stack safetly.
     * If not - reset the stack to the initial value. */
    "   ldr   r1, 101f                         \n"
    "   ldr   r2, 102f                         \n"

    /* MSP is in the range of the stack area */
    "   cmp   r0, r1                           \n"
    "   bhi   2f                               \n"
    "   cmp   r0, r2                           \n"
    "   bhi   3f                               \n"
    /* ----------------------------------------------------------------- */
    "2:                                        \n"
    "   mov   SP, r1                           \n"
    "   movs  r0, #0                           \n"

    "3:                                        \n"
    "   ldr r3, 103f                           \n"
    "   bx r3                                  \n"

    "DATA                                      \n"
    "100:                                      \n"
    "   DC32 0xFFFFFFFD                        \n"
    "101:                                      \n"
    "   DC32 %c0                               \n"
    "102:                                      \n"
    "   DC32 %c1                               \n"
    "103:                                      \n"
    "   DC32 %c2                               \n"
    : /* Outputs */
    : /* Inputs */
    "i"(__section_end("CSTACK")),
    "i"(__section_begin("CSTACK")),
    "i"(&HardFault_c_handler)
    );
}
__stackless void HardFault_Handler(void)
{
    __ASM volatile(
    "   ldr.n r3, 103f                          \n"
    "   tst   lr, #4                            \n"

    /* PSP is quite simple and does not require additional handler */
    "   itt   ne                                \n"
    "   mrsne r0, psp                           \n"
    /* Jump to the handler, do not store LR - returning from handler just exits exception */
    "   bxne  r3                                \n"

    /* Processing MSP requires stack checking */
    "   mrs r0, msp                             \n"

    "   ldr.n r1, 101f                          \n"
    "   ldr.n r2, 102f                          \n"

    /* MSP is in the range of the stack area */
    "   cmp   r0, r1                            \n"
    "   bhi.n 1f                                \n"
    "   cmp   r0, r2                            \n"
    "   bhi.n 2f                                \n"

    "1:                                         \n"
    "   mov   sp, r1                            \n"
    "   mov   r0, #0                            \n"

    "2:                                         \n"
    "   bx r3                                   \n"
    /* Data alignment if required */
    "   nop                                     \n"

    "DATA                                       \n"
    "101:                                       \n"
    "   DC32 %c0                                \n"
    "102:                                       \n"
    "   DC32 %c1                                \n"
    "103:                                       \n"
    "   DC32 %c2                                \n"
    : /* Outputs */
    : /* Inputs */
    "i"(__section_end("CSTACK")),
    "i"(__section_begin("CSTACK")),
    "i"(&HardFault_c_handler)
    );
}
Exemple #25
0
 int __low_level_init( void )
{
     extern void init_clocks(void);
     extern void init_memory(void);
     /* IAR allows init functions in __low_level_init(), but it is run before global
      * variables have been initialised, so the following init still needs to be done
      * When using GCC, this is done in crt0_GCC.c
      */
     /* Setup the interrupt vectors address */
     SCB->VTOR = (unsigned long )__section_begin(".intvec");

     /* Enable CPU Cycle counting */
     DWT->CYCCNT = 0;
     DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

     init_clocks();
     init_memory();
     return 1; /* return 1 to force memory init */
}
Exemple #26
0
/*
 * @ingroup finsh
 *
 * This function will initialize finsh shell
 */
int finsh_system_init(void)
{
	rt_err_t result;

#ifdef FINSH_USING_SYMTAB
#ifdef __CC_ARM                 /* ARM C Compiler */
    extern const int FSymTab$$Base;
    extern const int FSymTab$$Limit;
    extern const int VSymTab$$Base;
    extern const int VSymTab$$Limit;
	finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
	finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
#elif defined (__ICCARM__)      /* for IAR Compiler */
    finsh_system_function_init(__section_begin("FSymTab"),
                               __section_end("FSymTab"));
    finsh_system_var_init(__section_begin("VSymTab"),
                          __section_end("VSymTab"));
#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__)
    /* GNU GCC Compiler and TI CCS */
	extern const int __fsymtab_start;
	extern const int __fsymtab_end;
	extern const int __vsymtab_start;
	extern const int __vsymtab_end;
	finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
	finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
    finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
    finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(_MSC_VER)
	unsigned int *ptr_begin, *ptr_end;

	ptr_begin = (unsigned int*)&__fsym_begin; ptr_begin += (sizeof(struct finsh_syscall)/sizeof(unsigned int));
	while (*ptr_begin == 0) ptr_begin ++;

	ptr_end = (unsigned int*) &__fsym_end; ptr_end --;
	while (*ptr_end == 0) ptr_end --;

	finsh_system_function_init(ptr_begin, ptr_end);
#endif
#endif

	/* create or set shell structure */
#ifdef RT_USING_HEAP
	shell = (struct finsh_shell*)rt_malloc(sizeof(struct finsh_shell));
#else
	shell = &_shell;
#endif
	if (shell == RT_NULL)
	{
		rt_kprintf("no memory for shell\n");
		return -1;
	}
	
	memset(shell, 0, sizeof(struct finsh_shell));

	rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
	result = rt_thread_init(&finsh_thread,
		"tshell",
		finsh_thread_entry, RT_NULL,
		&finsh_thread_stack[0], sizeof(finsh_thread_stack),
		FINSH_THREAD_PRIORITY, 10);

	if (result == RT_EOK)
		rt_thread_startup(&finsh_thread);
	return 0;
}
Exemple #27
0
void MMU_CreateTranslationTable(void)
{
    mmu_region_attributes_Type region;
#if defined ( __ICCARM__ )
#pragma section=".intvec"
#pragma section=".rodata"
#pragma section=".rwdata"
#pragma section=".bss"

    Image$$VECTORS$$Base = (uint32_t) __section_begin(".intvec");
    Image$$VECTORS$$Limit= ((uint32_t)__section_begin(".intvec")+(uint32_t)__section_size(".intvec"));
    Image$$RO_DATA$$Base = (uint32_t) __section_begin(".rodata");
    Image$$RO_DATA$$Limit= ((uint32_t)__section_begin(".rodata")+(uint32_t)__section_size(".rodata"));
    Image$$RW_DATA$$Base = (uint32_t) __section_begin(".rwdata"); 
    Image$$RW_DATA$$Limit= ((uint32_t)__section_begin(".rwdata")+(uint32_t)__section_size(".rwdata"));
    Image$$RW_IRAM1$$Base = (uint32_t) __section_begin(".bss");  
    Image$$RW_IRAM1$$Limit= ((uint32_t)__section_begin(".bss")+(uint32_t)__section_size(".bss"));
#endif
    /*
     * Generate descriptors. Refer to core_ca.h to get information about attributes
     *
     */
    //Create descriptors for Vectors, RO, RW, ZI sections
    section_normal(Sect_Normal, region);
    section_normal_cod(Sect_Normal_Cod, region);
    section_normal_ro(Sect_Normal_RO, region);
    section_normal_rw(Sect_Normal_RW, region);
    //Create descriptors for peripherals
    section_device_ro(Sect_Device_RO, region);
    section_device_rw(Sect_Device_RW, region);
    section_normal_nc(Sect_Normal_NC, region);
    //Create descriptors for 64k pages
    page64k_device_rw(Page_L1_64k, Page_64k_Device_RW, region);
    //Create descriptors for 4k pages
    page4k_device_rw(Page_L1_4k, Page_4k_Device_RW, region);

    /*
     *  Define MMU flat-map regions and attributes
     *
     */

    //Create 4GB of faulting entries
    MMU_TTSection (&Image$$TTB$$ZI$$Base, 0, 4096, DESCRIPTOR_FAULT);

    // R7S72100 memory map.
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_NORFLASH_BASE0    , 64, Sect_Normal_RO);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_NORFLASH_BASE1    , 64, Sect_Normal_RO);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_SDRAM_BASE0       , 64, Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_SDRAM_BASE1       , 64, Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_USER_AREA0        , 64, Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_USER_AREA1        , 64, Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_SPI_IO0           , 64, Sect_Normal_RO);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_SPI_IO1           , 64, Sect_Normal_RO);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_ONCHIP_SRAM_BASE  , 10, Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_SPI_MIO_BASE      ,  1, Sect_Device_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_BSC_BASE          ,  1, Sect_Device_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_PERIPH_BASE0      ,  3, Sect_Device_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_PERIPH_BASE1      , 49, Sect_Device_RW);

#if defined( __ICCARM__ )
    //Define Image
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)Image$$RO_DATA$$Base , RO_DATA_SIZE , Sect_Normal_Cod);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)Image$$VECTORS$$Base , VECTORS_SIZE , Sect_Normal_Cod);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)Image$$RW_DATA$$Base , RW_DATA_SIZE , Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)Image$$RW_IRAM1$$Base, RW_IRAM1_SIZE, Sect_Normal_RW);
#else
    //Define Image
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RO_DATA$$Base , RO_DATA_SIZE , Sect_Normal_Cod);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$VECTORS$$Base , VECTORS_SIZE , Sect_Normal_Cod);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RW_DATA$$Base , RW_DATA_SIZE , Sect_Normal_RW);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RW_IRAM1$$Base, RW_IRAM1_SIZE, Sect_Normal_RW);
#endif

#if defined( __CC_ARM )
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_ONCHIP_SRAM_NC_BASE         ,              10, Sect_Normal_NC);
#elif defined ( __ICCARM__ ) 
    MMU_TTSection (&Image$$TTB$$ZI$$Base, RZ_A1_ONCHIP_SRAM_NC_BASE         ,              10, Sect_Normal_NC);

#else
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RW_DATA_NC$$Base, RW_DATA_NC_SIZE, Sect_Normal_NC);
    MMU_TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$ZI_DATA_NC$$Base, ZI_DATA_NC_SIZE, Sect_Normal_NC);
#endif

    /* Set location of level 1 page table
    ; 31:14 - Translation table base addr (31:14-TTBCR.N, TTBCR.N is 0 out of reset)
    ; 13:7  - 0x0
    ; 6     - IRGN[0] 0x0 (Inner WB WA)
    ; 5     - NOS     0x0 (Non-shared)
    ; 4:3   - RGN     0x1 (Outer WB WA)
    ; 2     - IMP     0x0 (Implementation Defined)
    ; 1     - S       0x0 (Non-shared)
    ; 0     - IRGN[1] 0x1 (Inner WB WA) */
    __set_TTBR0(((uint32_t)&Image$$TTB$$ZI$$Base) | 9);
    __ISB();

    /* Set up domain access control register
    ; We set domain 0 to Client and all other domains to No Access.
    ; All translation table entries specify domain 0 */
    __set_DACR(1);
    __ISB();
}
Exemple #28
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file startup_stm32f446xx.s) before to branch to application main. 
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */
  uint32_t address = 0, step = 0x00;

  /* Configure QSPI GPIO */
  QSPI_GPIO_Config();
  
  /* Initialize DMA ----------------------------------------------------------*/
  DMA_StructInit(&DMA_InitStructure);
  DMA_DeInit(QSPI_DMA_STREAM);
  
  /*DMA configuration*/
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&QUADSPI->DR ;
  DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Channel            = DMA_Channel_3;
  
  /* Initialize QuadSPI ------------------------------------------------------*/
  QSPI_StructInit(&QSPI_InitStructure);
  QSPI_InitStructure.QSPI_SShift    = QSPI_SShift_HalfCycleShift;
  QSPI_InitStructure.QSPI_Prescaler = 0x01; /* 90 MHZ */
  QSPI_InitStructure.QSPI_CKMode    = QSPI_CKMode_Mode0;
  QSPI_InitStructure.QSPI_CSHTime   = QSPI_CSHTime_2Cycle;
  QSPI_InitStructure.QSPI_FSize     = 0x18;
  QSPI_InitStructure.QSPI_FSelect   = QSPI_FSelect_1;
  QSPI_InitStructure.QSPI_DFlash    = QSPI_DFlash_Disable;
  QSPI_Init(&QSPI_InitStructure);
  
  /* Initialize Command Config -----------------------------------------------*/
  QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure);
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize      = QSPI_ComConfig_ADSize_24bit;
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode       = QSPI_ComConfig_IMode_1Line;
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_ABMode      = QSPI_ComConfig_ABMode_NoAlternateByte;
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_DDRMode     = QSPI_ComConfig_DDRMode_Disable;
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_SIOOMode    = QSPI_ComConfig_SIOOMode_Disable;
  QSPI_ComConfig_InitStructure.QSPI_ComConfig_DHHC        = QSPI_ComConfig_DHHC_Enable;
  QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure);
  QSPI_Cmd(ENABLE);
  
  while(1)
  {
    switch(step)
    {
    case 0:
      
      /* Enable write operations ---------------------------------------------*/
      QSPI_Cmd(ENABLE);
      QSPI_WriteEnable();
      
      /* Erasing Sequence ----------------------------------------------------*/
      QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); 
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize = QSPI_ComConfig_ADSize_24bit;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode  = QSPI_ComConfig_IMode_1Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode = QSPI_ComConfig_ADMode_1Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode  = QSPI_ComConfig_DMode_NoData;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode  = QSPI_ComConfig_FMode_Indirect_Write;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins    = SECTOR_ERASE_CMD;
      QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure);
      
      /* Set sector address to erase */
      QSPI_SetAddress(address);  
      
      while(QSPI_GetFlagStatus(QSPI_FLAG_TC) == RESET)
      {}
      step++;
      break;
      
    case 1:      
      /* Configure automatic polling mode to wait for end of erase -----------*/  
        QSPI_AutoPollingMemReady();
#if defined(__CC_ARM)
    FlashAddr = (uint8_t *)(&Load$$QSPI$$Base);
    MAXTransferSize = (uint32_t)(&Load$$QSPI$$Length);
#elif defined(__ICCARM__)
    FlashAddr = (uint8_t *)(__section_begin(".qspi_init"));
    MAXTransferSize = __section_size(".qspi_init");
#elif defined(__GNUC__)
    FlashAddr = (uint8_t *)(&_qspi_init_base);
	MAXTransferSize = (uint32_t)((uint8_t *)(&_qspi_init_length));
#endif		
      step++;
      break;
      
    case 2:
      /* Enable write operations ---------------------------------------------*/
      QSPI_WriteEnable();
      QSPI_DMACmd(ENABLE);
      
      /* Writing Sequence ----------------------------------------------------*/
      QSPI_SetDataLength(MAXTransferSize);
      
      QSPI_ComConfig_StructInit(&QSPI_ComConfig_InitStructure); 
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode       = QSPI_ComConfig_IMode_1Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode      = QSPI_ComConfig_ADMode_1Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode       = QSPI_ComConfig_DMode_4Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode       = QSPI_ComConfig_FMode_Indirect_Write;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize      = QSPI_ComConfig_ADSize_32bit; 
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins         = QUAD_IN_FAST_PROG_CMD;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_DummyCycles = 0;
      QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure); 
      
      /* DMA channel Tx Configuration */
      DMA_InitStructure.DMA_BufferSize      = MAXTransferSize;
      DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)FlashAddr;
      DMA_InitStructure.DMA_DIR             = DMA_DIR_MemoryToPeripheral;
      DMA_InitStructure.DMA_Priority        = DMA_Priority_Low;          
      DMA_Init(QSPI_DMA_STREAM, &DMA_InitStructure);
      DMA_Cmd(QSPI_DMA_STREAM, ENABLE);
      
      /* Wait for the end of Transfer */
      while(DMA_GetFlagStatus(QSPI_DMA_STREAM, QSPI_DMA_FLAG_TC) == RESET)
      {}  
      DMA_ClearFlag(QSPI_DMA_STREAM, QSPI_DMA_FLAG_TC);
      QSPI_AbortRequest();
      DMA_Cmd(QSPI_DMA_STREAM, DISABLE);
      QSPI_DMACmd(DISABLE);
      
      step++;
      break;
      
    case 3:
      /* Configure automatic polling mode to wait for end of program ---------*/  
      QSPI_AutoPollingMemReady(); 
      step++;
      break;
      
    case 4:
      /* Reading Sequence ----------------------------------------------------*/
      QSPI_TimeoutCounterCmd(DISABLE);
      QSPI_MemoryMappedMode_SetTimeout(0);
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADSize       = QSPI_ComConfig_ADSize_32bit;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_FMode        = QSPI_ComConfig_FMode_Memory_Mapped;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_ADMode       = QSPI_ComConfig_ADMode_4Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_IMode        = QSPI_ComConfig_IMode_1Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_DMode        = QSPI_ComConfig_DMode_4Line;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_Ins          = QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD;
      QSPI_ComConfig_InitStructure.QSPI_ComConfig_DummyCycles  = DUMMY_CLOCK_CYCLES_READ_QUAD;
      QSPI_ComConfig_Init(&QSPI_ComConfig_InitStructure);  
      
      GpioToggle();
      break;
            
    default :
      TransferStatus = FAILED; 
      break;
    }
  }
}
Exemple #29
0
void
common_startup(void)
{

#if (defined(CW))
    extern char __START_BSS[];
    extern char __END_BSS[];
    extern uint32 __DATA_ROM[];
    extern uint32 __DATA_RAM[];
    extern char __DATA_END[];
#endif

    /* Declare a counter we'll use in all of the copy loops */
    uint32 n;

    /* Declare pointers for various data sections. These pointers
     * are initialized using values pulled in from the linker file
     */
    uint8 * data_ram, * data_rom, * data_rom_end;
    uint8 * bss_start, * bss_end;


    /* Get the addresses for the .data section (initialized data section) */
#if (defined(CW))
    data_ram = (uint8 *)__DATA_RAM;
    data_rom = (uint8 *)__DATA_ROM;
    data_rom_end  = (uint8 *)__DATA_END; /* This is actually a RAM address in CodeWarrior */
    n = data_rom_end - data_ram;
#elif (defined(IAR))
    data_ram = __section_begin(".data");
    data_rom = __section_begin(".data_init");
    data_rom_end = __section_end(".data_init");
    n = data_rom_end - data_rom;
#endif

    /* Copy initialized data from ROM to RAM */
    while (n--)
        *data_ram++ = *data_rom++;


    /* Get the addresses for the .bss section (zero-initialized data) */
#if (defined(CW))
    bss_start = (uint8 *)__START_BSS;
    bss_end = (uint8 *)__END_BSS;
#elif (defined(IAR))
    bss_start = __section_begin(".bss");
    bss_end = __section_end(".bss");
#endif




    /* Clear the zero-initialized data section */
    n = bss_end - bss_start;
    while(n--)
        *bss_start++ = 0;

    /* Get addresses for any code sections that need to be copied from ROM to RAM.
     * The IAR tools have a predefined keyword that can be used to mark individual
     * functions for execution from RAM. Add "__ramfunc" before the return type in
     * the function prototype for any routines you need to execute from RAM instead
     * of ROM. ex: __ramfunc void foo(void);
     */
#if (defined(IAR))
    uint8* code_relocate_ram = __section_begin("CodeRelocateRam");
    uint8* code_relocate = __section_begin("CodeRelocate");
    uint8* code_relocate_end = __section_end("CodeRelocate");

    /* Copy functions from ROM to RAM */
    n = code_relocate_end - code_relocate;
    while (n--)
        *code_relocate_ram++ = *code_relocate++;
#endif
}
void
common_startup(void)
{

#if (defined(CW))	
    extern char __START_BSS[];
    extern char __END_BSS[];
    extern uint32 __DATA_ROM[];
    extern uint32 __DATA_RAM[];
    extern char __DATA_END[];
#endif

    /* 声明一个计数器在拷贝循环中使用 */
    uint32 n;

    /* 为不同的数据段定义指针。
     * 这些变量将由链接文件中获取的值初始化
     */
    uint8 * data_ram, * data_rom, * data_rom_end;
    uint8 * bss_start, * bss_end;


    /* 引进链接文件中的VECTOR_TABLE和VECTOR_RAM的地址 */
    extern uint32 __VECTOR_TABLE[];
    extern uint32 __VECTOR_RAM[];

    /* 将中断向量表复制到RAM中 */
    if (__VECTOR_RAM != __VECTOR_TABLE)
    {
        for (n = 0; n < 0x410; n++)
            __VECTOR_RAM[n] = __VECTOR_TABLE[n];
    }
    /* 将新的中断向量表指针赋给VTOR寄存器 */
    write_vtor((uint32)__VECTOR_RAM);

    /* 获得.data段的地址(已初始化的数据段) */
	#if (defined(CW))
        data_ram = (uint8 *)__DATA_RAM;
	    data_rom = (uint8 *)__DATA_ROM;
	    data_rom_end  = (uint8 *)__DATA_END; /* 该段在CodeWarrior编译器中为RAM地址 */
	    n = data_rom_end - data_ram;
    #elif (defined(IAR))
		data_ram = __section_begin(".data");
		data_rom = __section_begin(".data_init");
		data_rom_end = __section_end(".data_init");
		n = data_rom_end - data_rom;
	#endif		
		
	/* 从ROM复制已初始化的数据到RAM */
	while (n--)
		*data_ram++ = *data_rom++;
	
	
    /* 获得.bss段的地址 (初始化为0的数据) */
	#if (defined(CW))
		bss_start = (uint8 *)__START_BSS;
		bss_end = (uint8 *)__END_BSS;
	#elif (defined(IAR))
		bss_start = __section_begin(".bss");
		bss_end = __section_end(".bss");
	#endif
		
		
	

    /* 清零初始化为0的数据段 */
    n = bss_end - bss_start;
    while(n--)
      *bss_start++ = 0;

	/* 取得所有应该从ROM复制到RAM的代码段的地址。
         * IAR有一个预定义的关键字可以标记独立的函数为从RAM执行。
         * 在函数的返回类型前添加"__ramfunc"关键字可以将函数标记为从RAM中执行。
         * 例如:__ramfunc void foo(void);
	 */
	#if (defined(IAR))
		uint8* code_relocate_ram = __section_begin("CodeRelocateRam");
		uint8* code_relocate = __section_begin("CodeRelocate");
		uint8* code_relocate_end = __section_end("CodeRelocate");

		/* 将函数从ROM复制到RAM */
		n = code_relocate_end - code_relocate;
		while (n--)
			*code_relocate_ram++ = *code_relocate++;
	#endif
}