微信企业官方网站怎么做,做网站如何赚钱知乎,做影视网站 片源从哪里来,wordpress 后台拿shell驱动开发系列文章#xff1a; 驱动开发#xff08;一#xff09;#xff1a;驱动代码的基本框架 驱动开发#xff08;二#xff09;#xff1a;创建字符设备驱动 驱动开发#xff08;三#xff09;#xff1a;内核层控制硬件层 ←本文 目录… 驱动开发系列文章 驱动开发一驱动代码的基本框架 驱动开发二创建字符设备驱动 驱动开发三内核层控制硬件层 ←本文 目录
驱动是如何操作寄存器的
地址映射函数
物理地址映射为虚拟地址
取消映射
实际操作流程演示 驱动是如何操作寄存器的 驱动操作寄存器可以通过以下步骤实现 获取寄存器的地址首先需要确定要操作的寄存器的地址。这可以通过查阅芯片的数据手册或者使用芯片提供的寄存器映射文档来获得。 设置寄存器的值使用编程语言提供的位操作或者寄存器操作函数将需要设置的值写入到寄存器中。可以使用位掩码来确定要设置的位或者位域。 读取寄存器的值使用编程语言提供的位操作或者寄存器操作函数读取寄存器的当前值。可以使用位掩码来获取特定位或者位域的值。 需要注意的是在操作寄存器时要确保对寄存器的访问是合法的遵循芯片厂商的规定避免对未定义或者只读的寄存器进行写操作。此外还要考虑并发访问的问题如果多个驱动同时操作同一个寄存器可能会引发竞争条件或者数据不一致的问题需要进行同步或者互斥操作。 以点亮一盏灯为例控制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) | 128; //操作GPIOXOUT寄存器控制引脚电平 *(red_base1) | 128; //操作GPIOXOUTENB寄存器设置为输出模式 *(red_base9) ~(324); //操作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) ~(128); //操作寄存器*(red_base1) | 128;*(red_base9) ~(324);return 0;
}
static void __exit hello_exit(void)
{*(red_base) | (128); //还原LED状态iounmap(red_base); //取消映射
}
module_init(hello_init); //入口
module_exit(hello_exit); //出口
MODULE_LICENSE(GPL); //许可证