본문 바로가기
Linux BSP

[Linux BSP] U-Boot 어셈블리어로 메모리 read/write로 led on/off 하기

by TYB 2024. 2. 7.
반응형

data sheet를 보면 gpio의 주소 및 입출력 주소가 모두 나옴.

 

아래 주소에서 라즈베리파이4를 찾아서 data sheet를 받으면 됨.

https://datasheets.raspberrypi.com/

 

Raspberry Pi Datasheets

 

datasheets.raspberrypi.com

 

 

매뉴얼 65페이지로 가면 전반적인 블록 다이어그램이 나와있다.

 

 

이번에는 인터럽트 방식 대신에 폴링 방식을 사용하겠다.

윗 사진에서 필요한 부분을 살펴보면 function select registers, pin direction regs, pin set&clear Regs

출력일때는 function select regiseters 선택해야되고 pin direction regs로 방향설정해야되고 pin set&clear Regs로 high를 내보낼 것인지 low를 내보낼 것인지 결정.

입력일 때는 polling 방식으로 level register로 입력 받아야함.

 

 

매뉴얼 67page를 보면 register의 주소가 나온다. 

0x7e20000은 가상 메모리 주소임. 실제 물리적 메모리 주소는 리눅스프로그래밍 라즈베리파이 책 807 페이지에 나와있다.

실제 물리적 메모리 주소는 라즈베리파이2,3은 0x3F000000 / 라즈베리파이 4는 0xFE000000이다.

detect 들어간건 전부 다 interrupt기능임.

gpio sel과 set의 갯수가 다른 이유는 해당 기능을 사용할 때 사용하는 비트수의 차이임.

 

 

 

 

들어가기 전에 용어 정리하면

GPFSEL( General Purpose Function Select register)

FSEL( Function Select)

 

여기 적혀있는 0x7e200000은 가상 메모리 주소임. 우리는 실제 메모리에 접근해야됨.

 

 

raspberry pi의 gpio의 갯수가 57개고 그 57개를 적은 메모리를 통해 선택 및 access 하기 위해선 mapping을 해주는게 필요함. 그래서 57개의 GSEL을 GPFSEL0~5까지의 값으로 나눠놓은거임.

 

 fsel 하나는 32bit 사용이 가능하고 그 내부에 gpio 하나당 3bit씩을 부여함.

그래서 fsel 하나에 gpio 10개가 들어가고

57까지 줘야되니까 FSEL이 5까지 있는거임.

 그 중 fsel0만 살펴보면

GPFSEL0 Register에 대한 data sheet 내용임.

FSEL0의

0,1,2bit를 gpio0

3,4,5bit를 gpio1

6,7,8bit를 gpio2

9,10,11bit를 gpio3

이런식으로 쓰는거고 그렇게 쭉쭉 29bit 까지 gpio 9까지 쓰는거임.

30,31bit는 점유만 하는거임.

그러면 FSEL0이 GPIO0~9까지 갖고 있는거고

FSEL1이 GPIO10~19까지 갖고 있는거고

쭉 가다가 

FSEL5을 보면

GPFSEL5

 

 

 

매뉴얼 77페이지에 가면 부가기능에 대한 설명이 나와있다.

 


 

 

 

 

help를 치면 memory display md가 나옴

 

U-Boot> md
md - memory display

Usage:
md [.b, .w, .l] address [# of objects]
byte word long




U-Boot> md.l 0xfe200000 8
fe200000: 00000000 00012000 12000000 3ffff000  ..... .........?
fe200010: 00000064 00000000 00000000 6770696f  d...........oipg

 

 

이제 실제로 gpio를 제어해보겠음.

U-Boot> mw.l 0xfe200000 0x00040000
U-Boot> md.l 0xfe200000 4
0fe20000: 00040000 ffffffff ffffffff ffffffff  ................

gpio6을 001로 하려면 (여기가 31번지)00 000 000 000 001 000 000 000 000 000 000(여기가 0번지)을 해주면 오른쪽 3개의 bit부터 0으로 시작해서 6번째 3개의 bit가 001로  되어있는게 보일거임.

output mode로 설정은 했고

 

sel까지 됬으면 이제 set을 해줘야됨.

0x40을 써주게 되면

 

 

U-Boot> mw.l 0xfe20001c 0x00000040

 

끄려면 clear 해야됨. clear 하는 GPCLR0 register의 memory 주소는 0xfe200000에서 preset 0x28을 더한 값임. 거기에 0x00000040을 써주겠다고 하는거임.

켰으면 다시 꺼야되니까

 

 

U-Boot> mw.l 0xfe200028 0x00000040

 

 

 

 


 

 

하나는 해봤으니까 여러개를 계산해서 한번에 켜보자.

6~13까지는 led니까 output으로 줘야되는거고

16~23까지는 button이니까 input으로 줘야되는거고

 

 

GPIO 14, 15에 UART1 TX,RX를 사용중이니까 ALT Func 5을 써줘야되는거임.

 

 

010을 줘야겠죠? 이거 안주면 putty serial 연결 됬던거 나가뤼 됩니다잉~

 

 

 

6~13까지 output mode로 설정

U-Boot> mw.l 0xfe200000 0x09240000
U-Boot> mw.l 0xfe200004 0x00012249

6~13까지 gpio 1(high)로 설정

U-Boot> mw.l 0xfe20001c 0x00003fc0

6~13까지 다시 0(low)으로 설정

U-Boot> mw.l 0xfe200028 0x00003fc0



 

 

 

 

 

반응형