底层驱动day4作业

news2024/11/19 5:54:08

分布注册设备,实现文件和设备的绑定

代码:

//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_RCC 0x50000A28
#define PHY_GPIOE_MODER 0x50006000
#define PHY_GPIOF_MODER 0x50007000
#define PHY_GPIOE_ODR 0x50006014
#define PHY_GPIOF_ODR 0x50007014

typedef struct 
{
    unsigned int MODER;
    unsigned int OTYPER;
    unsigned int OSPEEDR;
    unsigned int PUPDR;
    unsigned int IDR;
    unsigned int ODR;
}gpio_t;

#define GPIOE 0x50006000
#define GPIOF 0x50007000
#define PHY_RCC_ADDR 0x50000A28
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)


#endif
//mycdev.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/device.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/uaccess.h>
#include<linux/slab.h>
#include"include/head.h"
unsigned int major = 0,minor = 0;
dev_t devno;
struct class *cls;
struct cdev* cdev;
struct device *dev;
gpio_t *vir_led1;
gpio_t *vir_led2;

unsigned int *vir_rcc;


int mycdev_open(struct inode *inode,struct file *file)
{
    int min = MINOR(inode->i_rdev);
    file->private_data = (void *)min;
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
    int min = (int)(file->private_data);
    switch(min)
    {
        case 0:
            switch(cmd)
            {
                case LED_OFF:
                    vir_led1->ODR &= (~(0x1 << 10));
                    break;
                case LED_ON:
                    vir_led1->ODR |= (0x1 << 10);
                    break;
            }
            break;
        case 1:
            switch(cmd)
            {
                case LED_OFF:
                    vir_led2->ODR &= (~(0x1 << 10));
                    break;
                case LED_ON:
                    vir_led2->ODR |= (0x1 << 10);
                    break;
            }
            break;
        case 2:
            switch(cmd)
            {
                case LED_OFF:
                    vir_led1->ODR &= (~(0x1 << 8));
                    break;
                case LED_ON:
                    vir_led1->ODR |= (0x1 << 8);
                    break;
            }
            break;
        default:
            break;
    }
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

int mycdev_close(struct inode *inode,struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

int all_led_init(void)
{
    vir_led1 = ioremap(GPIOE,sizeof(gpio_t));
    if(NULL == vir_led1)
    {
        printk("ioremap failed : %d\n",__LINE__);
        return -ENOMEM;
    }
    vir_led2 = ioremap(GPIOF,sizeof(gpio_t));
    if(NULL == vir_led2)
    {
        printk("ioremap failed : %d\n",__LINE__);
        return -ENOMEM;
    } 
    vir_rcc = ioremap(PHY_RCC,4);
    if(NULL == vir_rcc)
    {
        printk("ioremap failed : %d\n",__LINE__);
        return -ENOMEM;
    }
    
    printk("寄存器内存映射成功\n");
    (*vir_rcc) |= (0x1 << 4);
    (*vir_rcc) |= (0x1 << 5);
    (vir_led1->MODER) &= (~(0x3 << 20));    //led1_moder
    (vir_led1->MODER) |= (0x1 << 20);
    (vir_led1->MODER) &= (~(0x3 << 16));    //led3_moder
    (vir_led1->MODER) |= (0x1 << 16);
    (vir_led1->ODR) &= (~(0x1 << 10));      //led1_odr
    (vir_led1->ODR) &= (~(0x1 << 8));      //led3_odr
    (vir_led2->MODER) &= (~(0x3 << 20));    //led2_moder
    (vir_led2->MODER) |= (0x1 << 20);
    (vir_led2->ODR) &= (~(0X1 << 10));      //led2_odr
    return 0;
}

struct file_operations fops = {
    .open = mycdev_open,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};

static int __init mycdev_init(void)
{
    int ret;
    all_led_init();
    //申请对象空间
    cdev = cdev_alloc();
    if(NULL == cdev)
    {
        printk("申请字符设备驱动对象空间失败\n");
        ret = -EFAULT;
        goto out;
    }
    printk("申请字符设备驱动对象空间成功\n");   
    //初始化对象
    cdev_init(cdev,&fops);
    //申请设备号
    
    if(0 == major)
    {
        ret = alloc_chrdev_region(&devno,0,3,"mychrdev");
        if(0 != ret)
        {
            printk("动态申请设备号失败\n");
            goto out2;
        }
        major = MAJOR(devno);
        minor = MINOR(devno);
    }
    else
    {
        ret = register_chrdev_region(MKDEV(major,minor),3,"mychrdev");
        if(0 != ret)
        {
            printk("静态申请设备号失败\n");
            goto out2;
        }
    }
    printk("申请设备号成功\n");
    
        
    //注册驱动对象
    int ret2 = cdev_add(cdev,devno,3);
    if(0 != ret2)
    {
        printk("注册驱动对象失败\n");
        goto out3;
    }
    printk("注册字符设备驱动对象成功\n");
    //向上提交目录
    cls = class_create(THIS_MODULE,"mychrdev");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        goto out4;
    }
    printk("向上提交目录成功\n");
    //向上提交设备节点信息
    int i;
    for(i = 0;i < 3;i++)
    {
        dev = device_create(cls,NULL,MKDEV(major,i),NULL,"mychrdev%d",i);
        if(IS_ERR(dev))
        {
            printk("向上提交设备节点失败\n");
            goto out5;
        }
    }   
    printk("向上提交设备节点成功\n");
    return 0;
    out5:
        for(--i;i >= 0;i--)
        {
            device_destroy(cls,MKDEV(major,i));
        }
        class_destroy(cls);
    out4:
        cdev_del(cdev);
    out3:
        unregister_chrdev_region(MKDEV(major,minor),3);
    out2:
        kfree(cdev);
    
    out:
        
        return ret;
    
}

static void __exit mycdev_exit(void)
{
    //销毁设备节点信息
    int i;
    for(i = 0;i < 3;i++)
    {
        device_destroy(cls,MKDEV(major,i));
    }
    //销毁设备目录
    class_destroy(cls);
    //销毁字符设备驱动对象
    cdev_del(cdev);
    //释放设备号
    unregister_chrdev_region(MKDEV(major,minor),3);
    kfree(cdev);
    return;
}



module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

 

//test.c
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<stdio.h>
#include<string.h>
#include"include/head.h"

int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int led_id,led_state;
    fgets(buf,sizeof(buf),stdin);
    buf[strlen(buf) - 1] = 0;

    int fd = open(buf,O_RDWR);
    if(fd < 0)
    {

        printf("打开设备文件失败\n");
        return -1;
    }
    printf("打开设备文件成功\n");
    while(1)
    {
        // fgets(buf,sizeof(buf),stdin);
        // buf[strlen(buf) - 1] = 0;
        // write(fd,buf,sizeof(buf));
        // scanf("%d",&led_id);
        scanf("%d",&led_state);
        switch(led_state)
        {
            case 1:
                ioctl(fd,LED_ON);
                break;
            case 0:
                ioctl(fd,LED_OFF);
                break;
            default:
                break;
        }
    }
    
    //read(fd,buf,sizeof(buf));
    
    // memset(buf,0,sizeof(buf));
    // read(fd,buf,sizeof(buf));
    // printf("buf:%s\n",buf);
    close(fd);
    return 0;
}

