21
KEY 디디디디 디디디디 Lecture #12

KEY 디바이스 드라이버

  • Upload
    gada

  • View
    117

  • Download
    2

Embed Size (px)

DESCRIPTION

KEY 디바이스 드라이버. Lecture #12. 차례. GPIO 및 Control Registers KEY 하드웨어 구성 KEY Driver 프로그램 key-driver.c 시험 응용 프로그램 key-app.c. GPIO(General-Purpose I/O). PXA255 processor 는 81 개의 GPIO pin 이 있음 GPIO 는 27 개의 제어 register 에 의하여 제어된다 set pin direction (GPDR0~2) read pin level (GPLR0~2) - PowerPoint PPT Presentation

Citation preview

Page 1: KEY  디바이스 드라이버

KEY 디바이스 드라이버Lecture #12

Page 2: KEY  디바이스 드라이버

2

차례 GPIO 및 Control Registers

KEY 하드웨어 구성

KEY Driver 프로그램 key-driver.c

시험 응용 프로그램 key-app.c

Page 3: KEY  디바이스 드라이버

3

GPIO(General-Purpose I/O) PXA255 processor 는 81 개의 GPIO pin 이 있음 GPIO 는 27 개의 제어 register 에 의하여 제어된다

set pin direction (GPDR0~2) read pin level (GPLR0~2) set or clear pin level (GPSR0~2, GPCR0~2) set rising/falling edge detection (GRER0~2, GFER0~2) edge detection (GEDR0~2) alternate function (GAFR_L0~2, GAFR_U0~2)

사용하지 않는 GPIO 는 output 으로 configure 하면 전력 소비를 줄인다

Page 4: KEY  디바이스 드라이버

4

GPIO Control Registers (1) Pin Direction (GPDR) - 3 개

해당 GPIO 핀을 input 혹은 output 으로 사용할 것인지 설정함 0 이면 input 이고 1 이면 output 으로 설정됨

Pin Level (GPLR) - 3 개 해당 GPIO 핀의 현재 level 을 표시함 0 이면 low 이고 1 이면 high 임

Set or Clear (GPSR, GPCR) - 각각 3 개 해당 output GPIO 핀의 level 을 high 로 설정함 . 1 이면 high 해당 output GPIO 핀의 level 을 low 로 설정함 . 1 이면 low

Page 5: KEY  디바이스 드라이버

5

GPIO Control Registers (2) Rising or Falling Edge (GRER, GFER) - 각각 3 개

해당 GPIO 핀의 동작을 지정함 . 1 이면 rising edge 시 동작됨 해당 GPIO 핀의 동작을 지정함 . 1 이면 falling edge 시 동작됨

Edge Detection (GEDR) - 3 개 해당 GPIO 핀의 동작을 감지함 1 이면 rising/falling edge 의 동작이 감지되었음을 표시 해당 bit 를 clear 하려면 그 bit 에 1 을 씀

Page 6: KEY  디바이스 드라이버

6

GPIO Control Registers - 3/3 Alternate Functions (GAFR_L, GAFR_U) - 6 개

해당 GPIO 핀을 generic GPIO 핀으로 쓸 것인지 특정 기능을 위한 핀으로 쓸 것인지 설정함 . 00 - GPIO 설정 01 - 특정 기능 1 10 - 특정 기능 2 11 - 특정 기능 3

Page 7: KEY  디바이스 드라이버

7

Key Switch - 하드웨어 구조

0

3

1

2

4

7

5

6

8

b

9

a

Page 8: KEY  디바이스 드라이버

8

Key Encoder – 하드웨어 구조74C922 chip (Key Encoder)1. Key Switch

에 연결

1. Key Switch에 연결

1. Key Switch에 연결

2. Key 가 눌러지면 인터럽트

생성

2. 데이타생성 (4bits)

3. 인터럽트는 GPIO 0 에 연결

Page 9: KEY  디바이스 드라이버

9

Bidirectional Transceiver - 하드웨어 구조

4. 데이터 버스로들어감

3. Key Encoder 에서 생성된 데이타

Page 10: KEY  디바이스 드라이버

10

74C922 및 74LVT245

74C922 - Key Encoder KEY_ROW 1~3 과 KEY_COL 1~4 이 Key Switch(3x4) 에 연결 Encoding 된 값은 KEY_1~4 라인으로 출력 KEY_AVAL 라인은 PXA255 GPIO 0 와 연결 (interrupt 생성 )

74LVT245 - Bidirectional Transceiver KEY_1~4 라인이 입력 DATA00~03 라인이 출력 출력 데이터는 데이터 버스를 통하여 물리 주소 0x14000000 로

전달

Page 11: KEY  디바이스 드라이버

11

