ictol函数实现蜂鸣器,风扇,马达

led.h

#ifndef __HEAD_H__
#define __HEAD_H__
typedef struct
{
    unsigned int MODER;
    unsigned int OTYPER;
    unsigned int OSPEEDR;
    unsigned int PUPDR;
    unsigned int IDR;
    unsigned int ODR;
    unsigned int BSRR;

} gpio_t;
#define PHY_LED1_ADDR 0X50006000
#define PHY_LED2_ADDR 0X50007000
#define PHY_LED3_ADDR 0X50006000
#define PHY_RCC_ADDR 0X50000A28
#define PHY_PWN_ADDR 0X50003000
#define PHY_FAN_ADDR 0X50006000
#define PHY_MOTOR_ADDR 0X50007000
// 定义功能码
#define LED_ON _IOW('l', 1, int)  // 开灯
#define LED_OFF _IOW('l', 0, int) // 关灯
#define PWN_ON _IO('l', 1)        // 开蜂鸣器
#define PWN_OFF _IO('l', 0)       // 关蜂鸣器
#define FAN_ON _IO('l', 1)        // 开风扇
#define FAN_OFF _IO('l', 0)       // 关风扇
#define MOTOR_ON _IO('l', 1)      // 开马达
#define MOTOR_OFF _IO('l', 0)     // 关马达

#endif

灯.c

#include 
#include 
#include
#include
#include
#include"led.h"

