驱动开发day2

demo3.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include "head.h"

#include <linux/io.h>

unsigned int major;

char kbuf[128]={};

//定义三个指针指向映射后的虚拟内存

unsigned int *vir_moder1;

unsigned int *vir_odr1;

unsigned int *vir_moder2;

unsigned int *vir_odr2;

unsigned int *vir_moder3;

unsigned int *vir_odr3;

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

int ret;

ret=copy_to_user(ubuf,kbuf,size);

if(ret)

{

printk("copy_to_user filed\n");

return -EIO;

}

return 0;

}

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

{

printk("%s:%s:%d\n",FILE,func,LINE);

int ret;

ret=copy_from_user(kbuf,ubuf,size);

if(ret)

{

printk("copy_from_user filed\n");

return -EIO;

}

if(kbuf[0]=='1'&&kbuf[1]=='0') //关灯

{

(*vir_odr1) &= (~(0x1 << 10));

}

else if(kbuf[0]=='1'&&kbuf[1]=='1') //开灯

{

(*vir_odr1) |= (0x1 << 10);

}

if(kbuf[0]=='2'&&kbuf[1]=='0') //关灯

{

(*vir_odr2) &= (~(0x1 << 10));

}

else if(kbuf[0]=='2'&&kbuf[1]=='1') //开灯

{

(*vir_odr2) |= (0x1 << 10);

}

if(kbuf[0]=='3'&&kbuf[1]=='0') //关灯

{

(*vir_odr3) &= (~(0x1 << 8));

}

else if(kbuf[0]=='3'&&kbuf[1]=='1') //开灯

{

(*vir_odr3) |= (0x1 << 8);

}

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 s1(void)

{

//注册字符设备驱动

major = register_chrdev(0,"mychrdev",&fops);

if(major < 0)

{

printk("字符设备驱动注册失败\n");

return major;

}

printk("注册字符设备驱动成功major=%d\n",major);

//进行寄存器的地址映射,将物理地址映射为虚拟地址

vir_moder1=ioremap(PHY_LED1_MODER,4);

vir_moder2=ioremap(PHY_LED2_MODER,4);

vir_moder3=ioremap(PHY_LED3_MODER,4);

if(vir_moder1==NULL||vir_moder2==NULL||vir_moder3==NULL)

{

printk("物理内存地址映射失败%d\n",LINE);

return -EFAULT;

}

vir_odr1=ioremap(PHY_LED1_ODR,4);

vir_odr2=ioremap(PHY_LED2_ODR,4);

vir_odr3=ioremap(PHY_LED3_ODR,4);

if(vir_odr1==NULL||vir_odr2==NULL||vir_odr3==NULL)

{

printk("物理内存地址映射失败%d\n",LINE);

return -EFAULT;

}

vir_rcc=ioremap(PHY_RCC,4);

if(vir_rcc==NULL)

{

printk("物理内存地址映射失败%d\n",LINE);

return -EFAULT;

}

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

(*vir_rcc) |= (0x1<<4);//GPIOE控制器时钟使能

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

//LED1寄存器初始化

(*vir_moder1) &= (~(0x3<<20));

(*vir_moder1) |= (0x1<<20);

(*vir_odr1) &= (~(0x1<<10));//默认关灯

//LED2寄存器初始化

(*vir_moder2) &= (~(0x3<<20));

(*vir_moder2) |= (0x1<<20);

(*vir_odr2) &= (~(0x1<<10));//默认关灯

//LED3寄存器初始化

(*vir_moder3) &= (~(0x3<<16));

(*vir_moder3) |= (0x1<<16);

(*vir_odr3) &= (~(0x1<<8));//默认关灯

return 0;

}

static void __exit s2(void)

{

//取消物理地址内存映射

iounmap(vir_rcc);

iounmap(vir_moder1);

iounmap(vir_odr1);

iounmap(vir_moder2);

iounmap(vir_odr2);

iounmap(vir_moder3);

iounmap(vir_odr3);

//注销字符设备驱动

unregister_chrdev(major,"mychrdev");

}

module_init(s1);

module_exit(s2);

MODULE_LICENSE("GPL");

head.h

#ifndef HEAD__H

#define HEAD__H

#define PHY_LED1_MODER 0x50006000

#define PHY_LED1_ODR 0x50006014

#define PHY_LED2_MODER 0x50007000

#define PHY_LED2_ODR 0x50007014

#define PHY_LED3_MODER 0x50006000

#define PHY_LED3_ODR 0x50006014

#define PHY_RCC 0x50000A28

#endif

test.c

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

#include <unistd.h>

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

{

char buf[128]={0};

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

if(fd<0)

{

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

return -1;

}

printf("打开设备文件成功\n");

while(1)

{

printf("请输入要进行的操作:0(关灯)1(开灯)");

fgets(buf,sizeof(buf),stdin);//从终端读取一个字符串

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

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

memset(buf,0,sizeof(buf));

}

close(fd);

return 0;

}

相关推荐
普通网友9 小时前
深入探讨Linux驱动开发:字符设备驱动开发与测试_linux 驱动开发设备号(2)
java·linux·驱动开发
martian6659 小时前
深入解析C++驱动开发实战:优化高效稳定的驱动应用
开发语言·c++·驱动开发
sukalot9 小时前
window显示驱动开发—小型命令列表的优化
驱动开发
电子小子洋酱11 小时前
Linux显示设备驱动开发 Drm驱动&&Makefile
linux·驱动开发·笔记
小马过河R11 小时前
浅谈AI辅助编码从氛围编程Vibe Coding到基于spec规范驱动开发
人工智能·驱动开发·ai编程
信工 180213 小时前
camera驱动系列1-csi总体概述
驱动开发
森焱森14 小时前
当八字命理遇上软件开发:一张“流派架构图”+ 实战爬虫指南
驱动开发·爬虫·python·flask·pygame
点灯master1 天前
DAC8562的驱动设计开发
c语言·驱动开发·stm32
小a杰.1 天前
Flutter 测试驱动开发的基本流程
驱动开发·flutter
取个名字太难了a1 天前
驱动开发之遍历驱动
驱动开发