1、用户需求:需求写一个led的驱动,实现led2闪烁
2、驱动需求:设备led2 功能:亮 灭
3、寄存器操作:
1)原理图 :设备 → pin → 设备控制芯片
驱动需求(led2 亮/灭) → 设备需求(gpx1_1 高低电平)
2)芯片手册:设备控制芯片 → 寄存器
人 → 二进制代码 → CPU芯片 → 设备控制芯片→ 寄存器 → 设备
4.编写代码
搭好框架
1)头文件
2)函数实现
{
向上内核
向下硬件
}
3)函数注册
4)信息描述
完整代码
//1.header
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#define LEN_ON _IOW('L',0,int)
#define GPX1CON 0x114000c0
#define GPX1DAT 0x114000c4
static struct cdev mydev;
static int* gpx1con = NULL;
static int* gpx1dat = NULL;
int myopen(struct inode *pi, struct file *pf)
{
printk("kernel open\n");
return 0;
}
int myrelease(struct inode *pi, struct file *pf)
{
printk("kernel release\n");
return 0;
}
ssize_t mywrite (struct file *pf, char __user *ubuf, size_t len, loff_t *poff)
{
memcpy(kbuf,ubuf,len);
return len;
}
ssize_t myread (struct file *pf, char __user *ubuf, size_t len, loff_t *poff)
{
memcpy(ubuf,kbuf,len);
return len;
}
void addr_map(void)
{
gpx1con = ioremap(GPX1CON,4);
gpx1dat = ioremap(GPX1DAT,4);
}
//long (*unlocked_ioctl) (struct file *, unsigned int,unsigned long);
long myioctl (struct file *pf, unsigned int cmd,unsigned long arg)
{
switch (cmd)
{
case LED_ON:
led_on();
break;
case LED_OFF:
led_off();
break;
default:
break;
}
return 0;
}
void dev_init()
{
write1((read1(gpx1con)&~(0xf<<4))|(0x1<<4),gpx1con);
write1(read1(gpx1dat)&~(0x1<<1),gpx1dat);
}
void led_on(void)
{
write1(read1(gpx1dat)|(0x1<<1),gpx1dat);
}
void led_off(void)
{
write1(read1(gpx1dat)&~(0x1<<1),gpx1dat);
}
static const struct file_operations myfops ={
.open = myopen,
.release = myrelease,
.write = mywrite,
.read = myread
.unlocked_ioctl = myioctl;
};
//2.函数实现
static int myinit(void)
{
//向上:和内核相关
//1)reg
ret = register_chrdev_region(no,count,name);
//2)init
cdev_init(&mydev,&myfops);
//3)add
ret = cdev_add(&mydev, no, count);
//向下:和硬件相关
//1)地址映射
addr_map();
//2)设备初始化
dev_init();
return 0;
}
static int myexit(void)
{
//向上:和内核相关
//1)del
cdev_del(&mydev);
//2)unreg
unregister_chrdev_region(no,count);
//向下:和硬件相关
//1)取消映射
addr_unmap();
return;
}
//3、函数注册
module_init(myinit);
module_exit(myexit);
//4、信息描述
MODULE_LICENSE("GPL");