close_btn
로그인, 회원가입후 더 많은 혜택을 누리세요 로그인 회원가입 닫기

 

실행 방법

 1. 압축을 푼다.

 2. 디렉토리내에 있는 clean.cmd을 더블클릭한다.

 3. 디렉토리내에 있는 compile01.cmd을 더블클릭한다.

 

 

 

 

 

 

 

 

 

 

 

 
 
1. 목적
 
 
- C의 컴파일에 대한 개념을 이해한다.
- C소스를 가지고 컴파일 한다..
- 컴파일 과정마다 생성되는 것이 무엇인지를 이해한다.
 
 
 
 2. 사전 준비 사항
 
 
- 컴파일러 및 downloader 설치  http://cafe.naver.com/e2gedu/65
- USB to serial 설치                 http://cafe.naver.com/e2gedu/67
- editor 설치                           각자가 사용하기 편한 에디터 사용
- terminal 설치                        http://cafe.naver.com/e2gedu/69

 

 

 

 3. 기본 개념
 
 
기본 적인 C 파일과 gcc 명령어를 가지고 컴파일을 해서 보드에서 동작되는 과정을 정리해 보았습니다.

- 가장 단순한 구조의 컴파일 환경을 구축한다. 향후에 컴파일 과정이해를 돕고자 한다.

- c언어를 컴파일 하기 위해서는 Cortex-M3용 gcc가 설치되어야 한다.

- C언어를 Linker Scriptor와 makefile없이 컴파일하는 환경을 만든다.

- ARM Cortex-M3 완벽가이드의

     * 10장 Cotex-M3 프로그래밍

     * 19장 툴 체인을 사용하여 Cortex-M3 시작하기

   에 해당한다.

 

  4. 실행순서

 

 

- start_stm32f10x.c를 작성한다.

- compile01.cmd를 작성한다.

- compile01.cmd를 더블클릭한다.

- stm32에 fusing 한다.

- 터미널을 통하여 실행하다.

 

3-1 start_stm32f10x.c를 작성한다.

 

/******************************************************************************
 * @file      start_stm32f10x.c
 * @author    SmartRobot
 * @version   V0.1
 * @date      04/15/2013
 *******************************************************************************/

/* Private typedef -----------------------------------------------------------*/
typedef void( *const intfunc )( void );

/* init value for the stack pointer. defined in linker script */
//extern unsigned long _estack;
//extern unsigned long _ld_stack_address;

/* Private function prototypes -----------------------------------------------*/
void Reset_Handler(void) __attribute__((__interrupt__));

__attribute__ ((section(".isr_vectorsflash")))    //linker scriptor에서 사용됨
/* vector table*/
void (* g_pfnVectors[])(void) =
{
    (intfunc)((unsigned long)0x20000000 + 0x1000), /* The stack pointer after relocation */
    Reset_Handler,                      /* Reset Handler */
};

int a=1;
int b;

void Reset_Handler(void)
{
    unsigned long StartUpCounter = 0, HSEStatus = 0;
    // HSI or HSE 선택
    // PLLSRC
    // 8MHz/2 x 18 = 72MHz
    // 12MHz x 6 = 72MHz
   
   
    ////HSI(0x1) or HSE ON(0x1<<16)
    *(volatile unsigned long *) 0x40021000 |= 0x1;            //RCC_CR - HSION    Set HSION bit
    //*(volatile unsigned long *) 0x40021000 |= 0x1<<16;        //RCC_CR  CR_HSEON_Set

    // 설정된 clock 이 설정 되었는지 확인
    do
    {
    //   HSEStatus = (*(volatile unsigned long *) 0x40021000 & 0x1<<17);             // HSE 인경우
       HSEStatus = (*(volatile unsigned long *) 0x40021000 & 0x1<<1);             // HSI 인경우
       StartUpCounter++;
    } while((HSEStatus == 0) && (StartUpCounter != 0x0500));
 
    /////// PLL 설정 내부 일 경우 36MHz 외부 일 경우 72Mhz로 설정함
    *(volatile unsigned long *) 0x40021004 &= ~(0xF<<18 | 0x1<<17 | 0x1<<16); //0x3F0000;      //RCC_CFGR
    *(volatile unsigned long *) 0x40021004 |= (0x7<<18);                            //RCC_CFGR  //내부 4MHz
    //*(volatile unsigned long *) 0x40021004 |= (0x7<<18 | 0x1<<16);           //0x1D0000;       //RCC_CFGR  //8MHz
    //*(volatile unsigned long *) 0x40021004 |= (0x4<<18 | 0x1<<16);           //0x110000;       //RCC_CFGR    //12MHz
    *(volatile unsigned long *) 0x40021000 |= 0x01 << 24/*0x1000000*/;         //PLLON
    while( ((*(volatile unsigned long *) 0x40021000) & 0x01 << 25/*0x2000000*/) == 0);       //PLLRDY
   
    /////PLL을 선택한다.
    /////Bits 1:0 SW : System clock switch
    //00: HSI selected as system clock
    //01: HSE selected as system clock
    //10: PLL selected as system clock   <----------------- 선택됨
    //11: not allowed
    *(volatile unsigned long *) 0x40021004 &= ~0x3;
    *(volatile unsigned long *) 0x40021004 |= 0x2;
    while( ((*(volatile unsigned long *) 0x40021004) & 0xC) != 0x08);
   
    //APB2에 있는 UART 등 주변장치에 Clock 소스 동작제어
    //UART가 동작되기 위해서는 GPIO와 Alternation Function IO가 동작상태에 있어야 함
    *(volatile unsigned long *) 0x40021018 |= 0x1 << 14 | 0x1 << 2 | 0x1 << 0;         // uart/ IOPA EN / AFIO EN
  
     /* Configure the GPIO ports */
    *(volatile unsigned long *) 0x40010804 = 0x888444B4;
    *(volatile unsigned long *) 0x40011C00 = 0x33444444;
    *(volatile unsigned long *) 0x40011C04 = 0x44444433;
   
     /* USART1 configuration ------------------------------------------------------*/
     /* USART1 configured as follow:
      - BaudRate = 19200 baud
      - Word Length = 8 Bits
      - One Stop Bit
      - No parity
      - Hardware flow control disabled (RTS and CTS signals)
      - Receive and transmit enabled
     */
    *(volatile unsigned long *) 0x40013810 = 0x0;              // 1 stop bit
    *(volatile unsigned long *) 0x4001380C = 0x200C;        // 8bit no parity
    *(volatile unsigned long *) 0x40013814 = 0x0;
    *(volatile unsigned long *) 0x40013808 = 19 << 4 | 8;   // 내부 OSC 32Mhz인 경우 115200bps로 통신 속도 설정
    *(volatile unsigned long *) 0x4001380C |= 0x2000;

    while(1)
    {
      while( !((*(volatile unsigned long *) 0x40013800) & 0x80) ) ;
         *(volatile unsigned long *) 0x40013804 = 'c';
    }
}

 

