LED灯驱动

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include "mycdev.h"

#include <linux/io.h>

//

//定义三个指针  指向映射后的虚拟地址

unsigned int *VIR_GPIOE_MODER;

unsigned int *VIR_GPIOE_ODR;

unsigned int *VIR_GPIOF_MODER;

unsigned int *VIR_GPIOF_ODR;

unsigned int *VIR_RCC;

unsigned int major;

char kbuf[2]= {0};


 

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 *iof)

{

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

    int ret = 0;

    if (size > sizeof(kbuf))

        size = sizeof(kbuf);

    ret = copy_to_user(ubuf, kbuf, size);

    if (ret)

    {

        printk("copy to user filed\n");

        return -EIO;

    }

    return 0;

}

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

{

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

    int ret = 0;

    if (size > sizeof(kbuf))

        size = sizeof(kbuf);

    ret = copy_from_user(kbuf, ubuf, size);

    if (ret)

    {

        printk("copy from user filed\n");

        return -EIO;

    }

   

    switch(kbuf[0])

    {

        case '1':

        {

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

                (*VIR_GPIOE_ODR)    |= (0x1 << 10);

            else

                (*VIR_GPIOE_ODR)    &= (~(0x1 << 10));

                break;

        }

        case '2':

        {

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

                (*VIR_GPIOF_ODR)    |= (0x1 << 10);

            else

                (*VIR_GPIOF_ODR)    &= (~(0x0 << 10));

                break;

        }

        case '3':

        {

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

                (*VIR_GPIOE_ODR)    |= (0x1 << 8);

            else

                (*VIR_GPIOE_ODR)    &= (~(0x0 << 8));

                break;

        }

    }

    return 0;

}

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

{

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

    return 0;

}

struct file_operations fops={

    .open = mycdev_open,

    .read = mycdev_read,

    .write = mycdev_write,

    .release = mycdev_close,

};





 

//入口

//led_init uart_init lcd_init

//__init:是给编译器使用的, 告诉编译器这个函数放在.init.text段中

static int __init mycdev_init(void)

{

    //字符设备驱动的注册

    major = register_chrdev(0, "mycdev", &fops);

    if  (major < 0)

    {

        printk("字符设备驱动注册失败\n");

    }

    printk("字符设备驱动注册成功major = %d\n", major);

    ///

    //进行相关寄存器地址映射

    VIR_GPIOE_MODER = ioremap(PHY_GPIOE_MODER, 4);

    if (NULL == VIR_GPIOE_MODER)

    {

        printk("1物理地址映射失败\n");

        return -EFAULT;

    }

    VIR_GPIOE_ODR = ioremap(PHY_GPIOE_ODR, 4);

    if (NULL == VIR_GPIOE_ODR)

    {

        printk("2物理地址映射失败\n");

        return -EFAULT;

    }

    VIR_GPIOF_MODER = ioremap(PHY_GPIOF_MODER, 4);

    if (NULL == VIR_GPIOF_MODER)

    {

        printk("3物理地址映射失败\n");

        return -EFAULT;

    }

    VIR_GPIOF_ODR = ioremap(PHY_GPIOF_ODR, 4);

    if (NULL == VIR_GPIOF_ODR)

    {

        printk("4物理地址映射失败\n");

        return -EFAULT;

    }

    VIR_RCC = ioremap(PHY_RCC, 4);

    if (NULL == VIR_RCC)

    {

        printk("5物理地址映射失败\n");

        return -EFAULT;

    }

    //

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

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

    (*VIR_GPIOE_MODER) &= (~(0x3 << 20));

    (*VIR_GPIOE_MODER) |= (0x1 << 20);

    (*VIR_GPIOF_MODER) &= (~(0x3 << 20));

    (*VIR_GPIOF_MODER) |= (0x1 << 20);

    (*VIR_GPIOE_MODER) &= (~(0x3 << 16));

    (*VIR_GPIOF_MODER) |= (0x1 << 16);

    printk("相关寄存器初始化\n");

    return 0;

}


 

//出口

//demo_exit驱动出口的名字

//led_exit uart_exit lcd_exit

//__exit:是给编译器使用的

static void __exit mycdev_exit(void)

{

    iounmap(VIR_RCC);

    iounmap(VIR_GPIOE_ODR);

    iounmap(VIR_GPIOF_ODR);

    iounmap(VIR_GPIOF_MODER);

    iounmap(VIR_GPIOF_MODER);

    unregister_chrdev(major, "mycdev");

    printk(KERN_ERR "EXIT\n");

}



 

//告诉内核入口的地址

module_init(mycdev_init);

//告诉内核出口的地址

module_exit(mycdev_exit);

//许可证

MODULE_LICENSE("GPL");

#ifndef __MYCDEV_H__

#define __MYCDEV_H__

#define PHY_RCC              0X50000A28

#define PHY_GPIOE_MODER      0X50006000

#define PHY_GPIOE_ODR        0X50006014

#define PHY_GPIOF_MODER      0X50007000

#define PHY_GPIOF_ODR        0X50007014



 

#endif

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>



 

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

{

    char protocol[2] = {0};

    int fd = open("/dev/mycdev", O_RDWR);

    if (fd < 0)

    {

        perror("open");

        exit(1);

    }

    while (1)

    {

        printf("控制LED1 (1) LED2(2) LED3(3)\n");

        protocol[0] = fgetc(stdin);

        printf("控制亮(1) 灭(0)\n");

        protocol[1] = fgetc(stdin) ;

        write(fd, protocol, sizeof(protocol));

    }

    close(fd);

    return 0;

}

猜你喜欢

转载自blog.csdn.net/weixin_73148834/article/details/131194793