Linux内核版本号:linux 2.6.39
交叉编译工具:arm-linux-gcc 4.5.1
Linux内核下载:www.kernel.org
开发板:友善之臂Tiny6410
LCD:友善之臂S70
一、移植LED驱动
打开arch/arm/mach-s3c64xx/mach-mini6410.c添加下列代码:
1 static struct gpio_led tiny6410_gpio_led[] = { 2 [0] = { 3 .name = "led1", //设备名 4 .gpio = S3C64XX_GPK(4), //GPK4 5 .active_low = 1, //低电平点亮 6 .default_state = LEDS_GPIO_DEFSTATE_ON, //系统启动后默认为打开 7 }, 8 [1] = { 9 .name = "led2", 10 .gpio = S3C64XX_GPK(5), 11 .active_low = 1, 12 .default_state = LEDS_GPIO_DEFSTATE_OFF, //系统启动后默认关闭 13 }, 14 [2] = { 15 .name = "led3", 16 .gpio = S3C64XX_GPK(6), 17 .active_low = 1, 18 .default_state = LEDS_GPIO_DEFSTATE_ON, 19 }, 20 [3] = { 21 .name = "led4", 22 .gpio = S3C64XX_GPK(7), 23 .active_low = 1, 24 .default_state = LEDS_GPIO_DEFSTATE_OFF, 25 }, 26 }; 27 28 static struct gpio_led_platform_data tiny6410_leds_data = { 29 .num_leds = ARRAY_SIZE(tiny6410_gpio_led), 30 .leds = &tiny6410_gpio_led, 31 }; 32 33 static struct platform_device tiny6410_device_leds = { 34 .name = "leds-gpio", 35 .id = -1, 36 .dev = { 37 .platform_data = &tiny6410_leds_data, 38 }, 39 };
在mini6410_devices中添加tiny6410_device_leds,系统启动时将自动注册LED平台设备:
1 static struct platform_device *mini6410_devices[] __initdata = { 2 ... 3 &tiny6410_device_leds, 4 };
执行make menuconfig修改内核配置,添加对LED设备的支持:
Device Drivers --->
│ │ [*] LED Support --->
│ │ [*] LED Class Support
│ │ *** LED drivers ***
│ │ <*> LED Support for GPIO connected LEDs
│ │ [*] Platform device bindings for GPIO LEDs
编译并烧写内核,启动开发板可以看到第一、第三个LED被点亮。
编写应用程序控制LED:
系统LED设备名为每个LED设备创建了一个节点文件夹,位于/sys/devices/platform/leds-gpio/leds/目录下,对设备文件夹里面的brightness 文件写0或写非0即可对LED进行操作。
1 #include <stdio.h> 2 #include <sys/stat.h> 3 #include <sys/types.h> 4 #include <fcntl.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 9 int main(int argc,char** argv) 10 { 11 int fd = 0; 12 char path[64] = "/sys/devices/platform/leds-gpio/leds/"; 13 14 if(argc != 3) 15 { 16 printf("format error! "); 17 return -1; 18 } 19 20 strcat(path,argv[1]); 21 strcat(path,"/brightness"); 22 23 printf("%s ",path); 24 fd = open(path,O_RDWR); 25 if(fd == -1) 26 { 27 printf("open file failure! "); 28 return -1; 29 } 30 if(atoi(argv[2])) 31 write(fd,"1",1); 32 else 33 write(fd,"0",1); 34 35 close(fd); 36 return 0; 37 }
二、按键驱动移植
在arch/arm/mach-s3c64xx/mach-mini6410.c添加下列代码:
1 static struct gpio_keys_button tiny6410_gpio_keys[] = { 2 [0] = { 3 .code = KEY_F1, //键值 4 .type = EV_KEY, //按键输入类型 5 .gpio = S3C64XX_GPN(0), 6 .active_low = 1, //低电平表示按下 7 .wakeup = 0, 8 .debounce_interval = 5, /* ms */ //延时消抖 9 .desc = "Button 1", 10 }, 11 [1] = { 12 .code = KEY_F2, 13 .type = EV_KEY, 14 .gpio = S3C64XX_GPN(1), 15 .active_low = 1, 16 .wakeup = 0, 17 .debounce_interval = 5, /* ms */ 18 .desc = "Button 2", 19 }, 20 [2] = { 21 .code = KEY_F3, 22 .type = EV_KEY, 23 .gpio = S3C64XX_GPN(2), 24 .active_low = 1, 25 .wakeup = 0, 26 .debounce_interval = 5, /* ms */ 27 .desc = "Button 3", 28 }, 29 [3] = { 30 .code = KEY_F4, 31 .type = EV_KEY, 32 .gpio = S3C64XX_GPN(3), 33 .active_low = 1, 34 .wakeup = 0, 35 .debounce_interval = 5, /* ms */ 36 .desc = "Button 4", 37 }, 38 39 }; 40 41 static struct gpio_keys_platform_data tiny6410_key_data = { 42 .buttons = &tiny6410_gpio_keys, 43 .nbuttons = ARRAY_SIZE(tiny6410_gpio_keys), 44 }; 45 46 static struct platform_device tiny6410_device_keys = { 47 .name = "gpio-keys", 48 .id = -1, 49 .dev = { 50 .platform_data = &tiny6410_key_data, 51 }, 52 };
在mini6410_devices中添加tiny6410_device_keys:
1 static struct platform_device *mini6410_devices[] __initdata = { 2 .... 3 &tiny6410_device_leds, 4 &tiny6410_device_keys, 5 };
执行make menuconfig修改内核配置,添加对LED设备的支持:
Device Drivers --->
│ │ Input device support --->
│ │ [*] Keyboards --->
│ │ <*> GPIO Buttons
同时在Input device support里面添加event interface的支持,在/dev/下面就能生成一个event设备文件:
Device Drivers --->
│ │ Input device support --->
│ │ <*> Event interface
编译并烧写内核,启动开发板可以在/dev/目录下生成了event0设备文件,对按键驱动进行简单的测试:
执行hexdump /dev/event0
每次按下按键可以看到如下所示按键信息,表明按键是工作正常的。
1 /dev # hexdump event0 2 0000000 034d 0000 0e3b 000c 0001 003b 0001 0000 3 0000010 034d 0000 0e4c 000c 0000 0000 0000 0000 4 0000020 034d 0000 cd5f 000e 0001 003b 0000 0000 5 0000030 034d 0000 cd6b 000e 0000 0000 0000 0000
编写应用程序测试按键驱动:
按键驱动为输入子系统,应用程序中需要对event进行循环检测看系统有没有上报输入事件,按键的输入事件类型为EV_KEY,键值分别问KEY_F1、KEY_F2、KEY_F3、KEY_F4,数值为1表示按键按下为0表示按键释放。
1 #include <stdio.h> 2 #include <sys/stat.h> 3 #include <sys/types.h> 4 #include <fcntl.h> 5 #include <stdlib.h> 6 #include <linux/input.h> 7 8 int main(void) 9 { 10 int fd = 0; 11 struct input_event event_key; 12 int count = 0; 13 14 fd = open("/dev/event0",O_RDONLY); 15 if(fd == -1) 16 { 17 printf("open file failed "); 18 return -1; 19 } 20 21 while(1) 22 { 23 count = read(fd,&event_key,sizeof(struct input_event)); 24 if(count < 0) 25 { 26 printf("read failed "); 27 break; 28 } 29 if(event_key.type == EV_KEY) 30 { 31 switch(event_key.code) 32 { 33 case KEY_F1: 34 { 35 if(event_key.value == 1) 36 printf("key1 pressed "); 37 else if(event_key.value == 0) 38 printf("key1 released "); 39 } 40 break; 41 case KEY_F2: 42 { 43 if(event_key.value == 1) 44 printf("key2 pressed "); 45 else if(event_key.value == 0) 46 printf("key2 released "); 47 } 48 break; 49 case KEY_F3: 50 { 51 if(event_key.value == 1) 52 printf("key3 pressed "); 53 else if(event_key.value == 0) 54 printf("key3 released "); 55 } 56 break; 57 case KEY_F4: 58 { 59 if(event_key.value == 1) 60 printf("key4 pressed "); 61 else if(event_key.value == 0) 62 printf("key4 released "); 63 } 64 break; 65 } 66 } 67 68 } 69 70 close(fd); 71 return 0; 72 }
三、LCD显示屏移植
在arch/arm/mach-s3c64xx/mach-mini6410.c修改显示代码:
1 static struct s3c_fb_pd_win mini6410_fb_win[] = { 2 { 3 .win_mode = { /* 7.0" 800x480 */ 4 .left_margin = 0x2c,//26, 5 .right_margin = 0xd2,//210, 6 .upper_margin = 0x15,//13, 7 .lower_margin = 0x16,//22, 8 .hsync_len = 0x02,//20, 9 .vsync_len = 0x02,//10, 10 .xres = 800, 11 .yres = 480, 12 }, 13 .max_bpp = 32, 14 .default_bpp = 16, 15 }, 16 };
参数的值根据LCD显示屏规格书确定,具体参数解释及计算见博客http://blog.csdn.net/longxiaowu/article/details/24319933
执行make menuconfig修改内核配置,添加对LCD设备的支持:
Device Drivers --->
│ │ Input device support --->
│ │ Graphics support --->
│ │ <*> Support for frame buffer devices --->
│ │ <*> Samsung S3C framebuffer support
│ │ [*] Bootup logo ---> //开机显示小企鹅
│ │ --- Bootup logo │ │
│ │ [ ] Standard black and white Linux logo
│ │ [ ] Standard 16-color Linux logo
│ │ [*] Standard 224-color Linux logo
编译烧写内核并开机,屏幕上并没有看到小企鹅。加载Tiny6410一线触摸设备驱动之后小企鹅出来了,应该是Tiny6410 S70屏幕的背光是在一线触摸中进行打开的,由于一线触摸的协议并不开源所以没有进行深究。
四、触摸屏校验程序tslib移植