• 华清远见上海中心22071班


    #include

    #include

    #include

    #include

    #include

    #include "led.h"

    #define CNAME "led"

    volatile gpio_t *GPIOE=NULL;

    volatile gpio_t *GPIOF=NULL;

    int major;

    char kbuf[128] = {0};

    volatile unsigned int* virt_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 __user *ubuf, size_t size, loff_t *loffs)

    {

        int ret;

        printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

        //校验传输数据大小,如果用户空间传输数据的大小大于内核空间,需要更正传输数据大小

        if(size > sizeof(kbuf)) size = sizeof(kbuf);

        ret = copy_to_user(ubuf,kbuf,size);

        if(ret)

        {

            printk("copy from user is error\n");

            return -EIO;

        }

        return size;

    }

    ssize_t mycdev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loffs)

    {

        int ret;

        printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

        //1.校验传输数据大小,如果用户空间传输数据的大小大于内核空间,需要更正传输数据大小

        if(size > sizeof(kbuf)) size = sizeof(kbuf);

        ret = copy_from_user(kbuf,ubuf,size);

        if(ret)

        {

            printk("copy from user is error\n");

            return -EIO;

        }

        printk("copy from user kbuf = %s\n",kbuf);

        //2.实现灯点亮和熄灭的过程

        if(kbuf[0] == '1') //操作哪一盏灯

        {

            if(kbuf[1] == '1')

            {

                GPIOE->ODR |= (0x1 << 10); //led1输出高电平

                GPIOF->ODR |= (0x1 << 10); //led2输出搞电平

                GPIOE->ODR |= (0x1 << 8);  //led3输出高电平

            }

            else if(kbuf[1] == '0')

            {

                GPIOE->ODR &= (~(0x1 << 10));//led1输出低电平

                GPIOE->ODR &= (~(0x1 << 8));//led3输出低电平

                GPIOF->ODR &= (~(0x1 << 10));//led2输出低电平

            }

        }

        return size;

    }

    int  mycdev_close(struct inode *inode, struct file *file)

    {

        printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

        return 0;

    }

    const struct file_operations fops = {

            .open = mycdev_open,

            .read = mycdev_read,

            .write = mycdev_write,

            .release = mycdev_close,

    };

    //入口

    static int __init mycdev_init(void)

    {

        //1.注册字符设备驱动

        major = register_chrdev(0,CNAME,&fops);

        if(major < 0)

        {

            printk("register chrdev is error\n");

            return major;

        }    

        printk("major=%d\n",major);

        //2.将LED1物理地址映射为虚拟地址

        //1)将rcc地址进行映射

        virt_rcc = ioremap(PHY_RCC,4);

        if(NULL == virt_rcc)

        {

            printk("rcc ioremap is error\n");

            return -ENOMEM;

        }

        //2)将GPIO_MODER地址进行映射

        GPIOE = ioremap(IGPIOE,sizeof(gpio_t));

        GPIOF = ioremap(IGPIOF,sizeof(gpio_t));

        //3.将LED1--->PE10引脚初始化

        //将GPIOE时钟使能

        *virt_rcc |= (0x1 << 4);

        //将GPIOE时钟使能

        *virt_rcc |= (0x1 << 5);

        //设置PE10引脚为输出模式

        GPIOE->MODER &= (~(0x3 << 20));

        GPIOE->MODER |= (0x1 << 20);

       

        //设置Pf10引脚为输出模式

        GPIOF->MODER &= (~(0x3 << 20));

        GPIOF->MODER |= (0x1 << 20);

        //设置Pe8引脚为输出模式

        GPIOE->MODER &= (~(0x3 << 16));

        GPIOE->MODER |= (0x1 << 16);

        //3)设置PE10引脚默认为低电平

        GPIOE->ODR &= (~(0x1 << 10));

        GPIOE->ODR &= (~(0x1 << 8));

        GPIOF->ODR &= (~(0x1 << 10));

        return 0;

    }

    //出口

    static void __exit mycdev_exit(void)

    {

        //2.注销字符设备驱动

        unregister_chrdev(major,CNAME);

    }

    module_init(mycdev_init);

    module_exit(mycdev_exit);

    //许可证

    MODULE_LICENSE("GPL");

     

    #ifndef __LED_H__

    #define __LED_H__

    #define PHY_GPIO_MODER 0x50006000

    #define PHY_GPIO_ODR 0x50006014

    #define PHY_RCC  0x50000A28

    #define IGPIOE 0x50006000

    #define IGPIOF 0x50007000

    typedef struct{

        volatile unsigned int MODER;

        volatile unsigned int OTYPER;

        volatile unsigned int OSPEEDR;

        volatile unsigned int PUPDR;

        volatile unsigned int IDR;

        volatile unsigned int ODR;

    }gpio_t;

    #endif

     

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    char buf[128] = {""};

    int main(int argc, char const *argv[])

    {

        int fd = -1;

        fd = open("/dev/myled",O_RDWR);

        if(-1 == fd)

        {

            perror("open is error");

            exit(1);

        }

        while(1)

        {

            buf[0] = '1';

            write(fd,buf,sizeof(buf));

            buf[1] = '1';

            write(fd,buf,sizeof(buf));

            sleep(1);

            buf[1] = '0';

            write(fd,buf,sizeof(buf));

            sleep(1);

        }

        close(fd);

        return 0;

    }

     

     

  • 相关阅读:
    基于大语言模型的LoRA微调及模型合并技术实践指南
    115. 关于将本地 SAP UI5 应用配置到本地 Fiori Launchpad 的技术实现深入讲解
    【Linux信号专题】一、什么是信号
    以太坊 layer2: optimism 源码学习 (一)
    小说系统微信小程序
    Elasticsearch核心概念解析:索引、文档与类型
    win10 安装openssl并使用openssl创建自签名证书
    双向链表C语言版本
    Linux 中启动 SpringBoot 项目出现 java.lang.OutOfMemoryError Java heap space 错误
    uniapp 路由模式 history
  • 原文地址:https://blog.csdn.net/qq_60135456/article/details/127893805