您的位置:首页 > 其它

简单LED驱动创建和使用

2014-05-10 01:01 323 查看
LED设备是个字符设备,在mini2440中LED链接线使用引脚GPB5~8外接4个LED,操作方法是:
1)引脚功能设为输出。2)要点亮LED,令引脚输出为0.3)要熄灭LED,令引脚输出为1.

下边给出详细的源码注释:

必要的头文件

#include<linux/module.h>

#include<linux/kernel.h>

#include<linux/fs.h>

#include<linux/init.h>

#include<linux/delay.h>

#include<asm/irq.h>

#include<mach/regs-gpio.h>

#include<machhardware.h>

#include<linux/gpio.h>

#defineDEVICE_NAME"leds_control"/*加载模式后,执行”cat/proc/devices”命令看到的设备名称*/

#defineLED_MAJOR231/*主设备号*/
#defineIOCTL_LED_ON0/*应用程序执行ioctl(fd,cmd,arg)时的第2个参数*/
#defineIOCTL_LED_OFF1

staticunsignedlongled_table[]={/*用来指定LED所用的GPIO引脚*/
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
};

staticunsignedintled_cfg_table[]={/*用来指定GPIO引脚的功能:输出*/
S3C2410_GPIO_OUTP,
S3C2410_GPIO_OUTP,
S3C2410_GPIO_OUTP,
S3C2410_GPIO_OUTP,
};

//应用程序对设备文件/dev/leds执行open(...)时,就会调用s3c2410_leds_open函数
staticints3c2410_leds_open(structinode*inode,structfile*file)
{
inti;
for(i=0;i<4;i++){
//设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
}
return0;
}

//应用程序对设备文件/dev/leds执行ioclt(...)时,就会调用s3c2410_leds_ioctl函数
staticints3c2410_leds_ioctl(
structinode*inode,
structfile*file,
unsignedintcmd,
unsignedlongarg)
{
if(arg>4){
return-EINVAL;
}
switch(cmd){
caseIOCTL_LED_ON:
//设置指定引脚的输出电平为0
s3c2410_gpio_setpin(led_table[arg],0);
return0;

caseIOCTL_LED_OFF:
//设置指定引脚的输出电平为1
s3c2410_gpio_setpin(led_table[arg],1);
return0;

default:
return-EINVAL;
}
}

//字符设备驱动程序的核心,当应用程序操作设备文件时所调用的open、read、write等函数,最终会调用这个结构中指定的对应函数
staticstructfile_operationss3c2410_leds_fops={
.owner=THIS_MODULE,

.open=s3c2410_leds_open,
.ioctl=s3c2410_leds_ioctl,
};

//执行“insmods3c2410_leds.ko”命令时就会调用这个函数
staticint__inits3c2410_leds_init(void)
{
intret;

/*注册字符设备驱动程序
*参数为主设备号、设备名字、file_operations结构;
*这样,主设备号就和具体的file_operations结构联系起来了,
*操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数
*LED_MAJOR可以设为0,表示由内核自动分配主设备号
*/
ret=register_chrdev(LED_MAJOR,DEVICE_NAME,&s3c2410_leds_fops);
if(ret<0){
printk(DEVICE_NAME"can'tregistermajornumber\n");
returnret;
}
printk(DEVICE_NAME"initialized\n");
return0;
}


//执行”rmmods3c24xx_leds.ko”命令时就会调用这个函数
staticvoid__exits3c2410_leds_exit(void)
{
unregister_chrdev(LED_MAJOR,DEVICE_NAME);/*卸载驱动程序*/

}

module_init(s3c2410_leds_init);/*指定驱动程序的初始化函数和卸载函数*/
module_exit(s3c2410_leds_exit);


怎么使用,使用方法有两种(假设保存为leds_control.c):

方法一:

将代码放到内和drivers/char目录下,在drivers/char/Makefile中增加一行obj-m+=leds_control.o,然后在内核根目录下执行makemodules,就可以生成模块drivers/char/leds_control.ko。

方法二:

直接在当前驱动源码目录下,建立Makefile文件,内容如下:

CROSS=arm-linux-

#依赖的内核源代码目录,不一定是当前系统的,要是开发板系统源码的目录

KERNELDIR=/opt/linux-2.6.32.2

PWD:=$(shellpwd)

.PHONY:

<tab>modulesclean

obj-m+=leds_control.o

modules:

<tab>$(MAKE)-C$(KERNELDIR)M=$(PWD)modules

clean:

<tab>rm-rf*.o*~core.depend.*.cmd*.mod.c.tmp_versions

然后执行make,可以看到在当前目录下也会生成leds_control.ko.



通过以上两不,生成了leds_control.ko,下面就用ftp下载到开发板上,用:

insmod./leds_control.ko

mknod/dev/leds_controlc1500

就建好了驱动模块和设备节点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: