n CPSR Current Program Status Register n IRQ

  • Slides: 21
Download presentation

n 프로그램 상태 레지스터(CPSR, Current Program Status Register) n IRQ 인터럽트 서비스 준비를 위한

n 프로그램 상태 레지스터(CPSR, Current Program Status Register) n IRQ 인터럽트 서비스 준비를 위한 유사 코드 01 02 03 04 05 06 R 14_irq = <다음 명령어 주소> + 4 SPSR_irq = CPSR[0: 5] = 0 b 010010 CPSR[6] = unchanged CPSR[7] = 1 PC = 0 x 18

n ICPR 레지스터와 IRQ 헤더 파일(<linux>/include/asm-arm/arch -pxa/irqs. h) #define #define #define #define IRQ_SSP 3

n ICPR 레지스터와 IRQ 헤더 파일(<linux>/include/asm-arm/arch -pxa/irqs. h) #define #define #define #define IRQ_SSP 3 PXA_IRQ(0) /* SSP 3 service request */ IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */ IRQ_USBH 2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI) */ IRQ_USBH 1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI) */ IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */ IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt */ IRQ_PWRI 2 C PXA_IRQ(6) /* Power I 2 C interrupt */ IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error(PXA 26 x) */ IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4 -11 matches (PXA 27 x) */ IRQ_GPIO 0 PXA_IRQ(8) /* GPIO 0 Edge Detect */ IRQ_GPIO 1 PXA_IRQ(9) /* GPIO 1 Edge Detect */ IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2 -x] Edge Detect */ IRQ_USB PXA_IRQ(11) /* USB Service */

인터럽트 처리 함수 n 인터럽트 등록과 해제 #include <linux/interrupt. h> int request_irq(unsigned int irq,

