[ARM应用]按键中断驱动实例
*返回值:
*************************************************************************
*/
static struct file_operations s3c2410_button_fops = {
.owner = THIS_MODULE,
.open = s3c2410_button_open,
.release = s3c2410_button_release,
.ioctl = s3c2410_button_ioctl,
.read = s3c2410_button_read,
.write = s3c2410_button_write,
};
/*
**************************button_setup_cdev()****************************
*描述 :安装模块的函数,在设备加载模块里面调用
*参数 :无
*返回值:无
*************************************************************************
*/
static void button_setup_cdev(void)
{
int err,devno = MKDEV(button_major,0);
cdev_init(&dev.cdev,&s3c2410_button_fops);
dev.cdev.owner = THIS_MODULE;
dev.cdev.ops = &s3c2410_button_fops;
err = cdev_add(&dev.cdev,devno,1);
if(err)
printk("Error %d adding BUTTON%d",err);
}
/*
****************************s3c2410_button_init()************************
*描述 :模块加载,IO及相关变量初始化
*参数 :无
*返回值:无
*************************************************************************
*/
static int s3c2410_button_init(void)
{
int result;
set_irq_type(BUTTON_IRQ,IRQT_FALLING); //设置外部中断0为下降沿中断
dev_t devno = MKDEV(button_major,0);
if(button_major)
result = register_chrdev_region(devno,1,DEVICE_NAME);
else{
result = alloc_chrdev_region(&devno ,0 ,1,DEVICE_NAME);
button_major = MAJOR(devno);
}
if(result < 0)return result;
button_setup_cdev();
s3c2410_button_InitIO(); //初始化IO端口
dev.status = BUTTON_UP; //初始化按键状态为抬起状态
printk(DEVICE_NAME " initialized\n");
return 0;
}
/*
****************************s3c2410_button_exit()************************
*描述 :模块卸载
*参数 :无
*返回值:无
*************************************************************************
*/
static void s3c2410_button_exit(void)
{
cdev_del(&dev.cdev); //注销设备
unregister_chrdev_region(MKDEV(button_major,0),1); //释放设备号
}
module_init(s3c2410_button_init);
module_exit(s3c2410_button_exit);
MODULE_LICENSE("GPL");
(2)编写Makefile文件(主机的/home/kernel/rootfs/rootfs/usr/button/driver目录下)
vi Makefile
在该文件中加入以下内容:
#如果已定义KERNELRELEASE,则说明是从内核构造系统调用的,
#因此可利用其内建语句。
ifneq ($(KERNELRELEASE),)
obj-m := button.o
#要构建的模块名称为button.ko,
#并由两个源文件生成(比如file1.c和file2.c)
#module-objs := file1.o file2.o
#否则,是直接从命令行调用的,
#这时要调用内核构造系统。
else
KERNELDIR := /home/kernel/linux-2.6.24.4
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *symvers
(3)编译
make
执行make命令进行编译,编译完成后,该目录下有一些文件,其中button.ko就是编译成功的模块文件。
(4)加载模块
首先设置内核以NFS方式加载根文件系统,在宿主机上运行minicom,加载完U-Boot,内核和nfs文件系统之后按回车键进入目标机shell控制台,在目标机控制台中输入模块加载命令:
insmod usr/led/driver/led.ko
insmod usr/button/driver/button.ko
如果输出“button initialized”,表示button设备驱动加载成功
(5)编写测试文件button_led.c(该测试程序还依赖LED的驱动)
进入宿主机的/home/kernel/rootfs/rootfs/usr/button/test目录。
cd /home/kernel/rootfs/rootfs/usr/button/test
vi button_led.c
驱动测试文件button_led.c如下所示:
#include
#i
- Linux嵌入式系统开发平台选型探讨(11-09)
- 基于ARM体系的嵌入式系统BSP的程序设计方案(04-11)
- 在Ubuntu上建立Arm Linux 开发环境(04-23)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- SQLite嵌入式数据库系统的研究与实现(02-20)
- 革新2410D开发板试用手记(04-21)