주석을 참조하기 바람

이전의 에셈 루틴과 동일하다.

 
3-2 compile01.cmd를 작성한다.

 

arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c start_stm32f10x.c

pause

 

arm-none-eabi-ld --section-start .isr_vectorsflash=0x08000000 -Ttext 0x08000080 --entry=Reset_Handler -o

start_stm32f10x.elf start_stm32f10x.o

pause

 

arm-none-eabi-objcopy -O binary start_stm32f10x.elf start_stm32f10x.bin

pause

 

arm-none-eabi-objdump -D start_stm32f10x.elf > obj_dump_nomake.txt

pause

 

실행과정

c 파일(start_stm32f10x.c) -> 목적파일(start_stm32f10x.o) -> 실행파일(start_stm32f10x.elf) -> 바이너리(start_stm32f10x.bin)

                                                                                                                            -> 역어셈(obj_dump_nomake.txt)

c 파일 -> 목적파일
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c start_stm32f10x.c
       -c                      : 목적파일까지 컴파일한다.

       -mcpu=cortex-m3 : 사용되는 코아 

       -mthumb             : thumb 명령어

 

목적파일 -> 실행파일
arm-none-eabi-ld --section-start .isr_vectorsflash=0x08000000 -Ttext 0x08000080 --entry=Reset_Handler -o start_stm32f10x.elf start_stm32f10x.o

여기서는 가장 먼저 올라와야할 코드가 벡터테이블이기 때문에 벡터테이블이다. vector table의 섹션을 .isr_vectorsflash로 설정했다. 이를 0x08000000에 위치하도록 하였다. 그리고 text의 위치를 0x08000080로 설정하고 진입함수를 Reset_Handler로 설정한다.

      - o                                                           : 실행파일까지 컴파일한다.

      --section-start .isr_vectorsflash=0x08000000  : 맨먼저 위치하는 섹션을 결정하고 주소를 결정한다.

      -Ttext 0x08000080                                       : text 섹션의 주소를 결정한다.

      --entry=Reset_Handler                               : 진입함수를 Reset_Handler로 설정한다.

 

 

실행파일 -> binary
arm-none-eabi-objcopy -O binary start_stm32f10x.elf start_stm32f10x.bin
      -O binary    : 실행파일에서 binary를 추출하라는 의미

 

실행파일 -> 역어셈
arm-none-eabi-objdump -D start_stm32f10x.elf > obj_dump_nomake.txt

실행파일에서 역어셈을 해서 obj_dump_nomake.txt에 저장한다.


첫번째 수행하는 것이 start_stm32f10x.c에서 start_stm32f10x.o 목적 파일을 생성한다.
다음으로 실행파일을 생성 후에 실행파일에서 바이너리를 추출하고 역어셈을 하는 과정을 보여 준다.

 

 

3-3compile01.cmd를 더블클릭한다.

 

4번을 Enter를 누르면 실행이 종료된다.
차례로 목적파일 start_stm32f10x.o, 실행파일 art_stm32f10x.out, 바이너리 start_stm32f10x.bin, 그리고 역어셈 파일인 start_stm32f10x.list와 obj_dump.txt가 생성된다.


3-4 stm32에 fusing 한다.

flash_loader_demonstrator-235x300.jpg

 

3-5 터미널을 통하여 실행하다.

 

ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

 

Serial terminal 창에 'c'로 가득 찬다.