一个ARM裸机程序的优化


main.c


#include "utils.h"

static void LedDelay(void)
{
    	volatile unsigned int k;
    	for(k = 0; k < 20000000; k++);
}

int _main(void)
{

    Uart_Init();
    Port_Init();
    Uart_SendString("\r\nHello, Mini6410\r\n");
    
    for(;;) {
    	Led_Display(0x9); // 1001
		LedDelay();
    	Led_Display(0x6); // 0110
		LedDelay();
    }

    return 0;

}

utils.c

#include "s3c6410_addr.h"
#include "utils.h"
#include "soc_cfg.h"

#define rGPKCON0        (*(volatile unsigned *)(0x7F008800))
#define rGPKCON1        (*(volatile unsigned *)(0x7F008804))
#define rGPKDAT         (*(volatile unsigned *)(0x7F008808))
#define rGPKPUD         (*(volatile unsigned *)(0x7F00880C))

void Port_Init(void)
{
    rGPKCON0 = (rGPKCON0 & ~(0xffffU<<16))|(0x1111U<<16);
    rGPKPUD  = (rGPKPUD  & ~(0xffU << 8))|(0x00U<<8);
}

void Led_Display(int data)
{
    rGPKDAT = (rGPKDAT & ~(0xf<<4)) | ((data & 0xf)<<4);
}

static void Delay(void)
{
    volatile int i;

    for(i=0 ; i < 1000 ; i++)
    {
    }
}


void Uart_Init(void)
{
    // UART I/O port initialize (RXD0 : GPA0, TXD0: GPA1)
    rGPACON = (rGPACON & ~(0xff<<0)) | (0x22<<0);    // GPA0->RXD0, GPA1->TXD0
    rGPAPUD = (rGPAPUD & ~(0xf<<0)) | (0x1<<0);        // RXD0: Pull-down, TXD0: pull up/down disable

    // Initialize UART Ch0
    rULCON0 = (0<<6)|(0<<3)|(0<<2)|(3<<0);                    // Normal Mode, No Parity, 1 Stop Bit, 8 Bit Data
    rUCON0 = (0<<10)|(1<<9)|(1<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0);    // PCLK divide, Polling Mode
    rUFCON0 = (0<<6)|(0<<4)|(0<<2)|(0<<1)|(0<<0);            // Disable FIFO
    rUMCON0 = (0<<5)|(0<<4)|(0<<0);                        // Disable Auto Flow Control

    rUBRDIV0 = 35;                                    // Baud rate
    rUDIVSLOT0 = 0x80;//aSlotTable[DivSlot];
}

void Uart_SendByte(int data)
{
    while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.
    Delay();
    WrUTXH0(data);
}

void Uart_SendString(char *pt)
{
    while(*pt)
        Uart_SendByte(*pt++);
}

startup.s

    IMPORT      _main                    ; C entrypoint for Steppingstone loader.
	AREA |C$$code|, CODE, READONLY
	global		Start

Start
        b        _main

		DCB		"ABCDabcd"
        END


s3c6410_addr.h

#ifndef __S3C6410ADDR_H__
#define __S3C6410ADDR_H__