实现效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1124654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VR虚拟现实技术在法院技能培训中的应用

开展法治宣传教育&#xff0c;是全面贯彻落实科学发展观的重要决策&#xff0c;也是保障和促进经济设备会发展和实施“十一五”规划的内在要求。为了让全民法治文化宣传深入人们群众中&#xff0c;突破性地采用VR虚拟现实、web3d开发和三维仿真技术&#xff0c;开发线上法治文化…

Git的标签管理

Git标签管理 创建标签操作标签小结 创建标签 在Git中打标签非常简单&#xff0c;首先&#xff0c;切换到需要打标签的分支上&#xff1a; $ git branch $ git checkout master 然后&#xff0c;敲命令git tag 就可以打一个新标签&#xff1a; $ git tag v1.0 可以用命令git …

大一新生必备电脑软件插件有哪些?

毕业老学姐倾情分享珍藏必备软件和浏览器插件&#xff01;拥有后生活明朗&#xff0c;学习效率UPUP&#xff01; 纯干货分享建议【点赞收藏】后观看 速览 Office全家桶-Word、Excel、Powerpoint大学生必备 火绒安全-计算机防病毒软件 AI助手-AI对话写作阅读助手&#xff0c;…

HCIP-MGRE实验

实验拓扑图 需求 1 R5为ISP &#xff0c;只能进行IP地址配置;其所有地址均配为公有IP地址 2 R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方; R2于R5之间使用ppp的chap认证&#xff0c;R5为主认证方; R3于R5之间使用HDLC封装。 3 R1/R2/R3构建一个MGRE环境&#xff0c;R1为…

创新驱动|RFID技术在智能半导体行业的应用

半导体产业是我国重要的战略性新兴产业&#xff0c;是一个需要高度协同的领域&#xff0c;需要各个环节的紧密配合。RFID技术&#xff0c;作为一种自动识别和数据采集技术&#xff0c;在半导体生产线上具有独特的优势。通过应用RFID技术&#xff0c;半导体制造企业可以实现生产…

基于Python+Selenium+Unittest+PO设计模式

一、什么是PO设计模式&#xff08;Page Object Model&#xff09; 1、Page Object是一种设计模式&#xff0c;它主要体现在对界面交互细节的封装上&#xff0c;使测试用例更专注于业务的操作&#xff0c;从而提高测试用例的可维护性。 2、一般PO设计模式有三层 第一层&#x…

【鸿蒙软件开发】文本显示(Text/Span)

文章目录 前言一、Text控件1.1 创建文本string字符串引用Resource资源 1.2 添加子组件创建Span文本装饰线和样式文本装饰线设置文字一直保持大写/小写添加事件。 1.3 自定义文本样式文本对齐长文本处理设置行高通过decoration属性设置文本装饰线样式及其颜色。通过baselineOffs…

功率放大器在PZT陶瓷薄膜压电传感器研究中的应用

