字符设备驱动开发基础

字符设备驱动注册卸载

1
2
3
4
5
module_init(XXX); // 注册模块加载函数
module_exit(XXX); // 注册模块卸载函数

static int __init XXX(void);
static int __exit XXX(void);

加载卸载驱动

1
2
3
4
5
6
7
8
9
10
11
insmod xx.ko
modprobe xx.ko // more smart
<!-- 会自动从/lib/modules/内核版本 目录下寻找依赖驱动
直接调用会提示can't open 'modules.dep'
输入depmod 若不存在该命令,则需busybox中加入 -->
<!-- 创建节点文件 -->
mknod [-m MODE] NAME TYPE [MAJOR MINOR]
mknod /dev/chrdevbase.ko c 200 0

rmmod xx.ko
modeprobe -r xx.ko // not suggest

字符设备的注册与注销

1
2
static inline int register_chrdev(unsigned int major,const char *name, const struct file_oiperations *fops);
static inline void unregister_chrdev(unsigned int major, const char* name);

可通过cat /proc/devices命令查看已经被用掉的设备号

添加LICENSE和作者信息

1
2
MODULE_LICENSE()
MODULE_AUTHOR()

设备号

dev_t 本质是一个32位的无符号整数,其中高12位为设备号,低20号为次设备号,so 主设备号max 4095。

1
2
3
MAJOR(dev)
MINOR(dev)
MKDEV(ma, mi)

dynamic dev num

1
2
int alloc_chrdev_region(dev_t* dev, unsigned baseminor, unsigned count, const char* name);
void unregister_chrdev_region(dev_t from, unsigned count);

printk

printk有八个打印等级,如果不指名,默认采用等级4

1
2
3
4
5
6
7
8
9
10
11
12
13
#inlcude/linux/kern_levels.h

#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */

usage:
printk(KERN_EMERG "gsmi:Log Shutdown Reason\n");

在printk.h中存在宏定义 CONSOLE_LOGLEVEL_DEFAULT 当打印等级比该值高,才会显示在终端上