#ifdef __cplusplus
extern "C" {
#endif

// System Controller
#define SYSCON_BASE        (0x7E00F000)
#define rMEM_SYS_CFG    (*(volatile unsigned *)(SYSCON_BASE+0x120))

// GPIO
#define GPIO_BASE    (0x7F008000)
#define rGPACON        (*(volatile unsigned *)(GPIO_BASE+0x00))
#define rGPADAT        (*(volatile unsigned *)(GPIO_BASE+0x04))
#define rGPAPUD        (*(volatile unsigned *)(GPIO_BASE+0x08))
#define rGPBCON        (*(volatile unsigned *)(GPIO_BASE+0x20))
#define rGPBDAT        (*(volatile unsigned *)(GPIO_BASE+0x24))
#define rGPBPUD        (*(volatile unsigned *)(GPIO_BASE+0x28))
#define rGPNCON        (*(volatile unsigned *)(GPIO_BASE+0x830))
#define rGPNDAT        (*(volatile unsigned *)(GPIO_BASE+0x834))
#define rGPNPUD        (*(volatile unsigned *)(GPIO_BASE+0x838))

// NAND Flash Controller
#define NANDF_BASE    (0x70200000)
#define rNFCONF        (*(volatile unsigned *)(NANDF_BASE+0x00))        //NAND Flash configuration
#define rNFCONT        (*(volatile unsigned *)(NANDF_BASE+0x04))          //NAND Flash control
#define rNFCMD        (*(volatile unsigned *)(NANDF_BASE+0x08))         //NAND Flash command
#define rNFADDR        (*(volatile unsigned *)(NANDF_BASE+0x0C))         //NAND Flash address
#define rNFDATA        (*(volatile unsigned *)(NANDF_BASE+0x10))          //NAND Flash data
#define rNFDATA8    (*(volatile unsigned char *)(NANDF_BASE+0x10))    //NAND Flash data (byte)
#define rNFDATA32    (*(volatile unsigned *)(NANDF_BASE+0x10))       //NAND Flash data (word)
#define NFDATA        (NANDF_BASE+0x10)
#define rNFMECCD0    (*(volatile unsigned *)(NANDF_BASE+0x14))          //NAND Flash ECC for Main
#define rNFMECCD1    (*(volatile unsigned *)(NANDF_BASE+0x18))          //NAND Flash ECC for Main
#define rNFSECCD    (*(volatile unsigned *)(NANDF_BASE+0x1C))          //NAND Flash ECC for Spare Area
#define rNFSBLK         (*(volatile unsigned *)(NANDF_BASE+0x20))        //NAND Flash programmable start block address
#define rNFEBLK         (*(volatile unsigned *)(NANDF_BASE+0x24))            //NAND Flash programmable end block address
#define rNFSTAT         (*(volatile unsigned *)(NANDF_BASE+0x28))          //NAND Flash operation status
#define rNFECCERR0    (*(volatile unsigned *)(NANDF_BASE+0x2C))          //NAND Flash ECC Error Status for I/O [7:0]
#define rNFECCERR1    (*(volatile unsigned *)(NANDF_BASE+0x30))          //NAND Flash ECC Error Status for I/O [15:8]
#define rNFMECC0    (*(volatile unsigned *)(NANDF_BASE+0x34))          //SLC or MLC NAND Flash ECC status
#define rNFMECC1    (*(volatile unsigned *)(NANDF_BASE+0x38))            //SLC or MLC NAND Flash ECC status
#define rNFSECC         (*(volatile unsigned *)(NANDF_BASE+0x3C))          //NAND Flash ECC for I/O[15:0]
#define rNFMLCBITPT    (*(volatile unsigned *)(NANDF_BASE+0x40))         //NAND Flash 4-bit ECC Error Pattern for data[7:0]

// UART
#define UART0_BASE    (0x7F005000)
#define rULCON0        (*(volatile unsigned *)(UART0_BASE+0x00))
#define rUCON0        (*(volatile unsigned *)(UART0_BASE+0x04))
#define rUFCON0        (*(volatile unsigned *)(UART0_BASE+0x08))
#define rUMCON0        (*(volatile unsigned *)(UART0_BASE+0x0C))
#define rUTRSTAT0     (*(volatile unsigned *)(UART0_BASE+0x10))
#define rUERSTAT0     (*(volatile unsigned *)(UART0_BASE+0x14))
#define rUFSTAT0    (*(volatile unsigned *)(UART0_BASE+0x18))
#define rUMSTAT0    (*(volatile unsigned *)(UART0_BASE+0x1C))
#define rUTXH0        (*(volatile unsigned *)(UART0_BASE+0x20))
#define rURXH0        (*(volatile unsigned *)(UART0_BASE+0x24))
#define rUBRDIV0        (*(volatile unsigned *)(UART0_BASE+0x28))
#define rUDIVSLOT0     (*(volatile unsigned *)(UART0_BASE+0x2C))
#define rUINTP0        (*(volatile unsigned *)(UART0_BASE+0x30))
#define rUINTSP0        (*(volatile unsigned *)(UART0_BASE+0x34))
#define rUINTM0        (*(volatile unsigned *)(UART0_BASE+0x38))

#define UART1_BASE    (0x7F005400)
#define rULCON1        (*(volatile unsigned *)(UART1_BASE+0x00))
#define rUCON1        (*(volatile unsigned *)(UART1_BASE+0x04))
#define rUFCON1        (*(volatile unsigned *)(UART1_BASE+0x08))
#define rUMCON1        (*(volatile unsigned *)(UART1_BASE+0x0C))
#define rUTRSTAT1     (*(volatile unsigned *)(UART1_BASE+0x10))
#define rUERSTAT1     (*(volatile unsigned *)(UART1_BASE+0x14))
#define rUFSTAT1    (*(volatile unsigned *)(UART1_BASE+0x18))
#define rUMSTAT1    (*(volatile unsigned *)(UART1_BASE+0x1C))
#define rUTXH1        (*(volatile unsigned *)(UART1_BASE+0x20))
#define rURXH1        (*(volatile unsigned *)(UART1_BASE+0x24))
#define rUBRDIV1        (*(volatile unsigned *)(UART1_BASE+0x28))
#define rUDIVSLOT1     (*(volatile unsigned *)(UART1_BASE+0x2C))
#define rUINTP1        (*(volatile unsigned *)(UART1_BASE+0x2C))
#define rUINTSP1        (*(volatile unsigned *)(UART1_BASE+0x34))
#define rUINTM1        (*(volatile unsigned *)(UART1_BASE+0x38))

#define UART2_BASE    (0x7F005800)
#define rULCON2        (*(volatile unsigned *)(UART2_BASE+0x00))
#define rUCON2        (*(volatile unsigned *)(UART2_BASE+0x04))
#define rUFCON2        (*(volatile unsigned *)(UART2_BASE+0x08))
#define rUMCON2        (*(volatile unsigned *)(UART2_BASE+0x0C))
#define rUTRSTAT2     (*(volatile unsigned *)(UART2_BASE+0x10))
#define rUERSTAT2     (*(volatile unsigned *)(UART2_BASE+0x14))
#define rUFSTAT2    (*(volatile unsigned *)(UART2_BASE+0x18))
#define rUMSTAT2    (*(volatile unsigned *)(UART2_BASE+0x1C))
#define rUTXH2        (*(volatile unsigned *)(UART2_BASE+0x20))
#define rURXH2        (*(volatile unsigned *)(UART2_BASE+0x24))
#define rUBRDIV2        (*(volatile unsigned *)(UART2_BASE+0x28))
#define rUDIVSLOT2     (*(volatile unsigned *)(UART2_BASE+0x2C))
#define rUINTP2        (*(volatile unsigned *)(UART2_BASE+0x30))
#define rUINTSP2        (*(volatile unsigned *)(UART2_BASE+0x34))
#define rUINTM2        (*(volatile unsigned *)(UART2_BASE+0x38))



void Uart_Init(void);
void Uart_SendByte(int data);
void Uart_SendString(char *pt);
void Uart_SendDWORD(unsigned int d, int cr);
char *hex2char(unsigned int val);

#define WrUTXH0(ch)     (*(volatile unsigned char *)(UART0_BASE+0x20))=(unsigned char)(ch)
#define RdURXH0()       (*(volatile unsigned char *)(UART0_BASE+0x24))
#define WrUTXH1(ch)     (*(volatile unsigned char *)(UART1_BASE+0x20))=(unsigned char)(ch)
#define RdURXH1()       (*(volatile unsigned char *)(UART1_BASE+0x24))
#define WrUTXH2(ch)     (*(volatile unsigned char *)(UART2_BASE+0x20))=(unsigned char)(ch)
#define RdURXH2()       (*(volatile unsigned char *)(UART2_BASE+0x24))

#ifdef __cplusplus
}
#endif
#endif  //__S3C6410ADDR_H__

