作业要求:
通过字符设备驱动分步注册过程实现LED驱动的编写,编写应用程序测试,发布到CSDN
作业答案:
运行效果:
驱动代码:
#include #include #include #include #include #include #include #include #include "head.h" struct cdev *cdev; char kbuf[128] = {0}; unsigned int major = 0; // 主设备号 unsigned int minor = 0; // 次设备号 dev_t devno; struct class *cls; struct device *dev; gpio_t *vir_led1; gpio_t *vir_led2; gpio_t *vir_led3; unsigned int *vir_rcc; // 封装操作方法 // 定义操作方法对象并初始化 int mycdev_open(struct inode *inode, struct file *file) { printk("%s:%s:%d\n", __FILE__, __func__, __LINE__); return 0; } ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof) { printk("%s:%s:%d\n", __FILE__, __func__, __LINE__); unsigned long ret; // 向用户空间读取拷贝 if (size > sizeof(kbuf)) // 用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小 size = sizeof(kbuf); ret = copy_to_user(ubuf, kbuf, size); if (ret) // 拷贝失败 { printk("copy_to_user filed\n"); return ret; } return 0; } ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof) { unsigned long ret; // 从用户空间读取数据 if (size > sizeof(kbuf)) // 用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小 size = sizeof(kbuf); ret = copy_from_user(kbuf, ubuf, size); if (ret) // 拷贝失败 { printk("copy_to_user filed\n"); return ret; } return 0; } long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int wh; int ret=copy_from_user(&wh,(void *)arg,4); if(ret)//拷贝失败 { printk("copy_from_user filed\n"); return ret; } switch(cmd) { case LED_ON: switch(wh) { case 1: vir_led1->ODR |= (1