본문 바로가기

PROJECT/ex347_project

Mini2440_gpio-LED] 의 하나를 gpio 로 빼보자.

우선 이 작업을 하기 위해서는 우리 kernel source를 알아야 한다.

지금 우리가 건드리는 소스코드는 커널 소스안에 포한되어 있는 녀석이다.
커널안에 포함되어 있기때문에 우리가 이 소스코드를 건드린 다음에 반영시키기 위해서는..
다시 Kernel Image 를 Make하고 그 이미지 파일을 보드에 올려야 적용이 될 것이다.
(Make를 위해서는 cross compile환경을 구축해야 한다. arm-linux-gcc 버전은 4.4.3으로 한다.
http://kkangstory.tistory.com/entry/59
 이 링크로 따라가면 크로스컴파일 환경 구축 방법이 나와있다.)

 


이제 소스코드를 어떻게 바꿔 나갈 것인지 알아보도록하자. 


지금 작업하는 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번째 핀을 얘기함을 알 수 있다.

보다 더 정확히 이해하려면 H/W 관련 메뉴얼을 보면 이해가 쉽다.
그 안에서 GPB8 을 찾으면 아래와 같이 LED설명이 나와 있을 것이다.

딱 봐도 GPB5~8 을 gpio-leds 로 사용 함을 알수가 있다.

그리고 GPF0 을 찾으면 아래와 같이 GPIO설명이 나와 있을 것이다. 


우리가 사용한 GPF0 은 gpio 핀 중에서 9번 핀이다.


우리가 만든 소스로 led가 깜빡이는 것을 보고 싶다면
Ground 인 3번핀 GND와 9번 핀에 LED의 (-)극과 (+)극을 연결하면 깜빡이는 것을 확인 할 수 있을 것이다. 

http://kkangstory.tistory.com/entry/Mini2440GPIO-제어하기
Data sheet와 menual에 대해서 보다 자세한 내용은 위의 링크를 타고 가서 볼 수 있다...