• 华清远见上海中心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;

    }

     

     

  • 相关阅读:
    VirtualLab专题实验教程-2.分束器
    软文推广如何实现效果?媒介盒子为你支招
    B - Influence on Social media ,素因子分解,思维,unordered_map
    android studio修改字体大小
    PyTorch安装及环境配置(Win10)
    DeepMind CEO 预测 AI 未来:从被动问答到主动的学习者;华为官宣 Pocket 2 发布会
    C# 人像卡通化 Onnx photo2cartoon
    FP64、FP32、FP16、int8
    [Machine learning][Part4] 多维矩阵下的梯度下降线性预测模型的实现
    01 - Linux系统概要(再论计算机系统)
  • 原文地址:https://blog.csdn.net/qq_60135456/article/details/127893805