커널 Configure/Compile 현재 커널 이미지에는 key driver 가 포함되어 있기 때문에 key

driver 프로그래밍을 실습하기 위해서는 커널의 "Character devices" 에 포함된 "KEY GPIO" 기능을 disable 하고 다시 컴파일 하여야 한다

Page 12: KEY  디바이스 드라이버

12

Driver start Application start

module_init()

key_open()

Key_read() read()

open()

Interruptible_sleep_on()

key_handler()

wakeup_interruptible()

key_read() 함수 call

waiting key interrupt

waiting read() blocking

read() waking

Key Device Driver - 동작방식

key_open() 함수 call

Page 13: KEY  디바이스 드라이버

13

set_GPIO_IRQ_edge() GPDR 을 통하여 GPIO 방향 설정 GAFR 을 통하여 alternate function 설정 함수로 GPIO detect 방향 설정 request_irq() 함수로 interrupt 등록 key_handler() 함수로 인터럽트 핸들러 구현 ioremap(), iounmap() 을 이용하여 물리주소로 access

Key Device Driver – 커널 함수

Page 14: KEY  디바이스 드라이버

14

#include <linux/module.h> // 모듈에 관한 정의 ex)MOD_INC_USE_COUNT

#include <linux/init.h> // init_module() 과 cleanup_module()#include <linux/delay.h> // udelay()#include <asm/uaccess.h> // copy_to_user()#include <asm/io.h> // GPIO controller 에 관한 정의#include <asm/irq.h> // interrupt 에 관한 정의

key-driver.c: Header files

Page 15: KEY  디바이스 드라이버

15

key-driver.c: 매크로 / 전역 변수

#define DEVICE_NAME "key"#define KEY_MAJOR 242

#define KEY_ADDRESS 0x14000000

static DECLARE_WAIT_QUEUE_HEAD(wq);

static char *key_address;static char key_value;

Page 16: KEY  디바이스 드라이버

16

/* Prototypes */int init_module (void );void cleanup_module(void);int key_open(struct inode *, struct file *);int key_release(struct inode *, struct file *);ssize_t key_read (struct file *inode, char *gdata, size_t length, loff_t *off_

what); void key_handler(int irq, void *dev_id, struct pt_regs *regs);

static struct file_operations key_fops = { open: key_open, read: key_read, release: key_release,};

key-driver.c: 함수 prototype 선언

Page 17: KEY  디바이스 드라이버

17

key-driver.c : init/cleanupint init_module(void){ int i; if((i=register_chrdev(KEY_MAJOR,DEVICE_NAME,&key_fops))<0) return i; GPDR0 &=~(GPIO_0); // GPIO 0 은 input GAFR0_L &=~(0x3); // alternate function 을 generic GPIO 로

// GPIO 0 을 falling edge set_GPIO_IRQ_edge(0,GPIO_FALLING_EDGE);

if((i=request_irq(IRQ_GPIO(0),key_handler,SA_INTERRUPT,"key",NULL))<0) return i; return 0;}

void cleanup_module(void){ unregister_chrdev(KEY_MAJOR,DEVICE_NAME);}

Page 18: KEY  디바이스 드라이버

18

key-driver.c: open/releaseint key_open(struct inode *inode, struct file *file){ MOD_INC_USE_COUNT; return 0;}

int key_release(struct inode *inode, struct file *file){ MOD_DEC_USE_COUNT; return 0;}

Page 19: KEY  디바이스 드라이버

19

key-driver.c : read interruptssize_t key_read(struct file *inode, char *gdata, size_t length, loff_t *off_w

hat) { interruptible_sleep_on(&wq); copy_to_user(gdata,&key_value,1); return 1;}

void key_handler(int irq, void *dev_id, struct pt_regs *regs) { key_address=(char*)ioremap(KEY_ADDRESS,0x10); key_value=*(key_address)&0x0f; iounmap(key_address); wake_up_interruptible(&wq); }

Page 20: KEY  디바이스 드라이버

20

시험 응용 프로그램 (key-app.c)#include <stdio.h>#include <fcntl.h>

int main(void){ int fd; char c; if((fd=open("/dev/key",O_RDONLY))<0){ fprintf(stderr,"can not open /dev/key\n"); return 1; } while(1){ read(fd,&c,1); printf("c=0x%x\n",c); if(c==0x00) break; } close(fd); return 0;}

Page 21: KEY  디바이스 드라이버

21

Makefileall: key-driver.o key-app

key-driver.o: key-driver.carm-linux-gcc –O2 –Wall -D__KERNEL__ -DMODULE \-I/root/pxa255pro/linux-2.4.19/include \-c key-driver.c -o key-driver.o

key-app: key-app.carm-linux-gcc key-app.c -o key-app

clean:rm -f key-driver.o key-app