int major;
char kbuf[128]={0};
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
unsigned int *vir_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;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
     unsigned long ret;
    //向用户空间读取拷贝
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_to_user(ubuf,kbuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
    unsigned long ret;
    //从用户空间读取数据
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_from_user(kbuf,ubuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
//ioctl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    int which,ret;
    //将ioctl第三个参数的数值拷贝给which;
    ret=copy_from_user(&which,(void *)arg,sizeof(int));
    if(ret)
    {
        printk("copy_from_user filed\n");
        return -EIO;
    }
    //根据功能码进行硬件功能控制
    switch(cmd)
    {
        case LED_ON:
            switch(which)
            {
                case 1:
                    vir_led1->ODR |= (1<<10);
                    break;
                case 2:
                    vir_led2->ODR |= (1<<10);
                    break;
                case 3:
                    vir_led3->ODR |= (1<<8);
                    break;
            }
            break;
        case LED_OFF:
            switch(which)
            {
                case 1:
                    vir_led1->ODR &= (~(1<<10));
                    break;
                case 2:
                    vir_led2->ODR &= (~(1<<10));
                    break;
                case 3:
                    vir_led3->ODR &= (~(1<<8));
                    break;
            }
            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,
    .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close,
};

int all_led_init(void)
{
    //寄存器地址的映射
    vir_led1=ioremap(PHY_LED1_ADDR,sizeof(gpio_t));
    if(vir_led1==NULL)
    {
        printk("ioremap filed:%d\n",__LINE__);
        return -ENOMEM;
    }
     vir_led2=ioremap(PHY_LED2_ADDR,sizeof(gpio_t));
    if(vir_led2==NULL)
    {
        printk("ioremap filed:%d\n",__LINE__);
        return -ENOMEM;
    }
     vir_led3=vir_led1;
    vir_rcc=ioremap(PHY_RCC_ADDR,4);
    if(vir_rcc==NULL)
    {
        printk("ioremap filed:%d\n",__LINE__);
        return -ENOMEM;
    }
    printk("物理地址映射成功\n");
    //寄存器的初始化
    //rcc
    (*vir_rcc) |= (3<<4);
    //led1
    vir_led1->MODER &= (~(3<<20));
    vir_led1->MODER |= (1<<20);
    vir_led1->ODR &= (~(1<<10));
    //led2
    vir_led2->MODER &= (~(3<<20));
    vir_led2->MODER |= (1<<20);
    vir_led2->ODR &= (~(1<<10));
    //led3
    vir_led3->MODER &= (~(3<<16));
    vir_led1->MODER |= (1<<16);
    vir_led1->ODR &= (~(1<<18));
    printk("寄存器初始化成功\n");

    return 0;
}

static int __init mycdev_init(void)
{
    //字符设备驱动注册
    major=register_chrdev(0,"mychrdev",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n",major);
    //向上提交目录
    cls=class_create(THIS_MODULE,"mychrdev");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    //向上提交设备信息
    dev=device_create(cls,NULL,MKDEV(major,0),NULL,"mychrdev");
    if(IS_ERR(dev))
    {
        printk("向上提交设备信息失败\n");
        return PTR_ERR(dev);
    }
    printk("向上提交设备信息成功\n");

    //寄存器映射以及初始化
    all_led_init();

    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消地址映射
    iounmap(vir_led1);
    iounmap(vir_led2);
    iounmap(vir_rcc);
    //销毁设备信息
    device_destroy(cls,MKDEV(major,0));
    //销毁目录
    class_destroy(cls);
    //注销字符设备驱动
    unregister_chrdev(major,"mychrdev");


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

蜂鸣器.c

#include 
#include 
#include
#include
#include
#include"led.h"

int major;
char kbuf[128]={0};
gpio_t *vir_pwn;
unsigned int *vir_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;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
     unsigned long ret;
    //向用户空间读取拷贝
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_to_user(ubuf,kbuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
    unsigned long ret;
    //从用户空间读取数据
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_from_user(kbuf,ubuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
//ioctl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    //根据功能码进行硬件功能控制
    switch(cmd)
    {
        case PWN_ON:
    
             vir_pwn->ODR |= (1<<6);
             break;
        
        case PWN_OFF:
            vir_pwn->ODR &= (~(1<<6));
            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,
    .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close,
};
int all_pwn_init(void)
{
    //寄存器地址映射
    vir_pwn = ioremap(PHY_PWN_ADDR, sizeof(gpio_t));
    if(vir_pwn == NULL){
        printk("ioremap filed: %d\n", __LINE__);
        return -ENOMEM;
    }
    vir_rcc = ioremap(PHY_RCC_ADDR, 4);
    if(vir_rcc == NULL){
        printk("ioremap filed: %d\n", __LINE__);
        return -ENOMEM;
    }
    (*vir_rcc) |= (1<<1);
    //寄存器的初始化
    vir_pwn->MODER &= ~(3<<12);
    vir_pwn->MODER |= (1<<12);
    vir_pwn->ODR &= ~(1<<6);

    return 0;
}

static int __init mycdev_init(void)
{
    //字符设备驱动注册
    major=register_chrdev(0,"mycdev1",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n",major);
    //向上提交目录
    cls=class_create(THIS_MODULE,"mycdev1");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    //向上提交设备信息
    dev=device_create(cls,NULL,MKDEV(major,0),NULL,"mycdev1");
    if(IS_ERR(dev))
    {
        printk("向上提交设备信息失败\n");
        return PTR_ERR(dev);
    }
    printk("向上提交设备信息成功\n");

    //寄存器映射以及初始化
    all_pwn_init();

    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消地址映射
    iounmap(vir_pwn);
    iounmap(vir_rcc);
    //销毁设备信息
    device_destroy(cls,MKDEV(major,0));
    //销毁目录
    class_destroy(cls);
    //注销字符设备驱动
    unregister_chrdev(major,"mycdev1");


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

风扇.c

#include 
#include 
#include 
#include 
#include 
#include "led.h"

int major;
char kbuf[128] = {0};
gpio_t *vir_fan;
unsigned int *vir_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;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    unsigned long ret;
    // 向用户空间读取拷贝
    if (size > sizeof(kbuf)) // 用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size = sizeof(kbuf);
    ret = copy_to_user(ubuf, kbuf, size);
    if (ret) // 拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
    unsigned long ret;
    // 从用户空间读取数据
    if (size > sizeof(kbuf)) // 用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size = sizeof(kbuf);
    ret = copy_from_user(kbuf, ubuf, size);
    if (ret) // 拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
// ioctl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{

    // 根据功能码进行硬件功能控制
    switch (cmd)
    {
    case FAN_ON:
        vir_fan->ODR |= (1 << 9);
        break;

    case FAN_OFF:
        vir_fan->ODR &= (~(1 << 9));
        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,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};

int all_fan_init(void)
{
    //寄存器地址映射
    vir_fan = ioremap(PHY_FAN_ADDR, sizeof(gpio_t));
    if(vir_fan == NULL){
        printk("ioremap filed: %d\n", __LINE__);
        return -ENOMEM;
    }
    vir_rcc = ioremap(PHY_RCC_ADDR, 4);
    if(vir_rcc == NULL){
        printk("ioremap filed: %d\n", __LINE__);
        return -ENOMEM;
    }
    (*vir_rcc) |= (1 << 4);
    vir_fan->MODER &= ~(3 << 18);
    vir_fan->MODER |= (1 << 18);
    vir_fan->ODR &= ~(1 << 9);
    printk("寄存器初始化成功\n");

    return 0;
}

static int __init mycdev_init(void)
{
    // 字符设备驱动注册
    major = register_chrdev(0, "mycdev2", &fops);
    if (major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n", major);
    // 向上提交目录
    cls = class_create(THIS_MODULE, "mycdev2");
    if (IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    // 向上提交设备信息
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev2");
    if (IS_ERR(dev))
    {
        printk("向上提交设备信息失败\n");
        return PTR_ERR(dev);
    }
    printk("向上提交设备信息成功\n");

    // 寄存器映射以及初始化
    all_fan_init();

    return 0;
}
static void __exit mycdev_exit(void)
{
    // 取消地址映射
    iounmap(vir_fan);
    iounmap(vir_rcc);
    // 销毁设备信息
    device_destroy(cls, MKDEV(major, 0));
    // 销毁目录
    class_destroy(cls);
    // 注销字符设备驱动
    unregister_chrdev(major, "mycdev2");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

马达.c

#include 
#include 
#include
#include
#include
#include"led.h"

int major;
char kbuf[128]={0};
gpio_t *vir_motor;
unsigned int *vir_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;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
     unsigned long ret;
    //向用户空间读取拷贝
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_to_user(ubuf,kbuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
    unsigned long ret;
    //从用户空间读取数据
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_from_user(kbuf,ubuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}
//ioctl
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    //根据功能码进行硬件功能控制
    switch(cmd)
    {
        case MOTOR_ON:
            vir_motor->ODR |= (1<<6);
            break;

        case MOTOR_OFF:
        
             vir_motor->ODR &= (~(1<<6));
         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,
    .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close,
};

int all_motor_init(void)
{
    //寄存器地址的映射
    vir_motor=ioremap(PHY_MOTOR_ADDR,sizeof(gpio_t));
    if(vir_motor==NULL)
    {
        printk("ioremap filed:%d\n",__LINE__);
        return -ENOMEM;
    }
     vir_rcc = ioremap(PHY_RCC_ADDR, 4);
    if(vir_rcc == NULL){
        printk("ioremap filed: %d\n", __LINE__);
        return -ENOMEM;
    }
    printk("物理地址映射成功\n");
    //寄存器的初始化
    //rcc
    (*vir_rcc) |= (1<<5);
    vir_motor->MODER &= ~(3<<12);
    vir_motor->MODER |= (1<<12);
    vir_motor->ODR &= ~(1<<6);
    printk("寄存器初始化成功\n");

    return 0;
}

static int __init mycdev_init(void)
{
    //字符设备驱动注册
    major=register_chrdev(0,"mycdev3",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n",major);
    //向上提交目录
    cls=class_create(THIS_MODULE,"mycdev3");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");
    //向上提交设备信息
    dev=device_create(cls,NULL,MKDEV(major,0),NULL,"mycdev3");
    if(IS_ERR(dev))
    {
        printk("向上提交设备信息失败\n");
        return PTR_ERR(dev);
    }
    printk("向上提交设备信息成功\n");

    //寄存器映射以及初始化
    all_motor_init();

    return 0;
}
static void __exit mycdev_exit(void)
{
    //取消地址映射
    iounmap(vir_motor);
    iounmap(vir_rcc);
    //销毁设备信息
    device_destroy(cls,MKDEV(major,0));
    //销毁目录
    class_destroy(cls);
    //注销字符设备驱动
    unregister_chrdev(major,"mycdev3");


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

test.c

#include
#include
#include 
#include 
#include 
#include
#include
#include 
#include"led.h"


int main(int argc, char const *argv[])
{
    char buf[128]={0};
    int fd=open("/dev/mychrdev",O_RDWR);
    int fd1=open("/dev/mycdev1",O_RDWR);
    int fd2=open("/dev/mycdev2",O_RDWR);
    int fd3=open("/dev/mycdev3",O_RDWR);
    if(fd<0 | fd1<0 | fd2<0 |fd3<0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    int a,b;
    while(1)
    {
        printf("请输入要实现的功能:1(开灯) 0(关灯) 3(打开风扇) 4(关闭风扇) 5(打开蜂鸣器) 6(关闭蜂鸣器) 7(打开马达) 8(关闭马达)>>>");
        scanf("%d",&a);
        if(a==1)//开灯
        {
            printf("请输入要操作的灯:(1(LED1) 2(LED2) 3(LED3)>");
            scanf("%d",&b);
            ioctl(fd,LED_ON,&b); 
        }
        else if(a==0) //关灯
        {
            printf("请输入要操作的灯:(1(LED1) 2(LED2) 3(LED3)>");
            scanf("%d",&b);
            ioctl(fd,LED_OFF,&b); 
        }
        else if(a==3) //打开风扇
        {
            
            ioctl(fd2,FAN_ON); 
        }
        else if(a==4) //关闭风扇
        {
            
            ioctl(fd2,FAN_OFF); 
        }
        else if(a==5) //打开蜂鸣器
        {
           
            ioctl(fd1,PWN_ON); 
        }
        else if(a==6) //关闭蜂鸣器
        {
           
            ioctl(fd1,PWN_OFF); 
        }
        else if(a==7) //打开马达
        {
            
            ioctl(fd3,MOTOR_ON); 
        }
        else if(a==8) //关闭马达
        {
           
            ioctl(fd3,MOTOR_OFF); 
        }
    }

    

    
    close(fd);

    return 0;
}

你可能感兴趣的:(c语言)