Linux设备驱动程序之三 ---- LED驱动程序的实现
2015-10-10 10:54
267 查看
LED驱动程序:
#include
#include
#include
#include
#include
#include
#include
int major;
dev_t dev_num;
static struct class *led_drv_class;
static struct device *led_drv_dev;
volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL;
static int led_drv_open(struct inode *inode, struct file *file)
{
//printk("first_drv_open\n");
/* 配置GPB5,6,7,8为输出 */
*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));
*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));
return 0;
}
static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int val;
//printk("first_drv_write\n");
copy_from_user(&val, buf, count); // copy_to_user();
if (val == 1)
{
// 点灯
*gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
else
{
// 灭灯
*gpbdat |= ((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
return 0;
}
static struct file_operations led_drv_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_drv_open,
.write = led_drv_write,
};
static int led_drv_init(void)
{
major = register_chrdev(0, "led_drv", &led_drv_fops); // 注册, 告诉内核
dev_num = MKDEV(major,0);
led_drv_class = class_create(THIS_MODULE, "led_drv");
if (IS_ERR(led_drv_class))
return PTR_ERR(led_drv_class);
led_drv_dev = device_create(led_drv_class, NULL, dev_num, NULL, "led_drv");
if (unlikely(IS_ERR(led_drv_dev)))
return PTR_ERR(led_drv_dev);
gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
gpbdat = gpbcon + 1;
return 0;
}
static void led_drv_exit(void)
{
unregister_chrdev(major, "led_drv"); // 卸载
device_destroy(led_drv_class,dev_num);
class_destroy(led_drv_class);
iounmap(gpbcon);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
LED测试程序:
#include
#include
#include
#include
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/led_drv", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
if (argc != 2)
{
printf("Usage :\n");
printf("%s \n", argv[0]);
return 0;
}
if (strcmp(argv[1], "on") == 0)
{
val = 1;
}
else
{
val = 0;
}
write(fd, &val, 4);
return 0;
}
注:我是TQ2440的开发板。
注:关于次设备号的使用,可以参考:
leds.rar
关注微信公众号获取更多资讯
#include
#include
#include
#include
#include
#include
#include
int major;
dev_t dev_num;
static struct class *led_drv_class;
static struct device *led_drv_dev;
volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL;
static int led_drv_open(struct inode *inode, struct file *file)
{
//printk("first_drv_open\n");
/* 配置GPB5,6,7,8为输出 */
*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));
*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));
return 0;
}
static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int val;
//printk("first_drv_write\n");
copy_from_user(&val, buf, count); // copy_to_user();
if (val == 1)
{
// 点灯
*gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
else
{
// 灭灯
*gpbdat |= ((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
return 0;
}
static struct file_operations led_drv_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_drv_open,
.write = led_drv_write,
};
static int led_drv_init(void)
{
major = register_chrdev(0, "led_drv", &led_drv_fops); // 注册, 告诉内核
dev_num = MKDEV(major,0);
led_drv_class = class_create(THIS_MODULE, "led_drv");
if (IS_ERR(led_drv_class))
return PTR_ERR(led_drv_class);
led_drv_dev = device_create(led_drv_class, NULL, dev_num, NULL, "led_drv");
if (unlikely(IS_ERR(led_drv_dev)))
return PTR_ERR(led_drv_dev);
gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
gpbdat = gpbcon + 1;
return 0;
}
static void led_drv_exit(void)
{
unregister_chrdev(major, "led_drv"); // 卸载
device_destroy(led_drv_class,dev_num);
class_destroy(led_drv_class);
iounmap(gpbcon);
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
LED测试程序:
#include
#include
#include
#include
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/led_drv", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
if (argc != 2)
{
printf("Usage :\n");
printf("%s \n", argv[0]);
return 0;
}
if (strcmp(argv[1], "on") == 0)
{
val = 1;
}
else
{
val = 0;
}
write(fd, &val, 4);
return 0;
}
注:我是TQ2440的开发板。
注:关于次设备号的使用,可以参考:
leds.rar
关注微信公众号获取更多资讯
相关文章推荐
- 关于linux mysql启动错误问题
- Linux设备驱动程序之二 ---- 完善上一节的驱动程序
- Linux设备驱动前的工作准备 ---- 内核的配置及Makefile编写
- Linux设备驱动之一 ---- 驱动的框架及其操作流程
- Linux下的V4L2的API编程总结
- linux查找文件命令总结
- linux内核MKDEV()宏
- Image , zImage 和 vmlinux的区别
- arm-linux-gcc的下载与安装
- Linux下C++的man安装及使用方法
- Linux串口编程详解
- Hadoop I 搭建Linux下Hadoop2.6.0伪分布式环境
- Linux启动过程详解
- Linux上的终端设备
- Alsa是Linux高级音频接口(百度文库无下载券抄来的)
- 史上最经典的Linux内核学习方法论
- Linux内核驱动fsync机制实现图解
- linux中container_of(ptr, type, member)
- 程序的链接和装入及Linux下动态链接的实现
- linux编程段错误及调试方法