Busan IT/로봇제어2015. 11. 3. 17:44

==================================Outline====================================

저수준 C프로그래밍

- sysfs를 이용한 GPIO 제어

- 라즈베리 파이 커널 빌드와 디바이스 드라이버

- 커널 빌드

- 모듈 프로그래밍

디바이스 드라이버 프로그래밍

- 'file_operations' 구조체의 명령어

----------------------------------------------------------------------------

저수준 C프로그래밍


sysfs를 이용한 GPIO 제어

 

p/474

 

sys파일 시스템은 하드웨어에 대한 정보를 체계적으로 제공한다. Raspbian 커널에 GPIO포트를 제어하기 위한 드라이버가 포함되어 있고 sys 파일 시스템을 통해 사용자에게 GPIO포트 설정 및 제어를 수행할 수 있는 기능이 포함되어 있다.

 

 

export파일을 제어하고자 하는 GPIO 포트 번호를 써주면 해당 핀의 파일명이 심볼릭 링크 파일로 생성된다.

 

 

이 링크를 제어하여 led를 제어할 수 있다.

 






 

라즈베리 파이 커널 빌드와 디바이스 드라이버

 

p/478

 

리눅스 커널은 리눅스 커뮤니티에서 제공한다. 사용자 편의에 위해 다양한 기능을 추가하여 공개하는 것을 배포판이라고 한다. Debian은 잘 알려진 배포판이다.

 

//GPL(General Purpose License)

 

리눅스는 GPL을 기반으로 하는 오픈소스 커널이기 때문에 이것을 사용하는 모든 프로램은 소스 코드를 공개해야 할 의무가 있다.

 

안드로이드는 리눅스 기반이지만 gcc컴파일러와 헤더파일을 사용하지 않기 때문에 소스 코드를 공개할 필요가 없다.

 

간단한 C파일을 작성하여 컴파일해보자. 컴파일이 완료되면 해당 파일의 정보를 살펴본다.

 

 

ELF32 format, ARM 아키텍쳐 사용

 

//커널 소스 다운로드 이전에 했음으로 넘어간다.

 

커널 빌드

p/493 

 

ATmega32는 리눅스 기반에서도 작동한다.

'ia64' 인텔의 CPU를 말한다.

 

RaspberryPi2의 아키텍쳐는 'mach-bcm2709'를 사용한다.

 

초보자들을 위해 기본적인 설정이 ‘config' 파일로 제공된다. 초보자의 경우는 기본적인 ‘config’파일을 사용한다.

 



 

커널 빌드 시 교재 p/4931 - 4단계까지만 수행하고 나머지 과정은 파일을 복사하여 진행하는 것이 빠르다.

 

‘menu-config ’시 수정된 내용이 있으면 저장 메시지를 띄워준다.

 

‘WinSCP’는 파일 전송을 위해 사용되는 프로그램이다. 필요할 경우 설치하여 사용한다.

 

커널 빌드는 지난 시간에 수행했음으로 따로 할 필요는 없다.

 

모듈 프로그래밍

 

p/507

 

리눅스의 경우 주변 장치는 운영체제에 의해 관리된다. 운영체제는 커널 모드와 사용자 모드로 구분해 주소 공간을 분리하고 시스템 자원을 관리한다. 이 때 장치에 대한 관리 권한은 커널 모드에만 제공된다. 시스템 콜 기반으로 커널을 관리하는 경우는 커널 소스를 직접 수정해야 하고, 컴파일과 리셋의 과정을 수행해야 한다. 모듈을 사용한다면 커널 빌드 없이 장치를 사용할 수 있다. 다만 모듈을 사용할 경우 커널 버전이 모듈 커널의 버전과 일치해야 하며 root 계정으로만 작업 가능하다.

 

교재 p/508 ~ p/509의 소스를 실행하여 간단한 모듈 동작 과정과 사용법을 알아보자.


/*** 소스 ***/

[Makefile]

 obj-m := simple_mod.o

     KDIR := /usr/src/linux
 PWD := $(shell pwd)
     FILE := simple_mod

 all:
     @echo
         $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
         dmesg | tail -5

 clean:
     @echo
         $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
         dmesg | tail -5

 up:
     @echo
         insmod $(FILE).ko
         dmesg | tail -5
         lsmod

 down:
     @echo
         rmmod $(FILE)
         dmesg | tail -5
         lsmod


[simple_mod.c]


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

int simple_mod_init(void)
{
        printk("simple module loaded\n");
        return 0;
}

int simple_mod_exit(void)
{
        printk("simple module unloaded\n");
        return 0;
}

module_init(simple_mod_init);
module_exit(simple_mod_exit);
MODULE_LICENSE("GPL");

 

셸 명령어에 따른 모듈이 내부에 적재될 때 메모리 위치를 살펴보자.

4GB의 메모리라고 했을 때 커널은 상위 1GB영역에 위치한다. 이러한 커널은 다시 세 영역으로 나뉜다. 하위 16MB영역은 직접 액세스 영역, 16 ~ 896MB 영역은 Norname Zone, 896MB에서 나머지 영역은 High Memory Zone으로 구분된다.

 

shell 명령어 창에서 ‘/pro/kallsysm'명령어를 입력하면 커널 심볼 테이블을 볼 수 있다.

 

//페이지를 나누어서 출력시키기 위한 명령어 'more' -> '/pro/kallsysm | m



디바이스 드라이버 프로그래밍

 

p/517

디바이스 드라이버를 사용하기 위해서는 ‘file_operation’구조체에 정의 되어 있는 open, close, read, write 함수 등을 사용해야 한다.

file_operation 구조체는 linux/fs.h에 포함되어 있으며 함수 포인터들을 멤버로 가지고 있다.

 

프로그램이 직접적으로 하드웨어를 제어하는 것은 kernel에 의해 금지된다. 프로그램은 커널을 통해 하드웨어를 제어해야한다. 커널은 모든 장치를 파일화하여 관리한다. 하드웨어 대한 정보를 ‘/dev’ 폴더에 저장해 놓는다.

 

사용자는 임의적으로 하드웨어 장치를 생성할 수 있는 명령어는 'mknod'이다.

존재하는 장치의 구동을 위한 명령어는 'insmod'이다. 'insmod'는 장치를 초기화하기 위해 'Init' 함수를 사용한다. 또한 ‘file_oeration'구조체의 함수를 사용하여 장치를 제어하게 된다.

응용 프로그램 개발자는 파일이름만 알면 장치를 제어할 수 있다. 때문에 상세한 장치구조에 대해서는 굳이 알 필요가 없다.

 

'file_operations' 구조체의 명령어

 

open: 디바이스 드라이버가 실제로 사용되기 위해 호출되는 함수. ‘open'함수는 장치 열기에 성공했을 시, 파일 디스크립터가 아닌 ’0'을 반환한다.

 

release: 'close'함수와 같은 기능을 한다. 즉 연결되어 있는 파일 장치를 닫는 역할을 한다.

 

read: 디바이스에 대한 입력을 위해 사용되는 함수이다.

 

write: 디바이스의 출력을 위해 사용되는 함수이다.

 

ioctl: read/write 이 외의 다양한 연산을 제공한다. read/write 기능 또한 'ioctl'에서 구현 가능하다.

 

mmap: 메모리 매핑을 위한 함수로써 물리적 주소를 가상 공간으로 변환해 준다.

 

poll: 인터럽트의 처리와 연관되어 사용되는 함수이다.

'read' 함수의 4번째 인자는 읽어 들일 데이터의 시작점이다.

 

p/521 예제 코드 분석

 

예제는 내일 쳐본다.















  

 

 

 

반응형
Posted by newind2000
Busan IT/Assembly2015. 11. 3. 17:36

==================================Outline====================================

Bit Manipulation

Shift and Rotate Instructions

----------------------------------------------------------------------------

  

p/259

 

Converting a 2' Complement Integer to an ASCII string

 

아는 것임으로 패스

 

 

p/267

 

Bit Manipulation

 

다 아는 것임으로 넘어간다....

 

클럭 사이클이 메모리가 개입하면 눈에 띄게 커지는 것을 알 수 있다.

 

‘test'명령어는 결과 값이 accumulator 레지스터에 들어가는 것과는 제외하는 ’and' 연산과 동일하다. 'test'는 명령어는 특정 비트의 값을 확인하거나 추출하기 위해서 사용된다.

 

test dx, 2000h ; check bit 13

 

Shift and Rotate Instructions

 

p/278

h(로직): 쉬프트를 사용하면 빈 자리는 무조건 ‘0’으로 채워진다.

a(연산): 음수/양수를 판별하여 음수일 경우 빈자리를 ‘1’, 양수일 경우 ‘0’으로 채워준다.

 

예제를 통해 확인해 보자.



쉬프트 연산의 사이클은 곱셈과 나눗셈에 비해 낮기 때문에 2의 제곱의 곱셈과 나눗셈에서는 쉬프트 연산을 사용하는 효율적이다.

 


 

operand3개인 쉬프트연산도 사용할 수 있다.

//해당 명령어가 존재한다는 것만 알고 있자.

 



 

 

반응형
Posted by newind2000
Busan IT/Assembly2015. 11. 3. 12:53

==================================Outline====================================

String Instruction

- stos

- lods

Character Translation

- xlat

----------------------------------------------------------------------------

교재 p/249

 

stos

 

같은 문자를 반복하여 저장한다.

 

lods

 

‘esi’에 있는 문자열을 'eax'에 저장한다.

 

 

Character Translation

 

교재 p/254

 

xlat

 

'EBX' 문자열이 시작하는 주소를 가리키고 ‘AL’에서 배열의 값을 가지고 있는 상황에서 'AL'에 해당 값이 들어가게 된다.

 

 

[Figure 7.13 Translation program]



 

 /*** 소스 ***/


.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
INCLUDE io.h
cr  equ   0dh
Lf  equ   0ah

.STACK 4096

.DATA
string     BYTE   'This is a #!$& STRING'0
strLength  EQU  $ - string - 1
label1     BYTE   "Original string  ->"0
label2     BYTE   cr, Lf, "Translated string"0
crLf     BYTE   cr, Lf, 0
table     BYTE   48 DUP (' '), '0123456789'7 DUP (' ')
    BYTE   'abcdefghijklmnopqrstuvwxyz'6 DUP (' ')
    BYTE  'abcdefghijklmnopqrstuvwxyz'133 DUP (' ')

.CODE
_start:    output   label1
    output   string
    output   crlf
    mov   ecx, strLength
    lea  ebx, table
    lea  esi, string
    lea  edi, string

forIndex:  lodsb
    xlat
    stosb
    loop  forIndex
    
    output label2
    output string
    output crlf

    INVOKE ExitProcess, 0
PUBLIC _start

 

 

 

 

 

 

 

 

 

 

반응형
Posted by newind2000