驱动开发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 kbuf128={};

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

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(kbuf0=='1'&&kbuf1=='0') //关灯

{

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

}

else if(kbuf0=='1'&&kbuf1=='1') //开灯

{

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

}

if(kbuf0=='2'&&kbuf1=='0') //关灯

{

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

}

else if(kbuf0=='2'&&kbuf1=='1') //开灯

{

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

}

if(kbuf0=='3'&&kbuf1=='0') //关灯

{

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

}

else if(kbuf0=='3'&&kbuf1=='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 buf128={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);//从终端读取一个字符串

bufstrlen(buf)-1='\0';

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

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

}

close(fd);

return 0;

}

相关推荐
小小程序员mono1 小时前
CI 早已消亡,GitHub 还在固守旧时代
驱动开发
可以飞的话4 小时前
图像格式基础
驱动开发
大江东去浪淘尽千古风流人物4 天前
【Micro-WL Robot】桌面级轮腿机器人全栈解析:LQR平衡控制、SimpleFOC驱动与五连杆腿部机构源码深度拆解
驱动开发·机器人·esp32·lqr·simplefoc·轮腿机器人·平衡控制
咖啡星人k4 天前
自然语言驱动开发(NLDD):全栈开发的新范式与实践指南
驱动开发
阿昭L4 天前
Windows键盘过滤
windows·驱动开发·windows内核·过滤驱动
hai3152475435 天前
# 矩阵算法·算子对齐工具 v6.1 — 技术规格与使用手册
java·开发语言·驱动开发·神经网络·spring·目标检测·矩阵
qq_411262426 天前
sdk不支持分配psarm如何办,能不能象S3一样支持
驱动开发
湉湉家的小虎子6 天前
【科普贴】浅谈UFS接口——偏硬件解析
驱动开发·嵌入式硬件·fpga开发·硬件工程
枳实-叶7 天前
【Linux驱动开发】第18天:I2C驱动深度解析
linux·运维·驱动开发
小此方7 天前
Re:Linux系统篇(二十五)进程篇·十:深度硬核!Linux 进程等待,从 task_struct 源码到位图状态解构
linux·运维·驱动开发