字符设备记录
open -> swi val 汇编 引发中断
sys call interface ->根据传入的val 值来调用 sys_open,
VFS: sys_open
led_open
从 open ---> sys_open 依赖于驱动程序框架
怎么告诉内核?
file_operations first_drv_ops
register_chrdev(major, "first_drv", &first_drv_ops); \
or major = register_chrdev(0, "first_drv", &first_drv_ops);
入口 first_drv_init();
修饰 module_init();
VFS根据设备类型和主设备号找到驱动 cxxx xxx xxx major minor
在一个内核数组 chrdev 里 以major为索引, 把file_operations挂载进去
出口 first_drv_exit();
unregister_chrdev();
1,设备号
①驱动程序可以自动分配主设备号
②也可以手工指定
MKDEV
从大到小选择
主设备号12bits 次设备号20bits
dev_t类型
从dev_t获取
MAJOR(dev_t)
MINOR(dev_t)
从主次返回得到dev_t的设备号
MKDEV(int major, int minor)
③注册和注销设备号
void cdev_init
int cdev_add
void cdev_del
④结构体cdev
操作cdev函数
void cdev_init(struct cdev *cdev, struct file_opereations *fops);
struct cdev * cdev_alloc(void);
int cdev_add(struct cdev *dev, dev_t num, unsigned count);
void cdev_del(struct cdev *dev);
⑤如何分配设备号
手动分配
int register_chrdev_region(dev_t first/*通常为0*/, unsigned int count/*连续分配个数*/, char *name);
动态分配
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
释放
void unregister_chrdev_region(dev_t dev, unsigned int count);
2,应用程序
/dev/xxx 怎么来的
①mknod /dev/xxx c 主 次 手工
②自动创建 udev机制可以自动创建设备结点,
mdev根据系统信息创建设备节点 写在init函数中 通过以下函数在/sys/下创建class
struct class *firstdrv_class;
struct class_device *firstdrv_class_devs[4];
firstdrv_class = class_create()
firstdrv_class_devs = class_device_create()
③删除信息 exit函数中
class_destory()
class_device_unregister()
LED
1,看原理图
2,数据手册引脚
地址映射 --> 虚拟地址
ioremap()
iounmap()
write() --> copy_from_user
read() --> copy_to_user
次设备号怎么用?
次设备号是自己用的,想要怎么操作由自己决定
led1, led2, led3, leds