开发学习记录之字符设备驱动

内核驱动开发最简单的就是字符设备,字符设备的驱动模型就是学习其他设备的前提,这里我用一个最简单的设备led,来做字符设备,写作一个最简单的字符设备驱动模型,可以供大家参考:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#define LED_REGISTER 0x7f008000
MODULE_LICENSE("GPL");
struct up_led{
 struct cdev cdev; 
 unsigned long virt,phys;
 unsigned long *gpmcon,*gpmdat;
 dev_t devno;
 void (*led_init)(struct up_led *this);
 void (*led_exit)(struct up_led *this);
 void (*led_on)(struct up_led *this);
 void (*led_off)(struct up_led *this);
};
void my_led_init(struct up_led *this);
void my_led_exit(struct up_led *this);
void my_led_on(struct up_led *this);
void my_led_off(struct up_led *this);
int my_open(struct inode *no,struct file *fp);
int my_release(struct inode *no,struct file *fp);
ssize_t my_read(struct file *fp,char *buff,size_t len,off_t *off);
ssize_t my_write(struct file *fp,const char *buff,size_t len,off_t *off);
int my_ioctl(struct inode *no,struct file *fp,unsigned int cmd,unsigned long arg);
 
struct file_operations fops = {
 .open = my_open,
 .write = my_write,
 .release = my_release,
 .read = my_read,
 .ioctl = my_ioctl 
};
struct up_led led;
int up_init(void)
{
 led.led_init = my_led_init;
 led.led_exit = my_led_exit;
 
 led.led_init(&led);
 return 0;
}
void up_exit(void)
{
 led.led_exit(&led);
}
module_init(up_init);
module_exit(up_exit);
void my_led_init(struct up_led *this)
{
 this->led_on = my_led_on;
 this->led_off = my_led_off;
 this->phys = LED_REGISTER;
 this->virt = ioremap(this->phys,SZ_4K); 
 this->gpmcon = this->virt + 0x820;
 this->gpmdat = this->virt + 0x824;
 
 this->devno = MKDEV(9,1);
 cdev_init(&(this->cdev),&fops);
 cdev_add(&(this->cdev),this->devno,1);
}
void my_led_exit(struct up_led *this)
{
 cdev_del(this);
 iounmap(this->virt);
}
void my_led_on(struct up_led *this)
{
 *this->gpmcon &= ~0xf;
 *this->gpmcon |= 1;
 *this->gpmdat &= ~1;
}
void my_led_off(struct up_led *this)
{
 *this->gpmcon &= ~0xf;
 *this->gpmcon |= 1;
 *this->gpmdat |= 1;
}
int my_open(struct inode *no,struct file *fp)
{
 printk("%x\n",no->i_cdev);
 printk("%x\n",&led.cdev);
 
 struct up_led *this = container_of(no->i_cdev,struct up_led,cdev);
 fp->private_data = this;
 
 return 0;
}
int my_release(struct inode *no,struct file *fp)
{
 return 0;
}
ssize_t my_read(struct file *fp,char *buff,size_t len,off_t *off)
{
 return 0;
}
ssize_t my_write(struct file *fp,const char *buff,size_t len,off_t *off)
{
 return 0;
}
int my_ioctl(struct inode *no,struct file *fp,unsigned int cmd,unsigned long arg)
{
 struct up_led *this = fp->private_data;
 if(cmd == 1) 
 {
  printk("led-on\n");
  this->led_on(this);
 }
 else if(cmd == 0)
 { 
  printk("led-off\n");
  this->led_off(this);
 }
 else
  printk("command is err\n");
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值