이번 Part에서는 우리가 이번 프로젝트에서 사용할 디바이스 드라이버를 보다 자세히 들여다 볼 것이다.
이 파트를 마치고나면 모두들 우리가 가지고 있는 보드에 원하는 디바이스 드라이버를 짤 수 있으시길 바랍니다.
우선 이번 프로젝트에서 우리가 사용하게될 H/W와 디바이스 드라이버를 짝지어 보았다.
위의 내용을 보면 아주 간단함을 알 수 있을 것이다.
그렇다 별거 없다~ ㅋㅋ;
이제 슬슬 시작을 해 봅시다.
우선우리가 사용해야 할 핀의 주소값들은 메뉴얼과 Data Sheet에 잘 설명되어 있다.
(메뉴얼과 Data Sheet는 보드와 함께 동봉되서 온 CD에 들어있다. )
Data Sheet를 열어서 목차를 살펴보면 Chapter9. I/O PORTS 를 볼 수 있을것이다.
우리가 찾아보는 gpio(general purpose input/output))은 이름만 봐도 알겠듯이 I/O PORT이다.
Data Sheet를 읽어보면 gpio레지스터는 GPA0, GPG3 이런 식으로 GP다음에 A~J 까지 아파벳 으로 구분한후 번호를 부여했다.
메뉴얼에서는 우리가 사용하는 mini2440보드에서 사용자가 사용할수 있도록 빼놓은 GPIO 핀을 20페이지에 정리해 놓았다.
이렇게 우리는 Data Sheet와 Manual을 살펴서 우리가 원하는 핀의 주소를 알아보고 사용할 수 있다.
(보다 자세히 설명한 곳 :
이 파트를 마치고나면 모두들 우리가 가지고 있는 보드에 원하는 디바이스 드라이버를 짤 수 있으시길 바랍니다.
우선 이번 프로젝트에서 우리가 사용하게될 H/W와 디바이스 드라이버를 짝지어 보았다.
ir모듈 | rf모듈 | 3축 가속도 모듈 |
GPIO 드라이버 | SPI 드라이버 | ADC 드라이버 |
위의 내용을 보면 아주 간단함을 알 수 있을 것이다.
그렇다 별거 없다~ ㅋㅋ;
이제 슬슬 시작을 해 봅시다.
우선우리가 사용해야 할 핀의 주소값들은 메뉴얼과 Data Sheet에 잘 설명되어 있다.
(메뉴얼과 Data Sheet는 보드와 함께 동봉되서 온 CD에 들어있다. )
<file명 : DataSheets\S3C2440.pdf , Manual\ch1_hardware_manual_v1.pdf>
Data Sheet를 열어서 목차를 살펴보면 Chapter9. I/O PORTS 를 볼 수 있을것이다.
우리가 찾아보는 gpio(general purpose input/output))은 이름만 봐도 알겠듯이 I/O PORT이다.
Data Sheet를 읽어보면 gpio레지스터는 GPA0, GPG3 이런 식으로 GP다음에 A~J 까지 아파벳 으로 구분한후 번호를 부여했다.
메뉴얼에서는 우리가 사용하는 mini2440보드에서 사용자가 사용할수 있도록 빼놓은 GPIO 핀을 20페이지에 정리해 놓았다.
이렇게 우리는 Data Sheet와 Manual을 살펴서 우리가 원하는 핀의 주소를 알아보고 사용할 수 있다.
(보다 자세히 설명한 곳 :
이제 우리는 이 주소를 사용해서 우리가 원하는 GPIO핀에 LED를 달아서 그녀석이 깜빡이는 것을 확인함으로써 우리가 H/W와 레지스터에 대한 이해를 마무리 지어 보자.
우선 이 작업을 하기 위해서는 우리 kernel source를 알아야 한다.
지금 작업하는 kernel source는 보드 구입시 함께 동봉되어오는 CD에 있는 kernel 2.6.32.2 를 사용하고 있다.
우선 gpio-led는 character device 이다.
그러므로 이녀석이 있는 위치를 유추해서 찾아 볼수 있었다.
linux-2.6.32.2/drivers/char/mini2440-leds.c
이 파일이 바로 보드에 박혀있는 micro-led 4개를 깜빡거리게 하는 녀석이다.
이녀석을 열어보면 다음과 같다.
이 소스 코드에서 빨간색으로 칠해진 부분이 바로 바꾼 부분이다.
S3C2410_GPB(8) ==> S3C2410_GPF(0) 이렇게 바꿀 것이다.
이렇게 소스코드를 바꿔준 다음에 다시 Kernel Image를 만들기위해 make를 하고서 새로 생긴 zImage를 보드에 올려주면
원래 LED4개가 깜빡이는 것 중에 마지막 녀석 대신에 gpio핀에 달아주는 LED가 깜빡 거릴 것이다.
근데.. 어떤 핀에 LED를 달아주고 왜 하필 이렇게 소스코드를 바꿨는지 궁금할 것이다.
그것은 계속해서 설명하겠다...
이 녀석의 소스를 타고 들어가면..
linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h 파일에
다음과 같이 정의 되어 있다.
===========================================
S3C2410_GPB(8) 은 GPIO_B 의 8번째 핀을 얘기하고
S3C2410_GPF(0) 은 GPIO_F 의 0번째 핀을 얘기함을 알 수 있다.
S3C2410_GPB(8) ===> GPIO_B 의 8번째 핀 ===> GPB8
S3C2410_GPF(0) ===> GPIO_F 의 0번째 핀 ===> GPF0
이렇게 적고 보니 우리가 만진 레지스터 값이 어떤 녀석을 어떤 녀석으로 바꾼지 알 수 있을 것이다.
눈으로 확실히 보고 싶다면 Manual 에 ch1_hardware_manual_v1.pdf 파일을 열어서 GPB8 과 GPF0을 직접 찾아서 보면 될 것이다. ^^
우선 이 작업을 하기 위해서는 우리 kernel source를 알아야 한다.
지금 작업하는 kernel source는 보드 구입시 함께 동봉되어오는 CD에 있는 kernel 2.6.32.2 를 사용하고 있다.
우선 gpio-led는 character device 이다.
그러므로 이녀석이 있는 위치를 유추해서 찾아 볼수 있었다.
linux-2.6.32.2/drivers/char/mini2440-leds.c
이 파일이 바로 보드에 박혀있는 micro-led 4개를 깜빡거리게 하는 녀석이다.
이녀석을 열어보면 다음과 같다.
==============mini2440-leds.c================
===========================================
1 #include <linux/miscdevice.h>
2 #include <linux/delay.h>
3 #include <asm/irq.h>
4 #include <mach/regs-gpio.h>
5 #include <mach/hardware.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/mm.h>
10 #include <linux/fs.h>
11 #include <linux/types.h>
12 #include <linux/delay.h>
13 #include <linux/moduleparam.h>
14 #include <linux/slab.h>
15 #include <linux/errno.h>
16 #include <linux/ioctl.h>
17 #include <linux/cdev.h>
18 #include <linux/string.h>
19 #include <linux/list.h>
20 #include <linux/pci.h>
21 #include <linux/gpio.h>
22 #include <asm/uaccess.h>
23 #include <asm/atomic.h>
24 #include <asm/unistd.h>
25
26
27 #define DEVICE_NAME "leds"
28
29 static unsigned long led_table [] = {
30 S3C2410_GPB(5),
31 S3C2410_GPB(6),
32 S3C2410_GPB(7),
33 // S3C2410_GPB(8),
34 S3C2410_GPF(0),
35 };
36
37 static unsigned int led_cfg_table [] = {
38 S3C2410_GPIO_OUTPUT,
39 S3C2410_GPIO_OUTPUT,
40 S3C2410_GPIO_OUTPUT,
41 S3C2410_GPIO_OUTPUT,
42 };
43
44
45 static int sbc2440_leds_ioctl(
46 struct inode *inode,
47 struct file *file,
48 unsigned int cmd,
49 unsigned long arg)
50 {
51 switch(cmd) {
52 case 0:
53 case 1:
54 if (arg > 4) {
55 return -EINVAL;
56 }
57 s3c2410_gpio_setpin(led_table[arg], !cmd);
58 return 0;
59 default:
60 return -EINVAL;
61 }
62 }
63
64 static struct file_operations dev_fops = {
65 .owner = THIS_MODULE,
66 .ioctl = sbc2440_leds_ioctl,
67 };
68
69 static struct miscdevice misc = {
70 .minor = MISC_DYNAMIC_MINOR,
71 .name = DEVICE_NAME,
72 .fops = &dev_fops,
73 };
74
75 static int __init dev_init(void)
76 {
77 int ret;
78
79 int i;
80
81 for (i = 0; i < 4; i++) {
82 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
83 s3c2410_gpio_setpin(led_table[i], 0);
84 }
85
86 ret = misc_register(&misc);
87
88 printk (DEVICE_NAME"\tinitialized\n");
89
90 return ret;
91 }
92
93 static void __exit dev_exit(void)
94 {
95 misc_deregister(&misc);
96 }
97
98 module_init(dev_init);
99 module_exit(dev_exit);
100 MODULE_LICENSE("GPL");
101 MODULE_AUTHOR("FriendlyARM Inc.");
===========================================
===========================================
이 소스 코드에서 빨간색으로 칠해진 부분이 바로 바꾼 부분이다.
S3C2410_GPB(8) ==> S3C2410_GPF(0) 이렇게 바꿀 것이다.
이렇게 소스코드를 바꿔준 다음에 다시 Kernel Image를 만들기위해 make를 하고서 새로 생긴 zImage를 보드에 올려주면
원래 LED4개가 깜빡이는 것 중에 마지막 녀석 대신에 gpio핀에 달아주는 LED가 깜빡 거릴 것이다.
근데.. 어떤 핀에 LED를 달아주고 왜 하필 이렇게 소스코드를 바꿨는지 궁금할 것이다.
그것은 계속해서 설명하겠다...
이 녀석의 소스를 타고 들어가면..
linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h 파일에
다음과 같이 정의 되어 있다.
================gpio-nrs.h===================
===========================================
41
42 #define S3C2410_GPIO_NEXT(__gpio) \
43 ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0)
44
45 #ifndef __ASSEMBLY__
46
47 enum s3c_gpio_number {
48 S3C2410_GPIO_A_START = 0,
49 S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A),
50 S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B),
51 S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C),
52 S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D),
53 S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
54 S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
55 S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
56 };
57
58 #endif /* __ASSEMBLY__ */
59
60 /* S3C2410 GPIO number definitions. */
61
62 #define S3C2410_GPA(_nr) (S3C2410_GPIO_A_START + (_nr))
63 #define S3C2410_GPB(_nr) (S3C2410_GPIO_B_START + (_nr))
64 #define S3C2410_GPC(_nr) (S3C2410_GPIO_C_START + (_nr))
65 #define S3C2410_GPD(_nr) (S3C2410_GPIO_D_START + (_nr))
66 #define S3C2410_GPE(_nr) (S3C2410_GPIO_E_START + (_nr))
67 #define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
68 #define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
69 #define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
70
===========================================
S3C2410_GPB(8) 은 GPIO_B 의 8번째 핀을 얘기하고
S3C2410_GPF(0) 은 GPIO_F 의 0번째 핀을 얘기함을 알 수 있다.
S3C2410_GPB(8) ===> GPIO_B 의 8번째 핀 ===> GPB8
S3C2410_GPF(0) ===> GPIO_F 의 0번째 핀 ===> GPF0
이렇게 적고 보니 우리가 만진 레지스터 값이 어떤 녀석을 어떤 녀석으로 바꾼지 알 수 있을 것이다.
눈으로 확실히 보고 싶다면 Manual 에 ch1_hardware_manual_v1.pdf 파일을 열어서 GPB8 과 GPF0을 직접 찾아서 보면 될 것이다. ^^
'PROJECT > ex347_project' 카테고리의 다른 글
LDD_Part 3-2. SPI 디바이스 드라이버 (0) | 2011.05.23 |
---|---|
LDD_Part 3-1. GPIO 디바이스 드라이버 (0) | 2011.05.23 |
LDD_Part 2. 디바이스 드라이버 도우미 (0) | 2011.05.22 |
5/11 (0) | 2011.05.11 |
spi 보던 사이트 (0) | 2011.05.11 |