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

驱动开发(三):内核层控制硬件层

 驱动开发系列文章:
                驱动开发(一):驱动代码的基本框架    
                驱动开发(二):创建字符设备驱动
                驱动开发(三):内核层控制硬件层​​​​​​​         ←本文

目录

驱动是如何操作寄存器的

地址映射函数

物理地址映射为虚拟地址

取消映射

实际操作流程演示


驱动是如何操作寄存器的

驱动操作寄存器可以通过以下步骤实现:

  1. 获取寄存器的地址:首先需要确定要操作的寄存器的地址。这可以通过查阅芯片的数据手册或者使用芯片提供的寄存器映射文档来获得。

  2. 设置寄存器的值:使用编程语言提供的位操作或者寄存器操作函数,将需要设置的值写入到寄存器中。可以使用位掩码来确定要设置的位或者位域。

  3. 读取寄存器的值:使用编程语言提供的位操作或者寄存器操作函数,读取寄存器的当前值。可以使用位掩码来获取特定位或者位域的值。

需要注意的是,在操作寄存器时,要确保对寄存器的访问是合法的,遵循芯片厂商的规定,避免对未定义或者只读的寄存器进行写操作。此外,还要考虑并发访问的问题,如果多个驱动同时操作同一个寄存器,可能会引发竞争条件或者数据不一致的问题,需要进行同步或者互斥操作。

以点亮一盏灯为例,控制rgb_led灯的寄存器是物理地址,但是在Linux内核启动之后,在使用地址的时候,操作的全是虚拟地址需要将物理地址转换为虚拟地址。在驱动代码中操作的虚拟地址就相当于操作的实际物理地址。

地址映射函数

物理地址映射为虚拟地址

void * ioremap(phys_addr_t offset, unsigned long size)功能:将物理地址映射成虚拟地址参数:@offset :要映射的物理地址@size   :大小(字节)返回值:成功返回虚拟地址,失败返回NULL;

取消映射

void iounmap(void  *addr)功能:取消映射参数:	@addr :虚拟地址返回值:无

实际操作流程演示

1、以S5P6818的U21引脚输出高电平熄灭LED灯为例

2、在手册芯片搜索U21引脚

 GPIOXOUT寄存器:控制高低电平

GPIOXOUTENB寄存器:输入/输出模式 对应位置1设置为输出模式

 GPIOXALTFN寄存器:功能模式寄存器(配置引脚是哪种功能),刚刚查询引脚时可以看到,功能0为GPIO,选择功能0,

 GPIOA28 (0XC001A000)----> red_base   //起始地址

*(red_base) |= 1<<28;    //操作GPIOXOUT寄存器,控制引脚电平

*(red_base+1) |= 1<<28;   //操作GPIOXOUTENB寄存器,设置为输出模式

*(red_base+9) &= ~(3<<24);  //操作GPIOXALTFN寄存器,选择GPIO功能模式

 3、根据查询到的信息编写驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <asm/io.h>#define RED 0XC001A000      //起始物理地址
unsigned int *red_base = NULL;static int __init hello_init(void)
{red_base = ioremap(RED,40); //将物理地址映射成虚拟地址if (NULL == red_base ){printk("ioremap err\n");}*(red_base) &= ~(1<<28);    //操作寄存器*(red_base+1) |= 1<<28;*(red_base+9) &= ~(3<<24);return 0;
}
static void __exit hello_exit(void)
{*(red_base) |= (1<<28);    //还原LED状态iounmap(red_base);         //取消映射
}
module_init(hello_init); //入口
module_exit(hello_exit); //出口
MODULE_LICENSE("GPL");   //许可证

相关文章:

  • 英文字母表
  • uniapp运行到模拟器(联想模拟器)
  • 数据结构与算法笔记:基础篇 - 分治算法:谈一谈大规模计算框架MapReduce中的分治思想
  • 苏泊尔超声波清洗机怎么样?苏泊尔、小泽医生、希亦多个维度测评
  • 酱香型白酒派系介绍
  • IntelBroker 黑客声称入侵了苹果公司,窃取了内部工具的源代码
  • Leetcode Java学习记录——代码随想录哈希表篇
  • C++ 线程池
  • 盘点:20个大幅提高效率的开源网络安全工具
  • MongoDB 索引
  • Springboot + Mybatis 实现sql打印
  • 鸿蒙正在跨越“生态繁荣阈值”
  • 大语言模型-Transformer
  • html做一个分组散点图图的软件
  • 韩顺平0基础学java——第28天
  • .pyc 想到的一些问题
  • 【翻译】babel对TC39装饰器草案的实现
  • 【附node操作实例】redis简明入门系列—字符串类型
  • CSS实用技巧
  • extjs4学习之配置
  • Hexo+码云+git快速搭建免费的静态Blog
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Java,console输出实时的转向GUI textbox
  • jdbc就是这么简单
  • JS基础之数据类型、对象、原型、原型链、继承
  • Making An Indicator With Pure CSS
  • mysql常用命令汇总
  • Netty 4.1 源代码学习:线程模型
  • Redis 懒删除(lazy free)简史
  • vuex 笔记整理
  • 聚簇索引和非聚簇索引
  • 手写一个CommonJS打包工具(一)
  • 我有几个粽子,和一个故事
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • # 数论-逆元
  • #1015 : KMP算法
  • #预处理和函数的对比以及条件编译
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (1)(1.13) SiK无线电高级配置(六)
  • (12)Hive调优——count distinct去重优化
  • (8)STL算法之替换
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (HAL库版)freeRTOS移植STMF103
  • (LeetCode C++)盛最多水的容器
  • (WSI分类)WSI分类文献小综述 2024
  • (阿里云万网)-域名注册购买实名流程
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)、python程序--模拟电脑鼠走迷宫
  • (一)面试需要掌握的技巧
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)h264中avc和flv数据的解析