编写灯、风扇、蜂鸣器的驱动

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

.h头文件

#ifndef __LED_H__
#define __LED_H__

typedef struct led
{
    volatile unsigned int model;
    volatile unsigned int OTYPER;
    volatile unsigned int OSPEEDR;
    volatile unsigned int PUPDR;
    volatile unsigned int IDR;
    volatile unsigned int ODR;

}gpio_t;

#define RCC_ADDR 0x50000A28
#define GPIOE   0x50006000
#define GPIOF   0x50007000
#define GPIOZ   0x54004000
#define GPIOB   0x50003000            //b6 蜂鸣器
                                    //f6 马达
#define RCC_MP_AHB5LPENSETR 0x50000290
enum LED_ID
{
    LED1 = 1,
    LED2,
    LED3,
    LED4,
    LED5,
    LED6,
    BEEP1,
    FAN1,
};

enum PLACE
{
    MASTER,
    SOLVE,
};

enum DRVICE
{
    LED,
    BEEP,
    FAN,
};

#define LED_ON _IOW('a',1,int)
#define LED_OFF _IOW('a',0,int)


#endif

驱动函数

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include<linux/io.h>
#include<linux/delay.h>
#include<linux/string.h>
#include"led.h"

gpio_t *vir_gpioe;
gpio_t *vir_gpiof;
gpio_t *vir_gpioz;
gpio_t *vir_gpiob;
unsigned int *vir_rcc;
unsigned int *vir_RCC_MP_AHB5LPENSETR;
int major;
struct class *cls;
int chrdev_open(struct inode *inode,struct file *file)
{
    return 0;
}

ssize_t chrdev_write (struct file *fd, const char __user *user, size_t count, loff_t *off)
{
    return 0;
}

int chrdev_release (struct inode *node, struct file *fd)
{
    return 0;
}
void func(int cmd,int arg)
{
    if(cmd == LED_ON)
    switch(arg)
    {
        case LED1:
           vir_gpioe->ODR |= 1<<10;
           break;
        case LED2:
            vir_gpiof->ODR |= 1<<10;
            break;
        case LED3:
            vir_gpioe->ODR |= 1<<8;
            break;
        case LED4:
            vir_gpioz->ODR |= 1<<5;
            break;
        case LED5:
            vir_gpioz->ODR |= 1<<6;
            break;
        case LED6:
            vir_gpioz->ODR |= 1<<7;
            break;
        case BEEP1:
            vir_gpiob->ODR |= 1<<6;
            break;
        case FAN1:
            vir_gpiof->ODR |= 1<<6;
    }
    else
    switch(arg)
    {
        case LED1:
           vir_gpioe->ODR &= ~(1<<10);
           break;
        case LED2:
            vir_gpiof->ODR &= ~(1<<10);
            break;
        case LED3:
            vir_gpioe->ODR &= ~(1<<8);
            break;
        case LED4:
            vir_gpioz->ODR &= ~(1<<5);
            break;
        case LED5:
            vir_gpioz->ODR &= ~(1<<6);
            break;
        case LED6:
            vir_gpioz->ODR &= ~(1<<7);
            break;
        case BEEP1:
            vir_gpiob->ODR &= ~(1<<6);
            break;
        case FAN1:
            vir_gpiof->ODR &= ~(1<<6);
            break;
    }
    printk("cmd = %d choice = %d\r\n",cmd,arg);
}
long chrdev_ioctl (struct file *file, unsigned int cmd, unsigned long  arg)
{
    int whitch,ret;
    switch(cmd)
    {
        case LED_ON:
            ret = copy_from_user(&whitch,(void *)arg,sizeof(int));
            printk("whitch = %d\r\n",whitch);
            if (ret)
            {
                printk("copy_from_user failed!\r\n");
                return -1;
            }
            func(cmd,whitch);
        break;
        case LED_OFF:
            ret = copy_from_user(&whitch,(void *)arg,sizeof(int));
            printk("whitch = %d\r\n",whitch);
            if (ret)
            {
                printk("copy_from_user failed!\r\n");
                return -1;
            }
            func(cmd,whitch);
        
        break;
    }
    return 0;
}

struct file_operations ledchrdev_fops = 
{
    .open = chrdev_open,
    .release = chrdev_release,
    .write = chrdev_write,
    .unlocked_ioctl = chrdev_ioctl,
};

