收藏 分享(赏)

基于linux的led驱动程序实现.doc

上传人:精品资料 文档编号:10738221 上传时间:2020-01-03 格式:DOC 页数:7 大小:247KB
下载 相关 举报
基于linux的led驱动程序实现.doc_第1页
第1页 / 共7页
基于linux的led驱动程序实现.doc_第2页
第2页 / 共7页
基于linux的led驱动程序实现.doc_第3页
第3页 / 共7页
基于linux的led驱动程序实现.doc_第4页
第4页 / 共7页
基于linux的led驱动程序实现.doc_第5页
第5页 / 共7页
点击查看更多>>
资源描述

1、基于 linux 的 led 驱动程序实现一. 博创开发平台硬件 LED 的实现博创开发平台设置了 3 个 GPIO 控制的 LED 和一个可直接产生外部硬件中断的按键,LED 分别使用了 S3C2410 的 GPC5,GPC6 ,GPC7 三个 GPIO,按键接到 INT5 中断。下面对 S3C2410 GPIO 的各个寄存器作出说明,用 GPIO 控制的 LED 就是通过操作 GPIO 的各个寄存器进行配置和操作的。S3C2410 包含GPA 、GPB 、GPH 八个 I/O 端口。它们的寄存器是相似的:GPxCON用于设置端口功能(00 表示输入、01 表示输出、10 表示特殊功能、11

2、 保留不用),GPxDAT 用于读/写数据,GPxUP 用于决定是否使用内部上拉电阻 (某位为 0 时,相应引脚无内部上拉;为 1 时,相应引脚使用内部上拉 )。这里要稍微注意一点的地方是 PORTA 和其他几组端口的使用不太一样,这里不讨论 A 口,B 到 H 组口的使用完全相同。以下是 S3C2410 手册上的数据 13:图 1.1 S3C2410 端口GPC 口有 16 个 IO 口,查 datasheetS3C2410所用的地址为:图 1.2 C 组 GPIO 的地址即 GPCCON 地址为 0x56000020, GPCDAT 地址为 0x56000024,各位的设置具体见下图,则对

3、应的 GPCCON 寄存器的位为:图 1.3 GPCCON 寄存器相应的位这里用到了 5,6,7 三个口,CON 寄存器要完成对对应口的设置工作,将相应的口设置为输出状态,其他的口不用考虑,设置为输出的话就是 0x15i_rdev);printk(NAME“open success!n“);return 0;static int led_close(struct inode *inode,struct file *filp)printk(NAME“release!n“);return 0;static int led_ioctl(struct inode *inode,struct file

4、*filp,unsigned int cmd,unsigned long arg)switch(cmd)case 0:if(arg3)return -EINVAL;GPC_DAT=LED1_OFF|LED2_OFF|LED3_OFF;break;case 1:if(arg3)return -EINVAL;GPC_DAT=LED1_ONbreak;default:return -EINVAL;return 0;以上函数的接口集合在 file_operations 结构中,实现了系统提供给用户程序的接口。Open 函数在 file_operations 结构中的原型为 int (* open)(s

5、truct inode *,struct file *);这是设备的第一个操作,但是并不是要求驱动程序必须去实现这个方法,如果这个入口为 NULL,那么设备的打开操作将永远成功,一般驱动程序中open 要完成的工作有:增加使用计数;检查设备特定的错误;如果设备是首次打开,则对其进行初始化;识别次设备号,并且如果必要,更新 f_op 指针;分配并填写被置于 filp-private_data 里的数据结构。我的理解是, open 函数就是要完成设备驱动和文件系统的关联,上面已经讲过 file 和 inode 两个结构的关系,这里参数中的两个结构正是系统在/dev 创建设备节点后提供给驱动的文件结

6、构。本驱动中的 open 实现只是完成了对 C 组 GPIO 的 GPC_CON 寄存器进行初始化,将 3 个 LED 对应的 3 个口设置为输出模式,定义格式如下:GPC_CON=GPC5_OUT|GPC6_OUT|GPC7_OUT;其中 GPCX_OUT 的定义为:#define GPC5_OUT (1private_data 中的所有内容;在最后一次关闭操作时关闭设备;使用计数器减 1。这里和上面的 open 函数都提到了一个模块计数,意思就是内核要统计这个模块被打开的次数,这样才不会在还有使用的情况下卸载模块,在早期的 linux 版本中,模块计数的工作要由驱动程序自己完成,用到类似于

7、MOD_INC_USE_COUNT 的宏来实现,现在的内核版本是内核自动维护这个计数,不用在驱动中实现,所以本驱动中的 release 函数并没有实现具体的操作。Ioctl 在接口结构中的原型为:int (* ioctl)(struct inode *,struct file *,unsigned int, unsigned long);为用户程序的 ioctl 系统调用提供了一种执行设备特定命令的方法(即读写之外的操作) ,并且,内核还能识别一部分 ioctl 命令,而不必调用 fops 表中的 ioctl。如果设备不提供 ioctl 入口点,则对于任何内核未定义的请求,ioctl 系统调用

8、将返回错误,如果该设备方法返回一个非负值,那么相同的值会被调用返回给调用程序以表示调用成功。本驱动中的关键部分就是这个函数。用户空间系统调用 ioctl 的原型为:Int ioctl(int fd , int cmd, );Inode 和 file 两个指针的值对应于应用程序所传递的文件描述符 fd,参数cmd 会不经修改地传递给驱动程序,可选参数无论是指针还是整数都以unsigned long的形式被传递给驱动程序,其实, ioctl 实现的是一种 switch 语句选择功能。本驱动中此函数的功能为接受用户程序传下来的命令 cmd 和 arg 参数,然后选择命令对应的操作。Cmd 参数在用户

9、空间对应 0 或 1,表示 LED 的亮还是灭,arg 可以用来选择是哪个 LED,但是在本驱动中没有使用,无论哪个 LED 都是对全部 LED 的操作。以下是关操作:GPC_DAT=LED1_OFF|LED2_OFF|LED3_OFF;其中 LEDx_OFF 的定义为:#define LED1_OFF (15)#define LED2_OFF (16)#define LED3_OFF (17)这样 DAT 中对应的位就被设置为 1 即高电平 LED 灭。以下是开操作:GPC_DAT=LED1_ON其中 LEDx_ON 的定义为:#define LED1_ON (15)#define LED2

10、_ON (16)#define LED3_ON (17)这样 DAT 中对应的位就被设置为 0 即低电平 LED 亮。三对于 GPIO LED 的测试App_gpio.c 实现的功能为通过命令行参数控制 LED 的亮灭,这里要说明的一点是由于测试程序主要是完成的测试驱动是否正常工作的事情,所以测试程序中对某个 LED 选择的参数实际上是没作用的,不管针对哪个 LED 都是对全部的 LED 进行操作的。代码的具体实现见附录,这里只做简单的介绍。前面讲过要在/dev 下面创建设备节点 leds 和 dig_tube,所以第一步就要“打开”该设备即通过 open 系统调用( open(“/dev/leds“,O_RDWR)) ,然后通过 sscanf 获得命令行参数,再通过 ioctl 来完成对底层的控制即 ioctl(fd,on_off,led_num)11,on_off 中存放的就是 cmd,led_num 就是 arg 参数。测试过程如下图:图 3.1 GPIO LED 的测试平台上的 3 个 LED 全灭,达到了预期的效果。如下图:图 3.2 GPIO LED 初始状态图 3.3 GPIO LED 全灭

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报