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

}

相关推荐
TE-茶叶蛋15 小时前
Spec-Driven Development(规范驱动开发)
驱动开发
云栖梦泽1 天前
Camera驱动开发与应用开发中的零拷贝与DMA
linux·驱动开发·嵌入式硬件
脱胎换骨-军哥2 天前
C++ 嵌入式编程实例:从寄存器操作到底层驱动开发
开发语言·c++·驱动开发
智者知已应修善业2 天前
【使用D触发器74HC175实现0001 0011 0111 1111 1110 1100 1000的循环彩灯电路。】2025-4-28
驱动开发·经验分享·笔记·硬件架构·硬件工程
新元代码2 天前
SDD+TDD 双驱动开发模式实战指南
驱动开发
mk0153 天前
20V输入,12V 3A输出 效率96%DCDC降压芯片
驱动开发·单片机·硬件工程·智能硬件·pcb工艺
mounter6254 天前
跨越鸿沟:从内核驱动开发到超大规模云端生产环境的思考
linux·驱动开发·linux kernel·kernel
Saniffer_SH4 天前
NAND技术(二):从 Channel、Die/LUN、P/E Cycle 到 LDPC,一次讲透 NAND 里那些最容易误解的概念
人工智能·驱动开发·嵌入式硬件·测试工具·fpga开发·计算机外设·压力测试
2401_854151554 天前
嵌入式传感器驱动开发深度解析——从 I2C/SPI 驱动到数据融合算法
驱动开发·算法
Bug退散师4 天前
多路IO复用[select版TCP服务器与poll版TCP服务器]与常用网络编程函数详解
linux·服务器·c语言·网络·驱动开发·tcp/ip