이 블로그는 임베디드 컴퓨터를 이용한 장치(시스템) 개발과 원격제어에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Microchip 사의 ATmega128를 사용한 보드와 Arduino Mega 보드(ATmega2560), Raspberry Pi, Raspberry Pi Pico, WiFi 모듈을 사용 합니다.

avr-asm-programming-AVR-staudio

Assembly Language Programming - Microchip Studio
  Microchip Studio 환경에서 Assembly Language Program 작성 하기



  • Microchip Studio(AVR Studio7) 환경에서 AVR Assembly Program 작성 하기
    • 이 페이지에서는 AVR Studio에 포함되어 있는 AVR Assembler와 GCC(GNU C Compiler)에 포함 되어 있는 GCC Assembler 두가지를 사용 한다.

      AVR Assembler는 AVR microcontroller를 설계하고 Microchip Studio를 제공하는 Atmel(현 Microchip)에서 제공 하는 Assembler 이기 때문에 Microchip Studio의 기능을 잘 활용할 수 있는 장점이 있다.

      GCC Assembler는 GCC(GNU C Compiler)에 포함 되어 있는 Assembler 이기 때문에 GCC c와 Assembly Program을 Mixing 한 프로그램을 작성 하기에 적합 하다.

    • AVR ASM Project 만들기
      • Microchip Studio 를 실행 한다.
      • File → New → Project 를 실행하고 New Project 창에서 “Assembler” 선택한다.
      • New Project 창 예
      • Project name Box에 Project name 입력 한다.
      • Location Box 에 Browse... 버튼을 사용하여 Project 폴더를 설정한다.
      • Create directory for solution Box 를 Check 한다.
      • “OK”를 클릭한다.
      • Device Selection 창에서 Device를 선택(예: ATmega128)하고 “OK”를 클릭하면 Project 가 생성되고 main.asm 파일이 열린다.
      • main.asm 파일을 편집하여 프로그램을 작성한다.

    • Template 를 이용한 AVR Assembly Language Programming
      • 아래 설명은 본인이 작성한 Template를 이용하여 Assembly Language Programming을 보다 쉽게 작성하는 방법에 대한 설명이다.

        각자 자신이 자주 개발하는 프로그램에 적합한 Template를 작성하여 사용하면 프로그램 개발이 보다 편리하고 일정한 형태의 프로그램을 작성할 수 있기 때문에 보다 읽기 쉽고 디버깅이 용이한 프로그램을 작성할 수 있다.

        간단한 프로그램은 Template를 사용하지 않고 직접 작성하여도 된다.

      • 위 "AVR ASM Project 만들기"를 참고하여 Project(Project name: AVR_sw_led_basic)를 생성 한다.
      • 아래 avr128_template.asm을 main.asm 창에 복사 한다.
      • Assembly Language Program을 위한 Template 예: "avr128_template.asm"

      • main.asm 파일을 편집하여 아래와 같은 프로그램을 작성 한다. 이 예에서는 아래 프로그램을 main.asm 창에 복사하여 사용할 수 있다.
      • PD0, PD1에 연결된 Switch의 상태를 읽어 PORTF의 PF0, PF1에 표시 하는 프로그램 예

        • 프로그램 편집하기
          • Interrupt를 사용하지 않는 경우 ".include "avr128_interrupt_table.inc"을 Comment 처리 또는 삭제한다. 이 예에서는 RESET(전원이 처음 인가되는 경우 또는 Reset SW를 누르면 실행되는 Interrupt) Interrupt를 사용한다.
          • 레지스터의 기호 이름을 재 설정(사용하지 않는 Rg 설정은 삭제하고 사용하는 Rg의 이름은 프로그램 내용에 적합하게 재 설정)한다.
          • Program Constants을 재 설정(사용하지 않는 상수의 설정은 삭제하고 사용하는 상수는 프로그램 내용에 적합하게 재 설정)한다.
          • DSEG에 전역변수를 재 설정(사용하지 않는 전역변수의 설정은 삭제하고 사용하는 전역변수는 프로그램 내용에 적합하게 재 설정)한다.
          • CSEG에 필요한 사용자 프로그램을 작성한다.
      • Avr128_interrupt_table.inc File 을 Project Folder 에 복사 한다.
        • ATMega128 Interrupt Vector Table의 예: "avr128_interrupt_table.inc"

        • 위 "avr128_interrupt_table.inc"을 다운로드 하여 Project Folder(main.asm 파일이 있는 폴더)에 복사한다.
        • Interrupt를 사용하는 프로그램인 경우 사용하는 Interrupt의 ISR(Interrupt Service Routine)의 시작번지(Label)를 avr128_interrupt_table.inc에 등록한다.
        • 현재 "avr128_interrupt_table.inc"에는 RESET Interrupt(전원이 처음 인가되거나 Reset SW를 누르면 발생하는 Interrupt) 만 설정되어 있다.
      • AVR ASM Project Build 하기
        • Build → Build Solution 를 실행 하면 main.asm File 이 Assemble 되어 AVR_sw_led_basic.hex 파일이 생성된다.
        • Build 결과 AVR_sw_led_basic.hex 파일은 ProjectName 폴더 → projectName 폴더 → Debug 폴더에 위치한다.
        • Assembler에 의하여 Debug 폴더에 생성되는 파일의 종류는 아래와 같다.
          • AVR_sw_led_basic.hex: Assembler에 의하여 생성된 실행 파일(Binary File)을 Intel HEX File Format(Binary Instructions과 Instructions이 Load되는 주소를 HEX File로 저장)으로 저장한 Text 파일.
          • AVR_sw_led_basic.lss: Assembler에 의하여 생성된 Listing File. lss 파일은 소스 코드와 생성된 Machine code의 List로 Debugging에 사용된다.
          • AVR_sw_led_basic.obj: Assembler에 의하여 생성된 Object File.
          • AVR_sw_led_basic.map: Assembler에 의하여 생성된 Map File.

    • Debugger 환경에서 Simulator를 이용한 프로그램 실행
      • 작성한 프로그램에 오류가 있는 경우 이를 발견 하고, 정정 하기 위하여 AVR Simulator를 이용한 Debugging 이 필요 하다.

      • 위 "Template를 이용한 AVR Assembly Language Programming"을 참고하여 프로그램을 작성하고 Build 한다.
      • Simulator 설정: Project → (Project name) Properties... 를 실행하면 Property 창이 열린다. 이 창에서 Tool을 선택하고 “Selected debugger/programmer” Box 에서 Simulator 를 선택한다.
      • Debugging 하려는 .asm 파일(대부분의 경우 main.asm) 창을 선택하고 Debug → Start Debugging and Break을 실행 하면 Simulator 가 실행 되고, Debugging 에 필요한 창이 열린다.
      • Debugger를 이용한 프로그램 실행은 참고자료 "Debugger를 이용한 Instruction Set과 Microprocessor의 이해"를 참고(IN/OUT 명령 예)하여 프로그램을 실행(Debugging)한다.

    • Target Board에서 실행 하기

  • Microchip Studio(AVR Studio7) 환경에서 GCC Assembly Program 작성 하기
    • GCC Assembler는 GCC(GNU C Compiler)에 포함 되어 있는 Assembler 이기 때문에 GCC c와 Assembly Program을 Mixing 한 프로그램을 작성 하기에 적합하다.

    • GCC ASM Project 만들기
      • Microchip Studio 를 실행한다.
      • File → New → Project를 실행하고 New Project 창에서 “C/C++ → GCC C Executable Project C/C++”을 선택한다.
      • New Project 창 예
      • Project name Box에 Project name 입력 한다.
      • Location Box에 Browse... 버튼을 사용하여 Project 폴더를 설정한다.
      • Create directory for solution Box를 Check 한다.
      • “OK”를 클릭한다.
      • Device Selection 창에서 Device를 선택(예: ATmega128, ATmega128A는 GCC Assembler에서 지원 하지 않는다.)하고 “OK”를 클릭하면 Project가 생성되고 main.c 파일이 열린다. Assembly Source File은 아직 하나도 만들어 지지 않은 상태 임.
      • main.c File을 Assembly Language Source File로 변경하기: main.c의 File name을 main.s로 변경하고 이 파일에 Assembly Language 프로그램을 작성한다.
      • 새 Assembly Language Source File 추가하기: Solution Explorer 창에 있는 project_name 위에서 마우스 우측 버튼을 하고 Add → New Item… 을 클릭하면 Add New Item 창이 열린다. 이 창에서 C/C++ → Assembly File을 선택한다. Name Box에 File name을 입력하고 Add 버튼을 클릭하면 새 Assembly Flie이 Project 내에 추가된다.
      • "GCC C Executable Project C/C++" Project에서 Assembly Language 프로그램을 작성하는 방법
        • main.c File을 main.s로 Rename 하기: main 함수 자제를 Assembly Language로 작성하기 때문에 별도의 c 파일이 필요 없다.
        • Inline assembly: c Source code 내에서 asm Macro를 사용하여 직접 Assembly Code를 작성할 수 있다. 적은 Assembly Code를 사용하는 경우 적합하다.
        • c Source code 내에서 Assembly Code 파일을 Include 하는 경우: main 함수는 c로 작성하고 Hardware 특성과 실행 속도 등의 최적화가 필요한 함수를 Assembly Language로 작성한다. c 언어와 Assembly Language를 혼합(Mixing)하여 프로그램을 작성하기 때문에 c와 Assembly Language의 장점을 효과적으로 사용할 수 있다.

    • Template 를 이용한 GCC Assembly Language Programming
      • 아래 설명은 본인이 작성한 Template를 이용하여 GCC Assembly Language Programming을 보다 쉽게 작성하는 방법에 대한 설명이다.

        각자 자신이 자주 개발하는 프로그램에 적합한 Template를 작성하여 사용하면 프로그램 개발이 보다 편리하고 일정한 형태의 프로그램을 작성할 수 있기 때문에 보다 읽기 쉽고 디버깅이 용이한 프로그램을 작성할 수 있다.

        간단한 프로그램은 Template를 사용하지 않고 직접 작성하여도 된다.

      • 위 "GCC ASM Project 만들기"를 참고하여 Project(Project name: AVR_sw_led_basic)를 생성 한다.
      • main.c File을 main.s로 파일 확장자를 변경한다.
      • 아래 avr128_gcc_assembly_template.s을 main.s 창에 복사 한다.
      • GCC Assembly Language Program을 위한 Template 예: "avr128_gcc_assembly_template.s"

      • GNU Assemler에서 자주 사용하는 Directives
        • .org new-lc // Location Counter의 값을 new-lc로 설정 한다.
        • .align abs-expr // Location Counter의 값을 현재 위치로 부터 첫 번째 abs-expr 의 정수배가 되는 값으로 설정 한다.
        • .byte // Byte 단위로 데이터를 저장한다.
        • .word // Word 단위로 데이터를 저장한다.
        • .2byte expression // 2 Byte 단위로 데이터를 저장한다.
        • .4byte expression // 4 Byte 단위로 데이터를 저장한다.
        • .8byte expression // 8 Byte 단위로 데이터를 저장한다.
        • .space size, fill // size 수 만큼의 Byte를 fill 의 값으로 채운다. size 와 fill 은 둘다 절대 적인 expression 이어야 한다. 만일 콤마와 fill 이 생략되었다면 fill 은 0으로 가정 한다.
        • .ascii "String" // 문자열(String) 상수를 저장한다. 문자열의 끝에 Null 문자(0x00)가 첨부되지 않는다.
        • .asciz "String" // 문자열(String) 상수를 저장한다. 문자열의 끝에 Null 문자(0x00)를 첨부한다.
        • .section name // 다음 에 오는 Code 가 name section 영역에 할당 되도록 한다. .section name의 사용 예는 아래와 같다.
          • .section .text
          • .section .data
        • .end // Assembly 프로그램의 끝을 표시 한다.
        • .include “file” // 현재의 위치에 “file”에 주어진 이름의 Source Program을 포함 시킨다.
      • main.s 파일을 편집하여 아래와 같은 프로그램을 작성 한다. 이 예에서는 아래 프로그램을 main.s 창에 복사하여 사용할 수 있다.
      • PD0, PD1에 연결된 Switch의 상태를 읽어 PORTF의 PF0, PF1에 표시 하는 프로그램 예

        • 프로그램 편집하기
          • 레지스터에 기호 이름을 재 설정(사용하지 않는 Rg 설정은 삭제하고 사용하는 Rg는 프로그램 내용에 적합하게 재 설정)한다.
          • Program Constants을 재 설정(사용하지 않는 상수의 설정은 삭제하고 사용하는 상수는 프로그램 내용에 적합하게 재 설정)한다.
          • .data Section에 전역변수를 재 설정(사용하지 않는 전역변수의 설정은 삭제하고 사용하는 전역변수는 프로그램 내용에 적합하게 재 설정)한다.
          • .text Section에 필요한 사용자 프로그램을 작성한다.
      • GCC ASM Project Build 하기
        • Build → Build Solution를 실행 하면 main.s File 이 Assemble 되어 AVR_sw_led_basic.hex 파일이 생성된다.
        • Build 결과 AVR_sw_led_basic.hex 파일은 ProjectName 폴더 → projectName 폴더 → Debug 폴더에 위치한다.
        • Assembler에 의하여 Debug 폴더에 생성되는 파일의 종류는 아래와 같다.
          • AVR_sw_led_basic.hex: Assembler에 의하여 생성된 실행 파일(Binary File)을 Intel HEX File Format(Binary Instructions과 Instructions이 Load되는 주소를 HEX File로 저장)으로 저장한 Text 파일.
          • AVR_sw_led_basic.lss: Assembler에 의하여 생성된 Listing File. lss 파일은 소스 코드와 생성된 Machine code의 List로 Debugging에 사용된다.
          • AVR_sw_led_basic.elf: Linux OS의 실행 File.
          • AVR_sw_led_basic.map: Assembler에 의하여 생성된 Map File.
          • AVR_sw_led_basic.eep: EEPROM Data File.
      • GCC Assembly 프로그램 작성 시 주의 사항(AVR Assembler과 차이)
        • GCC Assembler는 GCC 환경에서 사용되는 다른 언어(예: c 언어)와 호환성을 고려 한 Assembler 이기 때문에 프로그램 실행에 필요한 기본 설정을 GCC Compiler 가 수행 한다.
        • RESET Vector의 설정
          • 개발 보드에서 Reset Switch를 누르면 프로세서가 Reset 되고, Interrupt Vector Table에서 Interrupt Vector 0 번에 있는 명령이 실행 된다. 그러므로 Reset Switch를 누른 다음 처음 실행 되는 프로그램의 시작 번지를 Interrupt Vector Table에 설정 하여 주어야 한다. GCC Assembler 에서는 이 설정을 GCC Compiler 가 하기 때문에 프로그램 개발자는 RESET Vector의 설정을 할 필요가 없다.
        • Stack pointer 설정(초기화)
          • GCC Assembler에서는 이 설정을 GCC Compiler 가 하기 때문에 프로그램 개발자는 Stack Pointer 설정을 할 필요가 없다.
        • Interrupt Vector 설정
          • Interrupt를 사용 하는 응용 프로그램을 작성 하는 경우, Interrupt 처리 Routine의 시작 번지를 Interrupt Vector Table에 설정 하여 주어야 한다.
          • WinAVR GCC Assembly 프로그램에서는 Interrupt Vector 이름(GCC에서 미리 정의한 고유한 이름을 사용하여야함)을 Global 변수로 선언 하면 GCC Compiler 가 Interrupt Vector Table에 자동으로 Interrupt Service Routine의 시작 번지를 설정 한다.
        • 전역변수(Global Variables)의 초기화가 필요한 경우 아래 예와 같은 Code를 사용하여 초기화 한다.
        • 전역변수(Global Variables)의 초기화에 필요한 상수는 프로그램 메모리(Flash Program Memory)에 첨부되어 있기 때문에 이 Data를 전역변수(Data RAM) 영역으로 복사(초기화) 하여야 한다.

          • 전역변수(Global Variables)를 초기화 하는 Code 예
        • SFR(Special Function Registers: I/O port 등)의 Address
          • GCC Assembler에서 I/O Ports의 Access는 sts(Store direct to SRAM), lds(Load direct from SRAM) 명령을 사용 하기 때문에 Data Memory $0020 - $005F에 Mapping 된 SFR (I/O port 등)의 Address는 SRAM Address를 사용 한다.
          • in(in Rg, Address), out(out Address, Rg) 명령은 Port 번호(0x00-0x3f)를 사용 하기 때문에 in, out 명령을 사용 하는 경우에는 Data Memory Address(0x20-0x5F)에서 0x20을 뺀 값을 사용 하여야 한다.
          • In, out 명령을 사용하는 경우 아래 예와 같이 Data Memory Address(0x20-0x5F)에서 0x20을 빼는 Macro 함수 _SFR_IO_ADDR을 사용한다.
          • out _SFR_IO_ADDR(PORTD), r16


    • Debugger 환경에서 Simulator를 이용한 프로그램 실행
      • 작성한 프로그램에 오류가 있는 경우 이를 발견 하고, 정정 하기 위하여 AVR Simulator 를 이용한 Debugging 이 필요 하다.

      • 위 "Template 를 이용한 GCC Assembly Language Programming"을 참고하여 프로그램을 작성하고 Build 한다.
      • Simulator 설정: Project → (Project name) Properties... 를 실행하면 Property 창이 열린다. 이 창에서 Tool을 선택하고 “Selected debugger/programmer” Box 에서 Simulator 를 선택한다.
      • Debugging 하려는 .s 파일(대부분의 경우 main.s) 창을 선택하고 Debug → Start Debugging and Break을 실행 하면 Simulator 가 실행 되고, Debugging 에 필요한 창(Disassembly 창, Processor Status 창, I/O 창 등)이 열린다.
      • GCC c(or Assembly Language Program)의 Debugging은 Disassembly 창에서 실행한다.
      • Debugger를 이용한 프로그램 실행은 참고자료 "Debugger를 이용한 Instruction Set과 Microprocessor의 이해"를 참고(IN/OUT 명령 예)하여 프로그램을 실행(Debugging)한다.

    • Target Board에서 실행 하기
      • 이 실험에서는 ATmega128 보오드를 실험에 사용한다.

      • 실험을 위한 준비
      • 실험 방법
        • 프로그램을 Target Board에 Upload 하고 프로그램을 실행한다. Upload Tool에 따라 프로그램을 실행 방법(Microchip Studio 7에서 AVRDUDE를 사용하는 경우 Upload 가 종료되면 프로그램이 자동으로 실행됨)이 다를 수 있다.
        • 프로그램이 처음 실행되면 PF0 와 PF1 LED가 모두 Turn on 된 상태이다.
        • PD0 Switch를 누르면 PF0에 연결된 LED가 Turn off 된다.
        • PD1 Switch를 누르면 PF1에 연결된 LED가 Turn off 된다.

  • Microchip Studio 환경에서 Assembly Language Program 작성 하기 관련 페이지 보기