当前位置: 首页 > news >正文

驱动开发--day2

实现三盏灯的控制,编写应用程序测试
head.h

#ifndef __HEAD_H__
#define __HEAD_H__#define LED1_MODER 0X50006000
#define LED1_ODR 0X50006014
#define LED1_RCC 0X50000A28#define LED2_MODER 0X50007000
#define LED2_ODR 0X50007014#endif

mychrdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"//保存主设备号
unsigned int major;char kbuf[128]={0};unsigned int* vir_moder;
unsigned int* vir_odr;
unsigned int* vir_rcc;unsigned int* vir_moder_F;
unsigned int* vir_odr_F;
//封装操作方法
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)
{int ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user err\n");return -EIO;}return 0;
}
ssize_t mycdev_write(struct file* file,const char *ubuf,size_t size,loff_t *lof)
{int ret;ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user err\n");return -EIO;}if(kbuf[0]=='1'){//开灯逻辑if(kbuf[1]=='1'){(*vir_odr) |= (0x1<<10);}else if(kbuf[1]=='2'){(*vir_odr_F) |= (0x1<<10);}else if(kbuf[1]=='3'){(*vir_odr) |= (0x1<<8);}}else if(kbuf[0]=='0'){//关灯逻辑if(kbuf[1]=='1'){(*vir_odr) &= (~(0x1<<10));}else if(kbuf[1]=='2'){(*vir_odr_F) &= (~(0x1<<10));}else if(kbuf[1]=='3'){(*vir_odr) &= (~(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 mycdev_init(void)
{//字符设备驱动的注册major=register_chrdev(0,"mychrdev",&fops);if(major<0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功 major=%d\n",major);//进行相关寄存器的内存映射vir_odr=ioremap(LED1_ODR,4);if(vir_odr==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_rcc=ioremap(LED1_RCC,4);if(vir_rcc==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_moder=ioremap(LED1_MODER,4);if(vir_moder==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");vir_moder_F=ioremap(LED2_MODER,4);if(vir_moder_F==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");vir_odr_F=ioremap(LED2_ODR,4);if(vir_odr_F==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");//硬件寄存器的初始化//RCC使能(*vir_rcc) |= (0x1<<4);(*vir_rcc) |= (0x1<<5);//设置PE10为输出(*vir_moder) &= (~(0x3<<20));(*vir_moder) |= (0x1<<20);//设置PF8为输出(*vir_moder_F) &= (~(0x3<<20));(*vir_moder_F) |= (0x1<<20);//设置PE8为输出(*vir_moder) &= (~(0x3<<16));(*vir_moder) |= (0x1<<16);//默认关灯(*vir_odr) &= (~(0X1<<10));(*vir_odr_F) &= (~(0X1<<10));(*vir_odr) &= (~(0X1<<8));return 0;
}
static void __exit mycdev_exit(void)
{//取消物理内存映射iounmap(vir_moder);iounmap(vir_odr);iounmap(vir_rcc);iounmap(vir_moder_F);iounmap(vir_odr_F);//字符设备驱动的注销unregister_chrdev(major,"mychrdev");
}module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

test.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char const *argv[])
{char buf[128]={0};int fd=open("/dev/mychrdev",O_RDWR);if(fd<0){printf("设备文件打开失败\n");exit(-1);}while(1){memset(buf,0,sizeof(buf));printf("请输入对LED1的控制命令11(开灯) 01(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));memset(buf,0,sizeof(buf));printf("请输入对LED2的控制命令12(开灯) 02(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));memset(buf,0,sizeof(buf));printf("请输入对LED3的控制命令13(开灯) 03(关灯)>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));}close(fd);
}

测试过程及现象:

1.编译>>>

2.测试>>>

3.现象>>>

http://www.lryc.cn/news/158706.html

相关文章:

  • 用户促活留存新方式——在APP中嵌入小游戏
  • MySQL 8.0.34(x64)安装笔记
  • 物流供应商实现供应链自动化的3种方法
  • Mysql更新时间列只改日期为指定日期不更改时间
  • 实时测试工具 Visual Studio 扩展 NCrunch 4.18 Crack
  • Neo4j 基本语法
  • docker常见面试题
  • 静态路由:配置和使用详解
  • 玩转Mysql系列 - 第15篇:详解视图
  • 0065__git fetch, git pull, git merge, git rebase
  • AJAX学习笔记4解决乱码问题
  • 【23种设计模式】享元模式【⭐】
  • 语音信号的仿真原理
  • VLDB 2023 | CDSBen: 字节跳动 veDB 数据库存储系统性能测试模型
  • crontab的配置参数和基础使用教程
  • 基于Python开发的玛丽大冒险小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)
  • K8S之使用yaml格式定义pod
  • SSH命令详解
  • Windows SQLYog连接不上VMbox Ubuntu2204 的Mysql解决方法
  • Python中的日期和时间(一)datetime模块
  • qt触控板手势检测
  • 数据库 Redis
  • Linux之权限
  • 【产线故障】线上接口请求过慢如何排查?
  • Increment Selection 插件
  • LeetCode刷题笔记【26】:贪心算法专题-4(柠檬水找零、根据身高重建队列、用最少数量的箭引爆气球)
  • LeetCode:移除元素
  • Spring中的JdbcTemplate的使用
  • 机器学习——boosting之GBDT
  • 如何选择报修管理系统?报修工单管理系统有哪些功能和优势?