IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【linux驱动开发】-字符设备驱动基础(二) -> 正文阅读

[嵌入式]【linux驱动开发】-字符设备驱动基础(二)

1.驱动中如何操控硬件

硬件操作的接口是寄存器,那么想要一个硬件工作,那就操作他的寄存器就可以了!

裸机与操作系统中操作硬件的不同

(1)裸机中操作硬件,直接操作的是寄存器的物理地址;习惯用函数指针操作寄存器的方法

(2)操作系统中操作硬件,操作的是寄存器物理地址在内核中映射的虚拟地址。内核中习惯用封装好的io读写函数来操作寄存器,已实现最大程度的可以执行。

2.内核的虚拟地址的映射方法

? ? ? 由上一个标题中我们知道,在操作系统中,我们操作硬件用到的地址是操作寄存器在内核中的虚拟地址!

为什么用虚拟地址映射

? ? ? ?因为虚拟地址是有MMU(内存管理单元)控制的,当操作系统没有启动的时候,所有的地址都是物理地址,当操作系统一旦启动,MMU启动,所有的物理地址都被映射成了虚拟地址!

映射方法以及区别

静态映射:系统开机自动建立、执行效率高,类似于C语言中的全局变量,坏处:内核移植时以代码的形式硬编码,如果要修改必须改源代码后重新编译内核,在内核启动时建立静态映射表,到内核关机时销毁,中间一直有效,始终占用虚拟地址空间。(对于移植好的内核,你用不用他都在那里)

动态映射:驱动程序根据需要随时动态的建立映射、使用、销毁映射,映射是短期的,相当于C中的malloc.

对于静态映射和动态映射,不管使用哪一个硬件进行工作,这两个映射方式都可以选,是一个双向通道,并不相悖!

3.使用静态映射的方式操作LED

?对于不同的SOC的平台,寻找静态映射表的步骤不通,具体如下:

不同内核版本的静态映射表的位置、文件名可能不同;

不同Soc静态映射表位置、文件名可能不同;

所谓的映射表其实就是头文件中的宏定义;

如何查找某个硬件的虚拟地址

(1)主映射表

? ? ? ?也就是Soc各个模块(硬件)的基地址的虚拟地址,是用宏定义的!CPU在安排寄存器地址时不是随意乱序分布的,而是按照模块区分的。每一个模块内部的很多寄存器的地址是连续的,所以内核在定义寄存器地址时先找到基地址,然后再用基地址+偏移量来找到具体的一个寄存器。

(2)虚拟地址基地址??

? ?所有端口的虚拟地址=虚拟地址基地址+偏移量(主映射表)

? ?eg: GPIO=0xfd000000+0x00500000;

(3)GPIO相关的主映射表

? ?GPIO又细分A\B\C\D....所以每个单位又细分地址;

? ?eg:GPIOJ0=0xfd000000+0x00500000+0x240=0xfd500240

(4)GPIO的具体寄存器定义?

? 例如:要操作LED,则要操作其对应的寄存器,GPIOJ0_con物理地址是0xe020_0240,其所对应的? ? 虚拟地址为0xfd500240。

?编写驱动进行测试

? ? ? ? 在驱动程序中,先增加以下的宏定义,然后在装载以及卸载函数里,分别增加以下语句。实验现象就是,当加载驱动时灯亮,当卸载驱动时灯灭!

#define GPIOCON S5pv210_GPIOCON
#define GPIODAT S5pv210_GPIODAT
#define rGPIOCON *((volatile unsigned int *)GPIOCON)
#define rGPIODAT *((volatile unsigned int *)GPIODAT)

/*然后在装载以及卸载模块的函数里增加以下灯的操作*/

/*在装载函数里写下面函数*/

rGPIOCON=0x11111111;
rGPIODAT=((0<<3)|(0<<4)|(0<<5));

/*在卸载函数里写下面函数*/
rGPIODAT=((1<<3)|(1<<4)|(1<<5));

优化驱动进行测试

? ? ? ? 上面的测试虽然也是有效果的,但是我们不可能一装载模块灯就亮,一卸载模块灯就灭,真正的硬件程序读取控制应该有应用层的函数去执行!我们编写应用程序,然后利用上一章节读取函数就行控制灯变化!

在应用程序中把读函数改为:

write(fd,"on",2);
sleep(2);
write(fd,"off",3);

在驱动中加入以下判断操作的函数:

/*对rGPIOCON的操作移植到open函数中,也就是当应用层打开这个驱动文件的时候,就执行以下代码*/

rGPIOCON=0x11111111;

/*以下代码加入到内核的写函数中,也就是从应用层读取数据到内核之后*/
if(!strcmp(kbuf,"on"))
{
  rGPIODAT=((0<<3)|(0<<4)|(0<<5));
}
else if(!strcmp(kbuf,"off"))
{
  rGPIODAT=((1<<3)|(1<<4)|(1<<5));
}

4.动态映射操作LED

?建立动态映射的步骤

? request_mem_region:向内核申请(报告)需要映射的内存资源。

? ioremap :真正实现映射,传给他一个物理地址,他给你映射返回一个虚拟地址。

?销毁动态映射

? iounmap

? release_mem_region

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:22:30  更:2022-08-19 19:25:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:33:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码