随着科技的进步和工业发展的需求&#xff0c;对于压力测量和控制的需求日益增加。压力传感器作为一种关键的传感器器件&#xff0c;在机械、自动化、医疗、航空等多个领域都有广泛应用。PZT陶瓷薄膜压电传感器由于其响应速度快、精度高、稳定性好等优点&#xff0c;成为了许多应…

OTA: Optimal Transport Assignment for Object Detection 论文和代码学习

OTA 原因步骤什么是最优传输策略标签分配的OT正标签分配负标签分配损失计算中心点距离保持稳定动态k的选取 整体流程代码使用 论文连接&#xff1a; 原因 1、全部按照一个策略如IOU来分配GT和Anchors不能得到全局最优&#xff0c;可能只能得到局部最优。 2、目前提出的ATSS和P…

做数据可视化,谨记三大要点

数据可视化报表就是“一图胜千言”的最佳例子。数据可视化&#xff0c;也就是将数据图形化、图表化&#xff0c;以良好的视觉效果呈现数据&#xff0c;达到发现、分析、预测、监控、决策等目的。要想做出一份优秀的数据可视化报表&#xff0c;那就要在做报表时谨记三大要点&…

3D模型在线格式转换工具

单模型上传格式 支持格式说明 支持RAR和ZIP压缩包上传&#xff0c;压缩包大小按原始文件大小计算&#xff0c;压缩包内只能包含一个模型文件 超过500MB的模型请联系客服 您也可以下载老子云客户端进行批量上传 不同会员级别的模型上传大小有不同的限制&#xff0c;详情请查询…

越来越好用的Edge浏览器,盘点Edge浏览器功能丨插件

前些年&#xff0c; Edge 浏览器也宣布加入 Chromium 内核&#xff1b;它的前身是IE浏览器&#xff0c; Edge之所以越来越多人用的一个原因是因为它的内核是Google Chrome的Chromium&#xff0c;而且不需要膜法就可以使用&#xff0c;这一点Chrome浏览器还不行&#xff0c;访问…

分拣设备运动仿真

这一次我们来分享一下如何在Solidworks 中做出传送台的分拣动作并通过分拣动作生成过程动画&#xff0c;以便于我们可以用于产品展示又或者验证运行程序无误的情况下结构是否会影响输送效率。 首先创建一个新的运动算例 将窗口切换至Motion分析 在设置之前我们先理清设置传送带…

税务某局 webpack 登录接口逆向分析

持续创作文章&#xff0c;只是为了更好的思考 这里不多介绍了&#xff0c;我放一张图大家就明白是什么接口了。这里只介绍整体加密逻辑&#xff0c;有些细的地方大家自行调整。 本次逆向的网址是 aHR0cHM6Ly90cGFzcy5qaWxpbi5jaGluYXRheC5nb3YuY246ODQ0My8jL2xvZ2luP3JlZGly…

vue3实现详情页返回列表页,返回原来列表页滚动条所在的位置

keepAlive缓存页面 组合式API 第一步第二步第三步第四步 第一步 首先在路由文件的meta里面定义 meta: {keepAlive: false, },第二步 在app.vue 根文件下定义代码 <template><keep-alive><router-view v-if"route.meta.keepAlive" /></keep-…

基于springboot实现广场舞团平台系统项目【项目源码+论文说明】

基于springboot实现广场舞团管理平台系统 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&am…

软设上午题错题知识点8

软设上午题错题知识点8 1、IPv4用32位二进制表示&#xff0c;能够表示的地址空间是232&#xff0c;IPv6用128位二进制表示&#xff0c;能够表示的地址空间是2128&#xff0c;本题选择2128 /232296 。 2、在应用散列函数构造哈希表&#xff08;或散列表&#xff09;时&#xf…

使用docker部署flask接口服务 一

文章目录 一&#xff1a;说明二&#xff1a;dockerfile 参数说明1. 一般常用的 参数&#xff0c;以及它的含义2. 我自己的 dockerfile 三&#xff1a;示例操作1. Gunicorn Gevent启动服务的好处2. 用Gunicorn Gevent的好处&#xff1a;3. Gunicorn Gevent的 使用示例4. 创建…

“数字赋能、智创未来”第三届中国(宁波)软件峰会暨程序员节即将开启

在“八八战略”的指引下,我们深入实施数字经济创新提质“一号发展工程”,以打造“全球智造创新之都”为目标,强化数字赋能、绿色赋能、低碳赋能、融合赋能,全速推动数字经济和实体经济深度融合。第三届(宁波)软件峰会暨程序员节将于10月24日下午在宁波泛太平洋大酒店三楼大宴会…

优优嗨聚集团:旅游经济繁荣,助力当地外卖市场崛起

随着全球旅游经济的飞速发展&#xff0c;越来越多的人选择在假期或周末出游。而在旅游过程中&#xff0c;餐饮是一个不可或缺的环节。近年来&#xff0c;随着移动支付和互联网技术的普及&#xff0c;外卖行业逐渐崛起&#xff0c;为旅游经济注入了新的活力。 一、旅游经济带动外…