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

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

目录

驱动是如何操作寄存器的

地址映射函数

物理地址映射为虚拟地址

取消映射

实际操作流程演示


驱动是如何操作寄存器的

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

  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");   //许可证
相关推荐
振南的单片机世界2 小时前
从数码管到点阵屏:动态扫描加595,3个IO驱动256个LED
stm32·单片机·嵌入式硬件
listhi5202 小时前
STC8 16通道模拟采集 + 4路串口 + 8路PWM 程序
stm32·单片机·嵌入式硬件
Deitymoon3 小时前
STM32——OLED显示字符串
单片机·嵌入式硬件
Graceful_scenery4 小时前
龙芯2k0300 - 走马观碑组按键驱动移植
单片机·嵌入式硬件
d111111111d4 小时前
MQTT+STM32+ESP8266网络程序分层+韦老师
笔记·stm32·单片机·嵌入式硬件·学习·php
长安第一美人4 小时前
RT-Thread 工业屏驱动开发实战:UART 串口屏协议解析 + 数据实时刷新 + 设备驱动框架完整实现
驱动开发·嵌入式硬件·rt-thread·工业控制·uart通信·串口屏驱动
LDR0064 小时前
突破快充壁垒,赋能全场景体验——LDR6600 2C1A快充协议芯片重磅来袭
嵌入式硬件
weixin_457943304 小时前
arduino-舵机驱动
单片机·嵌入式硬件
AUTO_150756759654 小时前
SCT2160FNBR:7V 输入、6A、高效率同步降压 DC-DC 转换器
单片机·嵌入式硬件
LCG元4 小时前
STM32实战:基于STM32F103的编码器电机测速与闭环控制
stm32·单片机·嵌入式硬件