2023.2.8作业【ioctl函数控制六个LED和蜂鸣器、蜂鸣器】

内核代码

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include <linux/io.h>

#include "myled.h"

#define CNAME "myled"

int major;//1.定义一个变量,保存字符设备创建成功之后,得到的主设备号

struct class *cls;

struct device *dev;

char kbuf[128]={0};

volatile gpio_t* virt_gpioe;

volatile gpio_t* virt_gpiof;

volatile gpio_t* virt_gpioz;

volatile gpio_t* virt_gpiob;

volatile unsigned int* virt_rcc_gpioe;

volatile unsigned int* virt_rcc_gpioz;

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

{

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

    return 0;

}

long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

    int flag,ret;

    switch(cmd)

    {

        //开灯

    case LED_ON:

        //从用户空间获取数据

        ret = copy_from_user(&flag,(void*)arg, sizeof(int));

        if(ret)

        {

            printk("copy_from_user error\n");

            return -ENOMEM;

        }

        //选择那一盏灯

        switch (flag)

        {

        case 1:

            virt_gpioe->ODR |= (1 << 10);

            break;

        case 2:

            virt_gpiof->ODR |= (1 << 10);

            break;

        case 3:

            virt_gpioe->ODR |= (1 << 8);

            break;  

       

        default:

            break;

        }

        break;

    //关灯

    case LED_OFF:

        ret = copy_from_user(&flag,(void*)arg, sizeof(int));

        if(ret)

        {

            printk("copy_from_user failed\n");

            return -ENOMEM;

        }

        switch (flag)

        {

        case 1:

            virt_gpioe->ODR &= (~(1 << 10));

            break;

        case 2:

            virt_gpiof->ODR &= (~(1 << 10));

            break;

        case 3:

            virt_gpioe->ODR &= (~(1 << 8));

            break;  

       

        default:

            break;

        }

        break;

    case LED_ZB_ON:

        ret = copy_from_user(&flag,(void*)arg, sizeof(int));

        if(ret)

        {

            printk("copy_from_user failed\n");

            return -ENOMEM;

        }

        switch (flag)

        {

        case 1:

            virt_gpioz->ODR |= (1 << 5);

            break;

        case 2:

            virt_gpioz->ODR |= (1 << 6);

            break;

        case 3:

            virt_gpioz->ODR |= (1 << 7);

            break;  

        default:

            break;

        }

        break;

    case LED_ZB_OFF:

        ret = copy_from_user(&flag,(void*)arg, sizeof(int));

        if(ret)

        {

            printk("copy_from_user failed\n");

            return -ENOMEM;

        }

        switch (flag)

        {

        case 1:

            virt_gpioz->ODR &= (~(1 << 5));

            break;

        case 2:

            virt_gpioz->ODR &= (~(1 << 6));

            break;

        case 3:

            virt_gpioz->ODR &= (~(1 << 7));

            break;  

       

        default:

            break;

        }

        break;

    case BEE_ON:

        virt_gpiob->ODR |= (1 << 6);

        break;

    case BEE_OFF:

        virt_gpiob->ODR &= (~(1 << 6));

        break;

    case MON_ON:

        virt_gpiof->ODR |= (1 << 6);

        break;

    case MON_OFF:

        virt_gpiof->ODR &= (~(1 << 6));

        break;

    }

   

    return 0;

}

ssize_t  mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *off)

{

    int ret;

    //判断kbuf的大小,如果<size,把size的数值修改为kbuf的大小

    if(size>sizeof(kbuf))

    size=sizeof(kbuf);

    ret=copy_to_user(ubuf,kbuf,size);

    if(ret)

    {

        printk("copy_to_user filed\n");

        return -EIO;//拷贝失败返回错误码

    }

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

    return 0;

}

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

{

    int ret;

    if(size>sizeof(kbuf))

    size=sizeof(kbuf);

    ret=copy_from_user(kbuf,ubuf,size);

    if(ret)

    {

        printk("copy_from_user filed\n");

        return -EIO;//拷贝失败返回错误码

    }

    return 0;

}

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

