驱动开发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;

}

相关推荐
喵叔哟2 小时前
从 Prompt 到可执行规格:认识 GitHub Spec Kit
驱动开发·prompt·github
飞多学堂12 小时前
每日开源硬件精选简报 2026-09-11
驱动开发·开源·开源硬件·硬件开源·电子制作
码农客栈18 小时前
Linux I2C驱动实验
linux·运维·驱动开发
智者知已应修善业1 天前
【如何将此图变为000到101就返回】2026-4-7
驱动开发·经验分享·笔记·硬件架构·硬件工程
国产化创客2 天前
创客开发入门(七)Arduino ESP32-WS2812开发
驱动开发·单片机·物联网·智能硬件
ItJavawfc3 天前
Linux驱动-RTC-RX8010集成-驱动开发-系统移植-移植RX8010驱动
驱动开发·rtc·8010rtc 驱动移植
sukalot3 天前
windows 驱动实例分析系列: HidHide驱动分析-HidHideClient 篇(中)
windows·驱动开发
HRTOS6 天前
HRTOS 4.0 驱动库:06_Storage 存储设备驱动——24C02 EEPROM与I²C驱动开发
c语言·驱动开发·嵌入式硬件·51单片机
KFCgrandpahhh6 天前
rk3576点灯
linux·驱动开发
HRTOS6 天前
HRTOS 4.0 正式发布:Driver Library 基础外设驱动模块介绍
驱动开发·单片机·嵌入式硬件·51单片机