soc_cfg.h


//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  soc_cfg.h
//
//  This file contains system constant specific for S3C6410 board.
//
#ifndef __SOC_CFG_H
#define __SOC_CFG_H

//------------------------------------------------------------------------------
// Define: SYNCMODE 
//
// SYNCMODE used to set cpu operation mode to syncronous mode or asyncronous mode
//------------------------------------------------------------------------------
#define SYNCMODE        (1)

//------------------------------------------------------------------------------
// Define : PRESET_CLOCK
//
// Use Predefined CLOCK SETTING.
//------------------------------------------------------------------------------
#define PRESET_CLOCK    (1)

//------------------------------------------------------------------------------
// CPU Revision (S3C6410 has EVT0, EVT1)
//------------------------------------------------------------------------------
#define EVT0            (36410100)
#define EVT1            (36410101)
#define CPU_REVISION    (EVT1)

//------------------------------------------------------------------------------
// Predefined System Clock setting selection
// Here are samples for clock setting that already tested.
// For S3C410, ARM 533Mhz, SystemBus 133Mhz is recommended.
// This values is only used on Driver written in C
//------------------------------------------------------------------------------

#if PRESET_CLOCK
#define CLK_25MHz        25000000
#define CLK_50MHz        50000000
#define CLK_33_25MHz     33250000
#define CLK_66_5MHz      66500000
#define CLK_96MHz        96000000
#define CLK_100MHz       100000000
#define CLK_133MHz       133000000
#define CLK_1333MHz      133333333
#define CLK_133_2MHz     133200000
#define CLK_150MHz       150000000
#define CLK_200MHz       200000000
#define CLK_233MHz       233000000
#define CLK_266MHz       266000000
#define CLK_266_4MHz     266400000
#define CLK_300MHz       300000000
#define CLK_400MHz       400000000
#define CLK_450MHz       450000000
#define CLK_532MHz       532000000
#define CLK_600MHz       600000000
#define CLK_634MHz       634000000
#define CLK_1332MHz      1332000000
#define CLK_666MHz       666000000
#define CLK_667MHz       667000000
#define CLK_798MHz       798000000
#define CLK_800MHz       800000000
#define CLK_900MHz       900000000

