day3ioctl

头文件

#ifndef __CKR_H__
#define __CKR_H__

typedef struct
{
    unsigned int MODER;   // 00
    unsigned int OTYPER;  // 04
    unsigned int OSPEEDR; // 08
    unsigned int PUPDR;   // 0C
    unsigned int IDR;     // 10
    unsigned int ODR;     // 14
} gpio_t;

// GPIO口
#define PHY_GPIOB 0X50003000
#define PHY_GPIOE 0X50006000
#define PHY_GPIOF 0X50007000
// RCC 总线
#define PHY_RCC 0X50000A28

// LED
#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l', 0, int)
// BEEP
#define BEEP_ON _IO('b', 1)
#define BEEP_OFF _IO('b', 0)
// FAN
#define FAN_ON _IO('f', 1)
#define FAN_OFF _IO('f', 0)
// MOTOR
#define MOTOR_ON _IO('m', 1)
#define MOTOR_OFF _IO('m', 0)

#endif

应用主函数

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "ckr.h"

int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int led_fd;
    int beep_fd;
    int fan_fd;
    int motor_fd;
    int operation;
    int flag;
    while (1)
    {
        system("clear");
        printf("-------------------------------\n");
        printf("-------------1.led-------------\n");
        printf("-------------2.beep------------\n");
        printf("-------------3.fan-------------\n");
        printf("-------------4.motor-----------\n");
        printf("-------------------------------\n");
        printf("请输入操作指令>>>");
        scanf("%d", &operation);

        switch (operation)
        {
        case 1: // led灯操作========================================
            led_fd = open("/dev/myled", O_RDWR);
            if (led_fd < 0)
            {
                printf("打开设备文件失败\n");
                exit(-1);
            }

            while (1)
            {
                system("clear");

                printf("请输入指令(0-关灯 1-开灯 2-退出)>>>");
                scanf("%d", &operation);
                if (operation == 2)
                {
                    break;
                }
                printf("请输入要控制的灯(1-LED1 2-LED2 3-LED3)>>>");
                scanf("%d", &flag);

                switch (operation)
                {
                case 0: // 关灯逻辑
                    ioctl(led_fd, LED_OFF, flag);
                    break;
                case 1: // 开灯逻辑
                    ioctl(led_fd, LED_ON, flag);
                    break;
                }
            }
            close(led_fd);
            break;
        case 2: // beep灯操作========================================
            beep_fd = open("/dev/mybeep", O_RDWR);
            if (beep_fd < 0)
            {
                printf("打开设备文件失败\n");
                exit(-1);
            }

            while (1)
            {
                system("clear");
                printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
                scanf("%d", &operation);
                if (operation == 2)
                {
                    break;
                }
                else if (operation == 0)
                {
                    ioctl(beep_fd, BEEP_OFF);
                }
                else if (operation == 1)
                {
                    ioctl(beep_fd, BEEP_ON);
                }
            }
            close(beep_fd);
            break;
        case 3: // fan风扇操作========================================
            fan_fd = open("/dev/myfan", O_RDWR);
            if (fan_fd < 0)
            {
                printf("打开设备文件失败\n");
                exit(-1);
            }

            while (1)
            {
                system("clear");
                printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
                scanf("%d", &operation);
                if (operation == 2)
                {
                    break;
                }
                else if (operation == 0)
                {
                    ioctl(fan_fd, FAN_OFF);
                }
                else if (operation == 1)
                {
                    ioctl(fan_fd, FAN_ON);
                }
            }
            close(fan_fd);
            break;
        case 4: // motor马达操作========================================
            motor_fd = open("/dev/mymotor", O_RDWR);
            if (motor_fd < 0)
            {
                printf("打开设备文件失败\n");
                exit(-1);
            }

            while (1)
            {
                system("clear");
                printf("请输入指令(0-关闭 1-开启 2-退出)>>>");
                scanf("%d", &operation);
                if (operation == 2)
                {
                    break;
                }
                else if (operation == 0)
                {
                    ioctl(motor_fd, MOTOR_OFF);
                }
                else if (operation == 1)
                {
                    ioctl(motor_fd, MOTOR_ON);
                }
            }
            close(motor_fd);
            break;
        default:
            break;
        }
    }

    return 0;
}

led驱动

#include 
#include 
#include 
#include 
#include 
#include "../ckr.h"

unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};

gpio_t *GPIOE;
gpio_t *GPIOF;
unsigned int *RCC;

struct class *cls;
struct device *dev;

// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
    case LED_ON:
        switch (arg)
        {
        case 1: // led1灯
            GPIOE->ODR |= (0x1 << 10);
            break;
        case 2: // led2灯
            GPIOF->ODR |= (0x1 << 10);
            break;
        case 3: // led3灯
            GPIOE->ODR |= (0x1 << 8);
            break;
        default:
            break;
        }
        break;
    case LED_OFF:
        switch (arg)
        {
        case 1: // led1灯
            GPIOE->ODR &= (~(0x1 << 10));
            break;
        case 2: // led2灯
            GPIOF->ODR &= (~(0x1 << 10));
            break;
        case 3: // led3灯
            GPIOE->ODR &= (~(0x1 << 8));
            break;
        default:
            break;
        }
        break;
    default:
        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,
    .release = mycdev_close,
    .unlocked_ioctl = mycdev_ioctl,

};

void myled_init(void)
{
    // 进行寄存器地址的映射-----------------------------------------------
    GPIOE = ioremap(PHY_GPIOE, 4);
    if (GPIOE == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    GPIOF = ioremap(PHY_GPIOF, 4);
    if (GPIOF == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    RCC = ioremap(PHY_RCC, 4);
    if (RCC == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    printk("映射物理内存成功\n");
    // 硬件寄存器的初始化
    (*RCC) |= (0X3 << 4); // rcc使能

    GPIOE->MODER &= (~(0x3 << 20));
    GPIOE->MODER |= (0x1 << 20);
    GPIOE->ODR &= (~(0x1 << 10));

    GPIOF->MODER &= (~(0x3 << 20));
    GPIOF->MODER |= (0x1 << 20);
    GPIOF->ODR &= (~(0x1 << 10));

    GPIOE->MODER &= (~(0x3 << 16));
    GPIOE->MODER |= (0x1 << 16);
    GPIOE->ODR &= (~(0x1 << 8));
}

static int __init mycdev_init(void)
{
    // 注册字符设备驱动
    major = register_chrdev(0, "mychrdev", &fops);
    if (major < 0)
    {
        printk("注册字符设备驱动失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n", major);
    myled_init(); // 初始化
    printk("硬件寄存器初始化成功\n");

    // 向上提交目录
    cls = class_create(THIS_MODULE, "myled");
    if (IS_ERR(cls))
    {
        printk("向上创建目录失败!\n");
        return -PTR_ERR(cls);
    }
    printk("向上创建目录成功!\n");
    // 向上提交节点
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "myled");
    if (IS_ERR(dev))
    {
        printk("向上提交节点失败!\n");
        return -PTR_ERR(dev);
    }

    printk("向上提交节点成功!\n");

    return 0;
}

static void __exit mycdev_exit(void)
{
    // 销毁节点信息

    device_destroy(cls, MKDEV(major, 0));

    // 销毁目录信息
    class_destroy(cls);

    iounmap(GPIOE);
    iounmap(GPIOF);
    iounmap(RCC);
    // 注销字符设备驱动
    unregister_chrdev(major, "mychrdev");
}

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

beep驱动

#include 
#include 
#include 
#include 
#include 
#include "../ckr.h"

unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};

gpio_t *GPIOB;

unsigned int *RCC;

struct class *cls;
struct device *dev;

// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
    case BEEP_ON:
        GPIOB->ODR |= (0x1 << 6);
        break;

    case BEEP_OFF:
        GPIOB->ODR &= (~(0x1 << 6));
        break;

    default:
        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,
    .release = mycdev_close,
    .unlocked_ioctl = mycdev_ioctl,

};

void mybeep_init(void)
{
    // 进行寄存器地址的映射-----------------------------------------------
    GPIOB = ioremap(PHY_GPIOB, 4);
    if (GPIOB == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    RCC = ioremap(PHY_RCC, 4);
    if (RCC == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }
    printk("映射物理内存成功\n");

    // 硬件寄存器的初始化
    (*RCC) |= (0X1 << 1); // rcc使能

    GPIOB->MODER &= (~(0x3 << 12));
    GPIOB->MODER |= (0x1 << 12);
    GPIOB->ODR |= (~(0x1 << 6));
}

static int __init mycdev_init(void)
{
    // 注册字符设备驱动
    major = register_chrdev(0, "mychrdev_beep", &fops);
    if (major < 0)
    {
        printk("注册字符设备驱动失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n", major);
    // 蜂鸣器初始化****************************
    mybeep_init();
    printk("硬件寄存器初始化成功\n");

    // 向上提交目录
    cls = class_create(THIS_MODULE, "mybeep");
    if (IS_ERR(cls))
    {
        printk("向上创建目录失败!\n");
        return -PTR_ERR(cls);
    }
    printk("向上创建目录成功!\n");
    // 向上提交节点
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mybeep");
    if (IS_ERR(dev))
    {
        printk("向上提交节点失败!\n");
        return -PTR_ERR(dev);
    }

    printk("向上提交节点成功!\n");

    return 0;
}

static void __exit mycdev_exit(void)
{
    // 销毁节点信息

    device_destroy(cls, MKDEV(major, 0));

    // 销毁目录信息
    class_destroy(cls);

    iounmap(GPIOB);
    iounmap(RCC);
    // 注销字符设备驱动
    unregister_chrdev(major, "mychrdev_beep");
}

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

fan驱动

#include 
#include 
#include 
#include 
#include 
#include "../ckr.h"

unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};

gpio_t *GPIOE;

unsigned int *RCC;

struct class *cls;
struct device *dev;

// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
    case FAN_ON:
        GPIOE->ODR |= (0x1 << 9);
        break;

    case FAN_OFF:
        GPIOE->ODR &= (~(0x1 << 9));
        break;

    default:
        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,
    .release = mycdev_close,
    .unlocked_ioctl = mycdev_ioctl,

};

void mybeep_init(void)
{
    // 进行寄存器地址的映射-----------------------------------------------
    GPIOE = ioremap(PHY_GPIOE, 4);
    if (GPIOE == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    RCC = ioremap(PHY_RCC, 4);
    if (RCC == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }
    printk("映射物理内存成功\n");

    // 硬件寄存器的初始化
    (*RCC) |= (0X1 << 4); // rcc使能

    GPIOE->MODER &= (~(0x3 << 18));
    GPIOE->MODER |= (0x1 << 18);
    GPIOE->ODR &= (~(0x1 << 9));
}

static int __init mycdev_init(void)
{
    // 注册字符设备驱动
    major = register_chrdev(0, "mychrdev_fan", &fops);
    if (major < 0)
    {
        printk("注册字符设备驱动失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n", major);
    // 蜂鸣器初始化****************************
    mybeep_init();
    printk("硬件寄存器初始化成功\n");

    // 向上提交目录
    cls = class_create(THIS_MODULE, "myfan");
    if (IS_ERR(cls))
    {
        printk("向上创建目录失败!\n");
        return -PTR_ERR(cls);
    }
    printk("向上创建目录成功!\n");
    // 向上提交节点
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "myfan");
    if (IS_ERR(dev))
    {
        printk("向上提交节点失败!\n");
        return -PTR_ERR(dev);
    }

    printk("向上提交节点成功!\n");

    return 0;
}

static void __exit mycdev_exit(void)
{
    // 销毁节点信息

    device_destroy(cls, MKDEV(major, 0));

    // 销毁目录信息
    class_destroy(cls);

    iounmap(GPIOE);
    iounmap(RCC);
    // 注销字符设备驱动
    unregister_chrdev(major, "mychrdev_fan");
}

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

motor驱动

#include 
#include 
#include 
#include 
#include 
#include "../ckr.h"

unsigned int major; // 定义一个变量保存主设备号
char kbuf[128] = {0};

gpio_t *GPIOF;

unsigned int *RCC;

struct class *cls;
struct device *dev;

// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

// ioctrl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
    case MOTOR_ON:
        GPIOF->ODR |= (0x1 << 6);
        break;

    case MOTOR_OFF:
        GPIOF->ODR &= (~(0x1 << 6));
        break;

    default:
        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,
    .release = mycdev_close,
    .unlocked_ioctl = mycdev_ioctl,

};

void mybeep_init(void)
{
    // 进行寄存器地址的映射-----------------------------------------------
    GPIOF = ioremap(PHY_GPIOF, 4);
    if (GPIOF == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }

    RCC = ioremap(PHY_RCC, 4);
    if (RCC == NULL)
    {
        printk("映射物理内存失败%d\n", __LINE__);
        return -EFAULT;
    }
    printk("映射物理内存成功\n");

    // 硬件寄存器的初始化
    (*RCC) |= (0X1 << 5); // rcc使能

    GPIOF->MODER &= (~(0x3 << 12));
    GPIOF->MODER |= (0x1 << 12);
    GPIOF->ODR |= (~(0x1 << 6));
}

static int __init mycdev_init(void)
{
    // 注册字符设备驱动
    major = register_chrdev(0, "mychrdev_motor", &fops);
    if (major < 0)
    {
        printk("注册字符设备驱动失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n", major);
    // 蜂鸣器初始化****************************
    mybeep_init();
    printk("硬件寄存器初始化成功\n");

    // 向上提交目录
    cls = class_create(THIS_MODULE, "mymotor");
    if (IS_ERR(cls))
    {
        printk("向上创建目录失败!\n");
        return -PTR_ERR(cls);
    }
    printk("向上创建目录成功!\n");
    // 向上提交节点
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mymotor");
    if (IS_ERR(dev))
    {
        printk("向上提交节点失败!\n");
        return -PTR_ERR(dev);
    }

    printk("向上提交节点成功!\n");

    return 0;
}

static void __exit mycdev_exit(void)
{
    // 销毁节点信息

    device_destroy(cls, MKDEV(major, 0));

    // 销毁目录信息
    class_destroy(cls);

    iounmap(GPIOF);
    iounmap(RCC);
    // 注销字符设备驱动
    unregister_chrdev(major, "mychrdev_motor");
}

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

你可能感兴趣的:(单片机,linux,嵌入式硬件)