__raw_writel(tmp,S3C64XX_GPMDAT);
//gpio_set_value(led_table[arg],!
cmd);
return0;
default:
return-EINVAL;
}
}
/*structfile_operations函数来定义我们能进行哪些操作,比如IOCTL*/
staticstructfile_operationss3c6410_leds_fops={
.owner=THIS_MODULE,
.ioctl=s3c6410_leds_ioctl,
};/*大家可以上去看一下s3c6410_leds_ioctl的定义*/
staticstructcdevcdev_leds;
structclass*my_class;
staticint__inits3c6410_leds_init(void)/*函数初始化,配置I/O口的模式*/
{
intret;
unsignedlongtmp;
inti;
dev_tdevno;
printk(KERN_NOTICE"enters3c6410_leds_init\n");
devno=MKDEV(LED_MAJOR,0);
ret=register_chrdev_region(devno,1,DEVICE_NAME);/*注册LED设备*/
ret=0;
if(ret<0)
{
printk(KERN_NOTICE"cannotregisterleddevice");
returnret;
}
cdev_init(&cdev_leds,&s3c6410_leds_fops);
cdev_leds.owner=THIS_MODULE;
ret=cdev_add(&cdev_leds,devno,1);
if(ret)
{
printk(KERN_NOTICE"cannotaddledsdevice");
returnret;
}
my_class=class_create(THIS_MODULE,"my_class");
if(IS_ERR(my_class))
{
printk("Err:
Failedincreatingclass\n");
return-1;
}
device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME);
//gpm0-3pullup
tmp=__raw_readl(S3C64XX_GPMPUD);
tmp&=(~0xFF);
tmp|=0xaa;
__raw_writel(tmp,S3C64XX_GPMPUD);
//gpm0-3outputmode
tmp=__raw_readl(S3C64XX_GPMCON);
tmp&=(~0xFFFF);
tmp|=0x1111;
__raw_writel(tmp,S3C64XX_GPMCON);
//gpm0-3output0
tmp=__raw_readl(S3C64XX_GPMDAT);
tmp|=0x10;
__raw_writel(tmp,S3C64XX_GPMDAT);
//printk("S3C64XX_GPMCONis%x\n",__raw_readl(S3C64XX_GPMCON));
//printk("S3C64XX_GPMDATis%x\n",__raw_readl(S3C64XX_GPMDAT));
//printk("S3C64XX_GPMPUDis%x\n",__raw_readl(S3C64XX_GPMPUD));
printk(DEVICE_NAME"initialized\n");
return0;
}
staticvoid__exits3c6410_leds_exit(void)/*模块卸载函数,大家可以参考我前一篇《字符设备驱动》*/
{
cdev_del(&cdev_leds);/*删除字符设备结构体*/
unregister_chrdev_region(MKDEV(LED_MAJOR,0),1);/*释放设备号*/
printk(KERN_NOTICE"s3c6410_leds_exit\n");
}
module_init(s3c6410_leds_init);/*首先从这里开始分析,这里是驱动程序的初始化函数*/
module_exit(s3c6410_leds_exit);
MODULE_LICENSE("GPL");因为我这里不想直接编译进内核,所以采取内核模块加载的方式把led的内核模块加载进内核,那么我这里就要自己写一个简单的makefile
makefile这里相对来说还是比较简单的,这个可以当做一个模板,因为需要修改的仅仅是obj-m:
=s3c6410_leds.o我的C文件就是s3c6410_leds.c.还有就是修改KDIR的路径,改成当前内核源码的路径。
然后我make,结果出错了
我看了我下makefile是没问题的,但是看到出错信息里面提示的makefile的第一个字母M是大写Makefile,然后我改了下。
结果好了
接下来我用nfs共享目录来进行led驱动模块向内核进行加载结果是这样
不能加载,错误提示里面显示不能创建一个类然后我cat/proc/devices查看了下,我内核里原本已经有一个LED的驱动了
既然这样吧,我决定重新编译个内核,没有led驱动的内核,makemenuconfig里面在devicedrivers里面的char类驱动设备里面把led的驱动设置为M。
然后保存退出,编译,makezImage然后把新的内核烧到板子上去接下来再试试加载内核模块
好了,终于加载上去了。
这里有一个要注意的,你的LED内核模块版本和当前板子上跑的linux系统的内核的版本需要一致才行。
如图
这是查看的板子上linux内核的版本
这是查看的编译的LED驱动模块的版本OK,都是linux2.6.28.6.——————————————————————————————我早上细看了下内核配置,如图
选上这个应该就能解决不同版本的模块的问题了...但不知道是否会出现BUG。