嵌入式驱动2
sys文件系统在嵌入式 Linux 开发中sys通常指sysfs系统文件系统是一个虚拟文件系统用于向用户空间导出内核对象设备、驱动、模块等的信息。内核信息的展示窗口通过文件查看/控制内核对象相关函数接口static struct class *pclass NULL; static struct device *pdevice NULL;定义了设备类class和设备节点device的指针用于在/sys和/dev中自动创建设备文件//创建一个设备的类 pclass class_create(THIS_MODULE, LED); if (IS_ERR(pclass)) { ret PTR_ERR(pclass); pr_err(class_create error%d\n, ret); return ret; } //创建设备节点 pdevice device_create(pclass, NULL, dev_no, NULL, myled0); if (IS_ERR(pdevice)) { ret PTR_ERR(pdevice); pr_err(device_create error%d\n, ret); return ret; }创建设备属性ret device_create_file(misc_dev.this_device, attr); if (ret) { pr_err(device_create_file error\n); return ret; } pr_info(hello,aaa\n); return 0;IS_ERR检查一个指针是否指向错误码而不是有效内存PTR_ERR从错误指针中提取实际的错误码。static ssize_t myshow(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t mystore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static struct device_attribute attr __ATTR(led_status, 0664, myshow, mystore);static ssize_t myshow(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len 0; if (LED_ON status) { strcpy(buf, LED_ON\n); } else { strcpy(buf, LED_OFF\n); } len strlen(buf); return len; } static ssize_t mystore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { // int ret 0; // char tmp[100] {0}; u32 v 0; // ret copy_from_user(tmp, buf, count); // if (ret) // { // pr_err(mystore error,size:%d\n, ret); // return count; // } v readl(pdata); if (0 strcmp(buf, 1\n)) { v ~(1 3); writel(v, pdata); status LED_ON; } else if (0 strcmp(buf, 0\n)) { v | (1 3); writel(v, pdata); status LED_OFF; } return count; }myshow在读取属性文件时返回当前 LED 状态mystore在写入属性文件时解析命令并控制 LED。整体流程创建好设备的类型以及设备节点调用device_create_file 函数创建设备的属性的属性用_ATTR, 填充 属性结构体。属性的名字(直接写str不用引号)读写权限读函 数写函数 。填入函数指针show(读属性)store(写属性)。建议值ioremap寄存器的设置都建议在init中完成。有可能插入模块后就查看设备属性了。show的返回值需要返回值输出字符串的长度。store的返回值要返回该函数形参的最后一个参数。否则会阻塞misc设备驱动MiscMiscellaneous杂项设备驱动是 Linux 中一种简化版的字符设备驱动用于管理那些不适合归类到其他类别的小型设备。特性传统字符设备Misc 设备主设备号动态分配固定 10次设备号手动分配自动分配注册函数cdev_addmisc_register注销函数cdev_delmisc_deregister设备节点手动创建 (class/device)自动创建代码量多 (~50行)少 (~10行)适用场景所有设备小型设备Misc 设备驱动是字符设备的简化版主设备号固定为10自动分配次设备号自动创建设备节点。适合 LED、GPIO、按键等小型设备代码简洁注册/注销方便函数接口static struct miscdevice misc_dev { .minor MISC_DYNAMIC_MINOR, //自动获取次设备号 .name DEV_NAME, // 设备节点名 /sys/class/misc/xxx .fops fops, //杂项设备 文件操作集合 };