// Change This Definition to choose BSP Clock !!! (and "s3c6410.inc")
//#define TARGET_ARM_CLK    CLK_66_5MHz      //< Sync 66.5:66.5:66.5 HCLKx2=266
//#define TARGET_ARM_CLK    CLK_133MHz      //< Sync 133:133:66.5 HCLKx2=266
//#define TARGET_ARM_CLK    CLK_266MHz      //< Sync 266:133:66.5 HCLKx2=266
//#define TARGET_ARM_CLK    CLK_400MHz      //< Async 400:100:50 HCLKx2=200
//#define TARGET_ARM_CLK    CLK_450MHz      //< Sync 450:150:37.5 HCLKx2=300
#define TARGET_ARM_CLK    CLK_532MHz      //< Sync 532:133:66.5 HCLKx2=266, Async is same
//#define TARGET_ARM_CLK    CLK_600MHz        //< Sync 600:150:75 HCLKx2=300
//#define TARGET_ARM_CLK    CLK_666MHz      //< Sync 666:133.2:66.6 HCLKx2=266.4, Async 666:133:66.5 HCLKx2=266
//#define TARGET_ARM_CLK    CLK_798MHz      //< Sync 798:133:66.5  HCLKx2=266
//#define TARGET_ARM_CLK    CLK_800MHz      //< Sync 800:133.33:33.33 HCLKx2=266.66, ASync 800:133:66.5  HCLKx2=266
//#define TARGET_ARM_CLK    CLK_900MHz      //< Sync 900:150:75, HCLKx2=300

/// MPLL Setting
#if (TARGET_ARM_CLK == CLK_400MHz)
#define MPLL_CLK            (CLK_200MHz)
#else   // 532, 634, 666, 800, 900, 133, 266, 66.5
#define MPLL_CLK            (CLK_266MHz)
#endif
#define MPLL_DIV            2
#define S3C6410_DoutMPLL    (MPLL_CLK/MPLL_DIV)     // 100 Mhz or 133Mhz


#if (TARGET_ARM_CLK == CLK_666MHz && SYNCMODE) || (TARGET_ARM_CLK == CLK_450MHz) || (TARGET_ARM_CLK == CLK_266MHz)
#define APLL_CLK            (TARGET_ARM_CLK*2)
#elif (TARGET_ARM_CLK == CLK_133MHz)
#define APLL_CLK            (TARGET_ARM_CLK*4)
#elif (TARGET_ARM_CLK == CLK_66_5MHz)
#define APLL_CLK            (TARGET_ARM_CLK*8)
#else
#define APLL_CLK            (TARGET_ARM_CLK)
#endif