static void led_init(void)
{
    
    //扩展板led灯初始化
    //led1初始化
    vir_gpioz = ioremap(GPIOZ,sizeof(gpio_t));
    vir_RCC_MP_AHB5LPENSETR = ioremap(RCC_MP_AHB5LPENSETR,4);
    vir_gpioz->model &= ~(3<<10);
    vir_gpioz->model |= 1<<10;
    vir_gpioz->ODR |= 1<<5;

    vir_gpioz->model &= ~(3<<12);
    vir_gpioz->model |= 1<<12;
    vir_gpioz->ODR |= 1<<6;

    vir_gpioz->model &= ~(3<<14);
    vir_gpioz->model |= 1<<14;
    vir_gpioz->ODR |= 1<<7;


    printk("扩展板LED初始化\r\n");
    vir_gpioe = ioremap(0x50006000,4);
    vir_rcc = ioremap(0x50000A28,4);
    *vir_rcc |= (3<<4);
    *vir_rcc |= 1<<1;
    vir_gpioe->model &= (~(3<<20));
    vir_gpioe->model |= (1<<20);
    vir_gpioe->ODR |= (1<<10);

    printk("led1_init success!\r\n");

    //led2初始化
    vir_gpiof = ioremap(0x50007000,4);

    vir_gpiof->model &= (~(3<<20));
    vir_gpiof->model |= (1<<20);
    vir_gpiof->ODR |= (1<<10);
     printk("led2_init success!\r\n");

    //led3初始化
    vir_gpioe->model &= (~(3<<16));
    vir_gpioe->model |= (1<<16);
    vir_gpioe->ODR |= (1<<8);
    printk("led3_init success!\r\n");

    vir_gpiob = ioremap(GPIOB,4);
    vir_gpiob->model &= ~(0x3<<12);
    vir_gpiob->model |= (1<<12);
    vir_gpiof->model &= ~(0x3<<12);
    vir_gpiof->model |= (0x1<<12);



}

int __init ioctldev_init(void)
{
     int i = 0;
    major = register_chrdev(0,"ioctldev",&ledchrdev_fops);
    if(major < 0)
    {
        printk("register_chrdev failed!\r\n");
        return major;
    }
    led_init();
    
    cls = class_create(THIS_MODULE,"LED");
    if(IS_ERR(cls))
    {
        printk("创建结点目录失败\r\n");
        return IS_ERR_VALUE(cls);
    }
    printk("创建结点目录成功\r\n");

    for(i=0;i<3;i++)
    {
        //向上提交设备节点
        device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
        printk("创建节点myled%d成功\r\n",i);
    }

    printk("major = %d\r\n",major);
    printk("ledchrdev init\r\n");
    return 0;
}
    
void __exit ioctldev_exit(void)
{
    int i = 0;
    iounmap(vir_gpioe);
    iounmap(vir_gpiof);
    iounmap(vir_rcc);
    iounmap(vir_gpioz);
    iounmap(vir_RCC_MP_AHB5LPENSETR);

    for(i = 0;i<3;i++)
    {
        device_destroy(cls,MKDEV(major,i));
        printk("销毁节点myled%d成功\r\n",i);
    }
    class_destroy(cls);
    printk("销毁节点目录成功\r\n");

    unregister_chrdev(major,"ioctldev");
    printk("ledchrdev exit\r\n");
}

module_init(ioctldev_init);
module_exit(ioctldev_exit);
MODULE_LICENSE("GPL");

 测试代码

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include"led.h"

int main()
{

    int device;
    int place;
    int choice;
    int pin;
    int fd = open("/dev/myled0",O_RDWR);
    if(fd < 0)
    {
        printf("open failed!]n");
        return -1;
    }
    while(1)
    {
        printf("请输入您想操作的设备1LED1 2 LED2 3 LED3 4 LED4 5 LED5 5 LED6 7马达 8蜂鸣器>>>");
        scanf("%d",&device);
        switch (device)
        {
        case LED1:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
            case LED2:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
            case LED3:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
            case LED4:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
            case LED5:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
            case LED6:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;

        case BEEP1:
                printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
        case FAN1:
            printf("请输入状态 1 0\n");
            scanf("%d",&choice);
            if(choice)
            ioctl(fd,LED_ON,&device);
            else
            ioctl(fd,LED_OFF,&device);
            break;
        default:
            printf("输入错误请重新输入0 1 2\n");
            break;
        }

    }


}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6