인터럽트 처리 함수 n 인터럽트 등록과 해제 #include <linux/interrupt. h> int request_irq(unsigned int irq, irqreturn_t (*handler)(int, pt_regs *), unsigned long flags, const char *device, void *dev_id); void free_irq(unsigned int irq, void *dev_id); n 인터럽트 대기 및 깨우기 #include <linux/sched. h> // 대기 상태로 만드는 함수 void interruptible_sleep_on(struct wait_queue **q); void sleep_on(struct wait_queue **q); // 대기 상태의 프로세스를 깨우는 함수 void wake_up_interruptible(struct wait_queue **q); void wake_up(struct wait_queue **q); void *, struct

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 001 …… 016 017 018 019

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 001 …… 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 …… 038 039 040 041 042 043 044 045 046 047 048 049 050 051 #include <linux/module. h> #define IRQ_KEY 1 IRQ_KEY 2 IRQ_KEY 3 IRQ_KEY 4 IRQ_GPIO(35) IRQ_GPIO(41) IRQ_GPIO(36) IRQ_GPIO(37) #define LED_PHYS 0 x 12400000 static void *mem_base; unsigned long mem_addr, mem_len; #define GPIO_MAJOR 241 #define GPIO_NAME "GPIO" #define GPIO_KEY_READ 0 x 1000 #define GPIO_LED 1_ON GPIO_LED 2_ON GPIO_LED 3_ON GPIO_LED 4_ON 0 x 2000 0 x 2100 0 x 2200 0 x 2300 char key_buf; char led_on=0 xff; DECLARE_WAIT_QUEUE_HEAD(key_queue); int gpio_open(struct inode *inode, struct file *filp) { printk("%sn", __func__); return 0; } int gpio_release(struct inode *inode, struct file *filp) { printk("%sn", __func__);

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 060 061 062 063 064 065

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 …… 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 ssize_t gpio_read (struct file *filp, char *buf, size_t count, loff_t *f_pos) { interruptible_sleep_on ( &key_queue); copy_to_user( buf, &key_buf, sizeof(key_buf)); return 0; } int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int data = 0; switch (cmd) { case GPIO_LED 1_ON: copy_from_user(&data, (void *)arg, sizeof(data)); if( data == 0) { led_on |= 0 x 01; (*((volatile unsigned char *)(mem_base))) = led_on; } else { led_on &= 0 xfe; (*((volatile unsigned char *)(mem_base))) = led_on; } break; case GPIO_LED 2_ON: } } return 0; static irqreturn_t key_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if(GPLR 1 & GPIO_bit(35)) key_buf = 1; if(GPLR 1 & GPIO_bit(41)) key_buf = 2; if(GPLR 1 & GPIO_bit(36)) key_buf = 3; if(GPLR 1 & GPIO_bit(37)) key_buf = 4; wake_up_interruptible(&key_queue); return IRQ_HANDLED;

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 128 129 130 131 132 133

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 …… 153 154 155 156 157 …… 166 …… 169 170 171 172 struct file_operations gpio_fops = {. owner = THIS_MODULE, . open = gpio_open, . read = gpio_read, . write = gpio_write, . ioctl = gpio_ioctl, . release = gpio_release, }; static int __init gpio_init(void) { int result, ret; result = register_chrdev(GPIO_MAJOR, GPIO_NAME, &gpio_fops); mem_addr = LED_PHYS; mem_len = 0 x 1000; mem_base = ioremap_nocache ( mem_addr, mem_len); if( !mem_base) { printk("Error mapping OHCI memeryn"); release_mem_region(mem_addr, mem_len); return -EBUSY; } (*((volatile unsigned char *)(mem_base))) = (0 x. FF); set_irq_type(IRQ_KEY 1, IRQT_RISING); set_irq_type(IRQ_KEY 4, IRQT_RISING); if ((ret = request_irq(IRQ_KEY 1, key_interrupt, SA_INTERRUPT, "GPIO 35_KEY 1", NULL))) { printk("failed to register IRQ KEY 1n"); return ret; } if ((ret = request_irq(IRQ_KEY 4, key_interrupt, SA_INTERRUPT, "GPIO 37_KEY 4", NULL))) { } key_buf = 0; printk("%s MAJOR %dn", GPIO_NAME, GPIO_MAJOR);

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 176 177 178 179 …… 184

실습 GPIO 디바이스 드라이버 및 테스트 프로그램 작성 176 177 178 179 …… 184 185 186 187 188 189 190 static void __exit gpio_exit(void) { disable_irq(IRQ_KEY 1); free_irq(IRQ_KEY 1, NULL); disable_irq(IRQ_KEY 4); free_irq(IRQ_KEY 4, NULL); unregister_chrdev(GPIO_MAJOR, GPIO_NAME); } MODULE_LICENSE("GPL"); module_init(gpio_init); module_exit(gpio_exit);

실습 GPIO 디바이스 드라이버 테스트 프로그램 작성 01 …… 06 07 08 09 10

실습 GPIO 디바이스 드라이버 테스트 프로그램 작성 01 …… 06 07 08 09 10 11 12 13 14 …… 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 …… 43 44 45 46 47 #include <stdio. h> #define #define GPIO_KEY_READ 0 x 1000 GPIO_LED 1_ON 0 x 2000 GPIO_LED 2_ON 0 x 2100 GPIO_LED 3_ON 0 x 2200 GPIO_LED 4_ON 0 x 2300 static char gpio_test. Dev[] = "/dev/GPIO"; static int gpio_test. Fd = -1; int ON = 1; int main() { char buf; if((gpio_test. Fd = open(gpio_test. Dev, O_RDWR )) < 0) { perror("open failed /dev/GPIO_TESTn"); exit(-1); } while(1) { read(gpio_test. Fd , &buf, sizeof(buf)); printf("KEY %x PUSH n", buf); ON ^= 0 x 0001; switch(buf) { case 1: ioctl(gpio_test. Fd , GPIO_LED 1_ON, &ON); break; case 2: } } return 0; default: break; }