{

    printk("close:%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,

    .unlocked_ioctl=mycdev_ioctl,

};

static int __init mycdev_init(void)

{

    major = register_chrdev(0,CNAME,&fops);

    if(major < 0)

    {

        printk("register chrdev is error\n");

    }

    printk("register chrdev major=%d\n",major);

    virt_gpioe = ioremap(PHY_GPIOE_MODER,sizeof(gpio_t));

    if(NULL == virt_gpioe)

    {

        printk("virt_gpioe ioremap is error\n");

        return -EIO;

    }

    virt_gpiob = ioremap(PHY_GPIOb_MODER,sizeof(gpio_t));

    if(NULL == virt_gpiob)

    {

        printk("virt_gpiob ioremap is error\n");

        return -EIO;

    }virt_gpioz = ioremap(PHY_GPIOZ_MODER,sizeof(gpio_t));

    if(NULL == virt_gpioz)

    {

        printk("virt_gpioz ioremap is error\n");

        return -EIO;

    }virt_gpiof = ioremap(PHY_GPIOF_MODER,sizeof(gpio_t));

    if(NULL == virt_gpiof)

    {

        printk("virt_gpiof ioremap is error\n");

        return -EIO;

    }

    virt_rcc_gpioe = ioremap(PHY_RCC_GPIOE,4);

    if(NULL == virt_rcc_gpioe)

    {

        printk("gpioe rcc ioremap is error\n");

        return -EIO;

    }

    virt_rcc_gpioz = ioremap(PHY_RCC_GPIOZ,4);

    if(NULL == virt_rcc_gpioz)

    {

        printk("gpioz rcc ioremap is error\n");

        return -EIO;

    }

    //PE10

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

    virt_gpioe->MODER &= (~(0x3 << 20));

    virt_gpioe->MODER |= (0x1 << 20);

    virt_gpioe->ODR &= (~(0x1 << 10));

    //PF10

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

    virt_gpiof->MODER &= (~(0x3 << 20));

    virt_gpiof->MODER |= (0x1 << 20);

    virt_gpiof->ODR &= (~(0x1 << 10));

    //PE8

    virt_gpioe->MODER &= (~(0x3 << 16));

    virt_gpioe->MODER |= (0x1 << 16);

    virt_gpioe->ODR &= (~(0x1 << 8));

    //PZ5-7

    *virt_rcc_gpioz |= (1 << 0);

    (virt_gpioz->MODER) &= (~(3 << 10));

    (virt_gpioz->MODER) |= (1 << 10);

    (virt_gpioz->ODR) &= (~(1<<5));

    (virt_gpioz->MODER) &= (~(3 << 12));

    (virt_gpioz->MODER) |= (1 << 12);

    (virt_gpioz->ODR) &= (~(1<<6));

    (virt_gpioz->MODER) &= (~(3 << 14));

    (virt_gpioz->MODER) |= (1 << 14);

    (virt_gpioz->ODR) &= (~(1<<7));

    //蜂鸣器

    (virt_gpiob->MODER) &= (~(3 << 12));

    (virt_gpiob->MODER) |= (1 << 12);

    (virt_gpiob->ODR) &= (~(1<<6));

    //马达

    (virt_gpiof->MODER) &= (~(3 << 12));

    (virt_gpiof->MODER) |= (1 << 12);

    (virt_gpiof->ODR) &= (~(1<<6));

    printf("register init successful!!!\n");

    return 0;

}


 

static void __exit mycdev_exit(void)

{

    iounmap(virt_rcc_gpioe);

    iounmap(virt_rcc_gpioz);

    iounmap(virt_gpiof);

    iounmap(virt_gpioe);

    iounmap(virt_gpiob);

    iounmap(virt_gpioz);

    unregister_chrdev(major,CNAME);

}

module_init(mycdev_init);

module_exit(mycdev_exit);

MODULE_LICENSE("GPL");

应用层代码

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>  

#include <sys/ioctl.h>

#include "myled.h"

char buf[128] = "0";

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

{

    int fd = -1;

    int whitch;

    int num, flag;

    fd = open("/dev/myled",O_RDWR);

    if(-1 == fd)

    {

        perror("open is error");

        exit(1);

    }

   

    while(1)

    {

        //先给一个无效的值

        whitch = -1;

        printf("1、辅助版LED亮灭\n");

        printf("2、主板LED亮灭\n");

        printf("3、蜂鸣器控制\n");

        printf("4、马达控制\n");

        printf("请选择一个操作>>>");

        scanf("%d", &whitch);

        switch (whitch)

        {

        case LED_FZ:

            num = -1;

            printf("1、LED1\n2、LED1\n3、LED1\n");

            printf("请选择一个操作>>>");

            scanf("%d", &num);

            printf("1、亮\n2、灭");

            printf("请选择一个操作>>>");

            scanf("%d", &flag);

            if(flag)

            {

                ioctl(fd,LED_ON,&flag);

            }else if(!flag)

            {

                ioctl(fd,LED_OFF,&flag);

            }

            break;

        case LED_ZB:

            num = -1;

            printf("1、LED1\n2、LED1\n3、LED1\n");

            printf("请选择一个操作>>>");

            scanf("%d", &num);

            printf("1、亮\n2、灭");

            printf("请选择一个操作>>>");

            scanf("%d", &flag);

            if(flag)

            {

                ioctl(fd,LED_ZB_ON,&flag);

            }else if(!flag)

            {

                ioctl(fd,LED_ZB_OFF,&flag);

            }

            break;

        case BEE:

            printf("1、工作\n2、不工作");

            printf("请选择一个操作>>>");

            scanf("%d", &flag);

            if(flag)

            {

                ioctl(fd,BEE_ON,&flag);

            }else if(!flag)

            {

                ioctl(fd,BEE_OFF,&flag);

            }

            break;

        case MON:

            printf("1、工作\n2、不工作");

            printf("请选择一个操作>>>");

            scanf("%d", &flag);

            if(flag)

            {

                ioctl(fd,MON_ON,&flag);

            }else if(!flag)

            {

                ioctl(fd,MON_OFF,&flag);

            }

            break;

        default:

            printf("输入有误,请重新输入!!!\n");

            break;

        }

    }

    close(fd);

    return 0;

}

头文件

#ifndef __LED_H__

#define __LED_H__


 

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;

typedef enum{

    LED1 = 0,

    LED2,

    LED3

}led_t;

enum{

    LED_FZ = 1,

    LED_ZB,

    BEE,

    MON

};

#define PHY_GPIOZ_MODER 0X54004000

#define PHY_GPIOb_MODER 0X50003000

#define PHY_GPIOE_MODER 0x50006000

#define PHY_GPIOF_MODER 0x50007000

#define PHY_RCC_GPIOE   0x50000A28

#define PHY_RCC_GPIOZ   0X50000210

//辅助板LED亮灭

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

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

//主板LED亮灭

#define LED_ZB_ON _IOW('a',1,int)

#define LED_ZB_OFF _IOW('a',0,int)

//蜂鸣器工作/不工作

#define BEE_ON _IOW('a',1,int)

#define BEE_OFF _IOW('a',0,int)

//马达工作/不工作

#define MON_ON _IOW('a',1,int)

#define MON_OFF _IOW('a',0,int)

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值