底层驱动day4作业

编程入门 行业动态 更新时间:2024-10-24 22:30:29

底层驱动day4<a href=https://www.elefans.com/category/jswz/34/1771149.html style=作业"/>

底层驱动day4作业

分布注册设备,实现文件和设备的绑定

代码:

//head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_RCC 0x50000A28
#define PHY_GPIOE_MODER 0x50006000
#define PHY_GPIOF_MODER 0x50007000
#define PHY_GPIOE_ODR 0x50006014
#define PHY_GPIOF_ODR 0x50007014typedef struct 
{unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR;
}gpio_t;#define GPIOE 0x50006000
#define GPIOF 0x50007000
#define PHY_RCC_ADDR 0x50000A28
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)#endif
//mycdev.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/device.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/uaccess.h>
#include<linux/slab.h>
#include"include/head.h"
unsigned int major = 0,minor = 0;
dev_t devno;
struct class *cls;
struct cdev* cdev;
struct device *dev;
gpio_t *vir_led1;
gpio_t *vir_led2;unsigned int *vir_rcc;int mycdev_open(struct inode *inode,struct file *file)
{int min = MINOR(inode->i_rdev);file->private_data = (void *)min;printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{int min = (int)(file->private_data);switch(min){case 0:switch(cmd){case LED_OFF:vir_led1->ODR &= (~(0x1 << 10));break;case LED_ON:vir_led1->ODR |= (0x1 << 10);break;}break;case 1:switch(cmd){case LED_OFF:vir_led2->ODR &= (~(0x1 << 10));break;case LED_ON:vir_led2->ODR |= (0x1 << 10);break;}break;case 2:switch(cmd){case LED_OFF:vir_led1->ODR &= (~(0x1 << 8));break;case LED_ON:vir_led1->ODR |= (0x1 << 8);break;}break;default:break;}printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}int mycdev_close(struct inode *inode,struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}int all_led_init(void)
{vir_led1 = ioremap(GPIOE,sizeof(gpio_t));if(NULL == vir_led1){printk("ioremap failed : %d\n",__LINE__);return -ENOMEM;}vir_led2 = ioremap(GPIOF,sizeof(gpio_t));if(NULL == vir_led2){printk("ioremap failed : %d\n",__LINE__);return -ENOMEM;} vir_rcc = ioremap(PHY_RCC,4);if(NULL == vir_rcc){printk("ioremap failed : %d\n",__LINE__);return -ENOMEM;}printk("寄存器内存映射成功\n");(*vir_rcc) |= (0x1 << 4);(*vir_rcc) |= (0x1 << 5);(vir_led1->MODER) &= (~(0x3 << 20));    //led1_moder(vir_led1->MODER) |= (0x1 << 20);(vir_led1->MODER) &= (~(0x3 << 16));    //led3_moder(vir_led1->MODER) |= (0x1 << 16);(vir_led1->ODR) &= (~(0x1 << 10));      //led1_odr(vir_led1->ODR) &= (~(0x1 << 8));      //led3_odr(vir_led2->MODER) &= (~(0x3 << 20));    //led2_moder(vir_led2->MODER) |= (0x1 << 20);(vir_led2->ODR) &= (~(0X1 << 10));      //led2_odrreturn 0;
}struct file_operations fops = {.open = mycdev_open,.unlocked_ioctl = mycdev_ioctl,.release = mycdev_close,
};static int __init mycdev_init(void)
{int ret;all_led_init();//申请对象空间cdev = cdev_alloc();if(NULL == cdev){printk("申请字符设备驱动对象空间失败\n");ret = -EFAULT;goto out;}printk("申请字符设备驱动对象空间成功\n");   //初始化对象cdev_init(cdev,&fops);//申请设备号if(0 == major){ret = alloc_chrdev_region(&devno,0,3,"mychrdev");if(0 != ret){printk("动态申请设备号失败\n");goto out2;}major = MAJOR(devno);minor = MINOR(devno);}else{ret = register_chrdev_region(MKDEV(major,minor),3,"mychrdev");if(0 != ret){printk("静态申请设备号失败\n");goto out2;}}printk("申请设备号成功\n");//注册驱动对象int ret2 = cdev_add(cdev,devno,3);if(0 != ret2){printk("注册驱动对象失败\n");goto out3;}printk("注册字符设备驱动对象成功\n");//向上提交目录cls = class_create(THIS_MODULE,"mychrdev");if(IS_ERR(cls)){printk("向上提交目录失败\n");goto out4;}printk("向上提交目录成功\n");//向上提交设备节点信息int i;for(i = 0;i < 3;i++){dev = device_create(cls,NULL,MKDEV(major,i),NULL,"mychrdev%d",i);if(IS_ERR(dev)){printk("向上提交设备节点失败\n");goto out5;}}   printk("向上提交设备节点成功\n");return 0;out5:for(--i;i >= 0;i--){device_destroy(cls,MKDEV(major,i));}class_destroy(cls);out4:cdev_del(cdev);out3:unregister_chrdev_region(MKDEV(major,minor),3);out2:kfree(cdev);out:return ret;}static void __exit mycdev_exit(void)
{//销毁设备节点信息int i;for(i = 0;i < 3;i++){device_destroy(cls,MKDEV(major,i));}//销毁设备目录class_destroy(cls);//销毁字符设备驱动对象cdev_del(cdev);//释放设备号unregister_chrdev_region(MKDEV(major,minor),3);kfree(cdev);return;
}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

 

//test.c
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/ioctl.h>
#include<stdio.h>
#include<string.h>
#include"include/head.h"int main(int argc, char const *argv[])
{char buf[128] = {0};int led_id,led_state;fgets(buf,sizeof(buf),stdin);buf[strlen(buf) - 1] = 0;int fd = open(buf,O_RDWR);if(fd < 0){printf("打开设备文件失败\n");return -1;}printf("打开设备文件成功\n");while(1){// fgets(buf,sizeof(buf),stdin);// buf[strlen(buf) - 1] = 0;// write(fd,buf,sizeof(buf));// scanf("%d",&led_id);scanf("%d",&led_state);switch(led_state){case 1:ioctl(fd,LED_ON);break;case 0:ioctl(fd,LED_OFF);break;default:break;}}//read(fd,buf,sizeof(buf));// memset(buf,0,sizeof(buf));// read(fd,buf,sizeof(buf));// printf("buf:%s\n",buf);close(fd);return 0;
}

实现效果:

更多推荐

底层驱动day4作业

本文发布于:2023-12-04 11:32:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1660775.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:作业   底层

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!