当前位置: 首页 > article >正文

4月19日驱动开发

点亮3个led灯和蜂鸣器和风扇

#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;

}gpio_t;

#define PHY_LED1 0x50006000

#define PHY_LED2 0x50007000

#define PHY_LED3 0x50006000

#define PHY_RCC 0x50000A28

#define PHY_FAN 0x50006000

#define PHY_BELL 0x50003000

#endif

#include<linux/init.h>

#include<linux/module.h>

#include<linux/fs.h>

#include<linux/uaccess.h>

#include<linux/io.h>

#include<linux/device.h>

#include"ledall.h"

int major;

char kbuf[128]={0};

unsigned int *vir_moder;

struct class *cls;

struct device *dev;

gpio_t *vir_led1;

gpio_t *vir_led2;

gpio_t *vir_led3;

gpio_t *vir_bell;

gpio_t *vir_fan;

unsigned int *vir_rcc;

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 failed\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_from_user failed\n");

        return ret;

    }

    printk("结果是:%s\n",kbuf);

    switch (kbuf[0]){

    case '1':

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

            vir_led1->odr |=(0x1<<10);

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

            vir_led1->odr &=(~(0x1<<10));

            break;

    case '2':

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

            {

                vir_led2->odr |=(0x1<<10);

            }

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

            {

                vir_led2->odr &=(~(0x1<<10));

            }

            break;

    case '3':

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

            vir_led3->odr |=(0x1<<8);

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

            vir_led3->odr &=(~(0x1<<8));

            break;

    case '4':

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

            (vir_bell->odr) |= (0x1<<6);

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

             (vir_bell->odr) &= (~(0x1<<6));

             break;

    case '5':

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

            (vir_fan->odr) |= (0x1<<9);

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

             (vir_fan->odr) &= (~(0x1<<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,

    .release=mycdev_close,

 

};

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");

    //灯的初始化

    vir_led1=ioremap(PHY_LED1,sizeof(gpio_t));

    vir_led2=ioremap(PHY_LED2,sizeof(gpio_t));

    vir_led3=ioremap(PHY_LED3,sizeof(gpio_t));

    vir_rcc=ioremap(PHY_RCC,4);

    vir_bell=ioremap(PHY_BELL,sizeof(gpio_t));

    vir_fan=ioremap(PHY_FAN,sizeof(gpio_t));

    if(vir_led1==NULL)

    {

        printk("ioremap1 failed:%d\n",__LINE__);

        return -ENOMEM;

    }

    if(vir_led2==NULL)

    {

        printk("ioremap2 failed:%d\n",__LINE__);

         return -ENOMEM;

    }

    if(vir_led3==NULL)

    {

        printk("ioremap3 failed:%d\n",__LINE__);

         return -ENOMEM;

    }

     if(vir_rcc==NULL)

    {

        printk("ioremaprcc failed:%d\n",__LINE__);

         return -ENOMEM;

    }

    printk("物理地址映射成功\n");

    //寄存器的初始化

    //GPIOE,GPIOF引脚使能

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

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

    //GPIOB引脚使能

    *(vir_rcc) |= (0x1<<1);

    (vir_led1->moder) &= (~(0x3<<20));

    (vir_led1->moder) |= (0x1<<20);

    (vir_led1->odr) &= (~(0x1<<10));

    (vir_led2->moder) &= (~(0x3<<20));

    (vir_led2->moder) |= (0x1<<20);

    (vir_led2->odr) &= (~(0x1<<10));

    (vir_led3->moder) &= (~(0x3<<16));

    (vir_led3->moder) |= (0x1<<16);

    (vir_led3->odr) &= (~(0x1<<8));

    //风扇和蜂鸣器

    (vir_bell->moder) &= (~(0x3<<12));

    (vir_bell->moder) |=(0x1<<12);

    (vir_bell->odr) &= (~(0x1<<6));

     (vir_fan->moder) &= (~(0x3<<18));

    (vir_fan->moder) |=(0x1<<18);

    (vir_fan->odr) &= (~(0x1<<9));

    printk("初始化寄存器成功!\n");

    return 0;

}

static void __exit mycdev_exit(void)

{

    //取消地址映射

    iounmap(vir_led1);

    iounmap(vir_led2);

    iounmap(vir_led3);

    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");

#include<stdlib.h>

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<string.h>

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

{

    char buf[128]={0};

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

    if(fd<0)

    {

        printf("打开设备失败\n");

        exit(-1);

    }

    while(1)

    {

        printf("请输入两个字符\n");

        fgets(buf,sizeof(buf),stdin);

        buf[strlen(buf)-1]='\0';

          write(fd,buf,sizeof(buf));

         }

   

    close(fd);

    return 0;

}


http://www.kler.cn/a/15260.html

相关文章:

  • 【电子设计】按键LED控制与FreeRTOS
  • 商业物联网详细指南:优势与挑战
  • 基于yolov8、yolov5的行人检测识别系统(含UI界面、训练好的模型、Python代码、数据集)
  • 【网络】什么是交换机?switch
  • 【论文模型复现】深度学习、地质流体识别、交叉学科融合?什么情况,让我们来看看
  • 哈希表学习分享
  • 数据类型决定了计算机的计算速度
  • macOS 13.4Beta 3(22F5049e)发布
  • 结构体指针、数组指针和结构体数组指针
  • electron入门 | 手把手带electron项目初始化
  • 数据结构(数组、链表、栈、队列、树)
  • 内网远程控制软件哪个好用
  • Spark on Yarn模式下执行过程
  • 二进制码与格雷码的相互转换原理与Verilog实现
  • Java 输出机制 数据类型 基本数据类型转换 基本数据类型和String类型的转换
  • 用LDA主题模型并进行可视化
  • Vivado增量编译:加速FPGA设计实现的利器
  • Qt连接MySql数据库(本地和远程数据库均可)
  • 【细读Spring Boot源码】重中之重refresh()
  • 用友自主研发企业商用版TimensionDB时序数据库重磅发布!
  • 【算法】【算法杂谈】判断点是否在三角形内部(面积法和向量法)
  • 西门子S7-1500与FANUC机器人进行EtherNetIP通信的具体方法示例
  • 从0搭建Vue3组件库(九):VitePress 搭建部署组件库文档
  • 【华为OD机试真题】简单的解压缩算法(javapython) 100%通过率 超详细代码注释
  • 大数据Doris(三):Apache Doris分布式部署准备工作
  • <网络编程>网络套接字