您的位置:首页 > 运维架构 > Linux

linux驱动之LED驱动_2

2014-12-19 21:35 155 查看
在上一个帖子中,讲述了如何给led编写驱动程序,但是实现的功能比较单一,接下来我们要实现的功能是在上一个的基础上能够单独控制每一个led灯。

上一个帖子的链接: linux驱动之LED驱动_1 

上一个帖子的驱动源码在:点击打开链接       测试源码在:点击打开链接

目的:

实现板子上每个led能够单独的控制。

方法:

0、通过次设备号来单独访问每个led

1、更改入口函数: 为每个led分配一个次设备号。

for(minor=0;minor<4;minor++)
{
firstdrv_class_dev[minor] = device_create(firstdrv_class,NULL,MKDEV(major,minor),NULL,"wq_led%d",minor);
if(unlikely(IS_ERR(firstdrv_class_dev[minor])))
return PTR_ERR(firstdrv_class_dev[minor]);
}


2、同理,更改出口地址:

for(minor=0;minor<4;minor++)
{
device_unregister(firstdrv_class_dev[minor]);
}


3、这样节点就挂上去了  会在/dev 里面 出现四个设备 分别是: wq_led0,wq_led1,wq_led2,wq_led3

4. 更改open 函数,增加单独设置每个led引脚的功能: 根据次设备号进行操作

int minor = MINOR(inode ->i_rdev);//获得次设备号
switch(minor)
{
case 0://GPB5 配置为输出
{
*gpbcon &=~(0x3<<(5*2));
*gpbcon |=(0x1<<(5*2));
break;
}
case 1://GPB6 配置为输出
{
*gpbcon &=~(0x3<<(6*2));
*gpbcon |=(0x1<<(6*2));
break;
}
case 2://GPB7 配置为输出
{
*gpbcon &=~(0x3<<(7*2));
*gpbcon |=(0x1<<(7*2));
break;
}
case 3://GPB8 配置为输出
{
*gpbcon &=~(0x3<<(8*2));
*gpbcon |=(0x1<<(8*2));
break;
}

}


5、更改 write 函数,根据用户空间传过来过来的数据和次设备号对led进行操作

int minor = MINOR(file->f_dentry->d_inode->i_rdev);//获得次设备号
copy_from_user(&val,buf,count);//从用户空间向内核空间拷贝数据
switch(minor)
{
case 0://GPB5
{
if(val == 1)//亮
{
*gpbdat &=~(1<<5);
}
else//灭
{
*gpbdat|=(1<<5);
}
break;
}
case 1://GPB6
{
if(val == 1)//亮
{
*gpbdat &=~(1<<6);
}
else//灭
{
*gpbdat|=(1<<6);
}
break;
}
case 2://GPB7
{
if(val == 1)//亮
{
*gpbdat &=~(1<<7);
}
else//灭
{
*gpbdat|=(1<<7);
}
break;
}
case 3://GPB8
{
if(val == 1)//亮
{
*gpbdat &=~(1<<8);
}
else//灭
{
*gpbdat|=(1<<8);
}
break;
}
}
详细代码:

驱动程序:点击打开链接

测试程序:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: