首先分析原来:
1.查看用户手册
led1、led2、led3、led4 连接的分别是 GPK4、GPK5、GPK6、GPK7
2、查询6410芯片手册
下面还需要3个步骤:
1、设置GPIO为OUTPUT。
将GPK4、GPK5、GPK6、GPK7设置为输出output=0001
即GPKCON0的19:28都配置为0001
2、设置GPIO的数据。
将GPKDATA的4:7位赋值为0
3、设置GPKUP为上拉。
将GPKUP的4:7位设置为10
3、代码
led_driver.c
#include #include #include #include #include #include #include #include #define LED_MAJOR 243 #define LED_ON 1 #define LED_OFF 0 #define LED_1_ON 2 #define LED_1_OFF 3 #define LED_2_ON 4 #define LED_2_OFF 5 #define LED_3_ON 6 #define LED_3_OFF 7 #define LED_4_ON 8 #define LED_4_OFF 9 static int led_open (struct inode *inode,struct file *filp) { unsigned tmp; tmp = readl(S3C64XX_GPKCON); tmp = (tmp&0x0000ffff)| 0x1111ffff; writel(tmp, S3C64XX_GPKCON); printk("#########open######n"); return 0; } static int led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos) { return count; } static int led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos) { char wbuf[10]; unsigned tmp; if(copy_from_user(wbuf,buf,count)) return -EFAULT; switch(wbuf[0]) { case LED_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0x0f); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_1_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0xef); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_1_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_2_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0xdf); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_2_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_3_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0xbf); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_3_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; case LED_4_ON: tmp = readl(S3C64XX_GPKDAT); tmp &= (0x7f); writel(tmp, S3C64XX_GPKDAT); printk("turn off!n"); break; case LED_4_OFF: tmp = readl(S3C64XX_GPKDAT); tmp |= (0xf0); writel(tmp, S3C64XX_GPKDAT); printk("turn on!n"); break; default : break; } return 0; } int led_release (struct inode *inode, struct file *filp) { printk("#########release######n"); return 0; } struct file_operations led_fops = { .owner = THIS_MODULE, .open = led_open, .read = led_read, .write = led_write, .release = led_release, }; int __init led_init (void) { int rc; printk ("Test led devn"); rc = register_chrdev(LED_MAJOR,"led",&led_fops); if (rc <0) { printk ("register %s char dev errorn","led"); return -1; } printk ("ok!n"); return 0; } void __exit led_exit (void) { unregister_chrdev(LED_MAJOR,"led"); printk ("module exitn"); return ; } module_init(led_init); module_exit(led_exit); Makefile obj-m := led_driver.o KDIR :=/home/workdir/kernel/linux-2.6.38 all: make -C $(KDIR) M=$(shell pwd) modules install: cp driver_led.ko /tftpboot/ clean: make -C $(KDIR) M=$(shell pwd) clean 测试文件 test_led.c #include #include #include #include #define LED_OFF 0 #define LED_ON 1 #define LED_1_ON 2 #define LED_1_OFF 3 #define LED_2_ON 4 #define LED_2_OFF 5 #define LED_3_ON 6 #define LED_3_OFF 7 #define LED_4_ON 8 #define LED_4_OFF 9 int main (void) { int i=0; int fd; char buf[10]={ LED_ON , LED_OFF , LED_1_ON, LED_1_OFF, LED_2_ON, LED_2_OFF, LED_3_ON, LED_3_OFF, LED_4_ON, LED_4_OFF, }; fd = open("/dev/led",O_RDWR); if (fd < 0) { printf ("Open /dev/led file errorn"); return -1; } while(i<10) { write(fd,&buf[i],4); sleep(1); i++; } close (fd); return 0; } 上述编译没有问题,就可以下到板子测试了。 加载驱动 insmod led_driver.ko 创建设备文件 mknod /dev/led c 243 0 其中243要跟驱动文件中的设备号一致 运行测试文件 ./test_led 完成。 ------------------------------------------------------------------------------------------ 参考资料: #include #include #include #include #include #include #include #include #include #define DEVICE_NAME "leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */ #define LED_MAJOR 231 /* 主设备号 */ /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */ #define IOCTL_LED_ON 1 #define IOCTL_LED_OFF 0 /* 用来指定LED所用的GPIO引脚 */ static unsigned long led_table [] = { S3C2410_GPB5, S3C2410_GPB6, S3C2410_GPB7, S3C2410_GPB8, }; /* 用来指定GPIO引脚的功能:输出 */ static unsigned int led_cfg_table [] = { S3C2410_GPB5_OUTP, S3C2410_GPB6_OUTP, S3C2410_GPB7_OUTP, S3C2410_GPB8_OUTP, }; struct leds_type { struct cdev cdev; }; struct leds_type *my_leds_dev; /* 应用程序对设备文件/dev/EmbedSky-leds执行open(...)时, * 就会调用EmbedSky_leds_open函数 */ static int EmbedSky_leds_open(struct inode *inode, struct file *file) { int i; for (i = 0; i < 4; i++) { // 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); } return 0; } /* 应用程序对设备文件/dev/EmbedSky-leds执行ioclt(...)时, * 就会调用EmbedSky_leds_ioctl函数 */ static int EmbedSky_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { if (arg > 4) { return -EINVAL; } switch(cmd) { case IOCTL_LED_ON: // 设置指定引脚的输出电平为0 s3c2410_gpio_setpin(led_table[arg], 0); return 0; case IOCTL_LED_OFF: // 设置指定引脚的输出电平为1 s3c2410_gpio_setpin(led_table[arg], 1); return 0; default: return -EINVAL; } } /* 这个结构是字符设备驱动程序的核心 * 当应用程序操作设备文件时所调用的open、read、write等函数, * 最终会调用这个结构中指定的对应函数 */ static struct file_operations EmbedSky_leds_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = EmbedSky_leds_open, .ioctl = EmbedSky_leds_ioctl, }; static char __initdata banner[] = "TQ2440/SKY2440 LEDS, (c) 2008,2009 www.embedsky.net/n";
上一篇:Linux内核模块驱动之---led驱动
下一篇:tiny4412内核自带led驱动分析
推荐阅读最新更新时间:2024-11-21 11:21
设计资源 培训 开发板 精华推荐
- MIC4576-5.0BT、8V-24V转5V/3A降压转换器通孔典型应用电路
- 基于NE555与CD4017的数字流水灯设计
- LT1776CS8 演示板、高电压、高效率、降压型开关稳压器、7V 至 60Vin、3.3V 和 5V @ 0.5A 输出
- 用于便携式的 5V DC 到 DC 单输出电源
- LM2904EDR2G 运算放大器函数发生器的典型应用
- RXCA10X115BF40-IDK00A,基于 Altera FPGA Arria 10 GX 的 ATTILA 即时开发套件 (ATTILA Instant Devkit -ES2)
- 1.5A 轨到轨输出同步降压稳压器通过单个电阻器进行调节
- 重制版IP5389[100瓦双向快充移动电源]
- TCR2EN25、200mA、2.5V 输出电压 CMOS 低压降稳压器的典型应用
- LDK120PU30R 3V低压降稳压器典型应用固定电路
- TI CC1310网络研讨会诚邀您预报名参加,惊喜奖不停!
- 你晒单我送礼,晒TI样片订单即可赢好礼!
- 直播已结束【使用 TI 低成本 MSPM0 MCU 快速开发 – 生态详解系列之二】(9:45开始入场)
- 安森美半导体移动与可穿戴设备解决方案下载有礼!
- 泰克直播:你真的了解示波器吗?
- 家电新风尚,PI开启您的家电新生活!下载产品资料答题赢好礼!
- TI 嵌入式处理主题直播月|报名观看直播赢好礼【低功耗WiFi MCU、Sitara AM57X平台、机器学习】
- 【ST板卡来了(下)】 品读STM32实战经验,汲取FAE经验闯关去抽奖
- 答题赢京东卡|《安森美和安富利物联网创新设计大赛作品集》
- 免费测评|涂鸦三明治Wi-Fi&BLE 开发板