#if (TARGET_ARM_CLK == CLK_450MHz) || (TARGET_ARM_CLK == CLK_666MHz) || (TARGET_ARM_CLK == CLK_266MHz)
#define APLL_DIV            2
#elif (TARGET_ARM_CLK == CLK_133MHz)
#define APLL_DIV            4
#elif (TARGET_ARM_CLK == CLK_66_5MHz)
#define APLL_DIV            8
#else
#define APLL_DIV            1
#endif
#define HCLK_DIV            2
#if (TARGET_ARM_CLK == CLK_66_5MHz)
#define PCLK_DIV            2
#else
#define PCLK_DIV            4
#endif


/// APLL and A:H:P CLK configuration
#if (SYNCMODE)
    #if (TARGET_ARM_CLK == CLK_666MHz) && (CPU_REVISION == EVT1)
        #define HCLKx2_DIV          5    // sync
    #elif (TARGET_ARM_CLK == CLK_532MHz) || (TARGET_ARM_CLK == CLK_600MHz) || (TARGET_ARM_CLK == CLK_266MHz) || (TARGET_ARM_CLK == CLK_133MHz)
        #define HCLKx2_DIV          2    // sync    
    #elif (TARGET_ARM_CLK == CLK_798MHz) || (TARGET_ARM_CLK == CLK_900MHz) || (TARGET_ARM_CLK == CLK_450MHz) || (TARGET_ARM_CLK == CLK_800MHz)
        #define HCLKx2_DIV          3    // sync        
    #elif (TARGET_ARM_CLK == CLK_66_5MHz)
        #define HCLKx2_DIV          4    // sync
    #endif
#else   // 400Mhz, 532Mhz, 666Mhz
#define HCLKx2_DIV          1    // Async
#endif

#define S3C6410_ACLK        (APLL_CLK/APLL_DIV)           

#if (SYNCMODE)
    #define S3C6410_HCLKx2      (APLL_CLK/HCLKx2_DIV)     
#else
    #define S3C6410_HCLKx2      (MPLL_CLK/HCLKx2_DIV)
#endif
#define S3C6410_HCLK        (S3C6410_HCLKx2/HCLK_DIV)
#define S3C6410_PCLK        (S3C6410_HCLKx2/PCLK_DIV)
#else   // PRESET_CLOCK = FALSE
#define APLLVALUE    (((S3C6410_SYSCON_REG*)(S3C6410_BASE_REG_PA_SYSCON))->APLL_CON)
#define MPLLVALUE    (((S3C6410_SYSCON_REG*)(S3C6410_BASE_REG_PA_SYSCON))->MPLL_CON)
#define CLKDIV      (((S3C6410_SYSCON_REG*)(S3C6410_BASE_REG_PA_SYSCON))->CLKD_IV0)



#endif  // PRESET_CLOCK


//------------------------------------------------------------------------------
// SMDK6410 EPLL Output Frequency
//------------------------------------------------------------------------------
//#define S3C6410_ECLK        (CLK_96MHz)        // 96 MHz         for USB Host, SD/HSMMC..
#define S3C6410_ECLK        (84666667)        // 84,666,667 Hz     for IIS Sampling Rate 44.1 KHz (384fs)
//#define S3C6410_ECLK        (92160000)        // 92,160,000 Hz     for IIS Sampling Rate 48 KHz (384fs)

//------------------------------------------------------------------------------
// System Tick Timer Definition
//------------------------------------------------------------------------------
// For Precision of System timer
// Use timer counter as large as possible. (32-bit Counter)
// Use timer divider as small as possible.
#define SYS_TIMER_PRESCALER     (2)    // PCLK / 2 (Do not use Prescaler as 1)
#define SYS_TIMER_DIVIDER       (1)
#define TICK_PER_SEC            (1000)
#define OEM_COUNT_1MS           (S3C6410_PCLK/SYS_TIMER_PRESCALER/SYS_TIMER_DIVIDER/TICK_PER_SEC-1)
#define RESCHED_PERIOD          (1)

//------------------------------------------------------------------------------
// SMDK6410 Static SYSINTR Definition
//------------------------------------------------------------------------------
#define SYSINTR_OHCI         (SYSINTR_FIRMWARE+1)    // for USB Host
//gao0129
#define SYSINTR_ETH          (SYSINTR_FIRMWARE+19)   // for DM9000A
#endif // __SOC_CFG_H



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值